老王旧壳之INT3异常、过期限制和数据附加脱壳分析,老王,脱壳技术 2008年06月23日 星期一 下午 05:22 【软件名称】: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。 |
|小黑屋|最新主题|手机版|微赢网络技术论坛 ( 苏ICP备08020429号 )
GMT+8, 2024-9-29 21:17 , Processed in 0.399411 second(s), 12 queries , Gzip On, MemCache On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.