4.菜单CALL
CALL是汇编中的一个指令,CPU执行这条指令会执行2个动作:(1)压入EIP入栈 (2)跳转到后面的地址。跟RETN指令配合就实现了汇编中子程序的作用,通常我们说的写CALL就是调用游戏中已经存在的功能子程序。
CALL指令具体原理请参阅汇编语言相关书籍。
下面来看下,扫雷游戏中菜单CALL(初级、中级、高级、自定义),并使用代码注入器,注入汇编代码来模拟一次菜单选择的调用。
用OllyDBG打开并运行扫雷游戏,选择菜单“查看”->“窗口”
(窗口用于列出所有属于被调试程序窗口及其窗口相关的重要参数)
在打开的Windows窗口上鼠标右键->刷新
在窗口过程上右键->跟随ClassProc,跟随一下回调函数
OD窗口跳转到地址0x01001BC9处
当访问某一个菜单的时候,都会向窗口的回调函数发送一个WM_COMMAND消息。
根据这个条件,来设置一个条件断点。
在设置条件断点之前,假定参数为WinProc(hWnd, msg, wParam, lParam)
(为了能在消息上设置断点,OllyDbg 创建了一个名为“<WinProc>”的特殊条件记录断点)
设置后在地址0x01001BC9的注释处变为 “解码为<WinProc>”
在该位置上设置条件断点 WM_COMMAND==msg
条件断点是一个带有条件表达式的普通INT3断点。断点为红色。
此时,访问扫雷程序的菜单,将会在断点处断下来,根据OD中堆栈窗口
找到CALL及相关参数如下图所示:
可以通过这个消息来控制菜单(或直接调用这个0x01001BC9的这个CALL)
点击不同的菜单,获取相关数据如下:
初级 | 中级 | 高级 | 自定义 | |
hWnd | 001C01B4 | |||
msg | 00000111 | |||
Notify | 00000209 | 0000020A | 0000020B | 0000020C |
hControl | 00000000 |
备注:消息处理函数WindowProc的原型,见WindowsAPI函数原型一节。
代码注入器测试
先加载扫雷游戏,选择菜单-初级,以便于观察窗口的变化。
在代码注入器窗口中写入以下汇编代码后,点击“注入远程代码”按钮,可以看到扫雷窗口变为中级。
push 0
push 0000020A
push 00000111
push 001C01B4
CALL 0x01001BC9