注册也有一段时间了,一直临时会员着,不久前通过分析论坛一个坛友写写的挂机客户端这才又涨了十几KX,凑够了50。这里先感谢一下这位坛友,下面的实例示范其实就是这位坛友的工具,希望这位坛友不要生气,因此示例程序就不发了,可在临时版块自行寻找到。
那么废话少说,进入正题。
首先用pEid查一下,发现是ACP1.0x(图1)
这个壳不会修改原始的节段,只是增加一个壳段,这里的”终极保镖”
Lord_PE查看区段(图2):
就是添加的段了。
OD载入后看一下Memory map(图3):
在观察一下数据窗口(图4):
结合上面图3和图4,我们有理由猜测这里就是IAT,直接F9跑跑看(图5):
确实是的。
那么重新载入OD,利用两次断点走到OEP,DUMP重建看是否可以了。
首先在rdata段下断点(图6):
F9断下之后,就在代码段下第二个断点(图7):
F9断下之后就到OEP了(图8):
看起来很标准的VC程序头部,
此时DUMP然后用import REC重建(图9):
发现一个问号,展开之后发现有一处未填充(图10):
偏移773e4处指向的这个地址是壳段,看来是对某个函数做了特殊处理,
那我们跟一下它是如何填充这个壳段地址的,重载然后在004773e0下
内存访问断点(就是处理偏移773e4的上一处),F9断下(图11):
这里应该就是填充IAT的代码了,那就F8单步看一下吧,因为马上要处理的就是
偏移773e4处这个特殊的函数了,跟了几步便有了如下发现(图12):
每次取得函数地址后,会做一次比较:
004D37C7 CMP EAX,DWORD PTR SS:[EBP+406E98] ;USER32.MessageBoxA
看是不是USER32.MessageBoxA,如果是则跳到
004D37D3 LEA EAX,DWORD PTR SS:[EBP+402123];正是之前import REC得到的值,
这样得知是MessageBoxA这个函数我们便自己处理一下(直接import REC手动修改)
然后用LordPE DUMP内存映像(当然直接OD也可以DUMP也可以)(图13):
用import REC导入IAT,这个时候就可以了,用PEID看一下,已经
能识别了,也能正常运行(图14):
用LordPE看一下(图15):
又增加了一个段,这是import REC加的.壳是去了,但是我们似乎可以更进一步,
我们继续跟一下IAT的填充代码吧!
-----------------------------------------------------------------------------------------------------
004D36F7 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] ;处理下一个导入模块
;[ESI+C]模块名RVA
004D36FA 0BC0 OR EAX,EAX
004D36FC 0F84 40010000 JE 看雪论坛.004D3842
004D3702 C746 0C 0000000>MOV DWORD PTR DS:[ESI+C],0 ;[ESI+C]填0
004D3709 03C2 ADD EAX,EDX ;EDX为镜像基址
004D370B 8BD8 MOV EBX,EAX
004D370D 50 PUSH EAX ;模块名
004D370E FF95 8C6E4000 CALL DWORD PTR SS:[EBP+406E8C]; GetModuleHandleA
004D3714 0BC0 OR EAX,EAX
004D3716 75 43 JNZ SHORT 看雪论坛.004D375B
004D3718 90 NOP
004D3719 90 NOP
004D371A 90 NOP
004D371B 90 NOP
004D371C 53 PUSH EBX
004D371D FF95 906E4000 CALL DWORD PTR SS:[EBP+406E90]
004D3723 0BC0 OR EAX,EAX
004D3725 75 34 JNZ SHORT 看雪论坛.004D375B
004D3727 90 NOP
004D3728 90 NOP
004D3729 90 NOP
004D372A 90 NOP
004D372B 8B95 801B4000 MOV EDX,DWORD PTR SS:[EBP+401B80]
004D3731 0195 14144000 ADD DWORD PTR SS:[EBP+401414],EDX
004D3737 0195 18144000 ADD DWORD PTR SS:[EBP+401418],EDX
004D373D 6A 00 PUSH 0
004D373F FFB5 14144000 PUSH DWORD PTR SS:[EBP+401414]
004D3745 FFB5 18144000 PUSH DWORD PTR SS:[EBP+401418]
004D374B 6A 00 PUSH 0
004D374D FF95 986E4000 CALL DWORD PTR SS:[EBP+406E98]
004D3753 6A 00 PUSH 0
004D3755 FF95 946E4000 CALL DWORD PTR SS:[EBP+406E94]
004D375B 8985 781B4000 MOV DWORD PTR SS:[EBP+401B78],EAX;存入模块基址
004D3761 C785 7C1B4000 0>MOV DWORD PTR SS:[EBP+401B7C],0
004D376B 8B95 801B4000 MOV EDX,DWORD PTR SS:[EBP+401B80] ;edx赋值为镜像基址
004D3771 8B06 MOV EAX,DWORD PTR DS:[ESI] ;[esi]应该为一个IID的VA
004D3773 0BC0 OR EAX,EAX
004D3775 75 07 JNZ SHORT 看雪论坛.004D377E
004D3777 90 NOP
004D3778 90 NOP
004D3779 90 NOP
004D377A 90 NOP
004D377B 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10] [ESI+10];导入模块IAT的RVA
004D377E 03C2 ADD EAX,EDX ; 导入模块IAT的VA
004D3780 0385 7C1B4000 ADD EAX,DWORD PTR SS:[EBP+401B7C]
; [EBP+401B7C]偏移位移
004D3786 8B18 MOV EBX,DWORD PTR DS:[EAX] ;函数名RVA
004D3788 8B7E 10 MOV EDI,DWORD PTR DS:[ESI+10]
004D378B 03FA ADD EDI,EDX
004D378D 03BD 7C1B4000 ADD EDI,DWORD PTR SS:[EBP+401B7C];EDI将要填充函数
;地址的指针
004D3793 85DB TEST EBX,EBX
004D3795 0F84 99000000 JE 看雪论坛.004D3834
004D379B F7C3 00000080 TEST EBX,80000000 ;比较是否为80000000型
004D37A1 75 09 JNZ SHORT 看雪论坛.004D37AC
004D37A3 90 NOP
004D37A4 90 NOP
004D37A5 90 NOP
004D37A6 90 NOP
004D37A7 03DA ADD EBX,EDX
004D37A9 83C3 02 ADD EBX,2
004D37AC 81E3 FFFFFF0F AND EBX,0FFFFFFF ;两种类型的函数名获取方式
004D37B2 53 PUSH EBX
004D37B3 FFB5 781B4000 PUSH DWORD PTR SS:[EBP+401B78]
004D37B9 FF95 886E4000 CALL DWORD PTR SS:[EBP+406E88] ;取得函数地址
004D37BF 0BC0 OR EAX,EAX
004D37C1 ^ 0F84 64FFFFFF JE 看雪论坛.004D372B
004D37C7 3B85 986E4000 CMP EAX,DWORD PTR SS:[EBP+406E98]; 比较MessageBoxA
004D37CD 75 0A JNZ SHORT 看雪论坛.004D37D9
004D37CF 90 NOP
004D37D0 90 NOP
004D37D1 90 NOP
004D37D2 90 NOP
004D37D3 8D85 23214000 LEA EAX,DWORD PTR SS:[EBP+402123]
004D37D9 56 PUSH ESI
004D37DA EB 49 JMP SHORT 看雪论坛.004D3825
004D37DC 90 NOP
004D37DD 90 NOP
004D37DE 90 NOP
004D37DF 8BB5 451C4000 MOV ESI,DWORD PTR SS:[EBP+401C45]
004D37E5 81EE DD684000 SUB ESI,看雪论坛.004068DD
004D37EB 2BF5 SUB ESI,EBP
004D37ED 83EE 0C SUB ESI,0C
004D37F0 83FE 00 CMP ESI,0
004D37F3 7F 30 JG SHORT 看雪论坛.004D3825
004D37F5 90 NOP
004D37F6 90 NOP
004D37F7 90 NOP
004D37F8 90 NOP
004D37F9 8BB5 451C4000 MOV ESI,DWORD PTR SS:[EBP+401C45]
004D37FF 53 PUSH EBX
004D3800 50 PUSH EAX
004D3801 0F31 RDTSC
004D3803 8BD8 MOV EBX,EAX
004D3805 58 POP EAX
004D3806 33C3 XOR EAX,EBX
004D3808 C606 B8 MOV BYTE PTR DS:[ESI],0B8
004D380B 8946 01 MOV DWORD PTR DS:[ESI+1],EAX
004D380E C646 05 35 MOV BYTE PTR DS:[ESI+5],35
004D3812 895E 06 MOV DWORD PTR DS:[ESI+6],EBX
004D3815 66:C746 0A FFE0 MOV WORD PTR DS:[ESI+A],0E0FF
004D381B 5B POP EBX
004D381C 8BC6 MOV EAX,ESI
004D381E 8385 451C4000 0>ADD DWORD PTR SS:[EBP+401C45],0C
004D3825 5E POP ESI
004D3826 8907 MOV DWORD PTR DS:[EDI],EAX ;填充
004D3828 8385 7C1B4000 0>ADD DWORD PTR SS:[EBP+401B7C],4
004D382F ^ E9 37FFFFFF JMP 看雪论坛.004D376B
004D3834 83C6 14 ADD ESI,14
004D3837 8B95 801B4000 MOV EDX,DWORD PTR SS:[EBP+401B80]
004D383D ^ E9 B5FEFFFF JMP 看雪论坛.004D36F7
------------------------------------------------------------------------------------------------------
通过分析发现它可能存在着完整的IID,于是想到我们可以不借助import REC便完成脱壳,
重新载入OD,我们需要断在它访问第一个IID的地方,这个例子方法很多,这里我们直接在rdata下断点,断下的地方其实就是了(图16):
004D36F7 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]
此处ESI便是第一个IID的VA,去看看(图17):
好了,就是这里F8跟一下发现:
004D3702 C746 0C 0000000>MOV DWORD PTR DS:[ESI+C],0
此处会将模块名称RVA填0,为了保持IID的完整,需要NOP掉它。
重新断到OEP然后DUMP,之后用LordPE打开修改入口点和IID(图18):
这样就可以了,可此时壳段还在。
直接去掉壳段是否可行,要看是否还有依赖壳段的地方。这个壳有一些资源在壳段
,那么要去掉壳段必须重建资源(图19)。
下面用DT FixResource提取资源段(图20):
用PE Tools将壳段和资源段填0(直接清空可能导致错误)(图21):
最后用LordPE清除壳段和资源段并载入之前提取的资源段并重建使PE有效(图22):
这样 便去掉壳段了。这个壳几乎没什么强度可言,这里主要演示了几种常用工具的使用。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)