Unp<span class="pediy">ack Acprotect 1.21 (三)程序修复
呵呵,又回家了。各位兄弟好!
该说说这第三个问题了。前有shinegood的脱壳版,后有tDasm的修复文章,我这个不会又...?管他的,一则说过的话总要兑现,二则各有各的方法,更何况他们的不是都还有点问题吗。(二者使用了相同的方法来修复)
修复中主要要解决的是Replace Code的地址,一般情况下,程序把Replace Code放到堆中执行,堆的结构由壳代码初始化时建立,这样,去了壳的程序就会出错。这里采用的方法就是修改放置Replace Code的地址。
od载入已修复iat的程序,隐藏od、忽略所有异常、eip定位到修复的oep、在6d540c处设断,执行程序。断下光标移到6b55b7,按F4,看到:
006D55B7 CALL Acprotect.006E1460
006D55BC MOV EAX,DWORD PTR SS:[ESP+20] ;获得返回地址
006D55C0 XOR ECX,ECX
006D55C2 MOV EBX,DWORD PTR SS:[EBP+ECX*4+4026E2] ;取表中元素
006D55C9 ADD EBX,DWORD PTR SS:[EBP+40D2AA] ;加Image Base
006D55CF CMP EAX,EBX ;
006D55D1 JE SHORT Acprotect.006D55DA ;查表
006D55D3 NOP
006D55D4 NOP
006D55D5 NOP
006D55D6 NOP
006D55D7 INC ECX
006D55D8 JMP SHORT Acprotect.006D55C2 ;再找
006D55DA MOV DWORD PTR SS:[EBP+ECX*4+4026E2],0 ;找到后把这个元素从表中删除
006D55E5 LEA ESI,DWORD PTR SS:[EBP+4055C2] ;取(变形)Replace Code表基地址
006D55EB MOV EAX,0A
006D55F0 MUL ECX
006D55F2 ADD ESI,EAX ;得到本次应取(变形)Replace Code地址
006D55F4 PUSH ESI
006D55F5 PUSH ECX
006D55F6 MOV AL,BYTE PTR SS:[EBP+4023FC] ;取还原Replace Code的操作数
006D55FC OR AL,AL
006D55FE JNZ SHORT Acprotect.006D5628 ;跳,则操作数已经存在
006D5600 NOP
006D5601 NOP
006D5602 NOP
006D5603 NOP
006D5604 MOV EAX,DWORD PTR SS:[EBP+40D2AA] ;
006D560A MOV ESI,DWORD PTR DS:[EAX+3C] ;
006D560D ADD ESI,DWORD PTR SS:[EBP+40D2AA] ;
006D5613 ADD ESI,28 ;
006D5616 LODS DWORD PTR DS:[ESI] ;得到Entry Point值
006D5617 MOV BL,AL
006D5619 ADD BL,AH
006D561B SHR EAX,10
006D561E ADD BL,AL
006D5620 ADD BL,AH
006D5622 MOV BYTE PTR SS:[EBP+4023FC],BL ;BL中为还原Replace Code的操作数
006D5628 POP ECX
006D5629 POP ESI
006D562A PUSHAD
006D562B MOV EAX,2
006D5630 CALL Acprotect.006E11EA
006D5635 OR EAX,EAX ;
006D5637 JNZ SHORT Acprotect.006D565D ;跳,表示把Replace Code放在原来变形码的位置
006D5639 NOP ; .
006D563A NOP ; .
006D563B NOP ; .
006D563C NOP ; .
006D563D POPAD ; .
006D563E MOV EDI,DWORD PTR SS:[EBP+40D2AE] ;否则放到位于[ebp+40d2ae]的指针指向的位置
006D5644 MOV EAX,0A ;一般情况下该指针指向堆中
006D5649 MUL ECX
006D564B ADD EDI,EAX
006D564D MOV ECX,0A
006D5652 MOV BL,BYTE PTR SS:[EBP+4023FC] ;取还原Replace Code的操作数
006D5658 JMP SHORT Acprotect.006D566B
006D565A NOP
006D565B NOP
006D565C NOP
006D565D POPAD
006D565E MOV EDI,ESI
006D5660 MOV ECX,0A
006D5665 MOV BL,BYTE PTR SS:[EBP+4023FC]
006D566B LODS BYTE PTR DS:[ESI] ;取变形Replace Code
006D566C XOR AL,BL ;还原
006D566E STOS BYTE PTR ES:[EDI] ;放置
006D566F LOOPD SHORT Acprotect.006D566B
006D5671 SUB EDI,0A ;得本次Replace Code入口地址
006D5674 PUSH EDI
006D5675 MOV ESI,DWORD PTR SS:[ESP+24]
006D5679 SUB ESI,4
006D567C LODS DWORD PTR DS:[ESI]
006D567D SUB EDI,Acprotect.0040240C
006D5683 SUB EDI,EBP
006D5685 ADD EAX,EDI
006D5687 MOV DWORD PTR DS:[ESI-4],EAX
006D568A POP EDI
006D568B PUSH EDI
006D568C XOR ECX,ECX
006D568E CMP ECX,8
006D5691 JE SHORT Acprotect.006D56A1
006D5693 NOP
006D5694 NOP
006D5695 NOP
006D5696 NOP
006D5697 MOV EAX,DWORD PTR SS:[ESP+ECX*4+4]
006D569B MOV DWORD PTR SS:[ESP+ECX*4],EAX
006D569E INC ECX
006D569F JMP SHORT Acprotect.006D568E
006D56A1 MOV DWORD PTR SS:[ESP+ECX*4],EDI
006D56A4 PUSHAD ;以下是把以上代码变形
006D56A5 CALL Acprotect.006D56AA
006D56AA POP ESI
006D56AB SUB ESI,6
006D56AE MOV ECX,0ED
006D56B3 SUB ESI,ECX
006D56B5 MOV EDX,4923BF69
006D56BA SHR ECX,2
006D56BD SUB ECX,2
006D56C0 CMP ECX,0
006D56C3 JL SHORT Acprotect.006D56DF
006D56C5 MOV EAX,DWORD PTR DS:[ESI+ECX*4]
006D56C8 MOV EBX,DWORD PTR DS:[ESI+ECX*4+4]
006D56CC ADD EAX,EBX
006D56CE ROR EAX,15
006D56D1 XOR EAX,EDX
006D56D3 ADD EDX,3BC3E0C
006D56D9 MOV DWORD PTR DS:[ESI+ECX*4],EAX
006D56DC DEC ECX
006D56DD JMP SHORT Acprotect.006D56C0
006D56DF POPAD
006D56E0 POPAD
006D56E1 RETN ;“回”到Replace Code入口地址
从以上注解可以看出,为了避免程序把Replace Code放到堆中,修改6D5637的jnz 为 jmp就可以了,但是这段代码是变了形的,所以必须作如下处理:
1.6D5637的jnz 为 jmp
2.改6D56A4的代码为 jmp 6d56e0,禁止程序作代码变形
3.把这个函数入口处第二条语句改成 jmp 6d55b7
保存以上修改。
F9执行程序,我这里看到程序出错!F12停下,检查后知是程序试图向堆中不存在的地址作串传输,于是重新载入,修改程序入口处代码,以加大堆的size
PUSH 5EA20
PUSH 40
CALL DWORD PTR DS:[691230] ; kernel32.LocalAlloc
执行上面三条语句后再转到修复的oep处执行,正常了,加壳,测试都没有问题。再加另一个壳,在压缩程序时程序不动了!这个现象和shinegood兄的一样。
想到在修复iat时碰到的MessageBox问题(至今我还这么笨,就没去看看看看Acpr的文档!),想想应该还原这两个函数吧?于是在上面的语句后又加上:
MOV EAX,Acprotect.006E084D
MOV DWORD PTR DS:[6911fc],EAX
MOV DWORD PTR DS:[691588],EAX
再试一试,没问题啦!(就是不能跨系统)
(注意:shinegood脱壳版不能按此修改)
