寻找真正的入口(OEP)--广义ESP定律

  1.前言

  略……

  2.准备知识

  在我们开始讨论ESP定律的前我先给你讲解些简单汇编知识

  1.call

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

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

00401029  . E8DA240A00  call004A3508
0040102E  . 5A      popedx
  在执行了00401029以后会将0040102E压入堆栈然后JMP到004A3508地址处!

  2.RET

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

  这个就完成了过程在这里关键地方是:如果我们要返回父则当我们在堆栈中进行堆栈操作时候定要保证在RET这条指令的前ESP指向是我们压入栈中地址这也就是著名“堆栈平衡”原理!

  3.狭义ESP定律

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

  让我们来到入口处看看吧!

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

EAX00000000
ECX0012FFB0
EDX7FFE0304
EBX7FFDF000
ESP0012FFC4
EBP0012FFF0
ESI77F51778ntdll.77F51778
EDI77F517E6ntdll.77F517E6
EIP0040EC90note-upx.<ModuleEntryPo>
C0 ES002332bit0(FFFFFFFF)
P1 CS001B32bit0(FFFFFFFF)
A0 SS002332bit0(FFFFFFFF)
Z0 DS002332bit0(FFFFFFFF)
S1 FS003832bit7FFDE000(FFF)
T0 GS0000NULL
D0
O0 LastErrERROR_MOD_NOT_FOUND(0000007E)
  2.这个是UPX壳JMP到OEP后寄存器值!

EAX00000000
ECX0012FFB0
EDX7FFE0304
EBX7FFDF000
ESP0012FFC4
EBP0012FFF0
ESI77F51778ntdll.77F51778
EDI77F517E6ntdll.77F517E6
EIP004010CCnote-upx.004010CC
C0 ES002332bit0(FFFFFFFF)
P1 CS001B32bit0(FFFFFFFF)
A0 SS002332bit0(FFFFFFFF)
Z1 DS002332bit0(FFFFFFFF)
S0 FS003832bit7FFDE000(FFF)
T0 GS0000NULL
D0
O0 LastErrERROR_MOD_NOT_FOUND(0000007E)
  呵呵~是不是除了EIP区别以外其他都样啊!

  为什么会这样呢?

  我们来看看UPX行:

0040EC90n> 60       pushad   //****注意这里*****
0040EC91  BE15B04000   movesi,note-upx.0040B015
  PUSHAD就是把所有寄存器压栈!我们在到壳最后看看:

0040EE0F  61       popad   //****注意这里*****
0040EE10 -E9B722FFFF   jmpnote-upx.004010CC //JMP到OEP
  POP就是将所有寄存器出栈!

  而当我们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
  所以这个时候在教程上面就告诉我们对ESP0012FFA4下硬件访问断点也就是说当要访问这些堆栈从而恢复原来寄存器准备跳向苦苦寻觅OEP时候OD帮助我们中断下来

  于是我们停在0040EE10这行!

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

  4.广义ESP定律

  很多人看完了教程就会问:ESP定律是不是就是0012FFA4ESP定律适用范围是不是只能是压缩壳!

  我回答是:NO!

  看完了上面你就知道你如果用0012FFA8也是可以ESP定律不仅用于压缩壳他也可以用于加密壳!!!

  首先告诉你条经验也是事实---当PE文件运行开始时候也就是进入壳行代码时候寄存器值总是上面那些值不信你自己去试试!而当到达OEP后绝大多都第句都是压栈!(除了BC编写BC般是在下面几句压栈)

  现在根据上面ESP原理我们知道多数壳在运行到OEP时候ESP=0012FFC4这就是说句是对0012FFC0进行写入操作!

  最后我们得到了广义ESP定律对只要在0012FFC0下硬件写入断点我们就能停在OEP第 2句处!!

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

  载入OD后来到这里:

0040D042N> B800D04000   moveax,Notepad.0040D000//停在这里
0040D047  684C584000   pushNotepad.0040584C
0040D04C  64:FF3500000000pushdwordptrfs:[0]  //第次硬件中断F9
0040D053  64:892500000000movdwordptrfs:[0],esp
0040D05A  66:9C      pushfw
0040D05C  60       pushad
0040D05D  50       pusheax
  直接对0012FFC0下硬件写入断点F9运行(注意硬件中断)

  在0040D04C第次硬件中断F9继续!

0040D135  A4       movsptres:[edi],ptrds:[esi]//访问异常不管他sht+F9继续
0040D136  33C9      xorecx,ecx
0040D138  83FB00     cmpebx,0
0040D13B ^7EA4      jleNotepad.0040D0E1
  第 2次硬件中断

004058B5   64      db64                //断在这里
004058B6   89      db89
004058B7   1D      db1D
004058B8   00      db00
004058B9   00      db00
  这里也不是F9继续!

004010CC /. 55      pushebp
004010CD |. 8BEC     movebp,esp //断在这里哈哈到了!(如果发现有花指令用ctrl+A分析下就能显示出来)
004010CF |. 83EC44    subesp,44
004010D2 |. 56      pushesi
  快吧!还不过瘾在来个例子

  脱壳进阶第 2篇

  如果按上面思路方法断不下来直接运行了!没什么我们在用另种思路方法!

  载入后停在这里用插件把OD隐藏!

0040DBD6N>^E925E4FFFF   jmpNote_tEl.0040C000         //停在这里
0040DBDB  0000      addptrds:[eax],al
0040DBDD  0038      addptrds:[eax],bh
0040DBDF  A4       movsptres:[edi],ptrds:[esi]
0040DBE0  54       pushesp
  F9运行然后用SHIFT+F9跳过异常来到这里:

0040D817 ^73DC      jnbNote_tEl.0040D7F5   //到这里
0040D819  CD2064678F06  vxdcall68F6764
0040D81F  0000      addptrds:[eax],al
0040D821  58       popeax
  在这里对0012FFC0下硬件写入断点!(命令行里键入HW12FFC0)SHIFT+F9跳过异常就来到OEP第 2行处:(用CTRL+A分析下)

004010CC /. 55      pushebp
004010CD |. 8BEC     movebp,esp           //断在这里
004010CF |. 83EC44    subesp,44
004010D2 |. 56      pushesi
004010D3 |. FF15E4634000 calldwordptrds:[4063E4]
004010D9 |. 8BF0     movesi,eax
004010DB |. 8A00     moval,ptrds:[eax]
004010DD |. 3C22     cmpal,22
  就这样我们轻松搞定了两个加密壳找OEP问题!

  5.整理总结

  现在我们可以轻松回答些问题了

  1.ESP定律原理是什么?

  堆栈平衡原理

  2.ESP定律适用范围是什么?

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

  3.是不是只能下断12FFA4访问断点?

  当然不是那只是ESP定律个体现我们运用是ESP定律原理而不应该是他具体数值不能说12FFA4或者12FFC0就是ESP定律他们只是ESP定律个应用罢了!

  4.对于STOLENCODE我们如何办?

  哈哈这正是寻找STOLENCODE最好办法!当我们断下时正好断在了壳处理STOLENCODE地方在F8会就到OEP了!

  6.后话

  以上思路方法原理都是我自己整理总结自己经验如果有什么不对地方有什么没解释清楚地方还请海涵!但是如果觉得我很厉害那就大可不必ESP定律也是别人教我不是我第个提出来!我只是个比你们早飞菜鸟罢了^-^

  看了上面文字希望能对你在寻找OEP时候有帮助但是别忘了句话:菜鸟认为找OEP很难高手认为修复才是最难!好了篇应该写IAT修复原理了!让我们共同努力吧!

Tags: 

延伸阅读

最新评论

发表评论