1 Win32应用程序入口识别
思路:根据WinMain的四个参数,由调用顺序,知道最后压栈的是hInstance句柄(也就是WinMain函数的第一个参数,其值等于ImageBase),根据反汇编,则判断压栈参数是GetModuleHandle函数的返回值,即可找到Win32应用入口。
004011AC |> \50 push eax
004011AD |. FF75 9C push [local.25]
004011B0 |. 56 push esi
004011B1 |. 56 push esi ; /pModule
004011B2 |. FF15 18504000 call dword ptr ds:[<&KERNEL32.GetModuleH> ; \GetModuleHandleA
004011B8 |. 50 push eax
004011B9 |. E8 12FFFFFF call Win32_Re.004010D0 ;即:这是Win32程序入口
2 ESP寻址的特点
程序入口处,esp+4一般是函数的第一个参数。
ESP寻址会受到push和pop的影响。
3 窗口回调函数的定位
思路:根据RegisterClass()函数的参数,找到WNDCLASS结构体的lpfnWndProc参数,从而找到了回调函数WindowProc。
4 具体事件的处理的定位
思路:在OD的设置断点中,右键设置条件断点,可根据相应的条件断下来。
5 按钮是什么
按钮的本质是窗口
void CreateButton(HWND hwnd)
{
HWND hwndPushButton;
HWND hwndCheckBox;
HWND hwndRadio;
hwndPushButton = CreateWindow (
TEXT("button"),
TEXT("普通按钮"),
//WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_DEFPUSHBUTTON,
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_DEFPUSHBUTTON,
10, 10,
80, 20,
hwnd,
(HMENU)1001, //子窗口ID
hAppInstance,
NULL);
hwndCheckBox = CreateWindow (
TEXT("button"),
TEXT("复选框"),
//WS_CHILD | WS_VISIBLE | BS_CHECKBOX | BS_AUTOCHECKBOX,
WS_CHILD | WS_VISIBLE | BS_CHECKBOX |BS_AUTOCHECKBOX ,
10, 40,
80, 20,
hwnd,
(HMENU)1002, //子窗口ID
hAppInstance,
NULL);
hwndRadio = CreateWindow (
TEXT("button"),
TEXT("单选按钮"),
//WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON | BS_AUTORADIOBUTTON,
WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON ,
10, 70,
80, 20,
hwnd,
(HMENU)1003, //子窗口ID
hAppInstance,
NULL);
}
6 按钮事件的处理
1、按钮是一种特殊的窗体,并不需要提供单独的窗口回调函数.
2、当按钮有事件产生时,会给父窗口消息处理程序发送一个WM_COMMAND消息
按钮--------------->系统提供WinProc---------------------->父窗口的WinProc
单击按钮 转换WM_COMMAND
//代码:
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 1001:
MessageBox(hwnd,"Hello Button 1","Demo",MB_OK);
return 0;
case 1002:
MessageBox(hwnd,"Hello Button 2","Demo",MB_OK);
return 0;
case 1003:
MessageBox(hwnd,"Hello Button 3","Demo",MB_OK);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
7 消息堆栈
7.1 回调函数的结构
LRESULT CALLBACK WindowProc(
IN HWND hwnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam
);
7.2 回调函数的堆栈
8 按钮事件处理逻辑定位
在OD中设置条件断点
[ESP+8]==WM_COMMAND && [ESP+0xC]==0x3EB