首页
社区
课程
招聘
Crackme中的游戏-----贪吃蛇(菜鸟的第一次发文)
发表于: 2006-3-23 15:33 7623

Crackme中的游戏-----贪吃蛇(菜鸟的第一次发文)

2006-3-23 15:33
7623

Crackme中的游戏-----贪吃蛇


   某日,闲来无聊,从C盘浏览到F盘,又从F盘浏览到C盘。无意中翻出个CrackMe。反正无事,就当复习好了。不看不知道,一看还真不错,不只是单调的函数拉,贪吃蛇的小游戏一定玩过吧?注册的过程就是个贪吃蛇游戏。(本文适合和我一样入门级的朋友,所以注释得很罗嗦,高手莫笑。)


废话不多说~,FI检查,无壳。OllyDbg载入。这种CrackMe就是很适合我们菜鸟,无壳无花样。下断,到下面地址:


00401092        >>pushad                         //从这里开始,取得我们添入的信息,开始处理。


00401093        .>push 7F                       


00401095        .>push Snake.00401E00            


0040109A        .>push 3E8                       


0040109F        .>push dword ptr ds:[401F00]        


004010A5        .>call dword ptr ds:[<&USER32.Get>  ; \GetDlgItemTextA


004010AB        .>test eax,eax        ;下面一小段是判断是否输入姓名和注册码的,我们跳过一些代码


004010AD        .>jnz short Snake.004010CB


…………


00401103        >>call Snake.004012AA  ; 这个CALL对输入的注册码进行形式上判断


00401108        .>test al,al ; 跟进很容易知道注册码只能是0-9,A-F


0040110A        .>jnz short Snake.00401128  ;注册码不合要求,不跳出错


0040110C        .>push 30                        


0040110E        .>push Snake.00401400            ; |Title = "Error"


00401113        .>push Snake.00401464            ; |Text = "There is something wrong with your Serial..."


00401118        .>push dword ptr ds:[401F00]      ; |hOwner = 000B01A8 ('Snake ',class='#32770')


0040111E        .>call dword ptr ds:[<&USER32.Mes>; \MessageBoxA


00401124        .>popad


00401125        .>xor eax,eax


00401127        .>retn


00401128        >>call Snake.00401173             ;  这个CALL是将401B00到401BFF清零,在这区域两边添加16个FF,作为边界


0040112D        .>call Snake.0040119B   ;对名字进行处理的关键call


00401132        .>call Snake.0040120C   ;对注册码进行处理的关键call


00401137        .>test al,al


00401139        .>jnz short Snake.00401157 ; 跳则成功,不跳OVER。爆破这里OK,不过我们的目的是找算法。


我们先跟进对注册名处理的CALL:


0040119B       /$>push eax


0040119C       |.>push ecx


0040119D       |.>push edx


0040119E       |.>push esi


0040119F       |.>push edi


004011A0       |.>xor ecx,ecx


004011A2       |.>mov esi,Snake.00401E00       ; 这是保存注册名的地址


004011A7       |.>mov edi,Snake.00401B00      ;记的前面1个CALL清零的区域不?这就是这区域的开始地址,也就是我们贪吃蛇的游戏范围


004011AC       |.>push esi


004011AD       |.>mov dl,0


004011AF       |>>/mov al,byte ptr ds:[esi]  ;[esi]保存的注册名


004011B1       |.>|inc esi


004011B2       |.>|add dl,al


004011B4       |.>|test al,al    ; 对名字各位求和,取低8位,记为S,即求和后与0x000000FF作与运算


004011B6       |.>\jnz short Snake.004011AF


004011B8       |.>pop esi


循环1:这个循环作用是产生名字长度个“CC”标志


004011B9       |>>/movzx eax,byte ptr ds:[esi]    ;  取名字的1位


004011BC       |.>|xor al,dl                      ;  记T=Name[n] XOR S;


004011BE       |>>|/sub dl,al           ;  S=(S-T)AND 000000FF(注意是低8位运算,始终只取低8位,所以我们算的时候要与0x000000FF作与运算


004011C0       |.>||or byte ptr ds:[edi+eax],0CC  ;  [401b00+T]=CC;


004011C4       |.>||jnz short Snake.004011CA   ;??上一步结果不可能为0


004011C6       |.>||dec dl


004011C8       |.>|\jmp short Snake.004011BE


004011CA       |>>|inc ecx    ;记数器,注册名长度为几,ecx+几次


004011CB       |.>|inc esi  


004011CC       |.>|cmp byte ptr ds:[esi],0  ; 注册名是否取完


004011CF       |.>\jnz short Snake.004011B9


上面这循环,在401B00-401BFF这段地址产生CC标志,即我们这游戏中蛇要吃的果子,其实,只要多看下就知道这段程序有问题,我在文末还会说明下。


循环2:这个循环是找个位置放‘DD’标志


004011D1       |.>mov dword ptr ds:[401F04],ecx   ;  名字长度


004011D7       |.>xor dl,al                       ;  S=S XOR T;


004011D9       |>>/sub al,dl                    ; T=(T-S) AND 0x000000FF;


004011DB       |.>|cmp byte ptr ds:[edi+eax],0CC  ;  比较是不是已经放了CC标志了


004011DF       |.>|jnz short Snake.004011E5       ; 不是就存放DD标志


004011E1       |.>|dec dl                         ;  是CC标志就再找位置


004011E3       |.>\jmp short Snake.004011D9       ;   


004011E5       |>>mov byte ptr ds:[edi+eax],0DD   ;   [401B00+T]=DD


004011E9       |.>mov al,dl                     ;  T=S;


这个小循环是找个没存放CC标志的位置放DD标志,后面我们可以知道,DD是最后1个果子


循环3:找个位置放99标志,从下面可知,99是蛇头


004011EB       |>>/cmp byte ptr ds:[edi+eax],0CC  ;  


004011EF       |.>|je short Snake.004011F7        ;  寻找1个既没存放CC,也没存放DD标志的位置


004011F1       |.>|cmp byte ptr ds:[edi+eax],0DD  ;  


004011F5       |.>|jnz short Snake.004011FB       ;  


004011F7       |>>|dec al


004011F9       |.>\jmp short Snake.004011EB


004011FB       |>>lea eax,dword ptr ds:[edi+eax]


004011FE       |.>mov byte ptr ds:[eax],99        ;  [401BDD+T]=99;


00401201       |.>mov dword ptr ds:[401700],eax


00401206       |.>pop edi


00401207       |.>pop esi


00401208       |.>pop edx


00401209       |.>pop ecx


0040120A       |.>pop eax


0040120B       \.>retn


从上面的分析可以知道,对注册名的处理结果是在401B00至401BFF的空间中产生数量与注册名长度相等的’CC’标志以及1个’DD’标志和1个’99’标志.


下面我们再跟进对注册码进行处理的CALL:


0040120C       /$>pushad                        ;  游戏开始,准备好吃果子了。


0040120D       |.>mov esi,Snake.00401D00          ;  注册码地址


00401212       |.>mov edi,Snake.00401700          ;  "99"标志的地址


00401217       |>>/movzx eax,byte ptr ds:[esi]    ;  取注册码的1位 记作PASS[n]


0040121A       |.>|test al,al                     ;


0040121C       |.>|je short Snake.00401260  


0040121E       |.>|sub al,30                  ;这几句ASCII码变成0-15的数字


00401220       |.>|cmp al,0A                    ;  


00401222       |.>|jb short Snake.00401226        ;  PASS[n]<10在401226处理


00401224       |.>|sub al,7                      ;  若是字母,就-7,结果是A=10,B=11…F=15


00401226       |>>|mov ecx,eax                 ;  


00401228       |.>|and al,3                      ;  即PASS[n] MOD 4


0040122A       |.>|shr cl,2                      ;  PASS[n]/4,是整数相除,ECX即下面的K


0040122D       |.>|mov edx,10     ;edx是每次蛇移动的距离


00401232       |.>|test al,al          ;看PASS[n] MOD 4是否为0


[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 225
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
补上crackme.
上传的附件:
2006-3-23 15:42
0
雪    币: 434
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
对于注册名长度不等于CC个数的问题,可以在填充CC的时候先做下判断,如果此位置已经有CC了,那么我们可以给al加一个随机的偏移,跳到另外一个地方填充CC,这样保证CC的个数等于注册名的长度。不然,如作者所说,当填充CC个数和用户名长度不等时,永远不能成功。

004011B9  |> /0FB606        /movzx   eax, byte ptr [esi]
004011BC  |. |32C2          |xor     al, dl
004011BE  |> |2AD0         |/sub     dl, al

L_add:
|cmp  byte ptr [edi+eax],0CC
    |jnz short 004011C0

    |add al,3C

    |jmp short L_add


004011C0  |. |800C07 CC  ||or      byte ptr [edi+eax], 0CC
004011C4  |. |75 04         ||jnz     short 004011CA
004011C6  |. |FECA          ||dec     dl
004011C8  |.^|EB F4        |\jmp     short 004011BE
004011CA  |> |41            |inc     ecx
004011CB  |. |46             |inc     esi
004011CC  |. |803E 00     |cmp     byte ptr [esi], 0
004011CF  |.^\75 E8        \jnz     short 004011B9

考虑了下注册机,感觉没有很好的算法~~哎,悲催啊
2012-9-4 00:12
0
游客
登录 | 注册 方可回帖
返回