• 标 题:皮特陈,这个是中文的不必翻译啦。 (7千字)
  • 作 者:飞刀浪子
  • 时 间:2001-6-4 12:15:47
  • 链 接:http://bbs.pediy.com

程序名:Crkme12.com 
这是皮特陈给我的3个DOS的CRACKME中的一个,另外的一个太简单,还有一个又太复杂,只有这个适中,所以用
他来写过程,也算对皮特陈有个交代,免得问的我连QQ都不敢上,呵呵。
跟踪工具:DEBUG

-U 100 L 142
128E:0100 E9EE00        JMP    01F1                             
    .
    .     
128E:01F1 E80000        CALL    01F4    ;跳到此处                       
128E:01F4 5D            POP    BP  ;取得相对偏移,这可是外壳病毒常用的手法哦
128E:01F5 33DB          XOR    BX,BX                             
128E:01F7 8BC3          MOV    AX,BX                             
128E:01F9 BFC300        MOV    DI,00C3                           
128E:01FC 893F          MOV    [BX],DI  ;将PSP+0的地方放一个RET,这可是有目的。
128E:01FE 81C39000      ADD    BX,0090  ;这个90做为结束代码的入口
128E:0202 53            PUSH    BX                               
128E:0203 2E            CS:                                     
128E:0204 FF363600      PUSH    [0036]  ;取段址,因是COM文件,其实没必要                       
128E:0208 1F            POP    DS                               
128E:0209 1E            PUSH    DS  ;此处压入DS,SI用做下面的RETF到程序入口用
128E:020A 56            PUSH    SI  ;!!!!!!这可是他的巧妙之处,后面再说
128E:020B 8D76E2        LEA    SI,[BP-1E]                       
128E:020E 8BFB          MOV    DI,BX                             
128E:0210 B90F00        MOV    CX,000F ;此处移动0F字节到PSP+90的地方,移了些什么,看注一
128E:0213 F2            REPNZ                                     
128E:0214 A4            MOVSB                                     
128E:0215 C64625BE      MOV    BYTE PTR [BP+25],BE  ;注意,此处会改变219的代码             
128E:0219 64            DB    64                ;被改为MOV SI,103               
128E:021A 0301          ADD    AX,[BX+DI]                       
128E:021C 66            DB    66    ;此处其实就是MOV EDX,[BP-0F],只不过DEBUG太老土,识别不了
128E:021D 8B56F1        MOV    DX,[BP-0F]                       
128E:0220 66            DB    66    ;同上                           
128E:0221 8B5EF5        MOV    BX,[BP-0B]                       
128E:0224 66            DB    66                               
128E:0225 8B6EF9        MOV    BP,[BP-07]                       
128E:0228 8B0E0101      MOV    CX,[0101]  ;CX为EE                       
128E:022C AC            LODSB              ;下面在做解码                       
128E:022D 66            DB    66        ;如果你用32位调试器就可以看到它们的真面目
128E:022E C1            DB    C1                               
128E:022F C20866        RET    6608                             
128E:0232 33D3          XOR    DX,BX                             
128E:0234 66            DB    66                               
128E:0235 03D5          ADD    DX,BP                             
128E:0237 66            DB    66                               
128E:0238 D3C5          ROL    BP,CL                             
128E:023A 32C2          XOR    AL,DL                             
128E:023C 8844FC        MOV    [SI-04],AL                       
128E:023F E2EB          LOOP    022C                             
128E:0241 CB            RETF    ;解码完毕,进入程序。如果程序正常执行会返回到128E:100处执行程序,                                ;如在DEBUG下,会返回到PSP+0的地方执行那条RET指令,之后回到PSP+90
                                ;的结束代码处,这就是上面那个SI的妙处

;此处为程序的入口,可以脱壳了,将BX=0,CX=EE,再取个名字,W 回写就不用我说了吧.
128E:0100 B409          MOV    AH,09                             
128E:0102 BA7201        MOV    DX,0172                           
128E:0105 CD21          INT    21                               
128E:0107 B40A          MOV    AH,0A                             
128E:0109 BAD201        MOV    DX,01D2                           
128E:010C CD21          INT    21                               
128E:010E B409          MOV    AH,09                             
128E:0110 BABA01        MOV    DX,01BA                           
128E:0113 CD21          INT    21                               
128E:0115 BF7201        MOV    DI,0172                           
128E:0118 33ED          XOR    BP,BP                             
128E:011A 33DB          XOR    BX,BX                             
128E:011C 33C0          XOR    AX,AX                             
128E:011E 33F6          XOR    SI,SI                             
128E:0120 56            PUSH    SI                               
128E:0121 BED201        MOV    SI,01D2  ;下面是一连串的运算                         
128E:0124 8A0ED301      MOV    CL,[01D3]  ;谁数学好,去做这道题吧,呵呵.                       
128E:0128 80C102        ADD    CL,02                             
128E:012B 50            PUSH    AX                               
128E:012C AC            LODSB                                     
128E:012D 8A25          MOV    AH,[DI]                           
128E:012F 84E4          TEST    AH,AH                             
128E:0131 7422          JZ    0155                             
128E:0133 02D8          ADD    BL,AL                             
128E:0135 1B45FE        SBB    AX,[DI-02]                       
128E:0138 12C4          ADC    AL,AH                             
128E:013A 03E8          ADD    BP,AX                             
128E:013C 86CB          XCHG    CL,BL                             
128E:013E D3D5          RCL    BP,CL                             
128E:0140 86CB          XCHG    CL,BL                             
128E:0142 AA            STOSB                                     
128E:0143 E2E7          LOOP    012C                             
128E:0145 58            POP    AX                               
128E:0146 5E            POP    SI                               
128E:0147 31AC6601      XOR    [SI+0166],BP  ;注三  ,此处的BP值随密码变动的
128E:014B 0F            DB    0F                               
128E:014C 95            XCHG    BP,AX                             
128E:014D C0            DB    C0                               
128E:014E 02E0          ADD    AH,AL                             
128E:0150 83C602        ADD    SI,+02                           
128E:0153 EBCB          JMP    0120                             
128E:0155 BAC501        MOV    DX,01C5                           
128E:0158 58            POP    AX                               
128E:0159 84E4          TEST    AH,AH    ;如想爆破,就是这里了                       
128E:015B 7503          JNZ    0160                             
128E:015D BACC01        MOV    DX,01CC                           
128E:0160 B409          MOV    AH,09                             
128E:0162 CD21          INT    21                               
128E:0164 5E            POP    SI                               
128E:0165 C3            RET     ;返回到PSP+90处执行退出代码。注二                           

注一:
128E:0090  33C0            XOR      AX,AX      ;程序执行完后将自己清0,想不让我们看他的代码
128E:0092  BF0001          MOV      DI,0100    ;在KV300中也有类似代码。
128E:0095  B9FFFE          MOV      CX,FEFF                             
128E:0098  F3              REPZ                                           
128E:0099  AA              STOSB         
128E:009A  B8004C          MOV      AX,4C00  ;由于程序破坏了PSP+0的代码,所以不能用INT 20结束 
128E:009D  CD21            INT      21
可以看出程序结束的最终代码在PSP+90的地方
注二:
我们脱壳后,此处已不在适合用RET了,我们可以用INT 20 或MOV AX,4C00,INT 21 来体面的结束它.
我用了INT 21来结束它,我们改了程序后,结果又被注三处改为其他代码,所以在注三处将[SI+166]改为[SI+16B]
也就是让他去修改后面的代码,只要不动到我的结束部分就行了.
其实我们还可以将程序裁剪小一些,留给你去做吧.

现在我讲一下那个SI的用处,其实就是程序正常执行时SI=IP=100,而在DEBUG下,SI被清0了,其中DX(它本该=DS)也一样,也有程序用它来做反跟踪。
我们只要用DEBUG载入程序后,手工将SI=100,就可正常进入程序入口了。说穿了,就是这么诈。

                                                  飞刀浪子  留
                                                            2001.6.4