首页
社区
课程
招聘
[原创]破解crackme5.1(逆推注册码)
2006-2-25 18:15 11558

[原创]破解crackme5.1(逆推注册码)

2006-2-25 18:15
11558
破解crackme5.1(逆推注册码)

【破文标题】破解crackme5.1(逆推注册码)
【对  象】新手
【破解工具】SoftICE
【保护方式】序列号
【任  务】分析算法,写出注册机
【破文作者】gdszmai
【破解过程】

  1 用PEiD查壳,无壳。

 2 运行程序,输入注册码"12345",点击“OK”,弹出对话框"Wrong S/N#"。

 3 用W32Dasm 反汇编,参考→串式数据参考→查找"Wrong S/N#"→双击来到代码处→向上查找发现是从[004011B1]处跳转来的,此为关键跳转,再往上0040119E:Call 004012A3为关键Call,要追进。

 4 运行crackme5.1,输入注册码"12345"

 5 Ctrl+D,调出SoftICE,下断点bpx getwindowtexta,F5退出SoftICE

6  点击“OK”,马上被SoftICE中断,来到下面:

*************************************************************************

* Reference To: USER32.GetWindowTextA, Ord:0000h
                                  |
:0040119E E800010000              Call 004012A3      ;取注册码位数
:004011A3 FF3544204000            push dword ptr [00402044]
:004011A9 E85D000000              call 0040120B      ;关键 call,跟进
:004011AE 83F801                  cmp eax, 00000001 ;关键比较
:004011B1 751E                    jne 004011D1     ;跳就出错,如改为9090,就可暴破
:004011B3 6A30                    push 00000030

* Possible StringData Ref from Data Obj ->"Good For U!"
                                  |
:004011B5 6881204000              push 00402081

* Possible StringData Ref from Data Obj ->"U Did It!!" ;成功标志
                                  |
:004011BA 688D204000              push 0040208D
:004011BF FF3548204000            push dword ptr [00402048]

* Reference To: USER32.MessageBoxA, Ord:0000h
                                  |
:004011C5 E8EB000000              Call 004012B5
:004011CA 5E                      pop esi
:004011CB 5F                      pop edi
:004011CC 5B                      pop ebx
:004011CD C9                      leave
:004011CE C21000                  ret 0010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011B1(C)
|
:004011D1 6A30                    push 00000030

* Possible StringData Ref from Data Obj ->"=)"
                                  |
:004011D3 6898204000              push 00402098

* Possible StringData Ref from Data Obj ->"Wrong S/N#"  ;失败标志
                                  |
:004011D8 689B204000              push 0040209B
:004011DD FF3548204000            push dword ptr [00402048]

* Reference To: USER32.MessageBoxA, Ord:0000h
                                  |
:004011E3 E8CD000000              Call 004012B5
:004011E8 5E                      pop esi
:004011E9 5F                      pop edi
:004011EA 5B                      pop ebx
:004011EB C9                      leave
:004011EC C21000                  ret 0010

*************************************************************************

* Referenced by a CALL at Address:   ;从上面的关键call跳来
|:004011A9   
|
:0040120B C8000000                enter 0000, 00
:0040120F 53                      push ebx
:00401210 52                      push edx
:00401211 33C0                    xor eax, eax  
:00401213 B8A6204000              mov eax, 004020A6    ;把注册码的地址送eax
:00401218 803800                  cmp byte ptr [eax], 00 ;检查是否输入了注册码
:0040121B 7460                    je 0040127D          ;如无输入就跳到出错处
:0040121D 33DB                    xor ebx, ebx       ;ebx 清零
:0040121F 33D2                    xor edx, edx         ;edx 清零

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040122C(C)
|
:00401221 8A18                    mov bl, byte ptr [eax] ;取注册码的第一位数给bl
:00401223 C1C308                  rol ebx, 08    ;ebx循环左移8位
:00401226 03D3                    add edx, ebx   ;循环左移8位后,累加到edx
:00401228 40                      inc eax        ;eax加一,准备取注册码的下一位数
:00401229 803800                  cmp byte ptr [eax], 00  ;是否取完?
:0040122C 75F3                    jne 00401221    ; 如没取完,继续取下一位数
:0040122E 52                      push edx    ;累加完后,数值压栈

* Possible StringData Ref from Data Obj ->"%lX"
                                  |
:0040122F 6854204000              push 00402054
:00401234 68BF204000              push 004020BF

* Reference To: USER32.wsprintfA, Ord:0000h
                                  |
:00401239 E88F000000              Call 004012CD
:0040123E BBBF204000              mov ebx, 004020BF ;累加后数值的地址送ebx
:00401243 803B38                  cmp byte ptr [ebx], 38     ;比较第一位是否为‘8’
:00401246 7535                    jne 0040127D               ;不相等就出错
:00401248 807B0144                cmp byte ptr [ebx+01], 44 ;比较第二位是否为‘D’
:0040124C 752F                    jne 0040127D              ;不相等就出错
:0040124E 807B0243                cmp byte ptr [ebx+02], 43 ;比较第三位是否为‘C’
:00401252 7529                    jne 0040127D              ;不相等就出错
:00401254 807B0341                cmp byte ptr [ebx+03], 41 ;比较第四位是否为‘A’
:00401258 7523                    jne 0040127D              ;不相等就出错
:0040125A 807B0446                cmp byte ptr [ebx+04], 46 ;比较第五位是否为‘F’
:0040125E 751D                    jne 0040127D              ;不相等就出错
:00401260 807B0533                cmp byte ptr [ebx+05], 33 ;比较第六位是否为‘3’
:00401264 7517                    jne 0040127D              ;不相等就出错
:00401266 807B0636                cmp byte ptr [ebx+06], 36 ;比较第七位是否为‘6’
:0040126A 7511                    jne 0040127D              ;不相等就出错
:0040126C 807B0738                cmp byte ptr [ebx+07], 38 ;比较第八位是否为‘8’
:00401270 750B                    jne 0040127D              ;不相等就出错
:00401272 B801000000              mov eax, 00000001         ;比较通过后,1送eax,成功标志
:00401277 5A                      pop edx
:00401278 5B                      pop ebx
:00401279 C9                      leave
:0040127A C20400                  ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040121B(C), :00401246(C), :0040124C(C), :00401252(C), :00401258(C)
|:0040125E(C), :00401264(C), :0040126A(C), :00401270(C)
|
:0040127D 33C0                    xor eax, eax   ;eax 清零,失败标志
:0040127F 5A                      pop edx
:00401280 5B                      pop ebx
:00401281 C9                      leave
:00401282 C20400                  ret 0004

*************************************************************************

7 分析算法:

  此算法比较简单,就是把注册码的每一位数逐一送入bl,循环左移8位,累加到EDX,其结果为8DCAF368则注册成功。虽然算法简单,但如果从输入数找正确的注册码却困难,那么我们来逆推注册码:(下面数字均为十六进制)

  ①先假设注册码为最少的4位数: a1  a2  a3  a4

        ebx                      循环左移8位后的ebx               edx=edx+ebx
     00  00  00  a1 循环左移8位→ 00  00  a1  00               00  00  a1  00

     00  00  a1  a2               00  a1  a2  00            +  00  a1  a2  00

     00  a1  a2  a3               a1  a2  a3  00            +  a1  a2  a3  00

     a1  a2  a3  a4               a2  a3  a4  a1            +  a2  a3  a4  a1
                                                         ______________________
                                                               8D  CA  F3  68

           从上面可以看出:a1=68                          字符:  "h"
                        a2=8D-a1=8D-68=25              字符:  "%"
                        a3=CA-a1-a2=CA-68-25=3D        字符:  "="
                        a4=F3-a1-a2-a3=F3-68-25-3D=29  字符:  ")"

           所以4位的注册码为“h%=)”

    ②假设注册码为5位数:a1  a2  a3  a4  a5
                    

           ebx                    循环左移8位后的ebx                edx=edx+ebx
     00  00  00  a1  循环左移8位→ 00  00  a1  00                 00  00  a1  00

     00  00  a1  a2                00  a1  a2  00              +  00  a1  a2  00

     00  a1  a2  a3                a1  a2  a3  00              +  a1  a2  a3  00

     a1  a2  a3  a4                a2  a3  a4  a1              +  a2  a3  a4  a1
              
     a2  a3  a4  a5                a3  a4  a5  a2              +  a3  a4  a5  a2
                                                                __________________
                                                                  8D  CA  F3  68

         从上面可以看出:a2=68-a1
                         a3=8D-a1-a2
                         a4=CA-a1-a2-a3
                         a5=F3-a1-a2-a3-a4

                 所以如果设a1=32,字符为: "2" ,则可计算出5位的注册码为"26%=)"

    ③假设注册码为6位数:a1  a2  a3  a4  a5  a6

              ebx                   循环左移8位后的ebx             edx=edx+ebx
        00  00  00  a1 循环左移8位为 00  00  a1  00              00  00  a1  00

        00  00  a1  a2               00  a1  a2  00            + 00  a1  a2  00

        00  a1  a2  a3               a1  a2  a3  00           +  a1  a2  a3  00

        a1  a2  a3  a4               a2  a3  a4  a1           +  a2  a3  a4  a1
              
        a2  a3  a4  a5               a3  a4  a5  a2           +  a3  a4  a5  a2
         
        a3  a4  a5  a6               a4  a5  a6  a3           +  a4  a5  a6  a3
                                                             ___________________
                                                                 8D  CA  F3  68
                                                                              

     所以从上面可以看出,如果设:   a1=21                         !
                           a2=23                         #

                            则:   a3=68-a2-a1=24                $
                                  a4=8D-a3-a2-a1=25             %
                                  a5=CA-a4-a3-a2-a1=3D          =
                                  a6=F3-a5-a4-a3-a2-a1=29       )

           即6位数的注册码为  "!#$%=)"

   ④假设注册码为7位数: a1  a2  a3  a4  a5  a6 a7

         ebx                    循环左移8位后的ebx                  edx=edx+ebx
   00  00  00  a1 循环左移8位为  00  00  a1  00                    00  00  a1  00

   00  00  a1  a2                00  a1  a2  00                 +  00  a1  a2  00

   00  a1  a2  a3                a1  a2  a3  00                 +  a1  a2  a3  00

   a1  a2  a3  a4                a2  a3  a4  a1                 +  a2  a3  a4  a1
              
   a2  a3  a4  a5                a3  a4  a5  a2                 +  a3  a4  a5  a2
           
   a3  a4  a5  a6                a4  a5  a6  a3                 +  a4  a5  a6  a3

   a4  a5  a6  a7                a5  a6  a7  a4                 +  a5  a6  a7  a4
                                                          __________________________
                                                  
                                                                   8D  CA  F3  68

         从上面可以看出:a4=68-a1-a2-a3 ,然而键盘上可输入的字符是!(ASCII码为21)到 ~(ASCII码为7E),假设a1,a2,a3都为!(ASCII码最少),则a4=68-21-21-21=5,而ASCII码为5的,并不是可输入的字符,所以正确的注册码不可能为7位。

 8 经过上面的分析,可以写出注册机(4-6位数):下面是C语言源程序
*************************************************************************
#include <stdio.h>
#include <math.h>

main()
{
         int a1,a2,a3,a4,a5,a6;

        printf("*******************************\n");
        printf("crackme5.1  Key Generator\n");
        printf("*******************************\n\n\n");

        /*4位数的注册码*/

        a1=0x68;
        a2=0x8d-a1;
        a3=0xca-a1-a2;
        a4=0xf3-a1-a2-a3;

        printf("%c%c%c%c\t",a1,a2,a3,a4);

        printf("\n\n");

        /*5位数的注册码*/

        for(a1=0x21;a1<=0x7e;a1++) {

                a2=0x68-a1; if(a2<0x21||a2>0x7e) continue;
                a3=0x8d-a1-a2; if(a3<0x21||a3>0x7e) continue;
                a4=0xca-a1-a2-a3; if(a4<0x21||a4>0x7e) continue;
                a5=0xf3-a1-a2-a3-a4; if(a5<0x21||a5>0x7e) continue;
                printf("%c%c%c%c%c\t",a1,a2,a3,a4,a5);

        }

    /*6位数的注册码*/

    printf("\n\n");
        for(a1=0x21;a1<=0x7e;a1++) {

                for(a2=0x21;a2<=0x7e;a2++) {

                a3=0x68-a1-a2;if(a3<0x21||a3>0x7e) continue;
                a4=0x8d-a1-a2-a3; if(a4<0x21||a4>0x7e) continue;
                a5=0xca-a1-a2-a3-a4; if(a5<0x21||a5>0x7e) continue;
                a6=0xf3-a1-a2-a3-a4-a5; if(a6<0x21||a6>0x7e) continue;
                printf("%c%c%c%c%c%c\t",a1,a2,a3,a4,a5,a6);

                }

        }

   printf("\n\n");

}

*************************************************************************
  C源程序经编译后,运行,算出4-6位所有的注册码为:

h%=)

!G%=)   "F%=)   #E%=)   $D%=)   %C%=)   &B%=)   'A%=)   (@%=)   )?%=)   *>%=)
+=%=)   ,<%=)   -;%=)   .:%=)   /9%=)   08%=)   17%=)   26%=)   35%=)   44%=)
53%=)   62%=)   71%=)   80%=)   9/%=)   :.%=)   ;-%=)   <,%=)   =+%=)   >*%=)
?)%=)   @(%=)   A'%=)   B&%=)   C%%=)   D$%=)   E#%=)   F"%=)   G!%=)

!!&%=)  !"%%=)  !#$%=)  !$#%=)  !%"%=)  !&!%=)  "!%%=)  ""$%=)  "##%=)  "$"%=)
"%!%=)  #!$%=)  #"#%=)  ##"%=)  #$!%=)  $!#%=)  $""%=)  $#!%=)  %!"%=)  %"!%=)
&!!%=)

把它输入后,点击“OK”,弹出"U Did It!!",成功破解了!唉,真累!


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (30)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
梁小玉 2006-2-27 19:11
2
0
我是一个菜鸟!请大虾多多指教!
雪    币: 424
活跃值: (2618)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gdszmai 2 2006-2-27 19:21
3
0
我也是菜鸟,我们一起学习,一起进步。
雪    币: 424
活跃值: (2618)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gdszmai 2 2006-2-27 19:48
4
0
我也是菜鸟,我们一起学习,一起进步。发重了,请版主删除。
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
寒冰沉默 2006-2-28 13:40
5
0
总算可以发帖了 下下来 自己看看
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
arron 2006-2-28 15:22
6
0
不错,很详细。
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
zhaoocn 7 2006-2-28 19:28
7
0
挺详细,这么复杂的算法
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
IORI 2006-2-28 22:56
8
0
我看不懂,只有自己慢慢研究!~还要各位高手帮帮忙!~
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Penitix 2006-2-28 23:24
9
0
功底太差了
向大家学习
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yixiayuan 2006-3-1 10:26
10
0
讲的很详细,值得学习,我是个新手 虽然难懂 还是要多加努力
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fishJerry 2006-3-1 17:30
11
0
好啊 好啊 好啊
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
一叶兰 2006-3-2 10:15
12
0
请教一下

:00401243 803B38                  cmp byte ptr [ebx], 38     ;比较第一位是否为‘8’
:00401246 7535                    jne 0040127D               ;不相等就出错
:00401248 807B0144                cmp byte ptr [ebx+01], 44 ;比较第二位是否为‘D’
:0040124C 752F                    jne 0040127D              ;不相等就出错
:0040124E 807B0243                cmp byte ptr [ebx+02], 43 ;比较第三位是否为‘C’
:00401252 7529                    jne 0040127D              ;不相等就出错
:00401254 807B0341                cmp byte ptr [ebx+03], 41 ;比较第四位是否为‘A’
:00401258 7523                    jne 0040127D              ;不相等就出错
:0040125A 807B0446                cmp byte ptr [ebx+04], 46 ;比较第五位是否为‘F’
:0040125E 751D                    jne 0040127D              ;不相等就出错
:00401260 807B0533                cmp byte ptr [ebx+05], 33 ;比较第六位是否为‘3’
:00401264 7517                    jne 0040127D              ;不相等就出错
:00401266 807B0636                cmp byte ptr [ebx+06], 36 ;比较第七位是否为‘6’
:0040126A 7511                    jne 0040127D              ;不相等就出错
:0040126C 807B0738                cmp byte ptr [ebx+07], 38 ;比较第八位是否为‘8’

这个怎么来??不知道是什么转换的
雪    币: 73
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
浪流 2006-3-2 17:55
13
0
查一下assii码表就知道了。
雪    币: 424
活跃值: (2618)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gdszmai 2 2006-3-2 20:13
14
0
最初由 一叶兰 发布
请教一下

:00401243 803B38 cmp byte ptr [ebx], 38 ;比较第一位是否为‘8’
:00401246 7535 jne 0040127D ;不相等就出错
:00401248 807B0144 cmp byte ptr [ebx+01], 44 ;比较第二位是否为‘D’
........


输入的注册码经运算后,其结果必须等于8DCAF368才能注册成功。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
我密密密 2006-3-3 14:40
15
0
我也要来学破解,希望各位高手帮助啊
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
我密密密 2006-3-3 15:21
16
0
有没有转换表来一个就方便多了,哈哈
雪    币: 108
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
vinston 2006-3-3 21:44
17
0
新来的,没权限下载,我水一下
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shiwenhui 2006-3-8 13:46
18
0
ebx:00 00 00 a1 循环左移8位后是00 00 a1 00吗?
我觉得应该是:00 00 00 a1
希望楼主解释一下
雪    币: 424
活跃值: (2618)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gdszmai 2 2006-3-8 19:25
19
0
最初由 shiwenhui 发布
ebx:00 00 00 a1 循环左移8位后是00 00 a1 00吗?
我觉得应该是:00 00 00 a1
希望楼主解释一下


ebx是32位寄存器,a1是其低八位的值,ebx:00 00 00 a1 循环左移8位后就是00 00 a1 00。
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shiwenhui 2006-3-9 12:13
20
0
谢谢楼上的,令某茅舍顿开!!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
knightage 2006-3-9 15:26
21
0
学习学习学习
雪    币: 424
活跃值: (2618)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
gdszmai 2 2006-3-9 19:32
22
0
最初由 knightage 发布
学习学习学习

奇怪!俺怎么会从1楼变为2楼的?
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
knightage 2006-3-10 10:26
23
0
一起学习中
雪    币: 32410
活跃值: (18730)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2006-3-11 21:13
24
0
最初由 gdszmai 发布
奇怪!俺怎么会从1楼变为2楼的?


服务器那个时间段出了点问题,变成了2005年,而帖是以时间排序的。现在问题己修正。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
eleen 2006-3-13 12:07
25
0
讲的很详细,值得学习
游客
登录 | 注册 方可回帖
返回