软件:动态跟踪调试示例(《加密解密第二版》例子)
实现功能:给程序菜单添加一个简单的功能项,只弹出一个MessageBoxA
(当然读者可以以此为基础添加其他功能)
首先PEID查壳,vc++6.0没有壳
这样就相对简单一点,省去了脱壳的麻烦。
我们要实现的功能是弹出一个对话框,那么就要有对话框的标题与内容
标题与内容,我们可以写在rdata段(因为这个段是可读可写的,方便,而且不容易出错)当然也可以写在其他地方,但要保证有可读的属性。
我用十六进制编辑器将标题“注意”写在了48a0的地方,对话框内容“这是增加的消息循环”写在了48b0的地方。
用loadpe查看原输入表并没有MessageBoxA这个函数,那么就需要添加这个函数了,为了简单我是用loadpe添加的这个函数(本来想截个图的,但是还不知道怎么贴进来一个图,所以这次就省了吧,相关添加函数的方法参见其他帖子)
调用的地址是7019(RVA).好了前期的准备工作就已经完成了,下面关键是添加菜单项了
用ResHacker,eXeScope或Visual C++等资源编辑工具在菜单-帮助下面,添加一个关于菜单,ID号是40001(十六进制是9c41)。
添加完资源后就可以添加功能了,当然添加功能首先应该找到消息循环的地方。经过跟踪分析,发现401925是处理菜单的
00401295 > \3D F6030000 CMP EAX,3F6
0040129A . 74 07 JE SHORT TraceMe.004012A3
0040129C . 3D 429C0000 CMP EAX,9C42 ;此处对应"关于(&A)..."菜单选项
004012A1 . 75 1D JNZ SHORT TraceMe.004012C0
004012A3 > 8B9424 000100>MOV EDX,DWORD PTR SS:[ESP+100] ; Cases 3F6,9C42 of switch 0040115E
004012AA . A1 E0544000 MOV EAX,DWORD PTR DS:[4054E0]
004012AF . 6A 00 PUSH 0 ; /lParam = NULL
004012B1 . 68 20104000 PUSH TraceMe.00401020 ; |DlgProc = TraceMe.00401020
004012B6 . 52 PUSH EDX ; |hOwner
004012B7 . 6A 67 PUSH 67 ; |pTemplate = 67
004012B9 . 50 PUSH EAX ; |hInst => NULL
004012BA . FF15 C8404000 CALL DWORD PTR DS:[<&USER32.DialogBoxPar>; \DialogBoxParamA
004012C0 > 5F POP EDI ; Default case of switch 0040115E
004012C1 . 33C0 XOR EAX,EAX
004012C3 . 5E POP ESI
004012C4 . 81C4 F4000000 ADD ESP,0F4
004012CA . C2 1000 RETN 10
刚才增加“关于”资源,应该留意到,程序原来"关于(&A)..."项的ID号是40002,十六进制是9c42,刚好就是原来菜单的关于选项
40129c这个代码意思是,如果单击了"关于(&A)..."按钮,则弹出一个对话框窗体。
我们增加菜单新功能就要在这段代码附近动手脚了。OD载入的时候发现这段代码后面的空白处不足以添加我们的代码,所以我们应该让其跳转到后面一大片空白代码处,这样我们就可以“为所欲为了”
00401295 > \3D F6030000 CMP EAX,3F6
0040129A . E9 81290000 JMP 增加菜单.00403C20
0040129F 90 NOP
004012A0 > 8B9424 000100>MOV EDX,DWORD PTR SS:[ESP+100]
004012A7 . A1 E0544000 MOV EAX,DWORD PTR DS:[4054E0]
004012AC . 90 NOP
004012AD . 90 NOP
004012AE . 90 NOP
这是我修改之后的代码。JMP 00403C20这条指令是无条件更改程序的流程,在403c20处的代码如下
00403C20 >^\0F84 7AD6FFFF JE 增加菜单.004012A0
00403C26 . 3D 429C0000 CMP EAX,9C42
00403C2B .^ 0F84 6FD6FFFF JE 增加菜单.004012A0
00403C31 . 3D 419C0000 CMP EAX,9C41 ;是不是单击了我们增加的关于菜单项
00403C36 .^ 0F85 84D6FFFF JNZ 增加菜单.004012C0
00403C3C . 60 PUSHAD ;注意保护原来的变量
00403C3D . 9C PUSHFD
00403C3E . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
00403C40 . 68 A0484000 PUSH 增加菜单.004048A0 ; |Title = "注意"
00403C45 . 68 B0484000 PUSH 增加菜单.004048B0 ; |Text = "这是增加的消息循环"
00403C4A . 6A 00 PUSH 0 ; |hOwner = NULL
00403C4C . FF15 19704000 CALL DWORD PTR DS:[<&user32.MessageBoxA>>; \MessageBoxA
00403C52 . 9D POPFD ;回复原来的变量
00403C53 . 61 POPAD
00403C54 .^ E9 67D6FFFF JMP 增加菜单.004012C0;跳回原代码处
添加代码时候,一定要注意堆栈的平衡以及寄存器的保护,以防出现异常。一般情况下,如果在OEP前面增加不需要保护标志位,
但此处不行,因为原代码附近有很多的比较跳转指令,所以保护标志位就非常重要了。
好了,增加菜单并实现其功能就完成了,是不是很简单?当然这只是一个很小的例子,如果要实现很复杂的功能,不是那么容易的
。比如,要准确定位消息循环,以及用最少的代码实现预期的功能等等。不过一切复杂的程序都是由许多简单的程序代码实现的,
希望这篇文章给大家以启示
- 标 题:为程序增加菜单新功能
- 作 者:wushaojie
- 时 间:2009-05-02 22:52
- 链 接:http://bbs.pediy.com/showthread.php?t=87738