开始打算写个inline-patch:
用同样的查表动作,把对应的变形码copy出来,得到对应的api地址,与跳过加密而得到的干净iat对比。查到匹配值后,修改对应的opcode,使其直接call到iat中的地址。
用ollyscript脚本跳过iat加密,得不到变形码(此时从变形码地址表中得到的就是api的真正地址,有46项指针无效,为0xcccccccc)。
另一个问题却是难以解决的,replaced code只有5字节:

这里的call是0xe8,调用壳中的绝对地址。inlinepatch写到一定程度才发现,如果要修复代码,使其调用到iat,需要相对地址调用6 bytesl。真是个低级错误。
现在patch的结果:

真正需要的是:

这样只有保留变形码。把壳中对应的代码copy过来,oep前生成正确的变形码。而且脱壳后的程序不能直接看到api名字,很不舒服。
只好把壳的相应代码搬过来。再次修改dumped_.exe入口处代码,在把loader空间中的iat填好后,跳到处理变形码的位置:

loader在处理iat时需要调用几个api,及判断dll的映射地址、api地址等,先保存需要的数据(我们有干净的iatj):

由于在前面避开了iat加密,生成变形码需要的数据已经被正确的api地址覆盖了。用loadpe把acprotect的idata section存到文件,然后加到dumped_.exe。

把这个section的密文数据copy到dumped_.exe的idata section,覆盖掉干净的iat,我们已经不需要它了。现在只要伪造好现场j。

往下执行loader的iat处理代码,做几处小小的修改,使其使用刚才保存的api地址等数据。

iat及变形码处理结束后回到oep。

执行。又挂了l。这次是内存访问异常。跟一跟可以知道,是在hooked messageboxa中。这里面的代码还没有仔细看,有几个switch-case分枝。第1次eax为5。

进去后有几个查表动作:

用调用hooked messageboxa的返回地址查表。这张表在721f25处,dumped_.exe中有,共21项。
注意查表时不是找相等值,而是找大于返回地址值且最接近的值。

继续->

这里出现了另外2张表。7220b5的表中数据为size。dumped_.exe中有:

问题出在第3张表:

dump出的数据为0。这段代码要把主程序中的一段数据copy到这张表中数据所指的地址。在loader中执行时,这里填入了指向动态分配内存的指针。

显然不能直接复制这些值。有个简单的办法可以骗过loader。从那张size表中可以看到,最大的数据fd5d。用loadpe再次增加1个section,size为ffff即可。

修改dumped_.exe,设置21项数据,使其全部指向该地址。

在w2k下运行,显示窗口,但不能响应输入。在winxp下运行什么也不显示。
下面该与主程序交手了,这需要把板凳坐穿的耐心l。
发表评论