壳常用函数定位 OEP
使用工具
分析思路
GetProcAddress
将程序导入 OD,goto 到 GetProcAddress 函数的行首,设置 F2 断点,然后运行程序;
程序中断在函数的行首,使用
shift + F4
设置条件记录断点:表达式的值填写
[esp]
,表示获取 ESP 中的数据,同时勾选记录表达式的值以及函数参数选项;清空 log 窗口,然后运行程序,条件记录断点会在 log 窗口记录每次调用 GetProcAddress 函数的调用地址及参数:
通过查看内存窗口得知,外壳程序对 GetProcAddress 的最后一次调用位于:0047009A:
重载程序,编辑条件记录断点:
勾选
按条件中断
选项,同时将条件设置为[ESP] == 0047009A
,表示当 ESP 的值为 0047009A 时中断;运行程序后,程序中断在条件记录断点位置,来到内存窗口,给代码段设置内存执行断点:
多次运行程序后,程序到达 OEP:
这里需要运行太多次了,所以这种方法因程序而异,灵活使用;
其实,设置了内存执行断点后,就可以将条件访问断点取消了,取消之后就和异常法大同小异了,好处是可以绕过部分反调试;
ExitThread
因为本例中有终止线程的动作,且位于代码段之外,可以使用 ExitThread;
将程序导入 OD,
F9
运行程序后,打开日志窗口:可以看到,在一堆异常中,有一个线程结束日志,位于最后一次异常之前;
打开 OD 调试设置菜单,事件选项卡,选中
中断于线程结束
选项:重载并运行程序,程序中断:
看提示信息可以得知,中断原因是某个线程结束了;
在内存窗口,给代码段设置内存执行断点,然后运行程序:
程序到达 OEP;