• 标 题:PesPin 1.1外壳简略分析
  • 作 者:randomizer
  • 时 间:2005-01-08,22:14
  • 链 接:http://bbs.pediy.com

【目    标】: 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时的代码就有点不而已。
 
感谢你耐着性子看完这篇滥文。更感谢过程中给我帮助的一位前辈,还有各位老大。