壳代码,都会重定向IAT表项到壳里的地址.
如果找到真正的IAT表项的API地址列表, 自己手工填到ImpREC中挺繁琐的.
这时, 可以在已经停在OEP处的OD中, 先在ImpREC中填写正确OEP, 得到IAT表项.
当IAT表项在壳内时(无效项), 在OD中根据ImpREC提示的IAT表项地址, 手工找到真实的API地址, 将IAT手工填充(2进制拷贝,2进制粘贴), Dump出去壳PE. 在用ImpREC再次Load, 修复IAT, 只要做少量确认和删除任务, IAT就可修复完成.
对于有对抗的壳, 大概只能采用异常技术法(相对于F8, F7)走到OEP.
OD载入PE后, 直接(SHIFT+F9), 记录N-1次的计数到程序启动.
再次载入PE, (SHIFT+F9)(N-1)次, 在Memory窗口F2断点到代码段(PE头下面就是代码段).
最后一次(SHIFT+F9), 命中时, 离OEP就几步(过了JMP就是OEP), 可以F8,F7走过去.
可以在无效表项上右击, 选择反汇编, 看看是不是找到有效IAT(包括IAT表项重定向)
可以看出, 这个IAT表项是ImpREC识别错了, 没有指向API地址, 也没有API重定向. 在这个IAT上看看, 如果表项都是无效的, 可以将这个IAT整个cut掉.
拿IAT为例子
这个表项内容在壳地址里.
IAT范围
IatAddrBegin = 00268284
IatAddrEnd = 00268284 + 0xB7 * 4 = 00268560
FirstRva = 00268284
FirstApiPtr = 003f0000
FirstRealApiPtr = [0x003f11f0] = 0x7c809bd7
IAT表项是以0结尾的, 从第一个IAT表项往下拉, 拖选到0结尾的地址, 选择2进制拷贝.
在CPU窗口内存小窗口, go到IatAddrBegin, 往下拖选到IatAddrEnd(如果实际API个数较少, 可以拖到多留一个\0的位置, 总之选择2进制粘贴时, 目标地址范围选择区域要>=原地址范围), 选择2进制粘贴.
此时, EIP就在OEP, 用OllyDump插件Dump出无壳PE.
用ImpREC再次载入OD中的目标程序, 填写OEP, 取IAT集合.
这时, 只有少量无效IAT, 可以用看反汇编的方法确认无效项, 然后cut掉.
当IAT全部有效时, 修复IAT. 可选PeRebuild, 脱壳完成.