本帖最后由 zf616545 于 2014-10-2 22:14 编辑ESP定律算是我们在脱壳当中最常使用的方法之一,也特别适合像我一样的新手!而今天文章说的是ESP脱壳的原理和分析!只有知道原理了,我们的技术才能走得列远! 一.准备知识 在我们开始讨论ESP定律之前,我先给你讲解一下一些简单的汇编知识。 1.call 这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。call真正的意义是什么呢?我们可以这样来理解: 1.向堆栈中压入下一行程序的地址; 2.JMP到call的子程序地址处。 例如: 代码: 00401029.E8 DA240A00 call 004A3508 0040102E.5A pop edx 在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处! 2.RETN 与call对应的就是RETN了。对于RETN我们可以这样来理解: 1.将当前的ESP中指向的地址出栈; 2.JMP到这个地址。 这个就完成了一次调用子程序的过程。在这里关键的地方是:如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候, 一定要保证在RETN这条指令之前,ESP指向的是我们压入栈中的地址。这也就是著名的“堆栈平衡”原理! 3.狭义ESP定律ESP定律的原理就是“堆栈平衡”原理。 让我们来到程序的入口处看看吧! 1.这个是加了ASPACK壳的入口时各个寄存器的值! 代码: EAX 00000000 ECX 0012FFB0 EDX 7FFE0304 //堆栈值 EBX 7FFDF000 //堆栈值 ESP 0012FFC4 EBP 0012FFF0 ESI 77F57D70 ntdll.77F57D70 EDI 77F944A8 ntdll.77F944A8 EIP 0040D000 ASPACK.<ModuleEntryPoint> 2.这个是ASPACK壳JMP到OEP后的寄存器的值! 代码: EAX 004010CC ASPACK.004010CC ECX 0012FFB0 EDX 7FFE0304 //堆栈值 EBX 7FFDF000 //堆栈值 ESP 0012FFC4 EBP 0012FFF0 ESI 77F57D70 ntdll.77F57D70 EDI 77F944A8 ntdll.77F944A8 EIP 004010CC ASPACK.004010CC 呵呵~是不是除了EIP不同以外,eax保存当前OEP值,其他都一模一样啊! 为什么会这样呢?我们来看看 0040D000 A> 60 pushad //注意这里ESP=0012FFC4 0040D001 E8 00000000 call ASPACK.0040D006 //ESP=0012FFA4 PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看: 代码: 0040D558 61 popad //ESP=0012FFA4 0040D559 75 08 jnz short ASPACK.0040D563 //注意这里ESP=0012FFC4 也就是说当我们对ESP的0012FFA4下硬件访问断点之后。当程序要通过堆栈访问这些值,从而恢复原来寄存器的值, 准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。 小结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理。因为大家对ESP理解各有异同,但是,大同小异!一般理解可以为: 1、在命令行下断hr esp-4(此时的ESP就是OD载入后当前显示的值) 2、hr ESP(关键标志下一行代码所指示的ESP值(单步通过)) |
脱壳_esp定律原理
最新推荐文章于 2024-03-15 19:29:17 发布