日期:2004年11月17日 破解人:csjwaman[DFCG]
―――――――――――――――――――――――――――――――――――――――――――
【软件名称】:EncryptPE1.0 V1.2003.5.18加壳的某程序
【软件限制】:INT3异常、过期限制、数据附加
【脱壳声明】:感谢fly、loveboom等高手的帮助!
【操作系统】:WIN2K
【脱壳工具】:OD等
―――――――――――――――――――――――――――――――――――――――――――
【脱壳过程】:
壳中加了INT3异常,还有过期限制,还有数据附加。
对INT3异常只要象脱EncryptPE V1.2003.5.1 Preview一样把INT3异常NOP掉就行了。过期限制用bp GetLocalTime下断。下面是脱壳和修复过程:
一、脱壳
用OD载入,隐藏OD,忽略所有异常,同时添加忽略0EEDFADF和C0000008异常。载入后停在:
0044D000 > 60 PUSHAD=====>停在这儿。
0044D001 9C PUSHFD
0044D002 64:FF35 0000000>PUSH DWORD PTR FS:[0]
0044D009 E8 79010000 CALL ?2.0044D187
0044D00E 0000 ADD BYTE PTR DS:[EAX],AL
0044D010 0000 ADD BYTE PTR DS:[EAX],AL
0044D012 0000 ADD BYTE PTR DS:[EAX],AL
0044D014 0000 ADD BYTE PTR DS:[EAX],AL
F9运行异常在:
77F813A2 FF75 0C PUSH DWORD PTR SS:[EBP+C]
77F813A5 FF75 08 PUSH DWORD PTR SS:[EBP+8]
77F813A8 E8 ECEC0000 CALL ntdll.77F90099
77F813AD 5D POP EBP
77F813AE C2 1800 RETN 18
77F813B1 > CC INT3======>NOP掉!
77F813B2 C3 RETN=======>停在此处。
77F813B3 33C9 XOR ECX,ECX
77F813B5 E9 A5BE0000 JMP ntdll.77F8D25F
77F813BA > 55 PUSH EBP
77F813BB 8BEC MOV EBP,ESP
77F813BD 56 PUSH ESI
77F813BE 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
77F813C1 8A06 MOV AL,BYTE PTR DS:[ESI]
77F813C3 3C 02 CMP AL,2
下断bp GetLocalTime后SHIFT+F9运行程序,断在:
77E649B6 > 55 PUSH EBP=====>断在此处。取消断点。看看堆栈区数据。
77E649B7 8BEC MOV EBP,ESP
77E649B9 83EC 18 SUB ESP,18
77E649BC 56 PUSH ESI
77E649BD A1 1800FE7F MOV EAX,DWORD PTR DS:[7FFE0018]
77E649C2 8B0D 1400FE7F MOV ECX,DWORD PTR DS:[7FFE0014]
77E649C8 3B05 1C00FE7F CMP EAX,DWORD PTR DS:[7FFE001C]
77E649CE ^ 75 ED JNZ SHORT kernel32.77E649BD
77E649D0 8B15 2400FE7F MOV EDX,DWORD PTR DS:[7FFE0024]
77E649D6 8B35 2000FE7F MOV ESI,DWORD PTR DS:[7FFE0020]
77E649DC 3B15 2800FE7F CMP EDX,DWORD PTR DS:[7FFE0028]
77E649E2 ^ 75 EC JNZ SHORT kernel32.77E649D0
77E649E4 2BCE SUB ECX,ESI
77E649E6 1BC2 SBB EAX,EDX
77E649E8 894D F8 MOV DWORD PTR SS:[EBP-8],ECX
堆栈区数据:
0123FBD8 7112A429 /CALL 到 GetLocalTime 来自 V1200351.7112A424
0123FBDC 0123FBE8 \pLocaltime = 0123FBE8
0123FBE0 71128B70 ASCII "%d"
到7112A429处:
7112A424 E8 8BC8FFFF CALL V1200351.71126CB4 ; JMP to kernel32.GetLocalTime
7112A429 66:8B4C24 0E MOV CX,WORD PTR SS:[ESP+E]=====>下断后F9运行到此。然后取消断点。
7112A42E 66:8B5424 0A MOV DX,WORD PTR SS:[ESP+A]
7112A433 66:8B4424 08 MOV AX,WORD PTR SS:[ESP+8]
7112A438 E8 1BFEFFFF CALL V1200351.7112A258
7112A43D DD5C24 18 FSTP QWORD PTR SS:[ESP+18]
7112A441 9B WAIT
7112A442 66:8B4424 16 MOV AX,WORD PTR SS:[ESP+16]
7112A447 50 PUSH EAX
7112A448 66:8B4C24 18 MOV CX,WORD PTR SS:[ESP+18]
7112A44D 66:8B5424 16 MOV DX,WORD PTR SS:[ESP+16]
7112A452 66:8B4424 14 MOV AX,WORD PTR SS:[ESP+14]
7112A457 E8 5CFCFFFF CALL V1200351.7112A0B8
7112A45C DC4424 18 FADD QWORD PTR SS:[ESP+18]
7112A460 DD1C24 FSTP QWORD PTR SS:[ESP]
7112A463 9B WAIT
7112A464 DD0424 FLD QWORD PTR SS:[ESP]
7112A467 83C4 20 ADD ESP,20
7112A46A C3 RETN=======>返回。
返回到:
711A0EF0 83C4 F8 ADD ESP,-8====>返回到这里。
711A0EF3 DD1C24 FSTP QWORD PTR SS:[ESP]
711A0EF6 9B WAIT
711A0EF7 8D95 90FDFFFF LEA EDX,DWORD PTR SS:[EBP-270]
711A0EFD B8 741B1A71 MOV EAX,V1200351.711A1B74 ; ASCII "yyyymmdd"
711A0F02 E8 3DA1F8FF CALL V1200351.7112B044
711A0F07 8B95 90FDFFFF MOV EDX,DWORD PTR SS:[EBP-270]
711A0F0D 58 POP EAX
711A0F0E E8 3D3BF8FF CALL V1200351.71124A50=====>日期比较CALL。
711A0F13 73 0D JNB SHORT V1200351.711A0F22=====>必须跳。修改C标志位为0。
711A0F15 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]
711A0F18 BA 881B1A71 MOV EDX,V1200351.711A1B88
711A0F1D E8 CA37F8FF CALL V1200351.711246EC
711A0F22 B2 01 MOV DL,1
711A0F24 A1 D0961371 MOV EAX,DWORD PTR DS:[711396D0]
711A0F29 E8 9628F8FF CALL V1200351.711237C4
711A0F2E 8945 D8 MOV DWORD PTR SS:[EBP-28],EAX
711A0F31 837D E8 00 CMP DWORD PTR SS:[EBP-18],0
711A0F35 0F85 32010000 JNZ V1200351.711A106D========>不能跳,修改Z标志位为1。
711A0F3B 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
711A0F3E 8078 34 00 CMP BYTE PTR DS:[EAX+34],0
711A0F42 0F85 18010000 JNZ V1200351.711A1060
711A0F48 8D8D 88FDFFFF LEA ECX,DWORD PTR SS:[EBP-278]
711A0F4E BA 08000000 MOV EDX,8
711A0F53 B8 01000000 MOV EAX,1
711A0F58 E8 177CF8FF CALL V1200351.71128B74
至此,日期限制已取消。直接F9运行,等出现注册框后在内存镜像401000段下内存访问断点,然后点注册框中的“确定”。程序断在:
00408AF7 55 PUSH EBP=====>这就是入口。现在可以DUMP了。
00408AF8 8BEC MOV EBP,ESP
00408AFA 6A FF PUSH -1
00408AFC 68 20434100 PUSH ?2.00414320
00408B01 68 F0C34000 PUSH ?2.0040C3F0
00408B06 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00408B0C 50 PUSH EAX
00408B0D 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00408B14 83EC 58 SUB ESP,58
00408B17 53 PUSH EBX
00408B18 56 PUSH ESI
00408B19 57 PUSH EDI
00408B1A 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00408B1D FF15 F0414100 CALL NEAR DWORD PTR DS:[4141F0] ; kernel32.GetVersion
00408B23 33D2 XOR EDX,EDX
00408B25 8AD4 MOV DL,AH
00408B27 8915 7C934100 MOV DWORD PTR DS:[41937C],EDX
00408B2D 8BC8 MOV ECX,EAX
DUMP后删除第二区段,然后用ImportREC直接修复IAT,重建PE后脱壳完成。
二、修复
运行脱壳后的程序提示某处不能访问等等。估计有自校验,用OD载入,下断bp GetFileSize,运行后程序断在:
77E66B4E > 55 PUSH EBP=====>断在这里,看看堆栈区数据。
77E66B4F 8BEC MOV EBP,ESP
77E66B51 51 PUSH ECX
77E66B52 51 PUSH ECX
77E66B53 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
77E66B56 50 PUSH EAX
77E66B57 FF75 08 PUSH DWORD PTR SS:[EBP+8]
77E66B5A E8 B7FFFFFF CALL KERNEL32.GetFileSizeEx
77E66B5F 85C0 TEST EAX,EAX
77E66B61 0F84 1F6E0200 JE KERNEL32.77E8D986
77E66B67 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
77E66B6A 85C0 TEST EAX,EAX
77E66B6C 0F85 612D0000 JNZ KERNEL32.77E698D3
77E66B72 837D F8 FF CMP DWORD PTR SS:[EBP-8],-1
77E66B76 0F84 FE6D0200 JE KERNEL32.77E8D97A
77E66B7C 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
77E66B7F C9 LEAVE
77E66B80 C2 0800 RETN 8
堆栈区数据:
0012FEFC 0040189A /CALL 到 GetFileSize 来自 dumped_.00401894
0012FF00 00000058 |hFile = 00000058 (window)
0012FF04 00000000 \pFileSizeHigh = NULL
到40189A处看看:
00401894 FF15 2C414100 CALL NEAR DWORD PTR DS:[<&kernel32.GetFi>; KERNEL32.GetFileSize
0040189A 56 PUSH ESI=====>来到这里。这时EAX=1A0F6F,其实就是文件长度。
0040189B 8BD8 MOV EBX,EAX
0040189D E8 6A030000 CALL dumped_.00401C0C
004018A2 8BE8 MOV EBP,EAX=====>经过上面的CALL后EAX=EOFBA。
004018A4 59 POP ECX
004018A5 3BEB CMP EBP,EBX=====>以上两个值比较。
004018A7 75 05 JNZ SHORT dumped_.004018AE====>不等则跳,跳则出错。原程序跳,脱壳后程序也跳。
004018A9 6A 0D PUSH 0D
004018AB 5B POP EBX
004018AC EB 71 JMP SHORT dumped_.0040191F
004018AE 57 PUSH EDI
004018AF 55 PUSH EBP
004018B0 56 PUSH ESI
004018B1 E8 3E010000 CALL dumped_.004019F4
004018B6 6A 04 PUSH 4
004018B8 68 10914100 PUSH dumped_.00419110
004018BD 56 PUSH ESI
004018BE E8 46010000 CALL dumped_.00401A09
004018C3 A1 10914100 MOV EAX,DWORD PTR DS:[419110]
004018C8 83C4 18 ADD ESP,18
004018CB 3BC7 CMP EAX,EDI
004018CD /74 09 JE SHORT dumped_.004018D8====>跳!
004018CF |50 PUSH EAX
004018D0 |E8 965E0000 CALL dumped_.0040776B
004018D5 |59 POP ECX
004018D6 |8BF8 MOV EDI,EAX
004018D8 \FF35 10914100 PUSH DWORD PTR DS:[419110]
004018DE 57 PUSH EDI
004018DF 56 PUSH ESI
004018E0 E8 24010000 CALL dumped_.00401A09
004018E5 FF35 10914100 PUSH DWORD PTR DS:[419110]
004018EB 57 PUSH EDI
004018EC E8 E3030000 CALL dumped_.00401CD4
004018F1 FF35 10914100 PUSH DWORD PTR DS:[419110]
004018F7 57 PUSH EDI
004018F8 E8 0F040000 CALL dumped_.00401D0C
004018FD 8BD8 MOV EBX,EAX
004018FF 83C4 1C ADD ESP,1C
00401902 85DB TEST EBX,EBX
00401904 75 0E JNZ SHORT dumped_.00401914
00401906 A1 10914100 MOV EAX,DWORD PTR DS:[419110]
0040190B 8D4428 04 LEA EAX,DWORD PTR DS:[EAX+EBP+4]
0040190F A3 14914100 MOV DWORD PTR DS:[419114],EAX
00401914 85FF TEST EDI,EDI
00401916 74 07 JE SHORT dumped_.0040191F
00401918 57 PUSH EDI
00401919 E8 FF5E0000 CALL dumped_.0040781D
0040191E 59 POP ECX
0040191F 56 PUSH ESI
00401920 E8 28010000 CALL dumped_.00401A4D
00401925 59 POP ECX
00401926 5D POP EBP
00401927 5F POP EDI
00401928 8BC3 MOV EAX,EBX
0040192A 5E POP ESI
0040192B 5B POP EBX
0040192C C3 RETN
那么004018A7处到底该不该跳?跟踪原程序后发现也是不跳的。原程序经过0040189D处的CALL后EAX=95000。那95000又是什么呢?经过跟踪原程序发现,原来95000是文件偏移地址,那里有数据“000011BA”。看看原来95000处的数据:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00095000 BA 11 00 00 DC ED BD A9 B2 46 A9 79 48 86 9F 50 ?..茼僵财?H?P
00095010 84 60 19 91 58 D9 31 A8 13 F3 B5 A2 C4 C3 D4 E5 ?.???蟮⒛迷?
00095020 CB 9D FF DC FE EF 8F 5B 4B 44 03 32 17 04 C7 83 ????KD.2..?
00095030 03 82 62 48 28 A8 C8 13 55 A4 E3 92 B7 65 A6 22 .?H(ㄈ.Uゃ?e?
00095040 A2 82 F3 44 03 32 17 A3 A4 DA EC EE ED EF 1E 9E ?竽.2.¥陟铐??
00095050 6A B4 43 DB DA 83 13 8A 8B 22 25 54 A5 95 F2 03 j疵圳??"%T??
00095060 33 28 48 08 68 C4 16 C3 B6 C3 17 A4 C5 F4 72 32 3(H.h?枚?づ趄2
00095070 C6 92 C2 25 33 82 C6 34 24 64 23 D3 F6 43 17 83 ??3?4$d#遇C.
........
再看看脱壳后文件的偏移EOFBA处:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
000E0FB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000E0FC0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000E0FD0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000E0FE0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000E0FF0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000E1000 00 00 00 00 00 00 00 00 00 00 00 00 A0 10 0E 00 ............?..
000E1010 00 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 .@..............
000E1020 E0 10 0E 00 10 40 01 00 00 00 00 00 00 00 00 00 ?...@..........
000E1030 00 00 00 00 04 11 0E 00 18 40 01 00 00 00 00 00 .........@......
000E1040 00 00 00 00 00 00 00 00 5A 12 0E 00 6C 40 01 00 ........Z...l@..
000E1050 00 00 00 00 00 00 00 00 00 00 00 00 58 19 0E 00 ............X...
000E1060 04 42 01 00 00 00 00 00 00 00 00 00 00 00 00 00 .B..............
000E1070 84 19 0E 00 14 42 01 00 00 00 00 00 00 00 00 00 ?...B..........
000E1080 00 00 00 00 D8 19 0E 00 28 42 01 00 00 00 00 00 ....?..(B......
000E1090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
根本没有这些数据。再搜索“000011BA”,也搜索不到,看来这些数据在脱壳时丢失了。现在得想加法补回去。
从原程序文件的偏移95000处到文件末尾复制后粘贴到脱壳后的文件末尾。我这里的起始地址是50D50。运行后程序还是提示原来的错误。什么原因?原来程序还是从偏移EOFBA处查找“000011BA”,当然找不到。好,现在得让程序从50D50处查找。我是直接修改:
0040189D E8 6A030000 CALL dumped_.00401C0C====>这个CALL是返回查找地址的,我直接改为MOV EAX,50D50 字节刚好。
004018A2 8BE8 MOV EBP,EAX
保存程序,运行OK。
附件:?2.part1.rar 附件:?2.part1.rar 附件:?2.part2.rar 附件:?2.part2.rar 附件:unpacked.rar 附件:unpacked.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)