首页
社区
课程
招聘
如何阻击“ESP定律”?
发表于: 2005-1-21 15:43 9823

如何阻击“ESP定律”?

2005-1-21 15:43
9823

如何阻击“ESP定律”?

作者:jney2
喜欢Crack,也关注加密手段。

首先,感谢kanxue终于推出了我苦苦等待的看雪学院论坛精华6,惊喜中居然还是五周年纪念收藏版。粗略了一下,精华6是分量足,精华多呀!
个人感觉Crack界变化较大的有三:1、Cracker队伍不断壮大,高手不断涌现;2、脱壳日益成为Cracker的必修功课;3、OllyDbg日益成为Cracker的首选调试工具。
OllyDbg,我一直用它!OllyDbg我选择,我喜欢!
其次,我来说一下“ESP定律”。
在五周年纪念收藏版中搜索“ESP定律”即可找到25篇文章,要了解“ESP定律”有3篇文章必看:
1、fly的(论坛里fly的印象给我最深了)《ESP定律 + 壹锅端――另类ACProtect V1.20壳的简便脱壳And修复方法》(2004年2月19日 03:46)。这篇文章首提“ESP定律”,相信老鸟一看就懂。我看了是有一种豁然开朗的感觉,我怎么没想到在我心爱的OllyDbg中可以这样下断呢?2、Lenus的《寻找真正的入口(OEP)--广义ESP定律》(不知由哪位仁兄转帖2004-09-14,15:43)。这篇文章具有释疑、解惑之功效,我等菜鸟是一看就懂,也更加明白什么是“堆栈平衡”原理。3、cater的《ESP 脱壳 个人小节》(2004-08-31,09:09)。这篇文章简直就是Cracker的众多加密软件的“ESP定律”应用宝典。在这里,无论Cracker还是软件加密者都可以看到“ESP定律”的存在已是众多加密软件的致命伤之一。
第三、如何阻击“ESP定律”?
“ESP定律”之所以存在,就是因为“堆栈平衡”原理。要是违反了这一原理,程序就无法正常运行。然尔学过汇编的人都应当知道以下几点的:1、堆栈是可以改变的;2、堆栈指针是可以改变的;3、堆栈内容是可以复制的;4、堆栈内容也是可以加密的;5、操作堆栈更是极其危险的。你也许会说,堆栈内容复制还要访问原始堆栈地址,还是要断下的,但我可在保护现场之后马上进行,然后再解壳,再改变堆栈指针。并且刚开始的堆栈内容不多,可以连续复制若干份,恢复时随机取一份,防止Cracker在新的位置下断。对堆栈内容加密也是可取的。这样“ESP定律”即使应用了也收效不大,有效的防止了快速脱壳。
还有,我做过试验,有些壳不恢复现场也还能正常运行,可见刚开始的堆栈平衡”并不十分重要。当然,这样的危险系数还是蛮大的。
第四、我的实例简单实现。
1、        UPX加壳记事本,这是大家最熟悉的壳了。
原始壳:
01014FE0 >  60              PUSHAD
01014FE1    BE 00100101     MOV ESI,notepad.01011000
01014FE6    8DBE 0000FFFF   LEA EDI,DWORD PTR DS:[ESI+FFFF0000]
01014FEC    57              PUSH EDI
01014FED    83CD FF         OR EBP,FFFFFFFF
01014FF0    EB 10           JMP SHORT notepad.01015002
01014FF2    90              NOP
01014FF3    90              NOP
01014FF4    90              NOP
01014FF5    90              NOP
01014FF6    90              NOP
01014FF7    90              NOP

刚好这里有6个90字节,可加入如下调用指令:
01014FF0    E8 75010000     CALL notepad .0101516A
01014FF5    90              NOP
01014FF6    EB 0A           JMP SHORT notepad.01015002

0101516a处是连续的0字节:

01015168    0000            ADD BYTE PTR DS:[EAX],AL      //用来保持复制后的指针位置;

以下复制堆栈内容到新置;
0101516A    60              PUSHAD
0101516B    8BFC            MOV EDI,ESP
0101516D    81EF 00000100   SUB EDI,10000                          ; UNICODE "=::=::\"
01015173    8BF4            MOV ESI,ESP
01015175    B9 40000000     MOV ECX,40
0101517A    893D 68510101   MOV DWORD PTR DS:[1015168],EDI
01015180    36:8B06         MOV EAX,DWORD PTR SS:[ESI]
01015183    36:8907         MOV DWORD PTR SS:[EDI],EAX
01015186    83C7 04         ADD EDI,4
01015189    83C6 04         ADD ESI,4
0101518C  ^ E2 F2           LOOPD SHORT notepad.01015180
0101518E    61              POPAD
0101518F    C3              RETN

原壳转到OEP处的代码:
0101512E    61              POPAD
0101512F  - E9 AC19FFFF     JMP notepad.01006AE0
01015134    0000            ADD BYTE PTR DS:[EAX],AL
01015136    0000            ADD BYTE PTR DS:[EAX],AL
01015138    0000            ADD BYTE PTR DS:[EAX],AL

修改为:
0101512E    8BF4            MOV ESI,ESP
01015130    81EE 00010000   SUB ESI,100
01015136    8B3D 68510101   MOV EDI,DWORD PTR DS:[1015168]
0101513C    B9 40000000     MOV ECX,40
01015141    36:8B07         MOV EAX,DWORD PTR SS:[EDI]
01015144    36:8906         MOV DWORD PTR SS:[ESI],EAX
01015147    83C6 04         ADD ESI,4
0101514A    83C7 04         ADD EDI,4
0101514D  ^ E2 F2           LOOPD SHORT notepad.01015141
0101514F    8BD4            MOV EDX,ESP
01015151    81EA 00010000   SUB EDX,100
01015157    83C2 28         ADD EDX,28
0101515A    8BE2            MOV ESP,EDX
0101515C   61               POPAD
0101515D   68 E06A0001      PUSH notepad1.01006AE0
01015162   C3               RETN
以上代码完成堆栈内容转移,指针调整,转到OEP处的功能。
第五、完成如上修改只是对我的构想最简单的实现,其实还有很多需要改进和注意的地方,在此只不过抛砖引玉,希望高手也来谈谈自己的感想和经验。

附修改后的Notepad


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
2
辛苦
方法在于发现和运用
2005-1-21 15:52
0
雪    币: 603
活跃值: (617)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
3
思考和总结才能进步,谢谢分享。
2005-1-21 21:38
0
雪    币: 212
活跃值: (70)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
哪里有修改后的notepad???
2005-1-21 22:16
0
雪    币: 319
活跃值: (2459)
能力值: ( LV12,RANK:980 )
在线值:
发帖
回帖
粉丝
5
自己改一个嘛
2005-1-21 22:19
0
雪    币: 97697
活跃值: (200824)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
6
鼓励一下!!!
2005-1-21 22:53
0
雪    币: 427
活跃值: (412)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我觉得不可取,既然有这个原理,没必要违反稳定性去反这个原理,完全可以找其它思路嘛,何必僵固自己的思想。呵呵:D
2005-1-23 14:03
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
8
dll有三个参数要保护堆栈,exe怎么破坏只要不搞得溢出了就没必要保留堆栈,干掉最后的popad都行.
2005-1-23 14:07
0
雪    币: 260
活跃值: (162)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
EXE 的加壳必须注意目标执行文件的退出方式  如果是ExitProcess退出的话,堆栈就有可以破坏的前提,如果是靠执行文件堆栈入口退出的话,必须要将该地址在壳最后进入OEP前压栈
2005-1-23 14:30
0
雪    币: 207
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
返回oep时 扩展堆栈应该没问题 上层函数应该能自动恢复 不过没做过试验
2005-1-23 20:21
0
雪    币: 204
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
若修改后的 0101515C   61  POPAD 和 原壳 0101512E   61  POPAD 恢复的值不同的话,那么费尽心思保存这些堆栈值就没有实在意义;若相同,还是躲不过广义ESP定律。
2005-2-23 17:16
0
游客
登录 | 注册 方可回帖
返回
//