首页
社区
课程
招聘
[原创]与大家分享第一次成功的喜悦
发表于: 2009-9-21 12:09 12618

[原创]与大家分享第一次成功的喜悦

2009-9-21 12:09
12618

来到论坛很久了,但是一直都没有成功破解过。
于是找到一个看雪论坛上以前的一个很简单的CrackMe试试,终于成功了。
发上来与大家一同分享我的喜悦,由于注释是调试的时候为了方便写的,所以有点乱。
请大家批评指正,不要笑话我。
【软件】: crackme6.exe crackme6.rar 不好意思,忘了作者是谁了
【作者】: cxxhcj
【软件大小】: 8.47k
【正文】:
首先运行crackme,发现没有错误提示
用PEiD查壳发现是ASPack,脱掉后用OD加载,尝试对GetDlgItemTextA下断,运气不错断下来了,来到取得name处
00401539  |.  E8 FA010000   call    <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
0040153E  |.  89C3          mov     ebx, eax                         ;  
00401540  |.  09DB          or      ebx, ebx                         ;  len_name != 0;
00401542  |.  75 04         jnz     short 00401548
00401544  |.  31C0          xor     eax, eax
00401546  |.  EB 50         jmp     short 00401598
00401548  |>  BF BC020000   mov     edi, 2BC
0040154D  |.  BE 30000000   mov     esi, 30
00401552  |.  B8 48000000   mov     eax, 48
00401557  |.  99            cdq
00401558  |.  F7FB          idiv    ebx                              ;  S = 48H / len_name;
0040155A  |.  29C6          sub     esi, eax                         ;  X = 30H - S;
0040155C  |.  8D34B6        lea     esi, dword ptr [esi+esi*4]       ;  X *= 5;
0040155F  |.  29F7          sub     edi, esi                         ;  Y = 2BCH - X;
00401561  |.  6BFF 6B       imul    edi, edi, 6B                     ;  Y *= 6BH;
00401564  |.  81EF 6CCF0000 sub     edi, 0CF6C                       ;  Y -= 0CF6CH;
0040156A  |.  81FF 00230000 cmp     edi, 2300                        ;  Y < 2300H
00401570  |.  7F 08         jg      short 0040157A
00401572  |.  81FF 90010000 cmp     edi, 190                         ;  Y > 190H
00401578  |.  7D 04         jge     short 0040157E
0040157A  |>  31C0          xor     eax, eax
0040157C  |.  EB 1A         jmp     short 00401598

为了方便自己设了一些变量S,X,Y
这里是一个不等式:190H<6BH*[2BCH-5(30H-48H/len_name)]-CF6CH<2300H
解得 3 < len_name < 9,是name长度的限制

可以通过修改零标志通过

继续往下可以找到爆破点:

00401589  |.  E8 77FDFFFF   call    00401305                         ;  serial读入以及相关算法
0040158E  |.  83C4 0C       add     esp, 0C
00401591  |.  09C0          or      eax, eax
00401593  |.  74 03         je      short 00401598                   ;  关键跳
00401595  |.  31C0          xor     eax, eax
00401597  |.  40            inc     eax                              ;  返回1则成功

进入serial算法部分:

004013AF  |.  E8 84030000   call    <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
004013B4  |.  09C0          or      eax, eax                         ;
004013B6  |.  0F84 48010000 je      00401504                         ;  Serial判空
004013BC  |.  B8 CF110000   mov     eax, 11CF
004013C1  |.  0FB68D E1FCFF>movzx   ecx, byte ptr [ebp-31F]          ;  A = Serial第一个字符ASCII;
004013C8  |.  99            cdq
004013C9  |.  F7F9          idiv    ecx
004013CB  |.  83FA 17       cmp     edx, 17                          ;  11CF % A == 17H;
004013CE  |.  74 07         je      short 004013D7
004013D0  |.  31C0          xor     eax, eax

11CFH对serial第一个字符的ASCII码取余应为17H,'T'字符可行

继续向下走可以发现形如Txxxxxx-xx的字符串,试过之后发现不是注册码,应该是中间产物,继续分析代码:

004013D7  |> \31DB          xor     ebx, ebx                         ;  中间产物算法开始
004013D9  |.  EB 0B         jmp     short 004013E6
004013DB  |>  8B45 10       /mov     eax, dword ptr [ebp+10]         ;  N_A_S = name所有字符ASCII相加
004013DE  |.  0FBE0418      |movsx   eax, byte ptr [eax+ebx]
004013E2  |.  0145 FC       |add     dword ptr [ebp-4], eax
004013E5  |.  43            |inc     ebx
004013E6  |>  3B5D 0C        cmp     ebx, dword ptr [ebp+C]
004013E9  |.^ 7C F0         \jl      short 004013DB

004013F2  |> /8B55 10       /mov     edx, dword ptr [ebp+10]
004013F5  |. |0FBE3C1A      |movsx   edi, byte ptr [edx+ebx]         ;  取name[i]字符,i 即 ebx;
004013F9  |. |8B75 FC       |mov     esi, dword ptr [ebp-4]          ;  取N = N_A_S;
004013FC  |. |89D9          |mov     ecx, ebx                        ;  m = i;
004013FE  |. |C1E1 02       |shl     ecx, 2                          ;  m *= 4;
00401401  |. |89DA          |mov     edx, ebx
00401403  |. |42            |inc     edx                             ;  j = i + 1;
00401404  |. |29D1          |sub     ecx, edx                        ;  m -= j;
00401406  |. |0FB68C0D E1FE>|movzx   ecx, byte ptr [ebp+ecx-11F]     ;  取字母c = 'A' + m,无对应字母时,取0
0040140E  |. |89FA          |mov     edx, edi
00401410  |. |31CA          |xor     edx, ecx                        ;  c ^= name[i];
00401412  |. |89F1          |mov     ecx, esi
00401414  |. |0FAFCB        |imul    ecx, ebx                        ;  E = N * i;
00401417  |. |29F1          |sub     ecx, esi                        ;  E -= N;
00401419  |. |89CE          |mov     esi, ecx                        ;  N = E;
0040141B  |. |83F6 FF       |xor     esi, FFFFFFFF                   ;  N ^= FFFFFFFFH;
0040141E  |. |8DB432 4D0100>|lea     esi, dword ptr [edx+esi+14D]    ;  N = c + N + 14DH;
00401425  |. |8B4D 0C       |mov     ecx, dword ptr [ebp+C]          ;  l = len_name;
00401428  |. |89DA          |mov     edx, ebx                        ;  n = i;
0040142A  |. |83C2 03       |add     edx, 3                          ;  n += 3;
0040142D  |. |0FAFCA        |imul    ecx, edx                        ;  l *= n;
00401430  |. |0FAFCF        |imul    ecx, edi                        ;  l *= name[i];
00401433  |. |89F0          |mov     eax, esi
00401435  |. |01C8          |add     eax, ecx                        ;  N += l;
00401437  |. |B9 0A000000   |mov     ecx, 0A                         ;  
0040143C  |. |31D2          |xor     edx, edx                        ;  
0040143E  |. |F7F1          |div     ecx                             ;  
00401440  |. |83C2 30       |add     edx, 30                         ;  n = N % 0AH + 30H;
00401443  |. |88941D FCFEFF>|mov     byte ptr [ebp+ebx-104], dl
0040144A  |. |0FB6BC1D FCFE>|movzx   edi, byte ptr [ebp+ebx-104]     ;  l = n & FFH;
00401452  |. |81F7 ACAD0000 |xor     edi, 0ADAC                      ;  l ^= 0ADACH;
00401458  |. |89DE          |mov     esi, ebx
0040145A  |. |83C6 02       |add     esi, 2
0040145D  |. |89F8          |mov     eax, edi
0040145F  |. |0FAFC6        |imul    eax, esi                        ;  a = l * (i + 2);
00401462  |. |B9 0A000000   |mov     ecx, 0A
00401467  |. |99            |cdq
00401468  |. |F7F9          |idiv    ecx                             ;  
0040146A  |. |83C2 30       |add     edx, 30                         ;  n = a % 0AH + 30H;
0040146D  |. |88941D FCFEFF>|mov     byte ptr [ebp+ebx-104], dl      ;  n & FFH 存入temp[i]
00401474  |. |43            |inc     ebx                             ;  i++;
00401475  |> |3B5D 0C        cmp     ebx, dword ptr [ebp+C]          ;  循环len_name次
00401478  |.^\0F8C 74FFFFFF \jl      004013F2

00401484  |.  50            push    eax                              ;  
00401485  |.  6A 54         push    54                               ;  'T'
00401487  |.  8D85 DCFBFFFF lea     eax, dword ptr [ebp-424]         ;  
0040148D  |.  50            push    eax                              ; |Format
0040148E  |.  8D85 E1FBFFFF lea     eax, dword ptr [ebp-41F]         ; |
00401494  |.  50            push    eax                              ; |s "%c%s"
00401495  |.  E8 CE020000   call    <jmp.&USER32.wsprintfA>          ; \wsprintfA

以上算法形成第一步中间码,即Ttemp的形式,继续往下:
0040149F  |.  0FAF45 FC     imul    eax, dword ptr [ebp-4]           ;  A = N_A_S * len_name;
004014A3  |.  B9 64000000   mov     ecx, 64
004014A8  |.  99            cdq
004014A9  |.  F7F9          idiv    ecx                              ;
004014AB  |.  89D7          mov     edi, edx
004014AD  |.  83C7 30       add     edi, 30                          ;  D = A % 64H + 30H
004014B0  |.  57            push    edi                              ;  D当做参数
004014B1  |.  8DBD E1FBFFFF lea     edi, dword ptr [ebp-41F]
004014B7  |.  57            push    edi                              ;  
004014B8  |.  8DBD D6FBFFFF lea     edi, dword ptr [ebp-42A]         ;  
004014BE  |.  57            push    edi                              ; |Format
004014BF  |.  8DBD E1FDFFFF lea     edi, dword ptr [ebp-21F]         ; |
004014C5  |.  57            push    edi                              ; |s "%s-%d"
004014C6  |.  E8 9D020000   call    <jmp.&USER32.wsprintfA>          ; \wsprintfA

以上算法形成最终中间码,即Ttemp-D的形式,接着往下:
004014DE  |.  50            push    eax                              ;  中间注册码长度
004014DF  |.  8D85 E1FCFFFF lea     eax, dword ptr [ebp-31F]
004014E5  |.  50            push    eax                              ;  输入的注册码
004014E6  |.  8D85 E1FDFFFF lea     eax, dword ptr [ebp-21F]
004014EC  |.  50            push    eax                              ;  中间注册码
004014ED  |.  E8 D0FDFFFF   call    004012C2                         ;  比较算法

出现输入的注册码,此时的call即是比较函数,F7进入call:
004012C8  |.  8B5D 10       mov     ebx, dword ptr [ebp+10]          ;  中间码长度len
004012CB  |.  31F6          xor     esi, esi
004012CD  |.  46            inc     esi                              ;  循环len-1次
004012CE  |.  EB 29         jmp     short 004012F9
004012D0  |>  8B55 08       /mov     edx, dword ptr [ebp+8]
004012D3  |.  0FBE3C32      |movsx   edi, byte ptr [edx+esi]         ;  取中间码esi处的字符c
004012D7  |.  89F8          |mov     eax, edi
004012D9  |.  83F0 20       |xor     eax, 20                         ;  
004012DC  |.  B9 0A000000   |mov     ecx, 0A
004012E1  |.  99            |cdq
004012E2  |.  F7F9          |idiv    ecx                             ;  
004012E4  |.  89D7          |mov     edi, edx
004012E6  |.  83C7 30       |add     edi, 30                         ;  c = (c^20H) % 0AH + 30H;
004012E9  |.  8B55 0C       |mov     edx, dword ptr [ebp+C]
004012EC  |.  0FBE1432      |movsx   edx, byte ptr [edx+esi]         ;  取输入的注册码相应字符d
004012F0  |.  39D7          |cmp     edi, edx                        ;  d == c;由此可见c即是真正的注册码相应字符
004012F2  |.  74 04         |je      short 004012F8
004012F4  |.  31C0          |xor     eax, eax
004012F6  |.  EB 08         |jmp     short 00401300
004012F8  |>  46            |inc     esi
004012F9  |>  39DE           cmp     esi, ebx
004012FB  |.^ 7C D3         \jl      short 004012D0

将算法整理后,可以很容易写出注册机:
#include<stdio.h>
#include<string.h>

main()
{
    int len_name, N_A_S, len_serial, i;
    char name[20], serial[100], temp[100], temp1[100];
   
    INPUT: printf("请输入name:"); scanf("%s", name);
    len_name = strlen(name);
    if(len_name == 0 || len_name <= 3 || len_name >=9){
        printf("name长度应在4-8!\n");
        goto INPUT;
    }
    N_A_S = 0;
    for(i = 0; i < len_name; i++){
        N_A_S += name[i];
    }
    for(i = 0; i < len_name; i++){
        char c, R;
        int m, N, l;
        m = 3*i - 1;
        if(m < 0 || m > 25) c = '\0';
        else c = 'A' + m;
        R = c ^ name[i];
        N = N_A_S;
        N *= i - 1;
        N ^= -1;
        N += R + 0x14D;
        l = (i+3)*len_name*name[i];
        N += l;
        l = (N % 0xA + 0x30) & 0xFF;
        l ^= 0xADAC;
        N = (l*(i+2))%0xA + 0x30;
        temp[i] = N & 0xFF;
    }
    temp[i] = '\0';
    sprintf(temp1, "T%s", temp);
    i = (N_A_S * len_name) % 0x64 + 0x30;
    sprintf(temp, "%s-%d", temp1, i);
    printf("中间码:%s\n", temp);
    len_serial = strlen(temp);
    for(i = 1; i < len_serial; i++){
        serial[i] = (temp[i] ^ 0x20) % 0xA + 0x30;
    }
    serial[0] = 'T';
    serial[i] = '\0';
    printf("注册码:%s\n", serial);
   
    system("pause");
    return 0;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (30)
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
经实验,有错误
2009-9-21 20:17
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶  看看 学习中!
2009-9-21 20:20
0
雪    币: 191
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
天书,看不懂~~~~~~
2009-9-21 21:10
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
5
Support!
2009-9-21 21:48
0
雪    币: 295
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
是吗?麻烦给我一组数据,我调试一下
2009-9-21 22:10
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
不管怎么样!第一次嘛,还是恭喜下
2009-9-21 22:10
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
很深奥啊,我也是看不懂
2009-9-22 06:34
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我还是没有太大的定力去学习这个
2009-9-22 06:46
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
膜拜一下

路过
2009-9-22 11:44
0
雪    币: 295
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
可能是我写的太乱了吧,我也不知道怎么写清楚一些
2009-9-22 12:10
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
12
多写几次就知道该如何表达了,写文章确实比动手分析麻烦啊
2009-9-22 12:24
0
雪    币: 200
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
hehe  感觉自己好渺小
2009-9-22 12:29
0
雪    币: 34
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不错,总算有第一次成功了,继续努力。
2009-9-22 14:58
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
怎么搞的喔 看不懂啊
2009-12-8 21:49
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这个得好好学习下,楼主高人啊
2009-12-9 15:07
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
看不懂
2009-12-11 19:15
0
雪    币: 360
活跃值: (82)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
18
support !
2009-12-12 23:43
0
雪    币: 110
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
support!
2009-12-13 00:40
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
哎!我想问下用不用先学习下汇编啊!否则我什么也看不懂呢!~
2009-12-13 15:47
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
哎 还是看不懂
2009-12-13 19:51
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
支持第一次,这是必须的
2009-12-14 11:35
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
在我看来,楼主的这个已经写的很明了啦。这么详细的分析文章还看不懂。
各位估计是没点程序功底的吧
2009-12-14 14:28
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
很无奈的发现  我也不太明白~!
2009-12-14 15:15
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
你把注册机写回汇编就看懂了
2009-12-25 17:26
0
游客
登录 | 注册 方可回帖
返回
//