ACProtect V.1.3x-1.41的CodeReplace都长成这样!
你在009D0612说代码解密后放到143270这个内存块.OK!那么你认为你Dump出来的程式会有143270这个内存块吗?我想不
太可能,你可以直接Patch它.例如
009D0416 PUSHAD
009D0417 Jmp 009D05C1
\
\
009D05C1 Call 009DF4D2 ; 取下面要用到的EBP的值
\
\
009D060A CMP AL,20 ; 等于20h会到另外一处解码
009D060C JNZ 009D0621 ; 改JMP让它跳至固定地址来解码
009D0612 MOV EDI,DWORD PTR SS:[EBP+40FC23] ; 找适当的地址来解码吧!
\
\
009D0673 PUSHAD
009D0674 JMP 009D06AE ;不让它破坏代码
\
\
009D06AE POPAD
009d06AF POPAD
009d06BO RETN
既然要找到一个适当的地方来解码,不如我们就来还原Code Replace.如何做呢?你应该知道这里有两个Table.
Table1 =返回地址的RVA
Table2 =相对于返回地址的编码,一个地址对应OAh bytes.
查看Table2 的SIZE,例如6000,OK.在DUMP出来的程式增加一个新的Section,大小为6000h,这时你需要4个Buffer.
Buffer1=用来存放返回地址
Buffer2=用来存放解码后的地址
Buffer3=用来存放有错误发生时写入CALL地址的指针(lpErrorAddr)
Buffer4=计数器
原程式可Patch成
009D05C1 E8 0CEF0000 CALL WinMain1.009DF4D2
////////////////////////////////////////////////////////////////////////////
009D05CA 33C9 XOR ECX,ECX
009D05CC 8B9C8D 69324000 MOV EBX,DWORD PTR SS:[EBP+ECX*4+403269]
ADD EBX,00400000
MOV DWORD PTR DS:[Buffer1],EBX
////////////////////////////////////////////////////////////////////////////
009D05E4 8DB5 49614000 LEA ESI,DWORD PTR SS:[EBP+406149]
009D05EA B8 0A000000 MOV EAX,0A
009D05EF F7E1 MUL ECX
009D05F1 03F0 ADD ESI,EAX
009D05F3 8DBD EF1B4000 LEA EDI,DWORD PTR SS:[EAX+YourNewSectionStartAddr]
MOV DWORD PTR DS:[Buffer2],EDI
MOV DWORD PTR DS:[Buffer4],ECX
JMP SHORT WinMain1.009D0621
/////////////////////////////////////////////////////////////////////////////
009D0621 8A9D 06244000 MOV BL,BYTE PTR SS:[EBP+402406]
009D0627 B9 0A000000 MOV ECX,0A
009D062C AC LODS BYTE PTR DS:[ESI]
009D062D 32C3 XOR AL,BL
009D062F AA STOS BYTE PTR ES:[EDI]
009D0630 ^ E2 FA LOOPD SHORT WinMain1.009D062C
CALL WriteCallAddr
MOV ECX,DWORD PTR DS:[Buffer4]
INC ECX
CMP DWORD PTR DS:[EBP+ECX*4+403269],0
JNZ SHORT WinMain1.009D05CC
WriteCallAddr:
PUSHAD
MOV EBX,DWORD PTR DS:[Buffer1]
SUB EBX,5
CMP BYTE PTR DS:[EBX],0E8
JNZ WritErrorAddr
MOV EAX,DWORD PTR DS:[Buffer2]
SUB EAX,5
SUB EAX,EBX
ADD EBX,1
MOV DWORD PTR DS:[EBX],EAX
POPAD
RETN
WritErrorAddr MOV EDX,DWORD PTR DS:[Buffer3]
MOV DWORD PTR DS:[EDX],EBX
ADD DWORD PTR DS:[Buffer3],4
POPAD
RETN
如此处理后,你会看到的CALL 009D0416变成CALL XXXXXXXX(你的新地址)记得先用0D去载入你的dumped程序,下
da 009D0416 或 ctrl+G输入009D0416再去Patch,在009D0416去重建EIP,修复后再dump出来.
其实OEP obfuscation,Code Replace和API random redirection并非是ACProtect最困难的,你修复好Code Replace
后接下来你可能要面对HookMessageBoxA,和 Embedded Protector,
HookMessageBoxA好解决,最麻烦的是
Embedded Protector(嵌套加密)所谓的Embedded Protector 就是ACProtect的用户能指定某段代码.例如,注册码
比较的地方,主要功能的地方等等...把它重新编码,你必须通过ACProtec的检验,这些检验包括:
文件的大小(SIZE)
目前的OEP是否等于加壳后的OEP,
目前的OEP是否等于加壳前的OEP.(嘻!!告诉我们的原始OEP在那里,真是可爱),
检查调试器的Driver是否存在,
检查PE部首的数据等...
通过重重的检验它才会给你正确的解码.麻烦的是这不止一处两处,而可能会
有十几处.
至于你的第二个问题,ACProtect它会留下Import Table的完美指针只清掉函数名而已(令我想起旧版的ASProtect)丢掉
的数据,在IAT的编码处能找回,若你想脱壳跨平台,修复原始的Import Table会为你省却不少麻烦,fly的教程有,
拉拉杂杂写了这么多,祝好运!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)