📄 lesson14061.htm
字号:
;ebp-01 = 8 <br>
:004010F9 806DFF02 小循环开始处->sub byte ptr [ebp-01], 02
;现在ebp-01 是 8-2=6 <br>
:004010FD 0FB64DFE
movzx ecx, byte ptr [ebp-02] ;现在ECX是零 <br>
:00401101 81C1E8344000 add
ecx, 004034E8 ;加上异或后字节的地址 <br>
:00401107 8A01
mov al, byte ptr [ecx] ;将首字节放入AL <br>
:00401109 8A4DFF
mov cl, byte ptr [ebp-01] ;CL=6 <br>
:0040110C D2E8
shr al, cl
;右移6 BIT <br>
:0040110E 2403
and al, 03
;仅仅使用低字节 <br>
:00401110 E81EFFFFFF
call 00401033
;call!!!! <br>
:00401115 85C0
test eax, eax
;测试如果eax=0 <br>
:00401117 7411
je 0040112A
;如果为零就未注册 <br>
:00401119 0FB655FF
movzx edx, byte ptr [ebp-01] ;edx = ebp-01 <br>
:0040111D 85D2 小循环结束处->test edx, edx
;为零吗? <br>
:0040111F 75D8
jne 004010F9----->如不为零,则继续开始小循环
<br>
:00401121 FE45FE
inc [ebp-02]
;ebp-02 现在是 0+1=1 <br>
:00401124 807DFE12 主循环结束处->cmp byte ptr [ebp-02], 12
;ebp-02是否已是12h <br>
:00401128 75CB
jne 004010F5
;如不是,则开始跳到主循环处 <br>
:0040112A C9
leave <br>
:0040112B C3
ret <br>
<br>
这是CRACKME中最重要的一段程序.幸好我能看懂它.你会看到这有一个循环的嵌套.呵,双循环.我把它称做小循环和主循环.小循环的开始处EBP-1=8.每执行一次循环会减2.一直循环到EBP-1为零.那就是(8-2-2-2-2=0)
4次.然后离开小循环.但是在小循环中有个CALL.它可能在比较一些东西.如果EAX=0,它就会提前结束循环.所以在那个CALL里必须让EAX=1才能继续.而后EBP-02加1.直到循环12H次才会结束循环.
<br>
<br>
你会看到AL会先右移6,再右移4,又右移2,最后右移0.它每次都使用最低的两个位.一个字节是8位.所以,它先使用最左边的两个字节,然后使用中间偏左的那两个字节,再使用中间偏右的那两个字节,再使用最右边的那两个字节.是不是很有趣?一个字节仅是1或0.所以仅能包括:00
01 10 11 这四种情况. <br>
00b (二进制) = 00 (十进制) <br>
01b (二进制) = 01 (十进制) <br>
10b (二进制) = 02 (十进制) <br>
11b (二进制) = 03 (十进制) <br>
<br>
<br>
让我们看看这个CALL: <br>
:00401033 55
push ebp <br>
:00401034 8BEC
mov ebp, esp <br>
:00401036 83C4F8
add esp, FFFFFFF8 <br>
:00401039 8B1584314000 mov
edx, dword ptr [00403184] ;edx=16进制偏移量.'C'! <br>
:0040103F 8955FC
mov dword ptr [ebp-04], edx ;再移入ebp-04 <br>
:00401042 0AC0
or al, al
;al是0吗? <br>
:00401044 7509
jne 0040104F
;如不为0就跳 <br>
:00401046 832D8431400010 sub dword
ptr [00403184], 00000010 ;在减去16 <br>
:0040104D EB1F
jmp 0040106E <br>
:0040104F 3C01
cmp al, 01
;AL不为0,难道al=1? <br>
:00401051 7508
jne 0040105B
;如不相等则跳 <br>
:00401053 FF0584314000 inc
dword ptr [00403184] ;加1 <br>
:00401059 EB13
jmp 0040106E <br>
:0040105B 3C02
cmp al, 02
;al不是1和0,也许是2? <br>
:0040105D 7509
jne 00401068
;如不同就跳 <br>
:0040105F 83058431400010 add dword
ptr [00403184], 00000010 ;加16 <br>
:00401066 EB06
jmp 0040106E <br>
:00401068 FF0D84314000 dec
dword ptr [00403184] ;al既不是1也不是0,那么肯定就是 3 <br>
;如果al=3,那么就减1
<br>
:0040106E 8B1584314000 mov
edx, dword ptr [00403184] ;然后将它移入EDX <br>
:00401074 8A02
mov al, byte ptr [edx] ;再移入AL
<br>
:00401076 3C2A
cmp al, 2A
;是字符 2Ah('*')吗? <br>
:00401078 7506
jne 00401080
;如果不是就跳了 <br>
:0040107A 33C0
xor eax, eax
;将EAX清零后返回 <br>
:0040107C C9
leave
<br>
:0040107D C3
ret
<br>
<br>
为1时就会跳到401080 <br>
如果AL的值不是'*'的话,就会跳到这: <br>
<br>
:00401080 3C58
cmp al, 58
;检查是否是字符'X' <br>
:00401082 752F
jne 004010B3
;如果不等于就跳 <br>
:00401084 6A00
push 00000000
;下面显示 registered!!!! <br>
:00401086 8D1559334000 lea
edx, dword ptr [00403359] <br>
:0040108C 52
push edx <br>
:0040108D 8D15EC324000 lea
edx, dword ptr [004032EC] <br>
:00401093 52
push edx <br>
:00401094 6A00
push 00000000 <br>
:00401096 8D15AC174000 lea
edx, dword ptr [004017AC] <br>
:0040109C FFD2
call edx <br>
:0040109E 8D157B324000 lea
edx, dword ptr [0040327B] <br>
:004010A4 52
push edx <br>
:004010A5 FF3520344000 push
dword ptr [00403420] <br>
:004010AB 8D15DC174000 lea
edx, dword ptr [004017DC] <br>
:004010B1 FFD2
call edx <br>
<br>
:004010B3 8B1584314000 mov
edx, dword ptr [00403184] ;如果既不是'*'又不是'X' <br>
:004010B9 C60243
mov byte ptr [edx], 43 ;把 'C' 存入 <br>
:004010BC 8B55FC
mov edx, dword ptr [ebp-04] <br>
:004010BF C60220
mov byte ptr [edx], 20 <br>
:004010C2 B801000000
mov eax, 00000001 ;EAX=1后返回
<br>
:004010C7 C9
leave
<br>
:004010C8 C3
ret
;可以继续循环了 <br>
<br>
这是我们能够跟踪到的代码.像个迷宫,从C开始到X只有一条路. <br>
->"**************** <br>
->"C*......*...**** <br>
->".*.****...*....* <br>
->".*..**********.* <br>
->"..*....*...*...* <br>
->"*.****.*.*...*** <br>
->"*.*....*.******* <br>
->"..*.***..*.....* <br>
->".*..***.**.***.* <br>
->"...****....*X..* <br>
->"**************** <br>
开始是'C'.很明显你必须为'X'.在循环中AL先被异或.它被分为四步.每一步都会指向另一个位置.首先它测试AL是否为0.如果是的话,就减16.再循环!减去16后你将看到指针会移动到你当前字符的上方.
<br>
这是四种移动: <br>
00B = 上 <br>
01B = 右 <br>
10B = 下 <br>
11B = 左 <br>
<br>
必须在72步后指向'X'.还记得那个异或后的12H=18吗?18个字节被分为4步. 那么就是4*18=72.哈,那么行动吧! <br>
我写了第一个字节的四步.像这样: <br>
第一步必须向下 <br>
第一步必须向下 <br>
第一步必须向下 <br>
第一步必须向右 <br>
所以: <br>
第一步必须是10B <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -