首页
社区
课程
招聘
[原创]Crackme 01 的详解
发表于: 2011-8-3 17:15 13588

[原创]Crackme 01 的详解

2011-8-3 17:15
13588

【破文标题】Crackme 01 的详解
【难度级别】初入门的新手
【下载地址】
【破解工具】OD,peid
【加壳方式】无壳
【保护方式】无Anti-debug
【破解声明】本人破解很菜,此CrackMe算是入门级的,希望以此作为一些简单的案例,给我室友以及才开始接触逆向的各位兄弟,希望大家有所收获,如果不出意外这是一个长期的学习笔记,请大家多多指教。
【备  注】老手勿看

首先用PEiD载入目标文件,发现时masm编写,米有壳。接着用OD载入,来到入口处。右键选择"超级字符串参考",然后选择"查找ASCII",这是很经典的一个方法,如图:


发现了很多有用的信息,看来作者没有将这些信息加密处理,算是比较温柔的,从这些信息中我们可以推测用户名的长度应该是5-32位,我们测试之后发现是正确的,看来作者的信息无误,值得信任。好了,接下来我们需要定位到关键的算法处,方法有很多种,在接下来的CrackMe中我们会逐一学习。我们双击"Good Cracker",我们来到0x004013A8处,我们发现这里有一系列的MessageBox,这些都是用来给用户作为提示信息的,我们来到0x004013A6,左键点击这一行,我们发现有条红色的箭头指向这一行,顺,着这条线往上走,我们来到0x0040131F,这里是个JE指令,看来这是最后的迈向成功的跳转处,那么这里已经进入算法部分了,我们往上走发现了重要的API:GetDlgItemText,这个函数的作用是获取用户输入的用户名和密码,好了现在我们就从第一个API调用开始分析算法吧。
首先我们来看对用户名的处理:

00401248  |.  6A 28         PUSH 28                                  ; /Count = 28 (40.)
0040124A  |.  68 8C314000   PUSH d2k2_cra.0040318C                   ; |Buffer = d2k2_cra.0040318C
0040124F  |.  6A 02         PUSH 2                                   ; |ControlID = 2
00401251  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401254  |.  E8 8F010000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
00401259  |.  84C0          TEST AL,AL                               ;  0x40318c存放输入的用户名
0040125B  |.  0F84 06010000 JE d2k2_cra.00401367
00401261  |.  3C 20         CMP AL,20
00401263  |.  0F8F 13010000 JG d2k2_cra.0040137C                     ;  如果长度大于32就退出
00401269  |.  3C 05         CMP AL,5
0040126B  |.  0F8C 20010000 JL d2k2_cra.00401391                     ;  如果长度小于5也退出
00401271  |.  8D1D 8C314000 LEA EBX,DWORD PTR DS:[40318C]
00401277  |.  33C9          XOR ECX,ECX
00401279  |.  B0 05         MOV AL,5                                 ;  用户名的前5个字符,AL依次减1
0040127B  |.  33D2          XOR EDX,EDX
0040127D  |>  8A0C1A        MOV CL,BYTE PTR DS:[EDX+EBX]             ;  依次取用户名的前5个字符,存放在CL里面(后面对CL进行操作)
00401280  |.  80F1 29       XOR CL,29                                ;  与0x29异或
00401283  |.  02C8          ADD CL,AL                                ;  加上al
00401285  |.  80F9 41       CMP CL,41                                ;  如果小于0x41
00401288  |.  7C 1C         JL SHORT d2k2_cra.004012A6
0040128A  |.  80F9 5A       CMP CL,5A
0040128D  |.  7F 17         JG SHORT d2k2_cra.004012A6               ;  如果大于0x5A
0040128F  |>  888A 3C314000 MOV BYTE PTR DS:[EDX+40313C],CL          ;  将处理之后的字符值放入0x40313C首地址中(数组)
00401295  |.  C682 3D314000>MOV BYTE PTR DS:[EDX+40313D],0           ;  下一个将要放入的地址清0(C语言中数组的结束符'\0')
0040129C  |.  FEC2          INC DL                                   ;  DL增加,指向下一个字符
0040129E  |.  FEC8          DEC AL                                   ;  AL减1(循环体执行一次)
004012A0  |.  3C 00         CMP AL,0                                 ;  判断前5个字符是否处理完毕
004012A2  |.  74 08         JE SHORT d2k2_cra.004012AC
004012A4  |.^ EB D7         JMP SHORT d2k2_cra.0040127D
004012A6  |>  B1 52         MOV CL,52                                ;  CL为0x52
004012A8  |.  02C8          ADD CL,AL                                ;  加上AL
004012AA  |.^ EB E3         JMP SHORT d2k2_cra.0040128F              ;  进过初步处理的前5个字符放在0x40313C
004012AC  |>  33D2          XOR EDX,EDX
004012AE  |.  B8 05000000   MOV EAX,5                                ;  同样是用户名的前5个字符
004012B3  |>  8A0C1A        MOV CL,BYTE PTR DS:[EDX+EBX]             ;  依次取用户名的前5个字符
004012B6  |.  80F1 27       XOR CL,27                                ;  与0x27异或
004012B9  |.  02C8          ADD CL,AL                                ;  加上Al
004012BB  |.  80C1 01       ADD CL,1                                 ;  加上1
004012BE  |.  80F9 41       CMP CL,41                                ;  如果小于0x41
004012C1  |.  7C 1C         JL SHORT d2k2_cra.004012DF
004012C3  |.  80F9 5A       CMP CL,5A
004012C6  |.  7F 17         JG SHORT d2k2_cra.004012DF               ;  如果大于0x5A
004012C8  |>  888A 41314000 MOV BYTE PTR DS:[EDX+403141],CL          ;  处理完毕后放入0x403141首地址中(注意141-13c=5!意味着与前面处理之后的5个字符恰好"相连")
004012CE  |.  C682 42314000>MOV BYTE PTR DS:[EDX+403142],0           ;  下一个将要放入的地址清0(C语言中数组的结束符'\0')
004012D5  |.  FEC2          INC DL                                   ;  DL增加,指向下一个字符
004012D7  |.  FEC8          DEC AL
004012D9  |.  3C 00         CMP AL,0
004012DB  |.  74 08         JE SHORT d2k2_cra.004012E5               ;  判断处理完毕否
004012DD  |.^ EB D4         JMP SHORT d2k2_cra.004012B3
004012DF  |>  B1 4D         MOV CL,4D                                ;  CL为0x4D
004012E1  |.  02C8          ADD CL,AL
004012E3  |.^ EB E3         JMP SHORT d2k2_cra.004012C8              ;  处理完毕之后的5个字符放在0x403141
004012E5  |>  33C0          XOR EAX,EAX
if (strlen(str_name) < 5 || strlen(str_name) > 32)
{
    break;
}
for(var_1 = 5, var_2 = 0, var_1 > 0, var_1--,var_2++)
{
   var_3 = var_1 + str_name[var_2] ^ 0x29;
  if (var_3 < 0x41 || var_3 > 0x5a)
  {
     var_3 = var_1 + 0x52;
  }
  str_name_temp[var_2] = var_3;
}
for (var_4 = 5, var_5 = 0, var_4 > 0, var_4--,var_5++)
{
   var_6 = var_4 + str_name[var_5] ^ 0x27 + 1;
  if(var_6 < 0x41 || var_6 > 0x5a)
  {
     var_6 = var_4 + 0x4d;
  }
  str_name_temp[var_5+5] = var_6;
}
004012E7  |.  6A 28         PUSH 28                                  ; /Count = 28 (40.)
004012E9  |.  68 B4314000   PUSH d2k2_cra.004031B4                   ; |Buffer = d2k2_cra.004031B4
004012EE  |.  6A 04         PUSH 4                                   ; |ControlID = 4
004012F0  |.  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004012F3  |.  E8 F0000000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004012F8  |.  66:85C0       TEST AX,AX                               ;  密码放在0x4031B4
004012FB  |.  74 55         JE SHORT d2k2_cra.00401352               ;  长度为空失败
004012FD  |.  66:83F8 0A    CMP AX,0A
00401301  |.  7F 4F         JG SHORT d2k2_cra.00401352               ;  长度大于10,失败
00401303  |.  7C 4D         JL SHORT d2k2_cra.00401352               ;  长度小于10,失败
00401305  |.  33C0          XOR EAX,EAX
00401307  |.  33DB          XOR EBX,EBX
00401309  |.  33C9          XOR ECX,ECX
0040130B  |.  33D2          XOR EDX,EDX
0040130D  |.  8D05 B4314000 LEA EAX,DWORD PTR DS:[4031B4]
00401313  |>  8A1C01        MOV BL,BYTE PTR DS:[ECX+EAX]             ;  依次取出输入的密码
00401316  |.  8A91 3C314000 MOV DL,BYTE PTR DS:[ECX+40313C]          ;  依次取出之前处理完毕的10个字符,放入DL中
0040131C  |.  80FB 00       CMP BL,0
0040131F  |.  0F84 81000000 JE d2k2_cra.004013A6                     ;  这条语句为真,注册成功
00401325  |.  80C2 05       ADD DL,5                                 ;  DL加5
00401328  |.  80FA 5A       CMP DL,5A
0040132B  |.  7F 14         JG SHORT d2k2_cra.00401341               ;  如果大于0x5A
0040132D  |>  80F2 0C       XOR DL,0C                                ;  与0xc异或
00401330  |.  80FA 41       CMP DL,41
00401333  |.  7C 11         JL SHORT d2k2_cra.00401346               ;  如果小于0x41
00401335  |.  80FA 5A       CMP DL,5A
00401338  |.  7F 12         JG SHORT d2k2_cra.0040134C               ;  如果大于0x5A
0040133A  |>  41            INC ECX
0040133B      38DA          CMP DL,BL                                ;  两者必须相等
0040133D    ^ 74 D4         JE SHORT d2k2_cra.00401313
0040133F      EB 11         JMP SHORT d2k2_cra.00401352              ;  否者失败
00401341  |>  80EA 0D       SUB DL,0D
00401344  |.^ EB E7         JMP SHORT d2k2_cra.0040132D
00401346  |>  B2 4B         MOV DL,4B
00401348  |.  02D1          ADD DL,CL
0040134A  |.^ EB EE         JMP SHORT d2k2_cra.0040133A
0040134C  |>  B2 4B         MOV DL,4B
0040134E  |.  2AD1          SUB DL,CL
00401350  |.^ EB E8         JMP SHORT d2k2_cra.0040133A

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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 697
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写得不错,学习学习,哈哈
2011-8-3 17:44
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
3
我也来写个KeyGen吧,虽然我是为了练习VC编程的……
代码编写和调试就花了15分钟,界面和调试折腾了2小时……

不过楼主这个不算“写”注册机啊……
上传的附件:
2011-8-3 20:45
0
雪    币: 386
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
牛-------啊。
2011-8-3 20:53
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
5
哈哈哈,其实站在用户的角度看我们两个的没有什么区别(偷懒了)
2011-8-3 21:34
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
6
后文更新,希望大家多多指教
2011-8-4 21:55
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我受益匪浅!好像开始入门了!小有成就感了,也更加有兴趣了,感谢楼主,感谢各位大侠,我会继续努力!!!!
2011-8-8 09:46
0
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
受益匪浅,开始入门了,谢谢楼主!
2011-8-9 23:11
0
雪    币: 3571
活跃值: (755)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
学习了。。。感谢lz
2011-8-21 10:00
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我从第一篇开始按楼主(应该叫您老师才对)文章学习,希望我也离开菜鸟进级为大虾
2011-10-13 22:40
0
雪    币: 248
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
刚开始 入门 谢了
2011-10-14 11:19
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
loongzyd 老师您这个教程用的OD版本是什么版本?我怎么都没找着您说的那个 超级字符串参考 这个菜单呢?烦请给个回复
2011-10-14 21:13
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
loongzyd 老师,您这个附件所带的注册机不能运行,另外,我按照您写的伪码翻译成C# 语言,经过测试发现得到的结果不符合验证需求,我是个菜鸟,正在学习中,希望您别见笑,附上我写的C#语句

  private string Crackme_1(string userName)
        {
            string result = "";
            int var_1 = 5;
            int var_3 = 0;
            int[] str_name_temp = new int[10];
            for (int var_2 = 0; var_2 < 5; var_2++)
            {

                var_3 = var_1 + userName[var_2] ^ 0x29;
                if (var_3 < 0x29 || var_3 > 0x41)
                {
                    var_3 = var_1 + 0x52;
                }
                str_name_temp[var_2] = var_3;
                var_1--;
            }

            int var_4 = 5;
            int var_6 = 0;
            for (int var_5 = 0; var_5 < 5; var_5++)
            {
                var_6 = var_4 + userName[var_5] ^ 0x27 + 1;
                if (var_6 < 0x41 || var_6 > 0x5a)
                {
                    var_6 = var_4 + 0x4d;
                }
                str_name_temp[var_5 + 5] = var_6;
                var_4--;
            }
            foreach (int i in str_name_temp)
            {
                result += Convert.ToChar(i);
            }
            return result;

        }


这个函数是处理crackme第一步处理name生成的10个字符,我通过OD 修改了
0040130D 这句改成 :lea     eax, dword ptr [40313C]

这样就看到crackedme生成的结果,与C#程序实际生成的结果不一致,望请告知是哪里错了呢?

期待您的回复,如有知道的老师大侠们,也请您不吝赐教
2011-10-15 16:35
0
雪    币: 1012
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
写的很好哦
2020-4-8 14:03
0
游客
登录 | 注册 方可回帖
返回
//