如何为按钮单击设置断点?

逆向工程 视窗 ollydbg
2021-07-09 02:06:08

我试图找出按钮的作用,所以我想设置一个断点来捕获按钮单击事件。那可能吗?

有什么工具或技巧可以帮助做到这一点?

2个回答

这在很大程度上取决于他们使用什么框架来进行窗口化。它可以是MFCWPFWinFormsWTLQTwxWidgets、纯Windows API有很多框架,它们都以不同的方式处理消息的最终路由。

我将回答直接构建在 Windows API 之上或直接使用 Windows API 的情况的问题。除了最外层的窗口,WPF 不使用 Windows API 窗口系统。

最初,程序注册了一个函数,用于处理特定窗口的消息。这可以使用RegisterClassRegisterClassEx函数来完成负责处理发送到窗口的消息的函数是传递给这些函数的结构的 lpfnWndProc 成员。这称为窗口过程。

当按下按钮时,Windows将消息(在本例中为WM_COMMAND)推送到线程消息队列中。然后使用GetMessagePeekMessage获取此消息 一些消息使用捷径,当您调用 GetMessage 时会导致直接调用窗口过程,而一些消息仅在应用程序调用DispatchMessage时导致调用窗口过程如果您正在处理一个对话框,消息将通过调用IsDialogMessage来处理

现在我们已经了解了它在幕后如何工作的一些背景知识,OllyDbg 实际上有一个处理此类事情的助手。您可以简单地打开 View->Windows 对话框项。右键单击要捕获按钮按下的窗口,在 classproc 上选择消息断点,从消息下拉列表中选择命令和通知或选择 WM_COMMAND 消息。现在,无论何时单击该按钮,您都会中断为该窗口注册的应用程序的窗口过程。您仍然需要跟踪代码,以便您可以找到检查消息类型然后处理消息的代码。从现在开始,它将根据使用的框架类型而有所不同。

在 ollydbg 中打开 calc.exec:\ollydbg.exe calc.exe
Ctrl + G and type GetMessageW
pressF2设置断点并按F9直到它中断
当它被破坏时 press ctrl+f9to run until return
press 在表达式编辑框中shift+f4设置条件日志断点
[esp+4]
表达式select pointer to MSG structure (UNICODE)
设置的解码值中键入单选按钮 pause tonever
将单选按钮日志表达式设置为Always
点击ok
现在查看所有处理的消息的日志窗口
细化您的条件断点以仅处理您要检查的情况,例如此条件将仅记录 mouseup 和 wm_char 消息

Breakpoints, item 1
 Address=7E41920E
 Module=USER32
 Active=Log when [[esp+4]+4] == WM_KEYDOWN || [[esp+4]+4] == WM_LBUTTONUP
 Disassembly=RETN    10

就像下面发布的结果一样,请注意每个按钮的 hwnd,您可以使用特定的 Window Handle hWnd 2e048a 等将其细化为多个条件

\Log data
Message
COND: 0007FEE8 WM_LBUTTONUP hw = 2E048A ("C") Keys = 0 X = 57. Y = 14.
COND: 0007FEE8 WM_LBUTTONUP hw = 10053E ("And") Keys = 0 X = 22. Y = 10.
COND: 0007FEE8 WM_LBUTTONUP hw = 200404 ("Xor") Keys = 0 X = 22. Y = 18.
COND: 0007FEE8 WM_LBUTTONUP hw = 270402 ("M+") Keys = 0 X = 22. Y = 11.
COND: 0007FEE8 WM_LBUTTONUP hw = D036A ("Sta") Keys = 0 X = 27. Y = 15.
COND: 0007FEE8 WM_LBUTTONUP hw = 1B04F0 ("x^2") Keys = 0 X = 18. Y = 17.
COND: 0007FEE8 WM_KEYDOWN hw = 1B04F0 ("x^2") Key = 35  ('5') KeyData = 60001
COND: 0007FEE8 WM_KEYDOWN hw = 4303EC (class="Edit") Key = 42  ('B') KeyData = 300001
COND: 0007FEE8 WM_KEYDOWN hw = 4303EC (class="Edit") Key = 41  ('A') KeyData = 1E0001

要在windbg 中模拟相同的内容,请将此命令放入txt 文件并运行windbg(您应该加载skywings sdbgext 扩展以进行详细显示)

bp user32!GetMessageW "pt;gc"
g
bc *
.load sdbgext
bp @eip ".if (poi(poi(esp+4)+4) == 0x202) {!hwnd poi(poi(esp+4));gc } .else {gc}"
g

windbg  -c "$$>a< ......\wtf.txt" calc

Window    00600438
Name      And
Class     Button
WndProc   00000000
Style     WS_OVERLAPPED 
ExStyle   WS_EX_NOPARENTNOTIFY WS_EX_LEFT WS_EX_LTRREADING WS_EX_RIGHTSCROLLBAR 
HInstance 01000000
ParentWnd 00490534
Id        00000056
UserData  00000000
Unicode   TRUE
ThreadId  00000df0
ProcessId 00000f68
Window    00150436
Name      Xor
Class     Button
WndProc   00000000
Style     WS_OVERLAPPED