文章见:
http://www.pediy.com/bbshtml/BBS6/pediy6083.htm
这个地方我有点不明白:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1.call
这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。
call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。例如:
00401029 . E8 DA240A00 call 004A3508
0040102E . 5A pop edx
在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<
这个地方,我一开始有点不明白,怎么是这个样子的?因为在我的理解里面,执行了call 004A3508以后,早不管下面这一行了。怎么可能是他说的“执行了00401029”的call后,又去执行0040102E呢?现在好象有点明白了,不过他的说法有点怪怪的。
应该是在执行00401029的call 004A3508之前,先把执行完这个call之后的下一步的地址先压入堆栈。不然执行完这个call,回来时不知道下一步是哪个地址了?
是不是这个理解?
=======================================
还有这个地方:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>
而当我们PUSHAD的时候,ESP将寄存器压入了0012FFC0--0012FFA4的堆栈中!如下:
0012FFA4 77F517E6 返回到 ntdll.77F517E6 来自 ntdll.77F78C4E //EDI
0012FFA8 77F51778 返回到 ntdll.77F51778 来自 ntdll.77F517B5 //ESI
0012FFAC 0012FFF0 //EBP
0012FFB0 0012FFC4 //ESP
0012FFB4 7FFDF000 //EBX
0012FFB8 7FFE0304 //EDX
0012FFBC 0012FFB0 //ECX
0012FFC0 00000000 //EAX
所以这个时候,在教程上面就告诉我们对ESP的0012FFA4下硬件访问断点。也就是说当程序要访问这些堆栈,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。
于是我们停在0040EE10这一行!
<<<<<<<<<<<<<<<<<<<<<<<<<<
作者的话我有点不解。他的文字中一会儿是0012FFA4,一会儿又是0012FFC4。注意这里A和C的区别。
我的理解:
不按这个ESP定律,反向用PUSHAD和POPAD来分析的话:
应该是先 POPAD,然后是JUMP OEP。
那么,按作者上面写的PUSHAD时各个被压入堆栈的寄存器来看,我记得好象以前学汇编(不好意思,已经忘得差不多了)时,压入堆栈是先把最底下的压入,再压上面的,一个一个压,直接压满。那么,POPAD弹出时,也是从上往下,一个一个弹出。所以最后弹出的是最底下的0012FFC0。
按我的理解,实质上POPAD可能就是一个一个弹出。最后如果分解成几步的话,最后一个是弹出 0012FFC0的那条。
所以,弹完了0012FFC0,下一步就是JUMP OEP。
所以,在OD中用 HW 12FFC0设置断点后,F9执行……
?按我现在的理解,到了断点,应该还没有JMP OEP啊。
看来我理解错了。有谁能指点我一下吗?
我主要搞不明白的是 作者他有没有写错?为什么一会儿说A4,一会儿又说C4?还有,ESP是什么?有什么专门的作用吗?我记得以前学汇编时有一个寄存器叫SP,可能是E+SP->ESP。但ESP是用来做什么的?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)