zainv673799 发表于 2017-12-5 16:39:48

VMP脱壳加脚本(2)

5、还原IAT
随便找一个IAT调用函数跟一下,刚好OEP下面就有两个 FF25 型的IAT 调用,跟进去看下
https://attach.52pojie.cn/forum/201602/20/001812hog19zg098p00om3.png
还是啥都看不懂,不过没关系 既然是调用IAT函数,肯定会在某一时刻调到真实函数地址去的 继续跟下面把整个跟的流程贴上来
https://attach.52pojie.cn/forum/201602/20/002310g7grg15xx8q1uerb.png
https://attach.52pojie.cn/forum/201602/20/002314zh6kt6pp7c6oa7ck.png
https://attach.52pojie.cn/forum/201602/20/002324yeuhjehunkk25z1g.png
https://attach.52pojie.cn/forum/201602/20/002330km7476sly4zl1qm1.png
https://attach.52pojie.cn/forum/201602/20/002358d3neytextdqjeeec.png
这是整个流程的实际执行的代码 ,现在分析下
01059D91    53            push ebx                     保护环境
01059D92    66:0FB6DB       movzx bx,bl          垃圾代码
01059D96    66:BB 5D55      mov bx,0x555D   垃圾代码
01059D9A    BB 5AC27200   mov ebx,0072C25A   这才是最终对EBX操作所以上面两条都是没用的代码
00F3BBFF    8B9B 25697400   mov ebx,dword ptr ds:    计算地址
01196B98    8D9B 5071F632   lea ebx,dword ptr ds:计算地址
00EA9FC2    871C24          xchg dword ptr ss:,ebx   和栈顶交换,并还原EBX的原始值
00F9FC9D    C2 0400         retn 0x4                  还原EBX 并返回函数
这时候看下堆栈 栈顶出现真实函数的地址
https://attach.52pojie.cn/forum/201602/20/002337ohpr9zlu2md9pgj7.png
00F9FC9D    C2 0400         retn 0x4       分析下这条指令的执行流程,先EIP=栈顶的值 也就是真实函数地址,栈顶+4+4 懂汇编的人就会发现,栈顶+8的位置保存是当前CALL的返回地址 那执行了这条指令后返回地址不是没有了么?因为这个IAT调用 没加密前是 FF25型的 也就是 jmp [????????] 所以不需要返回地址 ,而调用这个IAT的时候 是有一个CALL的进CALL的时候就会PUSH返回地址到堆栈,所以这个IAT处理的很巧妙!执行完真实函数后直接就返回到调用IATCALL的下面继续执行了。
看图片发现 这个CALL 下面有一条 RETN指令 看来这条 是VMP加上去的了,但是不要忽略了这条指令 因为这条指令很重要,VMP在获取 IAT地址的最后RETN的地址 会随机JMP到代码他添加的RETN 上,并不完全是在壳段 所以这个RETN 要留到最后处理。
再找一个FF25 型的IAT调用看看
https://attach.52pojie.cn/forum/201602/20/005223tarwxgyneeixgnw6.png
跟进去看下,下面是执行流程代码
00FB7DC7    90            nop
00FB7DC8    0FB7D6          movzx edx,si      垃圾代码
00FB7DCB    66:0FBED1       movsx dx,cl       垃圾代码
00FB7DCF    5A            pop edx                   出栈               
00FB7DD0    871424          xchg dword ptr ss:,edx         交换栈顶的值,还原 EDX原始值
00FB7DD3    52            push edx                              保护环境
00FB7DD4    66:0FBED1       movsx dx,cl   垃圾
00FB7DD8    0FB7D6          movzx edx,si      垃圾
00FB7DDB    BA B7757D00   mov edx,007D75B7   计算地址
010DFDAD    8B92 3D036900   mov edx,dword ptr ds:    计算地址
0102B837    8D92 B52FE512   lea edx,dword ptr ds:   计算地址
00EACB30    871424          xchg dword ptr ss:,edx   函数真实地址给栈顶 并还原环境         
0115D36E    C2 0400         retn 0x4
这个FF25 CALL 的第四行 有个POPedx 而进这个CALL之前有一个push edx ,可以看出 这个push edx 也是垃圾代码是 VMP自己添加上去的,看来VMP 会随机在上下 填充一个字节,在上面就是 PUSH 一个寄存器,在下面就是 retn
找一个 FF15型的CALL看看
https://attach.52pojie.cn/forum/201602/20/011005dc25j5kq518n28hf.png
跟进去看下流程
010B27B9    BE B34E6E0B   mov esi,0xB6E4EB3    垃圾代码
00EFFC5B    5E            pop esi               出栈
00EEB9B0    873424          xchg dword ptr ss:,esi    交换栈顶的值,还原 ESI原始值
00F437BB    56            push esi   保存环境
00F8D827    BE 4B084800   mov esi,0048084B    计算地址
00FA55B3    8BB6 C005B900   mov esi,dword ptr ds:计算地址
010E8053    8DB6 3F68AD31   lea esi,dword ptr ds: 计算地址
00F44191    873424          xchg dword ptr ss:,esi   真实函数地址给栈顶,还原环境
0057A761    C3            retn
第二行 pop esi看来这个CALL 的push esi 是垃圾指令了,但是 发现这个 是retn 为什么不是,retn 04 呢?因为这个是 FF15 型调用,也就是 call [????????]需要执行完后返回到call 下面继续执行
再找一个FF15型调用看看
https://attach.52pojie.cn/forum/201602/20/011816db8nh8srtccng9to.png


页: [1]
查看完整版本: VMP脱壳加脚本(2)