【目 标】: PeSpin 1.1主程序
【工 具】: Olydbg1.1
【任 务】: unpack
【操作平台】: WINXP pro sp1
【作 者】: randomizer
【相关链接】: http://pespin.w.interia.pl/(作者的官方站点)
第一步:修复 iat
od加载后,隐藏od, 异常选项全部选中,执行程序,出现来自400000段中的异常,点确定。在004135AA进行如下修改
004135AA 9C PUSHFD ;原来
004135AB F71424 NOT DWORD PTR SS:[ESP]
004135AE 832424 01 AND DWORD PTR SS:[ESP],1
->
004135AA 6A 01 PUSH 1 ;修改成这样然后在这里下断点
004135AC 90 NOP
004135AD 90 NOP
004135AE 90 NOP
004135AF 90 NOP
004135B0 90 NOP
004135B1 90 NOP
shit+f9,停在004135AA
把00412D44开始的五个字节改成 JMP PESpin.00416D6D
00412D44 3917 CMP DWORD PTR DS:[EDI],EDX ; 原来
00412D46 EB 07 JMP SHORT PESpin.00412D4F
00412D48 FA CLI
->
00412D44 E9 FA410000 JMP PESpin.00416D6D ;修改成这样
再转到00416D6D输入如下一小段程序
00416D6D 3917 CMP DWORD PTR DS:[EDI],EDX
00416D6F 74 05 JE SHORT PESpin.00416D76
00416D71 47 INC EDI
00416D72 ^E2 F9 LOOPD SHORT PESpin.00416D6D
00416D74 EB 16 JMP SHORT PESpin.00416D8C
00416D76 807F FF 25 CMP BYTE PTR DS:[EDI-1],25
00416D7A 74 09 JE SHORT PESpin.00416D85
00416D7C 66:C747 FF FF25 MOV WORD PTR DS:[EDI-1],25FF
00416D82 8957 01 MOV DWORD PTR DS:[EDI+1],EDX
00416D85 8902 MOV DWORD PTR DS:[EDX],EAX
00416D87 ^E9 9AC0FFFF JMP PESpin.00412E26
00416D8C CC INT3
00416D8D CC INT3
然后转到0041379A设断点,F9执行程序,程序停在下面的时候把[esp]由 0改成 1
0041379A 50 PUSH EAX ;这里下断,程序停这里的时候把[esp]由 0改成 1
然后转到0041390D下断点,F9程序执行到这里, 呵呵,iat就搞好啦。
0041390D 2BC0 SUB EAX,EAX ;这里是原来 oep的语句,被偷在这里来了
第二步:decrypted crypted code
转到00416D8E,type in
00416D8E 60 PUSHAD
00416D8F BF 00104000 MOV EDI,PESpin.00401000
00416D94 B9 70B10000 MOV ECX,0B170
00416D99 B0 9C MOV AL,9C
00416D9B F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00416D9D 75 6C JNZ SHORT PESpin.00416E0B ;跳转表示第一种crypted code搞定啦
00416D9F 803F 60 CMP BYTE PTR DS:[EDI],60
00416DA2 ^75 F5 JNZ SHORT PESpin.00416D99
00416DA4 66:817F 23 619D CMP WORD PTR DS:[EDI+23],9D61
00416DAA ^75 ED JNZ SHORT PESpin.00416D99
00416DAC 4F DEC EDI
00416DAD 41 INC ECX
00416DAE 8D77 02 LEA ESI,DWORD PTR DS:[EDI+2]
00416DB1 51 PUSH ECX
00416DB2 57 PUSH EDI
00416DB3 C647 1C C3 MOV BYTE PTR DS:[EDI+1C],0C3
00416DB7 FFD6 CALL ESI
00416DB9 E8 08000000 CALL PESpin.00416DC6
00416DBE 5F POP EDI
00416DBF 59 POP ECX
00416DC0 ^EB D7 JMP SHORT PESpin.00416D99
00416DC2 CC INT3
00416DC3 CC INT3
00416DC4 CC INT3
00416DC5 CC INT3
00416DC6 81EF 512738D9 SUB EDI,D9382751
00416DCC 87D9 XCHG ECX,EBX
00416DCE B9 26000000 MOV ECX,26
00416DD3 B0 90 MOV AL,90
00416DD5 FC CLD
00416DD6 F3:AA REP STOS BYTE PTR ES:[EDI]
00416DD8 87D9 XCHG ECX,EBX
00416DDA 8A07 MOV AL,BYTE PTR DS:[EDI]
00416DDC FEC8 DEC AL
00416DDE C0C8 D1 ROR AL,0D1
00416DE1 C0C8 D7 ROR AL,0D7
00416DE4 FEC8 DEC AL
00416DE6 04 4E ADD AL,4E
00416DE8 32C1 XOR AL,CL
00416DEA C0C8 0F ROR AL,0F
00416DED FEC8 DEC AL
00416DEF 02C1 ADD AL,CL
00416DF1 AA STOS BYTE PTR ES:[EDI]
00416DF2 49 DEC ECX
00416DF3 ^75 E5 JNZ SHORT PESpin.00416DDA
00416DF5 66:813F EB0B CMP WORD PTR DS:[EDI],0BEB
00416DFA 75 0D JNZ SHORT PESpin.00416E09
00416DFC 66:817F 2E EB05 CMP WORD PTR DS:[EDI+2E],5EB
00416E02 75 05 JNZ SHORT PESpin.00416E09
00416E04 C647 01 33 MOV BYTE PTR DS:[EDI+1],33
00416E08 C3 RETN
00416E09 CC INT3
00416E0A CC INT3
00416E0B BF 00104000 MOV EDI,PESpin.00401000 ;这里开始解第二种crypted code
00416E10 B9 70B10000 MOV ECX,0B170
00416E15 B0 FF MOV AL,0FF
00416E17 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00416E19 75 5C JNZ SHORT PESpin.00416E77 ;跳转表示第二种crypted code搞定啦
00416E1B 803F 15 CMP BYTE PTR DS:[EDI],15
00416E1E ^75 F5 JNZ SHORT PESpin.00416E15
00416E20 8B57 01 MOV EDX,DWORD PTR DS:[EDI+1]
00416E23 81FA 3E554100 CMP EDX,PESpin.0041553E
00416E29 ^75 EA JNZ SHORT PESpin.00416E15
00416E2B 57 PUSH EDI
00416E2C 51 PUSH ECX
00416E2D 8B4F 05 MOV ECX,DWORD PTR DS:[EDI+5]
00416E30 81E9 D46AE877 SUB ECX,77E86AD4
00416E36 83C7 09 ADD EDI,9
00416E39 E8 14000000 CALL PESpin.00416E52
00416E3E E8 2A000000 CALL PESpin.00416E6D
00416E43 59 POP ECX
00416E44 5F POP EDI
00416E45 4F DEC EDI
00416E46 83E9 09 SUB ECX,9
00416E49 E8 1F000000 CALL PESpin.00416E6D
00416E4E ^EB C5 JMP SHORT PESpin.00416E15
00416E50 CC INT3
00416E51 CC INT3
00416E52 8A07 MOV AL,BYTE PTR DS:[EDI]
00416E54 C0C8 42 ROR AL,42
00416E57 04 D0 ADD AL,0D0
00416E59 02C1 ADD AL,CL
00416E5B FEC8 DEC AL
00416E5D 04 09 ADD AL,9
00416E5F FEC8 DEC AL
00416E61 34 2C XOR AL,2C
00416E63 C0C0 DA ROL AL,0DA
00416E66 FEC8 DEC AL
00416E68 AA STOS BYTE PTR ES:[EDI]
00416E69 49 DEC ECX
00416E6A ^75 E6 JNZ SHORT PESpin.00416E52
00416E6C C3 RETN
00416E6D 51 PUSH ECX
00416E6E 6A 0A PUSH 0A
00416E70 59 POP ECX
00416E71 B0 90 MOV AL,90
00416E73 F3:AA REP STOS BYTE PTR ES:[EDI]
00416E75 59 POP ECX
00416E76 C3 RETN
00416E77 CC INT3
00416E78 CC INT3
第三步:PE头stolen code的找回
输入下面的指令
00416E79 BF 00104000 MOV EDI,PESpin.00401000 ;开始对 “call 头部”的修复
00416E7E B9 70B10000 MOV ECX,0B170
00416E83 B0 E8 MOV AL,0E8
00416E85 F2:AE REPNE SCAS BYTE PTR ES:[EDI] ;查 call
00416E87 75 4D JNZ SHORT PESpin.00416ED6 ;跳转表示对头部 call 型搞定啦
00416E89 8B17 MOV EDX,DWORD PTR DS:[EDI]
00416E8B 8D543A 04 LEA EDX,DWORD PTR DS:[EDX+EDI+4]
00416E8F 81FA C8014000 CMP EDX,PESpin.004001C8
00416E95 ^72 EE JB SHORT PESpin.00416E85 ;跳表示不是调用头部
00416E97 81FA 28044000 CMP EDX,PESpin.00400428
00416E9D ^73 E6 JNB SHORT PESpin.00416E85 ;跳表示不是调用头部
00416E9F 51 PUSH ECX
00416EA0 57 PUSH EDI
00416EA1 6A FF PUSH -1
00416EA3 59 POP ECX
00416EA4 8BFA MOV EDI,EDX
00416EA6 B0 E9 MOV AL,0E9
00416EA8 F2:AE REPNE SCAS BYTE PTR ES:[EDI] ;查头部的“重定向”
00416EAA 75 28 JNZ SHORT PESpin.00416ED4
00416EAC 8B1F MOV EBX,DWORD PTR DS:[EDI]
00416EAE 8D5C3B 04 LEA EBX,DWORD PTR DS:[EBX+EDI+4] ;得到绝对地址
00416EB2 81FB 00104000 CMP EBX,PESpin.00401000
00416EB8 ^72 EE JB SHORT PESpin.00416EA8 ;跳表示不是“重定向”到代码段
00416EBA 81FB 70C14000 CMP EBX,PESpin.0040C170
00416EC0 ^73 E6 JNB SHORT PESpin.00416EA8 ;跳表示不是“重定向”到代码段
00416EC2 F7D1 NOT ECX
00416EC4 49 DEC ECX
00416EC5 85C9 TEST ECX,ECX
00416EC7 75 0B JNZ SHORT PESpin.00416ED4 ;ecx!=0表示在头部中要执行“一段代码”
00416EC9 5F POP EDI
00416ECA 59 POP ECX
00416ECB 2BDF SUB EBX,EDI
00416ECD 83EB 04 SUB EBX,4 ;得到偏移量
00416ED0 891F MOV DWORD PTR DS:[EDI],EBX ;修复
00416ED2 ^EB AF JMP SHORT PESpin.00416E83
00416ED4 CC INT3
00416ED5 CC INT3
00416ED6 BF 00104000 MOV EDI,PESpin.00401000 ;开始对 “jmp 头部”的修复,原理和前一段
00416EDB B9 70B10000 MOV ECX,0B170 ;差不多,就不重复了
00416EE0 B0 E9 MOV AL,0E9
00416EE2 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00416EE4 75 58 JNZ SHORT PESpin.00416F3E
00416EE6 8B17 MOV EDX,DWORD PTR DS:[EDI]
00416EE8 8D543A 04 LEA EDX,DWORD PTR DS:[EDX+EDI+4]
00416EEC 81FA C8014000 CMP EDX,PESpin.004001C8
00416EF2 ^72 EE JB SHORT PESpin.00416EE2
00416EF4 81FA 28044000 CMP EDX,PESpin.00400428
00416EFA ^73 E6 JNB SHORT PESpin.00416EE2
00416EFC 51 PUSH ECX
00416EFD 57 PUSH EDI
00416EFE 6A FF PUSH -1
00416F00 59 POP ECX
00416F01 8BFA MOV EDI,EDX
00416F03 B0 E9 MOV AL,0E9
00416F05 F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00416F07 75 36 JNZ SHORT PESpin.00416F3F
00416F09 8B1F MOV EBX,DWORD PTR DS:[EDI]
00416F0B 8D5C3B 04 LEA EBX,DWORD PTR DS:[EBX+EDI+4]
00416F0F 81FB 00104000 CMP EBX,PESpin.00401000
00416F15 ^72 EE JB SHORT PESpin.00416F05
00416F17 81FB 70C14000 CMP EBX,PESpin.0040C170
00416F1D ^73 E6 JNB SHORT PESpin.00416F05
00416F1F F7D1 NOT ECX
00416F21 49 DEC ECX
00416F22 85C9 TEST ECX,ECX
00416F24 74 0D JE SHORT PESpin.00416F33
00416F26 5F POP EDI
00416F27 290C24 SUB DWORD PTR SS:[ESP],ECX
00416F2A 90 NOP
00416F2B 8BF2 MOV ESI,EDX
00416F2D 4F DEC EDI
00416F2E F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00416F30 59 POP ECX
00416F31 ^EB AD JMP SHORT PESpin.00416EE0
00416F33 5F POP EDI
00416F34 59 POP ECX
00416F35 2BDF SUB EBX,EDI
00416F37 83EB 04 SUB EBX,4
00416F3A 891F MOV DWORD PTR DS:[EDI],EBX
00416F3C ^EB A2 JMP SHORT PESpin.00416EE0
00416F3E 61 POPAD
00416F3F CC INT3
00416F40 CC INT3
主要工作终于完成,呵呵。
第四步:PE头stolen code的找回
这个太容易了,当偶们修复 iat执行到伪 oep(0041390D)时,如下,
不妨单步让它运行到0041392B,就是那条 jmp语句啦
0041390D 2BC0 SUB EAX,EAX ;这里是原来 oep的语句,被偷在
0041390F 90 NOP ;这里来了
00413910 90 NOP
00413911 90 NOP
00413912 68 1D39ACE7 PUSH E7AC391D
00413917 810424 63979418 ADD DWORD PTR SS:[ESP],18949763
0041391E 50 PUSH EAX
0041391F 90 NOP
00413920 90 NOP
00413921 90 NOP
00413922 50 PUSH EAX
00413923 90 NOP
00413924 90 NOP
00413925 90 NOP
00413926 68 30394100 PUSH PESpin.00413930
0041392B -E9 C261FFFF JMP PESpin.00409AF2
00413930 68 3A394100 PUSH PESpin.0041393A
00413935 -E9 E261FFFF JMP PESpin.00409B1C
0041393A 3D B7000000 CMP EAX,0B7
0041393F 90 NOP
00413940 90 NOP
00413941 90 NOP
00413942 -E9 025AFFFF JMP PESpin.00409349 ;这里跳转到代码段
这时候的堆栈如下
0012F9B4 00413930 /CALL to CreateMutexA
0012F9B8 00000000 |pSecurity = NULL
0012F9BC 00000000 |InitialOwner = FALSE
0012F9C0 0040D080 \MutexName = "PE_SPIN_v1.1"
根据0041390D--00413942及堆栈数据,转到00409331,修复成:
00409331 68 80D04000 PUSH 0040D080
00409336 6A 00 PUSH 0
00409338 6A 00 PUSH 0
0040933A E8 B3070000 CALL 00409AF2
0040933F E8 D8070000 CALL 00409B1C
00409344 3D B7000000 CMP EAX,0B7
00409349
呵呵
第五步:恢复头部:
虽然不值一提,为完整,还是说说。另起一个od,载入PESpin,把它头部中的相关数据复制粘贴过来就好啦。
第六步:patch一个anti.
在代码段下ctrl+f,搜索sub bl,[eax],找到后改成 mov bl,0
终于搞完了,用LordPE dump,注意纠正imageSize哦,再用一下ImportREC,全部完成。
后记:
notepad的脱壳和这个差不多,但是它那里对 api的修复略有不同,因为它是call [xxx],这里是jmp [xxx],注意这个差别,
修复 api时的代码就有点不而已。
感谢你耐着性子看完这篇滥文。更感谢过程中给我帮助的一位前辈,还有各位老大。