词条 | esp定律 |
释义 | call这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。 call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。例如: 00401029 . E8 DA240A00 call 004A3508 0040102E . 5A pop edx 在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处! RET与call对应的就是RET了。对于RET我们可以这样来理解:1.将当前的ESP中指向的地址出栈;2.JMP到这个地址。 堆栈平衡原理如果要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址。 狭义ESP定律ESP定律的原理就是“堆栈平衡”原理。 1.这个是加了UPX壳的入口时各个寄存器的值! EAX 00000000 ECX 0012FFB0 EDX 7FFE0304 EBX 7FFDF000 ESP 0012FFC4 EBP 0012FFF0 ESI 77F51778 ntdll.77F51778 EDI 77F517E6 ntdll.77F517E6 EIP 0040EC90 note-upx.<ModuleEntryPoint> C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 0 DS 0023 32bit 0(FFFFFFFF) S 1 FS 0038 32bit 7FFDE000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E) 2.这个是UPX壳JMP到OEP后的寄存器的值! EAX 00000000 ECX 0012FFB0 EDX 7FFE0304 EBX 7FFDF000 ESP 0012FFC4 EBP 0012FFF0 ESI 77F51778 ntdll.77F51778 EDI 77F517E6 ntdll.77F517E6 EIP 004010CC note-upx.004010CC C 0 ES 0023 32bit 0(FFFFFFFF) P 1 CS 001B 32bit 0(FFFFFFFF) A 0 SS 0023 32bit 0(FFFFFFFF) Z 1 DS 0023 32bit 0(FFFFFFFF) S 0 FS 0038 32bit 7FFDE000(FFF) T 0 GS 0000 NULL D 0 O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E) 以上数据可看出除了EIP不同以外,其他都一模一样,现在我们来看看UPX的壳的第一行: 0040EC90 n> 60 pushad //****注意这里***** 0040EC91 BE 15B04000 mov esi,note-upx.0040B015 PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看: 0040EE0F 61 popad //****注意这里***** 0040EE10 - E9 B722FFFF jmp note-upx.004010CC //JMP到OEP POPAD就是将所有寄存器出栈! 而当我们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这一行! 总结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理,让ESP执行到OEP的时候,使ESP=0012FFC4。 广义ESP定律对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处!! 下面我们来举个例子,就脱壳进阶第一篇吧! 载入OD后,来到这里: 0040D042 N> B8 00D04000 mov eax,Notepad.0040D000 //停在这里 0040D047 68 4C584000 push Notepad.0040584C 0040D04C 64:FF35 00000000 push dword ptr fs:[0] //第一次硬件中断,F9 0040D053 64:8925 00000000 mov dword ptr fs:[0],esp 0040D05A 66:9C pushfw 0040D05C 60 pushad 0040D05D 50 push eax 直接对0012FFC0下硬件写入断点,F9运行。(注意硬件中断) 在0040D04C第一次硬件中断,F9继续! 0040D135 A4 movs byte ptr es:[edi],byte ptr ds:[esi] //访问异常,不管他 shift+F9继续 0040D136 33C9 xor ecx,ecx 0040D138 83FB 00 cmp ebx,0 0040D13B ^ 7E A4 jle short Notepad.0040D0E1 第二次硬件中断。 004058B5 64 db 64 //断在这里 004058B6 89 db 89 004058B7 1D db 1D 004058B8 00 db 00 004058B9 00 db 00 这里也不是,F9继续! 004010CC /. 55 push ebp 004010CD |. 8BEC mov ebp,esp //断在这里,到了!(如果发现有花指令,用ctrl+A分析一下就能显示出来) 004010CF |. 83EC 44 sub esp,44 004010D2 |. 56 push esi 适用范围几乎全部的压缩壳,部分加密壳。只要是在JMP到OEP后,ESP=0012FFC4的壳,理论上我们都可以使用。但是在何时下断点避开校验,何时下断OD才能断下来,这还需要多多总结和多多积累。 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。