内存访问定位 OEP
OEP:当外壳保护的程序运行时,会先执行外壳程序,外壳程序负责在内存中把原程序解压、还原,并把控制权还给解压后的真正程序,再跳到原来程序的入口点,这个解压后真正程序的入口点称为 OEP(Original Entry Point,原始入口点);
EP:与 OEP 对应的是 EP(Entry Point,入口点),无壳程序的 EP 与 OEP 相同,加壳程序的 EP 是壳的入口点,而不是原程序的入口点;
使用工具
- OllyDbg 1.10原版,简称
OD
; - OllyDbg修改版,简称
OD
; OD
汉化
和插件
均来自互联网;- UnPackMe来自互联网,仅供学习使用;
- 文中特殊数字均是
HEX
,为了书写方便采用DEC
;
分析思路
使用改版 OD 到达 OEP
此方法来自SharkHeng;
将 CM 导入 OD 后,会弹出警告,提示入口点超出代码段范围,这是因为当前 EP 指向外壳部分,而不是代码段:
再来个中文版(感谢汉化 OD 的大佬):
虽然弹窗可以在 OD 设置中关闭,但弹窗也是一件好事儿,弹出这种窗口就是提示我们程序加壳了;
既然提示 EP 不在代码段,那就来到内存窗口,查看各区段范围:
可以看到,当前 EP 为 00413000,而代码段的范围是:00401000 ~ 00404FFF,确实不在这个范围,所以才会有一开始的弹窗;
在代码段(.text)设置内存访问断点,然后
F9
运行程序:加壳程序在运行时,会将原程序解压、还原,控制权交还,然后原程序执行,此时,就会触发
内存执行断点
,从而产生中断;中断位置的代码看起来像是数据,不过很有规律,按下
Ctrl + A
,分析程序:分析之后的代码就正常了,开始位置是生成栈帧的指令,表示函数要开始执行了,而且,当前 EIP 也处于代码段;
使用原版 OD 到达 OEP
此方法来自加密解密第 16 章:16.2.2;
将 CM 导入原版 OD,打开内存窗口,在代码段(.text)以及相邻的只读数据段(.rdata)设置
F2
断点:.rdata 设置的断点不是必须的,也可以在其它区段设置断点(外壳所在区段除外);
此处设置断点的意义是:加壳程序运行时,会依次解压各区段,所以,对后面的其它区段设置断点,如果程序在 .text 中断后再次中断,说明代码段已解压完毕;
运行程序,首先中断在 .text:
此时中断说明将要对代码段进行操作了;
再次运行程序,程序中断在 .rdata:
通过查看内存窗口知道,代码段的范围是:00401000 ~ 00404FFF;
而当前将要访问的位置是:00405000,不在代码段范围内,也就说明对代码段的操作结束了;
再次来到内存窗口,对代码段设置
F2
断点,然后运行程序:这里设置断点的意义是:既然外壳对代码段的解压、还原已经结束了,如果再次访问代码段的话,就是程序执行的时候;
中断位置与方法一一致;