内存访问定位 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

  1. 此方法来自SharkHeng

  2. 将 CM 导入 OD 后,会弹出警告,提示入口点超出代码段范围,这是因为当前 EP 指向外壳部分,而不是代码段:

    英文版

    再来个中文版(感谢汉化 OD 的大佬):

    中文版

    虽然弹窗可以在 OD 设置中关闭,但弹窗也是一件好事儿,弹出这种窗口就是提示我们程序加壳了;

  3. 既然提示 EP 不在代码段,那就来到内存窗口,查看各区段范围:

    各区段范围

    可以看到,当前 EP 为 00413000,而代码段的范围是:00401000 ~ 00404FFF,确实不在这个范围,所以才会有一开始的弹窗;

  4. 在代码段(.text)设置内存访问断点,然后F9运行程序:

    加壳程序在运行时,会将原程序解压、还原,控制权交还,然后原程序执行,此时,就会触发内存执行断点,从而产生中断;

    产生中断

    中断位置的代码看起来像是数据,不过很有规律,按下Ctrl + A,分析程序:

    分析程序

    分析之后的代码就正常了,开始位置是生成栈帧的指令,表示函数要开始执行了,而且,当前 EIP 也处于代码段;

使用原版 OD 到达 OEP

  1. 此方法来自加密解密第 16 章:16.2.2;

  2. 将 CM 导入原版 OD,打开内存窗口,在代码段(.text)以及相邻的只读数据段(.rdata)设置F2断点:

    设置`F2`断点

    .rdata 设置的断点不是必须的,也可以在其它区段设置断点(外壳所在区段除外);

    此处设置断点的意义是:加壳程序运行时,会依次解压各区段,所以,对后面的其它区段设置断点,如果程序在 .text 中断后再次中断,说明代码段已解压完毕;

  3. 运行程序,首先中断在 .text:

    中断在 .text

    此时中断说明将要对代码段进行操作了;

  4. 再次运行程序,程序中断在 .rdata:

    中断在 .rdata

    通过查看内存窗口知道,代码段的范围是:00401000 ~ 00404FFF;

    而当前将要访问的位置是:00405000,不在代码段范围内,也就说明对代码段的操作结束了;

  5. 再次来到内存窗口,对代码段设置F2断点,然后运行程序:

    这里设置断点的意义是:既然外壳对代码段的解压、还原已经结束了,如果再次访问代码段的话,就是程序执行的时候;

    程序中断在 OEP

    中断位置与方法一一致;