首页
社区
课程
招聘
[原创]四个入门级CrackMe详尽分析之一---献给和我一样刚入门的初哥初姐
发表于: 2009-11-8 01:44 34115

[原创]四个入门级CrackMe详尽分析之一---献给和我一样刚入门的初哥初姐

2009-11-8 01:44
34115

【标    题】 四个入门级CrackMe详尽分析之一
【作    者】 dickpj
【邮    箱】 996658218@qq.com
【软件名称】 CrackMe v1.0
【软件作者】 Cruehead/MiB
【软件大小】 12K
【软件出处】 PEDIY_CrackMe_2007
【破解声明】 我是一只小菜鸟,偶有一点心得,愿与大家分享。失误之处敬请诸位大侠赐教!
【破解工具】 PEiD,OD   

学习破解没多久,只能进行简单的爆破。曾就一爆破的软件向前辈们讨教算法分析,却得不到回应。求人不如求己,于是苦读汇编,苦练Crackme。现就自己Crack过的简单的小程序总结一下,与像我一样的新手交流。

一、PEiD查壳,显示MASM32 / TASM32 [Overlay]。试运行,点Help/Register随便输入Name、Serial,提示No luck there,mate!
二、OD载入,运行,下GetWindowTextA断点,返回程序输入任意注册信息,点OK,被OD断下:

77D3216B >  6A 0C           PUSH 0C
77D3216D    68 D021D377     PUSH USER32.77D321D0
77D32172    E8 4964FEFF     CALL USER32.77D185C0
77D32177    8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
……
……

取消77D3216B处断点,选择调试下执行到用户代码,逐步跟踪:
004012B5  |.  6A 0B         |PUSH 0B                                 ; /Count = B (11.)!!!!!!!!!
004012B7  |.  68 8E214000   |PUSH CRACKME1.0040218E                  ; |X
004012BC  |.  68 E8030000   |PUSH 3E8                                ; |ControlID = 3E8 (1000.)
004012C1  |.  FF75 08       |PUSH DWORD PTR SS:[EBP+8]               ; |hWnd
004012C4  |.  E8 07020000   |CALL <JMP.&USER32.GetDlgItemTextA>      ; \GetDlgItemTextA
004012C9  |.  83F8 01       |CMP EAX,1                               ;  是否输入用户名
004012CC  |.  C745 10 EB030>|MOV DWORD PTR SS:[EBP+10],3EB
004012D3  |.^ 72 CC         \JB SHORT CRACKME1.004012A1
004012D5  |.  6A 0B         PUSH 0B                                  ; /Count = B (11.)
004012D7  |.  68 7E214000   PUSH CRACKME1.0040217E                   ; |x
004012DC  |.  68 E9030000   PUSH 3E9                                 ; |ControlID = 3E9 (1001.)
004012E1  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004012E4  |.  E8 E7010000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004012E9  |.  B8 01000000   MOV EAX,1
004012EE  |.  EB 07         JMP SHORT CRACKME1.004012F7
004012F0  |>  B8 00000000   MOV EAX,0
004012F5  |.^ EB 8D         JMP SHORT CRACKME1.00401284
004012F7  |>  50            PUSH EAX                                 ; /Result
004012F8  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004012FB  |.  E8 B2010000   CALL <JMP.&USER32.EndDialog>             ; \EndDialog
00401300  |.  B8 01000000   MOV EAX,1
00401305  \.^ E9 7AFFFFFF   JMP CRACKME1.00401284

返回到:
77D18734    64:8B0D 1800000>MOV ECX,DWORD PTR FS:[18]
77D1873B    80A1 B40F0000 0>AND BYTE PTR DS:[ECX+FB4],0
……
……

注意OD标题栏,为CPU - 主线程 - 模块 - USER32,系统领空,执行到用户代码:
00401223   .  83F8 00       CMP EAX,0
00401226   .^ 74 BE         JE SHORT CRACKME1.004011E6
00401228   .  68 8E214000   PUSH CRACKME1.0040218E                   ;  X压入用户名
0040122D   .  E8 4C010000   CALL CRACKME1.0040137E                   ;  关键CALL1
00401232   .  50            PUSH EAX
00401233   .  68 7E214000   PUSH CRACKME1.0040217E                   ;  x压入假码
00401238   .  E8 9B010000   CALL CRACKME1.004013D8                   ;  关键CALL2
0040123D   .  83C4 04       ADD ESP,4
00401240   .  58            POP EAX                                  ;  值出栈送到EAX
00401241   .  3BC3          CMP EAX,EBX                              ;  关键比较 爆破点
00401243      74 07         JE SHORT CRACKME1.0040124C               ;  关键跳转 爆破点
……
……

跟入关键CALL1:
0040137E >/$  8B7424 04     MOV ESI,DWORD PTR SS:[ESP+4]             ;  用户名地址送ESI
00401382  |.  56            PUSH ESI
00401383  |>  8A06          /MOV AL,BYTE PTR DS:[ESI]                ;  用户名首字母送AL
00401385  |.  84C0          |TEST AL,AL                              ;  是否转换结束
00401387  |.  74 13         |JE SHORT CRACKME1.0040139C
00401389  |.  3C 41         |CMP AL,41                               ;  与A比较即判断是否为字母,如不是则Game over
0040138B  |.  72 1F         |JB SHORT CRACKME1.004013AC
0040138D  |.  3C 5A         |CMP AL,5A                               ;  与Z比较
0040138F  |.  73 03         |JNB SHORT CRACKME1.00401394
00401391  |.  46            |INC ESI
00401392  |.^ EB EF         |JMP SHORT CRACKME1.00401383
00401394  |>  E8 39000000   |CALL CRACKME1.004013D2                  ;  如为小写字母则变为大写并替换原字母
00401399  |.  46            |INC ESI                                 ;  ESI加1指向下一位
0040139A  |.^ EB E7         \JMP SHORT CRACKME1.00401383             ;  继续
0040139C  |>  5E            POP ESI                                  ;  转换为大写的用户名
0040139D  |.  E8 20000000   CALL CRACKME1.004013C2                   ;  将用户名每一位ASC值累加到EDI
004013A2  |.  81F7 78560000 XOR EDI,5678                             ;  与5678异或
004013A8  |.  8BC7          MOV EAX,EDI                              ;  送到EAX
004013AA  |.  EB 15         JMP SHORT CRACKME1.004013C1              ;  返回
004013AC  |>  5E            POP ESI
004013AD  |.  6A 30         PUSH 30                                  ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF  |.  68 60214000   PUSH CRACKME1.00402160                   ; |No luck!
004013B4  |.  68 69214000   PUSH CRACKME1.00402169                   ; |No luck there, mate!
004013B9  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
004013BC  |.  E8 79000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
004013C1  \>  C3            RETN

CALL 004013D2:
004013D2  /$  2C 20         SUB AL,20                                ;减去20
004013D4  |.  8806          MOV BYTE PTR DS:[ESI],AL                 ;替换原字母
004013D6  \.  C3            RETN

CALL 004013C2:
004013C2  /$  33FF          XOR EDI,EDI                              ;  本CALL的作用为将每一位ASC值累加到EDI
004013C4  |.  33DB          XOR EBX,EBX
004013C6  |>  8A1E          /MOV BL,BYTE PTR DS:[ESI]                ;  用户名ASC值依次送BL
004013C8  |.  84DB          |TEST BL,BL                              ;  是否运算结束
004013CA  |.  74 05         |JE SHORT CRACKME1.004013D1              ;  结束则跳
004013CC  |.  03FB          |ADD EDI,EBX                             ;  累加到EDI
004013CE  |.  46            |INC ESI                                 ;  指向下一位
004013CF  |.^ EB F5         \JMP SHORT CRACKME1.004013C6
004013D1  \>  C3            RETN

跟入关键CALL2:
004013D8  /$  33C0          XOR EAX,EAX
004013DA  |.  33FF          XOR EDI,EDI
004013DC  |.  33DB          XOR EBX,EBX
004013DE  |.  8B7424 04     MOV ESI,DWORD PTR SS:[ESP+4]             ;  假码地址送ESI
004013E2  |>  B0 0A         /MOV AL,0A                               ;  AL=0A(10)
004013E4  |.  8A1E          |MOV BL,BYTE PTR DS:[ESI]                ;  假码ASC值依次送BL
004013E6  |.  84DB          |TEST BL,BL                              ;  是否计算完
004013E8  |.  74 0B         |JE SHORT CRACKME1.004013F5              ;  计算完则跳出
004013EA  |.  80EB 30       |SUB BL,30                               ;  减去30,即变为数值形式
004013ED  |.  0FAFF8        |IMUL EDI,EAX                            ;  EDI*0A
004013F0  |.  03FB          |ADD EDI,EBX                             ;  再加该位的数字值
004013F2  |.  46            |INC ESI                                 ;  指针加1
004013F3  |.^ EB ED         \JMP SHORT CRACKME1.004013E2             ;  继续下一位
004013F5  |>  81F7 34120000 XOR EDI,1234                             ;  与1234异或
004013FB  |.  8BDF          MOV EBX,EDI                              ;  送到EBX
004013FD  \.  C3            RETN

三、注册算法总结
  1 用户名首先全部转换为大写字母,然后将每位ASC值累加,再与0X5678异或,形成A;
  2 将注册码由字符形式转换为数值形式("12345678"变为数字12345678),与0x1234异或,形成B;
  3 如A=B,注册成功,否则失败。

四、注册机源码 VB 6.0
  
  在编写注册机时发现,一旦用户名超过10位则形成的注册码无效。经过跟踪,才发现程序用于计算的用户名只取前11位,而限定这个10

位的地方就在004012B5  |. 6A 0B  |PUSH 0B ; /Count = B (11.)即我们一开始对话框中断的地方!而我们习惯输入的注册名一般不超过

10位,跟踪程序过程中不会发现异常,而一旦编写出注册机,则会出现错误。佩服作者,又学了一手。

Private Sub Command1_Click()
Dim i, m As Integer
Dim s As String
If IsLetter(Text1.Text) <> 1 Then
   MsgBox ("用户名不得为空,且只能为英文字母!")
Else
  s = Text1.Text
  s = UCase(s)
  m = 0
  For i = 1 To Len(s)
      If i = 11 Then Exit For       '教训啊!!!
      m = m + Asc(Mid(s, i, 1))
  Next i
  m = m Xor &H5678
  m = m Xor &H1234
  Text2.Text = Trim(Str(m))
End If
End Sub

Function IsLetter(lstr As String) As Integer

'判断一个字符串是否为全为字母,如全为英文字母返回值为1,包含非字母返回值为2,未输入返回值为0。
Dim i As Integer
If lstr = "" Then
   IsLetter = 0
   Exit Function
Else
   IsLetter = 1
   For i = 1 To Len(lstr)
       If Not ((Asc(Mid(lstr, i, 1)) > 64 And Asc(Mid(lstr, i, 1)) < 91) Or (Asc(Mid(lstr, i, 1)) > 96 And Asc(Mid(lstr,

i, 1)) < 123)) Then
       IsLetter = 2
       Exit Function
       End If
    Next i
End If
End Function

五、破解总结
    该CrackMe非常简单,对新手来说是一个非常好的试炼程序。比如领空概念,如果对此不熟悉将会陷入系统领空;再比如调试技巧,

跟踪时需要多次重载程序,如没有很好的跟踪习惯及时在关键位置设置断点,将导致跟踪效率低下;再比如API调用时参数的把握,

004012B5处就是教训;再比如英文字母大小写转换等常用换算、常用API断点设置等等。
    感谢作者为我们初学者做的贡献。
    感谢Kanxue、Piaoyun、Nisy、Tigerisme、NBA2005等很多前辈,我是看着你们的教程成长起来的新手。
    希望新入门的朋友和我一起进步。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (53)
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
顶一下  大牛都是菜菜的结晶!!!!

总有一天我们也会起飞
2009-11-13 23:16
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
文章很详细,学习了
2009-11-13 23:20
0
雪    币: 149
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
支持下……
2009-11-14 12:38
0
雪    币: 505
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢,支持一下
2009-11-14 13:15
0
雪    币: 91
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
学习了,为我们新人加油。
2009-11-22 21:16
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢分享过程
2009-11-24 00:16
0
雪    币: 160
活跃值: (209)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好.对新手来说确实不错.
2009-11-28 18:34
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
一直以来都想知道crackMe什么意思。
2009-12-1 08:32
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习了,看雪的入门教程真不错啊。。。。。。
2009-12-3 10:26
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
附件传上来搞一下啊
2010-1-29 10:26
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
SORRY,打错了,我不是灌水。
2010-1-29 10:27
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
入门教程真不错啊
2010-2-15 15:12
0
雪    币: 65
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
路过。支持下楼主
2010-2-27 19:15
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
顶一个,一定要顶上去,必须的!
2010-3-9 17:31
0
雪    币: 204
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
感谢。。学习了
2010-3-11 11:53
0
雪    币: 160
活跃值: (56)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
谢谢,我是新人,正在学习中!
2010-3-11 13:32
0
雪    币: 78
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
走到int 0x2b这条指令后,打开OD的内存镜像窗口,在代码段上F2下断点,然后直接F9,回调函数执行完毕,内核会返回被中断的线程,此时应该会立即中断的。最后到达这里

0040137E >/$  8B7424 04     MOV ESI,DWORD PTR SS:[ESP+4]             ;  用户名地址送ESI
00401382  |.  56            PUSH ESI
00401383  |>  8A06          /MOV AL,BYTE PTR DS:[ESI]                ;  用户名首字母送AL
00401385  |.  84C0          |TEST AL,AL                              ;  是否转换结束
00401387  |.  74 13         |JE SHORT CRACKME1.0040139C
00401389  |.  3C 41         |CMP AL,41                               ;  与A比较即判断是否为字母,如不是则Game over
0040138B  |.  72 1F         |JB SHORT CRACKME1.004013AC
0040138D  |.  3C 5A         |CMP AL,5A                               ;  与Z比较
0040138F  |.  73 03         |JNB SHORT CRACKME1.00401394
00401391  |.  46            |INC ESI
00401392  |.^ EB EF         |JMP SHORT CRACKME1.00401383
00401394  |>  E8 39000000   |CALL CRACKME1.004013D2                  ;  如为小写字母则变为大写并替换原字母
00401399  |.  46            |INC ESI                                 ;  ESI加1指向下一位
0040139A  |.^ EB E7         \JMP SHORT CRACKME1.00401383             ;  继续
0040139C  |>  5E            POP ESI                                  ;  转换为大写的用户名
0040139D  |.  E8 20000000   CALL CRACKME1.004013C2                   ;  将用户名每一位ASC值累加到EDI
004013A2  |.  81F7 78560000 XOR EDI,5678                             ;  与5678异或
004013A8  |.  8BC7          MOV EAX,EDI                              ;  送到EAX
004013AA  |.  EB 15         JMP SHORT CRACKME1.004013C1              ;  返回
004013AC  |>  5E            POP ESI
004013AD  |.  6A 30         PUSH 30                                  ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF  |.  68 60214000   PUSH CRACKME1.00402160                   ; |No luck!
004013B4  |.  68 69214000   PUSH CRACKME1.00402169                   ; |No luck there, mate!
004013B9  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
004013BC  |.  E8 79000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
004013C1  \>  C3            RETN
2010-3-11 15:52
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
贴一个我逆的结果 有点混乱见量
DWORD unameCheck(char * uname)
{
        int i = 0;
        char c;
        while((c = uname[i]) != 0)
        {
                if(c < 0x41)//如果非字母就完蛋
                        return 0;
                if(c>= 0x5A)//大小写转换
                {
                        c -= 0x20;
                        uname[i] = c;
                        i++;
                }
                else
                {
                        i++;
                }
        }
       
       
        int r = 0;
        i=0;
        do
        {
                c = uname[i];
                r += c;
                i++;
        }while(c != 0);
        r ^= 0x5678;
        return r;
}
DWORD regsnCheck(char * sn)
{
        char c;
        char a;
        int r = 0;
        int i = 0;
        a = 0x0a;
        while((c = sn[i]) != 0)
        {
       
          
         
           c-= 0x30;
           r *= a;
           r+=c;
          
           i++;
        }
        r ^= 0x1234;
        return r;
}
CString JwtSn(DWORD uValue)
{
       

        DWORD v = 0;
        char a = 0x0a;
       
        DWORD r = 0;
        CString ret;
        r = uValue ^ 0x1234;
       
        char c[] = " ";
        do
        {
                c[0] = (char)(r % 0x0a + 0x30);
                r /= 0x0a;
                ret = c + ret;
        }while(r != 0);

        return ret;
}

//=============================================
        char uname[] = "jwtok";
        char sn[20];
        memset(sn, 0, 20);
        DWORD unameVal = unameCheck(uname);
        CString ret = JwtSn(unameVal);

        strcpy(sn, (LPCTSTR)ret);
        DWORD snVal = regsnCheck(sn);
2010-6-18 15:47
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
1111111111111111111111111111111111111
2010-6-18 16:41
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
谢谢楼主照顾我们新手
2010-6-21 08:48
0
雪    币: 38
活跃值: (33)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
就是破解的意思
CrackMe

  他们都是一些公开给别人尝试破解的小程序,制作 crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 cracker,想挑战一下其它 cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破。
  不会了 要学会自己搜索。
2010-6-22 11:34
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
下来玩玩下。。
2010-6-26 19:35
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
支持原创精品
2010-6-26 22:31
0
雪    币: 13
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
谢谢楼主啦,这个CM很简单啊,很适合我们这种菜鸟
2010-6-28 01:05
0
游客
登录 | 注册 方可回帖
返回
//