一、学习目标:EncryptPE V2.2008.6.18 主程序
二、使用工具:OllyDbg v1.10,ImportREC 1.6 Final,LordPE
三、联系作者:DarkBull#126.com
四、具体过程:
1.寻找OEP
简单的观察了一下,EPE主程序运行时创建了4个进程:
第一个创建第二个,带参数“-EPEDEBUGFLAG”,调试模式。
第二个创建第三个,带参数“-EPEDEBUGFLAG”,调试模式。
第三个创建第四个,无参数,非调试模式。
第一个进程创建第二个进程后发送选定的消息,然后第一个进程终止。所以程序运行时系统里只能看见三个进程。
出现主程序的界面后,DUMP第四个进程。通过查找DELPHI的特征码能找到OEP为:004E6830。
Encryptp.<> $ 55 PUSH EBP
004E6831 . 8BEC MOV EBP,ESP
004E6833 . 83C4 F0 ADD ESP,-10
004E6836 . B8 F8654>MOV EAX,Encryptp.004E65F8
004E683B . E8 5005F>CALL Encryptp.00406D90
004E6840 . EB 04 JMP SHORT Encryptp.004E6846
004E6842 45 DB 45 ; CHAR 'E'
004E6843 50 DB 50 ; CHAR 'P'
004E6844 45 DB 45 ; CHAR 'E'
004E6845 25 DB 25 ; CHAR '%'
004E6846 > E8 9574F>CALL Encryptp.004CDCE0
004E684B . E8 40DFF>CALL Encryptp.00404790
004E6850 . 0000 ADD BYTE PTR DS:[EAX],AL
004E6852 . 0000 ADD BYTE PTR DS:[EAX],AL
004E6854 . 0000 ADD BYTE PTR DS:[EAX],AL
004E6840处的嵌入代码居然没有被替换。
2.修复IAT
经观察发现IAT处的函数地址被Hook到01130000段里(这个地址是不固定的),大小为10000H个字节。
01130000 E8 1F550C7>CALL V2200806.711F5524
01130005 - FF25 0B001>JMP NEAR DWORD PTR DS:[113000B]
0113000B 05 0013010>ADD EAX,11300
01130010 0080 7C1AC>ADD BYTE PTR DS:[EAX+4EC91A7C],AL
01130016 0058 81 ADD BYTE PTR DS:[EAX-7F],BL
01130019 41 INC ECX
0113001A 010432 ADD DWORD PTR DS:[EDX+ESI],EAX
0113001D D200 ROL BYTE PTR DS:[EAX],CL
0113001F 011A ADD DWORD PTR DS:[EDX],EBX
01130021 C9 LEAVE
01130022 0E PUSH CS
01130023 00CF ADD BH,CL
01130025 97 XCHG EAX,EDI
01130026 B1 FF MOV CL,0FF
01130028 F1 INT1
01130029 0000 ADD BYTE PTR DS:[EAX],AL
进入711F5524这个过程,返回时就可以得到函数地址,将它写回IAT即可。IATRVA: 000EC17C IATSize: 00000774。
3.修复Code Replace
被替换的代码有以下几种形式:
(1)JMP NEARPROC被替换成JMP EPE1段,JMP NEARPROC。修复方法:进入EPE1段把替换的地址写回原处。
(2)CALL NEARPROC被替换成CALL EPE1段,JMP NEARPROC。修复方法:进入EPE1段把替换的地址写回原处。
(3)有很多6、7、10个字节的指令被替换成JMP 01130000段。修复方法:
跟进JMP,来到以下过程:
011347FC E8 87110C7>CALL V2200806.711F5988
01134801 0052 1F ADD BYTE PTR DS:[EDX+1F],DL
01134804 40 INC EAX
01134805 0000 ADD BYTE PTR DS:[EAX],AL
01134807 0000 ADD BYTE PTR DS:[EAX],AL
01134809 006D 72 ADD BYTE PTR SS:[EBP+72],CH
0113480C 59 POP ECX
0113480D 005462 D2 ADD BYTE PTR DS:[EDX-2E],DL
01134811 0006 ADD BYTE PTR DS:[ESI],AL
01134813 32D2 XOR DL,DL
01134815 0000 ADD BYTE PTR DS:[EAX],AL
01134817 0018 ADD BYTE PTR DS:[EAX],BL
01134819 B6 4E MOV DH,4E
0113481B 0000 ADD BYTE PTR DS:[EAX],AL
0113481D 0000 ADD BYTE PTR DS:[EAX],AL
0113481F 0000 ADD BYTE PTR DS:[EAX],AL
01134821 000432 ADD BYTE PTR DS:[EDX+ESI],AL
01134824 D200 ROL BYTE PTR DS:[EAX],CL
01134826 0157 3D ADD DWORD PTR DS:[EDI+3D],EDX
01134829 18B6 4E00C>SBB BYTE PTR DS:[ESI+97CF004E],DH
0113482F B1 FF MOV CL,0FF
在HEX DUMP里是这样的:
011347FC E8 87 11 0C 70 00 52 1F 40 00 00 00 00 00 6D 72 .p.R@.....mr
0113480C 59 00 54 62 D2 00 06 32 D2 00 00 00 18 B6 4E 00 Y.Tb?2?...
0113481C 00 00 00 00 00 00 04 32 D2 00 01 57 3D 18 B6 4E ......2?W=
0113482C 00 CF 97 B1 FF .?
注意最后4个数字,0FFB197CF XOR 0FFFFFFFF = 004E6830(OEP)。继续进入,如下代码:
711F5988 9C PUSHFD
711F5989 60 PUSHAD
711F598A E8 0500000>CALL V2200806.711F5994
711F598F 61 POPAD
711F5990 9D POPFD
711F5991 C3 RET
执行完后,见到HEX DUMP如下:
011347FC E8 87 11 0C 70 FF 52 1F 40 00 00 00 00 00 6D 72 .pR@.....mr
0113480C 59 00 54 62 D2 00 06 32 D2 00 CC CC CC 03 00 00 Y.Tb?2?烫?..
0113481C 68 FF 18 B6 4E 00 04 32 D2 00 01 57 3D 18 B6 4E h.2?W=
0113482C 00 CF 97 B1 FF .?
EIP来到01134816,代码是:
01134816 CC INT3
01134817 CC INT3
01134818 CC INT3
01134819 0300 ADD EAX,DWORD PTR DS:[EAX]
解码的工作交给调试进程了。经过对其父进程的分析,发现解码过程是先将CC后的第6个和第7个字节 XOR 0FF,得到索引。索引值有以下几种:
05:CALL EV。6个字节。
06:JMP EV。6个字节。
07:INC EV。6个字节。
08:DEC EV。6个字节。
09:PUSH EV。6个字节。
0A:POP EV。6个字节。
0B:MOV EV,IZ。10个字节。
0C:MOV EV,IB。7个字节。
0D-14:ADD EV,GV。6个字节。
15-1C:ADD GV,EV。6个字节。
1D-24:ADC EV,GV。6个字节。
25-2C:ADC GV,EV。6个字节。
2D-34:AND EV,GV。6个字节。
35-3C:AND GV,EV。6个字节。
3D-44:XOR EV,GV。6个字节。
45-4C:XOR GV,EV。6个字节。
4D-54:OR EV,GV。6个字节。
55-5C:OR GV,EV。6个字节。
5D-64:SBB EV,GV。6个字节。
65-6C:SBB GV,EV。6个字节。
6D-74:SUB EV,GV。6个字节。
75-7C:SUB GV,EV。6个字节。
8D-94:MOV EV,GV。6个字节。
95-9C:MOV GV,EV。6个字节。
其中最后一位:5、D是EAX,6、E是ECX,7、F是EDX,8、0是EBX,9、1是ESP,A、2是EBP,B、3是ESI,C、4是EDI。
内存操作数是索引号后的4个字节,这里是004EB618。
上面这些索引在修复时没有全部用到,所以可能存在错误,请高手指点。
4.修复Embed Code
原程序里嵌入如下代码:
asm
db $EB, $04, $45, $50, $45, $25
end;
加壳后此处指令被替换成JMP 01130000段。跟进JMP后见如下过程:
711F56D4 9C PUSHFD
711F56D5 60 PUSHAD
711F56D6 E8 0500000>CALL V2200806.711F56E0
711F56DB 61 POPAD
711F56DC 9D POPFD
711F56DD C3 RET
执行完上面的过程后,壳自动将嵌入代码后的一个字节解码。
5.由于EPE主程序用了SDK的一些功能,脱壳后无法正常运行,有知道的高手请指点。 
 
2008.12.17

上传的附件 EncryptPE V2.rar [解压密码:PEDIY]