在旧版本的LyScript插件中,并没有集成直接打开和关闭进程的功能。然而,在新版本的LyScript中,增加了open_debug()close_debug()这两个方法来处理打开和关闭被调试进程的操作。

  • open_debug()方法用于打开一个磁盘上的可执行文件,该文件将成为调试器的目标程序。通过该方法,可以启动调试会话并与目标程序建立连接。
  • close_debug()方法用于关闭当前调试会话,断开与目标程序的连接,并释放调试器资源。

这些新功能的添加使得LyScript在处理调试操作时更加便捷和灵活,可以直接打开和关闭被调试进程,为调试过程提供了更多的控制和操作选项。

首先来看一下如何在不适用通用调试接口的情况下如何载入一个被调试进程,通过win32api和win32gui模块来操作窗口和键盘,从而实现打开和关闭调试程序的功能。

具体的实现流程如下:

  1. 首先定义了一个cWindow类,用于操作窗口相关的功能。其中包括设置窗口为前台窗口、最大化窗口、根据正则表达式查找窗口、隐藏置顶窗口等方法。
  2. OpenFile函数中,通过正则表达式匹配到调试程序的窗口,并将其设置为前台窗口。然后使用win32clipboard模块来操作剪贴板,将文件路径复制到剪贴板中。接着模拟按下Ctrl+V粘贴文件路径,并按下回车键打开文件。
  3. DeatchFile函数中,同样通过正则表达式匹配到调试程序的窗口,并将其设置为前台窗口。然后模拟按下Ctrl+Alt+F2组合键,将调试程序分离。
  4. 在主程序中,使用OpenFile函数打开指定路径的文件,并在打开后延时3秒,然后使用DeatchFile函数将调试程序分离。通过循环遍历列表中的文件路径,可以实现批量打开和关闭调试程序的操作。

利用win32api和win32gui模块来操作窗口和键盘,即可实现打开和关闭调试程序的功能。

import win32api
import win32gui, win32con
import win32clipboard
import re
import time

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()

if __name__ == "__main__":

    # 批量打开一个列表
    for item in ["C:\Program Files (x86)\Kingsoft\kwifi\dbghelp.dll","C:\Program Files (x86)\Kingsoft\kwifi\keasyipcn.dll"]:
        OpenFile(item)
        time.sleep(3)
        DeatchFile()


新版本的插件中提供了两个函数,使用起来很简单 dbg.open_debug("D:\\Win32Project.exe")只需要指定一个进程即可将其载入到调试器内,当然提醒读者,调试器必须以管理员模式运行。