ESP定律

ESP定律

目录导航

call

这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。

call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。例如:

00401029.E8DA240A00call004A3508

0040102E.5Apopedx

在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处!

RET

与call对应的就是RET了。对于RET我们可以这样来理解:1.将当前的ESP中指向的地址出栈;2.JMP到这个地址。

堆栈平衡原理

如果要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址。

狭义ESP定律

ESP定律的原理就是“堆栈平衡”原理。

1.这个是加了UPX壳的入口时各个寄存器的值!

EAX00000000

ECX0012FFB0

EDX7FFE0304

EBX7FFDF000

ESP0012FFC4

EBP0012FFF0

ESI77F51778ntdll.77F51778

EDI77F517E6ntdll.77F517E6

EIP 0040EC90 note-upx.<ModuleEntryPoint>

C0ES002332bit0(FFFFFFFF)

P1CS001B32bit0(FFFFFFFF)

A0SS002332bit0(FFFFFFFF)

Z0DS002332bit0(FFFFFFFF)

S1FS003832bit7FFDE000(FFF)

T 0 GS 0000 NULL

D0

O0LastErrERROR_MOD_NOT_FOUND(0000007E)

2.这个是UPX壳JMP到OEP后的寄存器的值!

EAX00000000

ECX0012FFB0

EDX7FFE0304

EBX7FFDF000

ESP0012FFC4

EBP0012FFF0

ESI77F51778ntdll.77F51778

EDI77F517E6ntdll.77F517E6

EIP004010CCnote-upx.004010CC

C0ES002332bit0(FFFFFFFF)

P1CS001B32bit0(FFFFFFFF)

A0SS002332bit0(FFFFFFFF)

Z1DS002332bit0(FFFFFFFF)

S0FS003832bit7FFDE000(FFF)

T0GS0000NULL

D0

O0LastErrERROR_MOD_NOT_FOUND(0000007E)

以上数据可看出除了EIP不同以外,其他都一模一样,现在我们来看看UPX的壳的第一行:

0040EC90n>60pushad//****注意这里*****

0040EC91BE15B04000movesi,note-upx.0040B015

PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看:

0040EE0F61popad//****注意这里*****

0040EE10-E9B722FFFFjmpnote-upx.004010CC//JMP到OEP

POP就是将所有寄存器出栈!

而当我们PUSHAD的时候,ESP将寄存器压入了0012FFC0--0012FFA4的堆栈中!如下:

0012FFA477F517E6返回到ntdll.77F517E6来自ntdll.77F78C4E//EDI

0012FFA877F51778返回到ntdll.77F51778来自ntdll.77F517B5//ESI

0012FFAC0012FFF0//EBP

0012FFB00012FFC4//ESP

0012FFB47FFDF000//EBX

0012FFB87FFE0304//EDX

0012FFBC0012FFB0//ECX

0012FFC000000000//EAX

对ESP的0012FFA4下硬件访问断点。也就是说当程序要访问这些堆栈,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。

于是我们停在0040EE10这一行!

总结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理,让ESP执行到OEP的时候,使ESP=0012FFC4。

广义ESP定律

对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处!!

下面我们来举个例子,就脱壳进阶第一篇吧!

载入OD后,来到这里:

0040D042 N> B8 00D04000 mov eax,Notepad.0040D000 //停在这里

0040D047684C584000pushNotepad.0040584C

0040D04C64:FF3500000000pushdwordptrfs:[0]//第一次硬件中断,F9

0040D05364:892500000000movdwordptrfs:[0],esp

0040D05A66:9Cpushfw

0040D05C60pushad

0040D05D50pusheax

直接对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^7EA4jleshortNotepad.0040D0E1

第二次硬件中断。

004058B564db64//断在这里

004058B689db89

004058B71Ddb1D

004058B800db00

004058B900db00

这里也不是,F9继续!

004010CC/.55pushebp

004010CD |. 8BEC mov ebp,esp //断在这里,到了!(如果发现有花指令,用ctrl+A分析一下就能显示出来)

004010CF|.83EC44subesp,44

004010D2|.56pushesi

适用范围

几乎全部的压缩壳,部分加密壳。只要是在JMP到OEP后,ESP=0012FFC4的壳,理论上我们都可以使用。但是在何时下断点避开校验,何时下断OD才能断下来,这还需要多多总结和多多积累。

相关百科
返回顶部
产品求购 求购