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