zl程序教程

您现在的位置是:首页 >  Java

当前栏目

LyScriptTools 调试控制类API接口手册

2023-02-18 16:37:48 时间

LyScriptTools模块中的DebugControl类主要负责控制x64dbg调试器的行为,例如获取或设置寄存器组,执行单步命令等,此类内的方法也是最常用的。

调试类命令总结如下表所示:

DebugControl 类内函数名

函数作用

GetEAX()

获取通用寄存器系列

SetEAX(decimal_value)

设置特定寄存器中的值(十进制)

GetZF()

获取标志寄存器系列

SetZF(decimal_bool)

设置标志寄存器的值(布尔型)

Script_InitDebug(path)

传入文件路径,载入被调试程序

Script_CloseDebug()

终止当前被调试进程

Script_DetachDebug()

让进程脱离当前调试器

Script_RunDebug()

让进程运行起来

Script_ERun()

释放锁并允许程序运行,忽略异常

Script_SeRun()

释放锁并允许程序运行,跳过异常中断

Script_Pause()

暂停调试器运行

Script_StepInto()

步进

Script_EStepInfo()

步进,跳过异常

Script_SeStepInto()

步进,跳过中断

Script_StepOver()

步过到结束

Script_StepOut()

普通步过F8

Script_Skip()

跳过执行

Script_Inc(register)

递增寄存器

Script_Dec(register)

递减寄存器

Script_Add(register,decimal_int)

对寄存器进行add运算

Script_Sub(register,decimal_int)

对寄存器进行sub运算

Script_Mul(register,decimal_int)

对寄存器进行mul乘法

Script_Div(register,decimal_int)

对寄存器进行div除法

Script_And(register,decimal_int)

对寄存器进行and与运算

Script_Or(register,decimal_int)

对寄存器进行or或运算

Script_Xor(register,decimal_int)

对寄存器进行xor或运算

Script_Neg(register,decimal_int)

对寄存器参数进行neg反转

Script_Rol(register,decimal_int)

对寄存器进行rol循环左移

Script_Ror(register,decimal_int)

对寄存器进行ror循环右移

Script_Shl(register,decimal_int)

对寄存器进行shl逻辑左移

Script_Shr(register,decimal_int)

对寄存器进行shr逻辑右移

Script_Sal(register,decimal_int)

对寄存器进行sal算数左移

Script_Sar(register,decimal_int)

对寄存器进行sar算数右移

Script_Not(register,decimal_int)

对寄存器进行not按位取反

Script_Bswap(register,decimal_int)

进行字节交换也就是反转

Script_Push(register_or_value)

对寄存器入栈

Script_Pop(register_or_value)

对寄存器弹出元素

Pause()

内置API暂停

Run()

内置API运行

StepIn()

内置API步入

StepOut()

内置API步过

StepOut()

内置API到结束

Stop()

内置API停止

Wait()

内置API等待

IsDebug()

判断调试器是否在调试

IsRunning()

判断调试器是否在运行

自动控制类主要功能如上表示,其中Script开头的API是调用的脚本命令实现,其他的是API实现,我们以批量自动载入程序为例,演示该类内函数是如何使用的。

import os
import pefile
import time
from LyScript32 import MyDebug
from LyScriptTools32 import Module
from LyScriptTools32 import Disassemble
from LyScriptTools32 import DebugControl

# 得到特定目录下的所有文件,并返回列表
def GetFullFilePaht(path):
    ref = []
    for root,dirs,files in os.walk(str(path)):
        for index in range(0,len(files)):
            ref.append(str(root + "/" + files[index]))
    return ref

if __name__ == "__main__":
    dbg = MyDebug()
    connect_flag = dbg.connect()
    print("连接状态: {}".format(connect_flag))

    # 初始化调试控制器
    debug = DebugControl(dbg)

    # 得到特定目录下的所有文件
    full_path = GetFullFilePaht("d://test/")

    for i in range(0,len(full_path)):
        debug.Script_InitDebug(str(full_path[i]))
        time.sleep(0.3)
        debug.Script_RunDebug()

        time.sleep(0.3)
        local_base = dbg.get_local_base()
        print("当前调试进程: {} 基地址: {}".format(full_path[i],local_base))

        time.sleep(0.3)
        # 关闭调试
        debug.Script_CloseDebug()

    dbg.close()

如果你不使用Script_InitDebug来加载被调试进程,你也可以使用如下方式打开一个文件。

import win32api
import win32gui, win32con
import win32clipboard
import re
import time
from LyScript32 import MyDebug

class cWindow:
    def __init__(self):
        self._hwnd = None

    def SetAsForegroundWindow(self):
        win32gui.SetForegroundWindow(self._hwnd)

    def Maximize(self):
        # 最大化
        win32gui.ShowWindow(self._hwnd, win32con.SW_MAXIMIZE)

    def _window_enum_callback(self, hwnd, regex):
        if self._hwnd is None and re.match(regex, str(win32gui.GetWindowText(hwnd))) is not None:
            self._hwnd = hwnd

    def find_window_regex(self, regex):
        self._hwnd = None
        win32gui.EnumWindows(self._window_enum_callback, regex)

    def hide_always_on_top_windows(self):
        win32gui.EnumWindows(self._window_enum_callback_hide, None)

    def _window_enum_callback_hide(self, hwnd, unused):
        if hwnd != self._hwnd:
            if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) & win32con.WS_EX_TOPMOST:
                className = win32gui.GetClassName(hwnd)
                if not (className == 'Button' or className == 'Shell_TrayWnd'):
                    win32gui.ShowWindow(hwnd, win32con.SW_FORCEMINIMIZE)

    def OpenFile(self,path):
        # 按下F3
        win32api.keybd_event(0x72, 0, 0, 0)
        win32api.keybd_event(0x72, 0, win32con.KEYEVENTF_KEYUP, 0)

        # 打开剪贴板
        win32clipboard.OpenClipboard()
        # 清空剪贴板
        win32clipboard.EmptyClipboard()
        # 设置剪贴板内容
        win32clipboard.SetClipboardData(win32con.CF_UNICODETEXT, path)
        # 获取剪贴板内容
        date = win32clipboard.GetClipboardData()
        print("[*] OpenFile = {}".format(date))
        # 关闭剪贴板
        win32clipboard.CloseClipboard()
        time.sleep(0.2)

        # 按下ctrl+v
        win32api.keybd_event(0x11, 0, 0, 0)
        win32api.keybd_event(0x56, 0, 0, 0)
        win32api.keybd_event(0x56, 0, win32con.KEYEVENTF_KEYUP, 0)
        win32api.keybd_event(0x11, 0, win32con.KEYEVENTF_KEYUP, 0)

        # 按下回车
        win32api.keybd_event(0x0D, 0, 0, 0)
        win32api.keybd_event(0x0D, 0, win32con.KEYEVENTF_KEYUP, 0)

    def deatch(self):
        # 按下Ctrl+Alt+F2
        win32api.keybd_event(0x11, 0, 0, 0)
        win32api.keybd_event(0x12, 0, 0, 0)
        win32api.keybd_event(0x71, 0, 0, 0)
        win32api.keybd_event(0x11, 0, win32con.KEYEVENTF_KEYUP, 0)
        win32api.keybd_event(0x12, 0, win32con.KEYEVENTF_KEYUP, 0)
        win32api.keybd_event(0x71, 0, win32con.KEYEVENTF_KEYUP, 0)

# 打开调试程序
def OpenFile(path):
    regex = ".*x32dbg.*"
    cWindows = cWindow()
    cWindows.find_window_regex(regex)
    cWindows.SetAsForegroundWindow()
    cWindows.SetAsForegroundWindow()
    cWindows.OpenFile(path)

# 关闭调试程序
def DeatchFile():
    regex = ".*x32dbg.*"
    cWindows = cWindow()
    cWindows.find_window_regex(regex)
    cWindows.SetAsForegroundWindow()
    cWindows.SetAsForegroundWindow()
    cWindows.deatch()

# 得到脚本返回值
def GetScriptValue(dbg,script):
    try:
        ref = dbg.run_command_exec("push eax")
        if ref != True:
            return None
        ref = dbg.run_command_exec(f"eax={script}")
        if ref != True:
            return None
        reg = dbg.get_register("eax")
        ref = dbg.run_command_exec("pop eax")
        if ref != True:
            return None
        return reg
    except Exception:
        return None
    return None

if __name__ == "__main__":
    dbg = MyDebug()
    dbg.connect()

    # 批量打开一个列表
    for item in ["D:\Win32Project.exe","D:\Windows Tools\C32ASM\c32asm.exe"]:
        OpenFile(item)
        time.sleep(3)

        for i in range(1,100):
            dbg.set_debug("StepIn")
            time.sleep(0.2)

        eip = dbg.get_register("eip")
        print("eip = > {}".format(hex(eip)))

        time.sleep(3)
        DeatchFile()