游戏的call
- MessageBoxA call函数
OD打开winmine.exe程序后crl+g查找MessageBoxA,即可到达MessageBoxA call地址,我们用代码注入工具测试(详见《注入工具学习笔记》),无误。
//话柄(窗口指针),消息文本(字符串的内存首地址),标题(字符串的内存首地址),消息类型(error/warning/ok)
int MessageBox{
__in HWND hWnd,
__in LPSTSTR lpText,
__in LPCTSTR lpCaption,
__in UNIT uType
}
- windows 窗口类函数
//话柄(窗口指针),消息类型,菜单消息参数,窗口消息函数
LRESULT CALLBACK WindowProc{
__in HWND hwnd,
__in UINT uMsg,
__in WPARAM wParam,
__in LPARAM lParam
}
//当点击菜单时,WindowProc会被系统调用,uMsg=WM_COMMAND,wParam赋值为对应菜单ID(重点分析)
-
启动:OD打开winmine.exe程序,运行,按上面w按钮,刷新,右击根窗口,跟随ClassProc,即可找到WindowProc地址,本例程测试得到的地址是01001BD2
-
希望:我们希望做到在WindowProc函数处下条件断点:uMsg==WM_COMMAND,以过滤掉不必要的消息
-
观察:因exe程序不认识uMsg,故观察反汇编有mov edx,dword ptr ss:[ebp+0xC],顺便留意右上方寄存器区edx的值是00000111
-
加点:在下一行mov ecx,dword ptr ss:[ebp+0x14]右击,断点,条件断点,edx==WM_COMMAND
-
测试:按雷框不触发断点,按菜单切换初/中/高级会触发断点,实现条件中断
-
双击mov edx,[arg,2],看到mov edx,dword ptr ss:[ebp+0xC]
-
右下角堆栈地址右击,地址,相对于EBP,看到EBP+C的值是00000111
-
EBP+8,+C,+10,+14分别就是local.1,2,3,4,注意这里local是顺序调出,因为我们知道函数调用前压栈是倒序压入的,本例程测试得到的信息如下:
EBP+8 >|00230A22
EBP+C >|00000111
EBP+10 >|00000209
EBP+14 >|00000000 -
读出EBP+10的值,就是当前菜单项的ID,多次测试可以得到:
开局:0x1FE
初级:0x209
中级:0x20A
高级:0x20B