【标  题】在98系统下用OD脱PEtite 2.X壳一法

【作  者】小虾(战神[DFCG])

【日  期】2004-11-22

【使用工具】OllyDBG, ImportREC

【主  页】http://www.chinadfcg.com

【平  台】windows98系统

【练习程序】win98下的记事本

【下载地址】实例点击下载

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
【正  文】

  呵呵,近来一直很忙,都没有时间再玩Cracker了(最多上坛子灌灌水),这一天比较闲,就试试在98系统下来脱PEtite 2.2的壳(顺便看看能不能坐上精华六的末班车)。这个壳属于入门级的加密壳,如果在XP系统下UnPack完全可以秒杀。但若在98系统中可有点不太好脱(使用SoftICE也可以秒杀这个壳,但是用TRW2000和OllyDBG的话...)。

  废话少说,现在来看看为什么98下不好脱这个壳。首先启动OD,在OD调试选项中除Kernel32中的异常选上之外其余全部不要选。然后加载目标程序,

代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;载入程序后选不分析代码后将中断在0040D042外壳的入口处 ;经这跟踪,得知以下代码只是解压数据,不必细跟,现按F9直接运行程序 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040D042 >  B8 00D04000     MOV EAX,NOTEPAD.0040D000 0040D047    68 4C584000     PUSH NOTEPAD.0040584C  ;0040584c入栈, 0040D04C    64:FF35 0000000>PUSH DWORD PTR FS:[0]  ;记住这个地址 0040D053    64:8925 0000000>MOV DWORD PTR FS:[0],ESP  ;挂SEH,当程序产生异常后将跳到0040584C处继续运行。 0040D05A    66:9C           PUSHFW 0040D05C    60              PUSHAD 0040D05D    50              PUSH EAX 0040D05E    68 00004000     PUSH NOTEPAD.00400000


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;当程序数据解压完毕后将在这里产生一个写入异常 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040D135    A4              MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]  ;产生内存写入异常 0040D136    33C9            XOR ECX,ECX 0040D138    83FB 00         CMP EBX,0 0040D13B  ^ 7E A4           JLE SHORT NOTEPAD.0040D0E1 0040D13D    E8 AAFFFFFF     CALL NOTEPAD.0040D0EC 0040D135    A4              MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 0040D136    33C9            XOR ECX,ECX 0040D138    83FB 00         CMP EBX,0 0040D13B  ^ 7E A4           JLE SHORT NOTEPAD.0040D0E1 0040D13D    E8 AAFFFFFF     CALL NOTEPAD.0040D0EC


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;在前面我们已经知道程序产生异常后将跳到0040584C处继续运行 ;所以我们在命令行中输入“BP 0040584C"处下一个INT 3断点 ;按Shift+F9运行忽略异常,程序将中断在0040584C处, ;到这里后我们就要慢慢的跟踪了。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040584C    E8 4F000000     CALL NOTEPAD.004058A0  ;变形Call,F7进入 00405851    D9D7            FST EDI 00405853  ^ 71 AC           JNO SHORT NOTEPAD.00405801 00405855  ^ E0 B9           LOOPDNE SHORT NOTEPAD.00405810 00405857    58              POP EAX 00405858    098E CDC22DD8   OR DWORD PTR DS:[ESI+D82DC2CD],ECX


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;进入后到这里, ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004058A0    33C0            XOR EAX,EAX 004058A2    5E              POP ESI 004058A3    64:8B18         MOV EBX,DWORD PTR FS:[EAX] 004058A6    8B1B            MOV EBX,DWORD PTR DS:[EBX] 004058A8    8D63 D6         LEA ESP,DWORD PTR DS:[EBX-2A] 004058AB    5D              POP EBP 004058AC    8D8E BD020000   LEA ECX,DWORD PTR DS:[ESI+2BD] 004058B2    894B 04         MOV DWORD PTR DS:[EBX+4],ECX 004058B5    64:891D 0000000>MOV DWORD PTR FS:[0],EBX 004058BC    8B3C24          MOV EDI,DWORD PTR SS:[ESP] 004058BF    81C7 39000000   ADD EDI,39 004058C5    6A 0E           PUSH 0E 004058C7    59              POP ECX 004058C8    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[> 004058CA    FF33            PUSH DWORD PTR DS:[EBX] 004058CC    56              PUSH ESI 004058CD    57              PUSH EDI 004058CE    8DB7 71010000   LEA ESI,DWORD PTR DS:[EDI+171] 004058D4    8BCE            MOV ECX,ESI 004058D6    2BCF            SUB ECX,EDI 004058D8    F3:AA           REP STOS BYTE PTR ES:[EDI]


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;单步运行到这里时,程序开始设置单步异常 ;这时,不能再单步跟踪了,不然等下解压出的代码就不正确了 ;按F9运行程序 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004058DA    60              PUSHAD 004058DB    66:9C           PUSHFW 004058DD    0FBA3C24 08     BTC DWORD PTR SS:[ESP],8 004058E2    66:9D           POPFW 004058E4    5B              POP EBX


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;单步异常,我们在004058E6处下一个断点,按Shift+F9忽略异常 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004058E5    5A              POP EDX      ;单步异常


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;程序中断这里,POP DWORD PTR FS:[0]语句,典型的释放异常代码 ;到这里开始程序已常没有异常了。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004058E6    64:8F05 0000000>POP DWORD PTR FS:[0]  ;释放异常 004058ED    58              POP EAX 004058EE    6A 00           PUSH 0 004058F0    53              PUSH EBX 004058F1    33DB            XOR EBX,EBX 004058F3    68 3D030000     PUSH 33D


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;到这里要注意了,OllyDBG在98系统为什么脱不了这个壳,关键点就在下面 ;这下面的代码是解密跨段跳到入口的代码,若这里解密不成功,我们就找不 ;到程序的OEP了。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004058F8    8B0C24          MOV ECX,DWORD PTR SS:[ESP] 004058FB    0FBAE3 00       BT EBX,0 004058FF    72 16           JB SHORT NOTEPAD.00405917 00405901    64:8B35 1C00000>MOV ESI,DWORD PTR FS:[1C] 00405908    0FBAF6 00       BTR ESI,0


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;0040590C是最关健的一句,只要将这一句NOP掉,我们就能找到程序的跨段 ;跳到OEP的代码。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040590C    64:0335 2200000>ADD ESI,DWORD PTR FS:[22]  ;将这一句NOP掉 00405913    46              INC ESI 00405914    66:33DE         XOR BX,SI 00405917    321C11          XOR BL,BYTE PTR DS:[ECX+EDX] 0040591A    C1C3 07         ROL EBX,7 0040591D    49              DEC ECX 0040591E  ^ 7D DB           JGE SHORT NOTEPAD.004058FB 00405920    8D48 37         LEA ECX,DWORD PTR DS:[EAX+37] 00405923    3119            XOR DWORD PTR DS:[ECX],EBX 00405925    3159 04         XOR DWORD PTR DS:[ECX+4],EBX 00405928    3159 08         XOR DWORD PTR DS:[ECX+8],EBX 0040592B    3159 0C         XOR DWORD PTR DS:[ECX+C],EBX 0040592E    59              POP ECX 0040592F    315C11 01       XOR DWORD PTR DS:[ECX+EDX+1],EBX ;解密后的代码 00405933    33DB            XOR EBX,EBX 00405935    8BF2            MOV ESI,EDX


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;单步反跟踪,若是单步跟踪到这里的话,比较结果将不相同。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 00405937    81BA 71A8FFFF 4>CMP DWORD PTR DS:[EDX+FFFFA871],0D042 00405941    75 21           JNZ SHORT NOTEPAD.00405964  ;跳就OVER了 00405943    81EE B7570000   SUB ESI,57B7 00405949    0FB64E 06       MOVZX ECX,BYTE PTR DS:[ESI+6] 0040594D    6BC9 0A         IMUL ECX,ECX,0A 00405950    66:81C1 3E00    ADD CX,3E 00405955    331E            XOR EBX,DWORD PTR DS:[ESI] 00405957    D3C3            ROL EBX,CL 00405959    83C6 04         ADD ESI,4 0040595C    49              DEC ECX 0040595D  ^ 75 F6           JNZ SHORT NOTEPAD.00405955 0040595F    3958 04         CMP DWORD PTR DS:[EAX+4],EBX  ;再比较 00405962    74 08           JE SHORT NOTEPAD.0040596C   ;不跳就OVER 00405964    83C4 2A         ADD ESP,2A 00405967  - E9 A9760000     JMP NOTEPAD.0040D015      ;OVER 0040596C    BE 00600000     MOV ESI,6000 00405971    03F5            ADD ESI,EBP 00405973    8D8D 00080000   LEA ECX,DWORD PTR SS:[EBP+800] 00405979    8BD8            MOV EBX,EAX 0040597B    833E 00         CMP DWORD PTR DS:[ESI],0


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;0040597E最后跳到00405B92将跳出大循环,所以我们在00405B92处下断 ;F9运行程序。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040597E    0F84 0E020000   JE NOTEPAD.00405B92 00405984    51              PUSH ECX 00405985    51              PUSH ECX 00405986    FF95 90070000   CALL DWORD PTR SS:[EBP+790]


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;程序中断在这里。 00405B92    59              POP ECX 00405B93    5E              POP ESI 00405B94    FD              STD 00405B95    33C0            XOR EAX,EAX 00405B97    B9 56030000     MOV ECX,356 00405B9C    E8 98740000     CALL NOTEPAD.0040D039


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;这个Call若是前面没有经过处理,将是以下的样子。这个Call是我没有处理 ;上面的代码所得到的结果,可以看出和上面的Call地址完全不一样,我们若是 ;再走一步程序就OVER了。 ;00405B9C    E8 7AA55CB5     CALL B59D011B ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;经过上面的Call之后来到这里。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 0040D039    5F              POP EDI 0040D03A    F3:AA           REP STOS BYTE PTR ES:[EDI] 0040D03C    61              POPAD 0040D03D    66:9D           POPFW 0040D03F    83C4 08         ADD ESP,8 0040D042 >- E9 8540FFFF     JMP NOTEPAD.004010CC ;跳到记事本入口, 0040D047  - E9 22204566     JMP SHELL32.DragFinish


代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;记事本入口,以后的事不用我说了吧,DOWN和修复。 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 004010CC  /.  55            PUSH EBP 004010CD  |.  8BEC          MOV EBP,ESP 004010CF  |.  83EC 44       SUB ESP,44 004010D2  |.  56            PUSH ESI 004010D3  |.  FF15 E4634000 CALL DWORD PTR DS:[4063E4]                       ; [GetCommandLineA 004010D9  |.  8BF0          MOV ESI,EAX 004010DB  |.  8A00          MOV AL,BYTE PTR DS:[EAX] 004010DD  |.  3C 22         CMP AL,22 004010DF  |.  75 1B         JNZ SHORT NOTEPAD.004010FC


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
【总  结】
  这个壳怪就怪在0040590C处的ADD ESI,DWORD PTR FS:[22]这一句上,这一句语句当我们没有加载OD时和加载OD时得出的值完全不同(在98系统),我曾用汇编测试过这一句,结果也一样,用OD加载和不用OD加得出的结果完全不同,也就是这一句语句令到程序解码错误,从而没办法在98下脱壳(在2K和XP下则没有这情况)。搞不明白FS:[22h]的内存地址和OD和有什么关系,望知道的说一下,不胜感激。

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
【声  明】本文欢迎转载,但请保持文章完整性。谢谢!
                                                 ----战神 2004-11-22