首页
社区
课程
招聘
[原创]一个简单的CRACKME
发表于: 2009-8-9 02:17 5152

[原创]一个简单的CRACKME

2009-8-9 02:17
5152
【破文标题】一个简单的CRACKME
【破解作者】吹风生
【使用工具】OllDbg1.10、VISUAL C++08
【破解日期】2009-08-09
【下载地址】http://bbs.pediy.com/upload/2005/37/files/crackme6.rar
【软件简介】07年CRACKME中找的。。算法是中间注册码
【破解声明】我是一只菜鸟,做个实例,发表下感想,高手别笑话哈。

前一段时间一直在看书之类的。。觉得不动手不行啊。。趁着看雪又要举办CRACKME2009,就找个以前07的
的。呵呵,这是我这个菜鸟的第一篇文章。写的不好大家见谅哈。

好了,说下这个CRACKME,这个CRACKME很早了。4nil大侠早就破过。。原文章:http://bbs.pediy.com/showthread.php?t=11222只是觉得这里面有一些地方我们不懂但他觉得很容易呵呵,所以就没写。。我给他补充补充。顺便说下里面的一个问题。。

【破解过程】
这个CRACKME加了ASPack 2.x壳,脱掉壳的过程原文章已经有了。这里不再讲了(话说自己脱壳不是很好的说)
首先自己随便输入Name:zlslyf和Serial:19891001..没提示。。用OD载入。。很简单。直接下GetDlgItemTextA断点。F9运行
,断后,ALT+F9返回。。来到:

00401509  /$  55           push    ebp
0040150A  |.  89E5        mov     ebp, esp
0040150C  |.  81EC 00010000 sub     esp, 100
00401512  |.  53            push    ebx
00401513  |.  56            push    esi
00401514  |.  57            push    edi
00401515  |.  8DBD 00FFFFFF lea     edi, [local.64]
0040151B  |.  8D35 5E244000 lea     esi, dword ptr ds:[40245E]
00401521  |.  B9 40000000   mov     ecx, 40
00401526  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
00401528  |.  68 00010000   push    100                                          ; /Count = 100 (256.)
0040152D  |.  8D85 00FFFFFF lea     eax, [local.64]                              ; |
00401533  |.  50            push    eax                                          ; |Buffer
00401534  |.  6A 65         push    65                                           ; |ControlID = 65 (101.)
00401536  |.  FF75 08       push    [arg.1]                                      ; |hWnd
00401539  |.  E8 FA010000   call    <jmp.&USER32.GetDlgItemTextA>                ; \GetDlgItemTextA
0040153E  |.  89C3          mov     ebx, eax                                     ;  去NAME字符串长度。0则结束。
00401540  |.  09DB          or      ebx, ebx
00401542  |.  75 04         jnz     short unpacked.00401548
00401544  |.  31C0          xor     eax, eax
00401546  |.  EB 50         jmp     short unpacked.00401598
00401548  |>  BF BC020000   mov     edi, 2BC                                     ;  [1]从这开始。
0040154D  |.  BE 30000000   mov     esi, 30
00401552  |.  B8 48000000   mov     eax, 48
00401557  |.  99            cdq
00401558  |.  F7FB          idiv    ebx
0040155A  |.  29C6          sub     esi, eax
0040155C  |.  8D34B6        lea     esi, dword ptr ds:[esi+esi*4]
0040155F  |.  29F7          sub     edi, esi
00401561  |.  6BFF 6B       imul    edi, edi, 6B
00401564  |.  81EF 6CCF0000 sub     edi, 0CF6C
0040156A  |.  81FF 00230000 cmp     edi, 2300
00401570  |.  7F 08         jg      short unpacked.0040157A
00401572  |.  81FF 90010000 cmp     edi, 190
00401578  |.  7D 04         jge     short unpacked.0040157E                      ;  [1]到这结束。字符串长度name_len必须满足:0x190<=(0x2bc-(0x30-0x48/name_len)*5)*0x6b-0x0cf6c<=0x2300
0040157A  |>  31C0          xor     eax, eax
0040157C  |.  EB 1A         jmp     short unpacked.00401598
0040157E  |>  8D85 00FFFFFF lea     eax, [local.64]
00401584  |.  50            push    eax                                          ;  Name
00401585  |.  53            push    ebx                                          ;  Name_len
00401586  |.  FF75 08       push    [arg.1]
00401589  |.  E8 77FDFFFF   call    unpacked.00401305                            ;  序列号生成过程。。。
0040158E  |.  83C4 0C       add     esp, 0C
00401591  |.  09C0          or      eax, eax
00401593  |.  74 03         je      short unpacked.00401598
00401595  |.  31C0          xor     eax, eax
00401597  |.  40            inc     eax
00401598  |>  5F            pop     edi
00401599  |.  5E            pop     esi
0040159A  |.  5B            pop     ebx
0040159B  |.  C9            leave
0040159C  \.  C3            retn
进入序列号生成过程

00401305  /$  55            push    ebp
00401306  |.  89E5          mov     ebp, esp
00401308  |.  81EC 2C040000 sub     esp, 42C
0040130E  |.  53            push    ebx
0040130F  |.  56            push    esi
00401310  |.  57            push    edi
00401311  |.  8DBD FCFEFFFF lea     edi, [local.65]
00401317  |.  8D35 38204000 lea     esi, dword ptr ds:[402038]
0040131D  |.  B9 40000000   mov     ecx, 40
00401322  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
00401324  |.  8DBD E1FBFFFF lea     edi, dword ptr ss:[ebp-41F]
0040132A  |.  8D35 38214000 lea     esi, dword ptr ds:[402138]
00401330  |.  B9 40000000   mov     ecx, 40
00401335  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
00401337  |.  8DBD E1FDFFFF lea     edi, dword ptr ss:[ebp-21F]
0040133D  |.  8D35 38224000 lea     esi, dword ptr ds:[402238]
00401343  |.  B9 40000000   mov     ecx, 40
00401348  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
0040134A  |.  8DBD E1FCFFFF lea     edi, dword ptr ss:[ebp-31F]
00401350  |.  8D35 38234000 lea     esi, dword ptr ds:[402338]
00401356  |.  B9 40000000   mov     ecx, 40
0040135B  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
0040135D  |.  8DBD DCFBFFFF lea     edi, [local.265]
00401363  |.  8D35 38244000 lea     esi, dword ptr ds:[402438]
00401369  |.  B9 05000000   mov     ecx, 5
0040136E  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr ds:[esi]
00401370  |.  8DBD D6FBFFFF lea     edi, dword ptr ss:[ebp-42A]
00401376  |.  8D35 3D244000 lea     esi, dword ptr ds:[40243D]
0040137C  |.  B9 03000000   mov     ecx, 3
00401381  |.  F3:66:A5      rep     movs word ptr es:[edi], word ptr ds:[esi]
00401384  |.  8DBD E1FEFFFF lea     edi, dword ptr ss:[ebp-11F]
0040138A  |.  8D35 43244000 lea     esi, dword ptr ds:[402443]
00401390  |.  B9 1B000000   mov     ecx, 1B
00401395  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr ds:[esi]    ;  前面是在初始化为0.。。。
00401397  |.  C745 FC 00000>mov     [local.1], 0
0040139E  |.  68 00010000   push    100                                          ; /Count = 100 (256.)
004013A3  |.  8D85 E1FCFFFF lea     eax, dword ptr ss:[ebp-31F]                  ; |
004013A9  |.  50            push    eax                                          ; |Buffer
004013AA  |.  6A 66         push    66                                           ; |ControlID = 66 (102.)
004013AC  |.  FF75 08       push    [arg.1]                                      ; |hWnd
004013AF  |.  E8 84030000   call    <jmp.&USER32.GetDlgItemTextA>                ; \GetDlgItemTextA
004013B4  |.  09C0          or      eax, eax                                     ;  取序列号。。
004013B6  |.  0F84 48010000 je      unpacked.00401504
004013BC  |.  B8 CF110000   mov     eax, 11CF                                    ;  [2]从这。
004013C1  |.  0FB68D E1FCFF>movzx   ecx, byte ptr ss:[ebp-31F]
004013C8  |.  99            cdq
004013C9  |.  F7F9          idiv    ecx
004013CB  |.  83FA 17       cmp     edx, 17
004013CE  |.  74 07         je      short unpacked.004013D7                      ;  [2]到此。。对序列号的第一个字母必须满足:0x11cf%Name[0]==0x17...注册机我就直接拿一个字母H了。
004013D0  |.  31C0          xor     eax, eax
004013D2  |.  E9 2D010000   jmp     unpacked.00401504
004013D7  |>  31DB          xor     ebx, ebx
004013D9  |.  EB 0B         jmp     short unpacked.004013E6
004013DB  |>  8B45 10       /mov     eax, [arg.3]
004013DE  |.  0FBE0418      |movsx   eax, byte ptr ds:[eax+ebx]
004013E2  |.  0145 FC       |add     [local.1], eax
004013E5  |.  43            |inc     ebx                                         ;  这个过程计算NAME各个字母的ASCII值的总和。。
004013E6  |>  3B5D 0C        cmp     ebx, [arg.2]
004013E9  |.^ 7C F0         \jl      short unpacked.004013DB
004013EB  |.  31DB          xor     ebx, ebx
004013ED  |.  E9 83000000   jmp     unpacked.00401475
004013F2  |>  8B55 10       /mov     edx, [arg.3]
004013F5  |.  0FBE3C1A      |movsx   edi, byte ptr ds:[edx+ebx]
004013F9  |.  8B75 FC       |mov     esi, [local.1]                              ;  [local.1]存放Name各字母和。。。
004013FC  |.  89D9          |mov     ecx, ebx
004013FE  |.  C1E1 02       |shl     ecx, 2
00401401  |.  89DA          |mov     edx, ebx
00401403  |.  42            |inc     edx
00401404  |.  29D1          |sub     ecx, edx
00401406  |.  0FB68C0D E1FE>|movzx   ecx, byte ptr ss:[ebp+ecx-11F]              ;重点是这。也是写这篇文章的很多一部分原因。当i=0时。3i-1=-1,没有访问到字母表。下面讨论。。
0040140E  |.  89FA          |mov     edx, edi
00401410  |.  31CA          |xor     edx, ecx
00401412  |.  89F1          |mov     ecx, esi
00401414  |.  0FAFCB        |imul    ecx, ebx
00401417  |.  29F1          |sub     ecx, esi
00401419  |.  89CE          |mov     esi, ecx
0040141B  |.  83F6 FF       |xor     esi, FFFFFFFF
0040141E  |.  8DB432 4D0100>|lea     esi, dword ptr ds:[edx+esi+14D]
00401425  |.  8B4D 0C       |mov     ecx, [arg.2]
00401428  |.  89DA          |mov     edx, ebx
0040142A  |.  83C2 03       |add     edx, 3
0040142D  |.  0FAFCA        |imul    ecx, edx
00401430  |.  0FAFCF        |imul    ecx, edi
00401433  |.  89F0          |mov     eax, esi
00401435  |.  01C8          |add     eax, ecx
00401437  |.  B9 0A000000   |mov     ecx, 0A
0040143C  |.  31D2          |xor     edx, edx
0040143E  |.  F7F1          |div     ecx
00401440  |.  83C2 30       |add     edx, 30
00401443  |.  88941D FCFEFF>|mov     byte ptr ss:[ebp+ebx-104], dl
0040144A  |.  0FB6BC1D FCFE>|movzx   edi, byte ptr ss:[ebp+ebx-104]
00401452  |.  81F7 ACAD0000 |xor     edi, 0ADAC
00401458  |.  89DE          |mov     esi, ebx
0040145A  |.  83C6 02       |add     esi, 2
0040145D  |.  89F8          |mov     eax, edi
0040145F  |.  0FAFC6        |imul    eax, esi
00401462  |.  B9 0A000000   |mov     ecx, 0A
00401467  |.  99            |cdq
00401468  |.  F7F9          |idiv    ecx
0040146A  |.  83C2 30       |add     edx, 30
0040146D  |.  88941D FCFEFF>|mov     byte ptr ss:[ebp+ebx-104], dl
00401474  |.  43            |inc     ebx
00401475  |>  3B5D 0C        cmp     ebx, [arg.2]
00401478  |.^ 0F8C 74FFFFFF \jl      unpacked.004013F2                           ;  这个过程得出中间注册码。过程详见注册机。
0040147E  |.  8D85 FCFEFFFF lea     eax, [local.65]
00401484  |.  50            push    eax
00401485  |.  6A 54         push    54
00401487  |.  8D85 DCFBFFFF lea     eax, [local.265]
0040148D  |.  50            push    eax                                          ; |Format
0040148E  |.  8D85 E1FBFFFF lea     eax, dword ptr ss:[ebp-41F]                  ; |
00401494  |.  50            push    eax                                          ; |s
00401495  |.  E8 CE020000   call    <jmp.&USER32.wsprintfA>                      ; \wsprintfA
0040149A  |.  8B7D 0C       mov     edi, [arg.2]                                 ;  “T458527"以T+数字部分输出..
0040149D  |.  89F8          mov     eax, edi
0040149F  |.  0FAF45 FC     imul    eax, [local.1]
004014A3  |.  B9 64000000   mov     ecx, 64
004014A8  |.  99            cdq
004014A9  |.  F7F9          idiv    ecx
004014AB  |.  89D7          mov     edi, edx
004014AD  |.  83C7 30       add     edi, 30
004014B0  |.  57            push    edi
004014B1  |.  8DBD E1FBFFFF lea     edi, dword ptr ss:[ebp-41F]
004014B7  |.  57            push    edi
004014B8  |.  8DBD D6FBFFFF lea     edi, dword ptr ss:[ebp-42A]
004014BE  |.  57            push    edi                                          ; |Format
004014BF  |.  8DBD E1FDFFFF lea     edi, dword ptr ss:[ebp-21F]                  ; |
004014C5  |.  57            push    edi                                          ; |s
004014C6  |.  E8 9D020000   call    <jmp.&USER32.wsprintfA>                      ; \wsprintfA
004014CB  |.  83C4 20       add     esp, 20                                      ;  "T458527-104"再加上EDI的十进制。。。
004014CE  |.  8D8D E1FDFFFF lea     ecx, dword ptr ss:[ebp-21F]
004014D4  |.  83C8 FF       or      eax, FFFFFFFF
004014D7  |>  40            /inc     eax
004014D8  |.  803C01 00     |cmp     byte ptr ds:[ecx+eax], 0
004014DC  |.^ 75 F9         \jnz     short unpacked.004014D7
004014DE  |.  50            push    eax                                          ; /Arg3
004014DF  |.  8D85 E1FCFFFF lea     eax, dword ptr ss:[ebp-31F]                  ; |
004014E5  |.  50            push    eax                                          ; |Arg2
004014E6  |.  8D85 E1FDFFFF lea     eax, dword ptr ss:[ebp-21F]                  ; |
004014EC  |.  50            push    eax                                          ; |Arg1
004014ED  |.  E8 D0FDFFFF   call    unpacked.004012C2                            ; \这个过程是最后验证了。。
004014F2  |.  83C4 0C       add     esp, 0C
004014F5  |.  83F8 00       cmp     eax, 0
004014F8  |.  75 07         jnz     short unpacked.00401501
004014FA  |.  B8 00000000   mov     eax, 0
004014FF  |.  EB 03         jmp     short unpacked.00401504
00401501  |>  31C0          xor     eax, eax
00401503  |.  40            inc     eax
00401504  |>  5F            pop     edi
00401505  |.  5E            pop     esi
00401506  |.  5B            pop     ebx
00401507  |.  C9            leave
00401508  \.  C3            retn

进入:

004012C2  /$  55            push    ebp
004012C3  |.  89E5          mov     ebp, esp
004012C5  |.  53            push    ebx
004012C6  |.  56            push    esi
004012C7  |.  57            push    edi
004012C8  |.  8B5D 10       mov     ebx, [arg.3]
004012CB  |.  31F6          xor     esi, esi
004012CD  |.  46            inc     esi
004012CE  |.  EB 29         jmp     short unpacked.004012F9
004012D0  |>  8B55 08       /mov     edx, [arg.1]
004012D3  |.  0FBE3C32      |movsx   edi, byte ptr ds:[edx+esi]
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
004012E9  |.  8B55 0C       |mov     edx, [arg.2]
004012EC  |.  0FBE1432      |movsx   edx, byte ptr ds:[edx+esi]
004012F0  |.  39D7          |cmp     edi, edx
004012F2  |.  74 04         |je      short unpacked.004012F8
004012F4  |.  31C0          |xor     eax, eax
004012F6  |.  EB 08         |jmp     short unpacked.00401300
004012F8  |>  46            |inc     esi
004012F9  |>  39DE           cmp     esi, ebx
004012FB  |.^ 7C D3         \jl      short unpacked.004012D0                     ;  这个过程将刚才得到的注册码进行(midname[i]^0x20)%10+0x30运算后与输入的序列号作比较。。全对则成功。。
004012FD  |.  31C0          xor     eax, eax
004012FF  |.  40            inc     eax
00401300  |>  5F            pop     edi
00401301  |.  5E            pop     esi
00401302  |.  5B            pop     ebx
00401303  |.  5D            pop     ebp
00401304  \.  C3            retn

好了,整个过程很简单,就两个过程。。一个得出中间注册码,将中间注册码格式为某种形式后,进行某种运算。。运算后与输入的Serial进行比较,正确则成功。。

接下来说下上面说的访问不到字母表的问题。。在软件上运行的时候因为全被初始化为0,所以就等于与0进行异或。但在写注册机的时候,就不知道怎么初始化到table[]数组的前面的堆栈空间。。在VISUAL C++里调试中观察到name位于0x0013ff0c,table位于0x0013ff44.于是想扩大name的大小.以便能够初始化到table数组的堆栈空间前。但后来发现随着我的扩大,编译器把name的内存地址减小,这样扩大空间就没用了。尽管我计算好相差的大小来设计name的空间大小,但一直相差8.。于是想到好像以前看过内存中数组后好像还有两个指针。有知道的人请告诉我。。实在没办法就把注册机分两种情况了。大家有好的办法交流下。。。呵呵。。下面是注册机代码:

#include  "stdafx.h"
#include  "stdio.h"
#include  "string.h"
#include  "stdlib.h"

int main()
{
        char table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";char name[20]={0};int sum=0;
        char midname[20]={0};char lastname[6];char serial[20]={0};int i,p;
        scanf("%s",name);
        int name_len=strlen(name);
        for(int i=0;i<name_len;i++)
        {
                sum+=name[i];
        }
        if(0x190<=(0x2bc-(0x30-0x48/name_len)*5)*0x6b-0x0cf6c<=0x2300)
        {
             serial[0]='H';               
             for(i=0;i<name_len;i++)
                         {
                                 if(!i)
                                 {
                                         p=name[0];
                                 }
                                 else
                                 {
                                    int t=3*i-1; p=name[i]^table[t];
                                 }
                                    int SUM=(sum*i-sum)^0xffffffff;
                                    int d=SUM+p+0x14d+name_len*(i+3)*name[i];
                                    int result=(((d%10+0x30)^0x0adac)*(i+2))%10+0x30;
                                    midname[0]='T';
                                    midname[i+1]=result;
                                 
                         }

                         midname[name_len+1]='\0';
                         int s=(name_len*sum)%0x64+0x30;
                         ultoa(s,lastname,10);              这小段自己写的很繁琐,看了4nil的,觉得很好,就拿来了,请见谅哈。。
                         strcat(midname,"-");
                         strcat(midname,lastname);
                         int serial_len=strlen(midname);
                         for(i=1;i<serial_len;i++)
                         {
                                 serial[i]=(midname[i]^0x20)%10+0x30;
                         }
             printf("%s",serial);
               
        }
        system("PAUSE");
        return 0;
}

PS:看了这么多。。还不如做一遍来的深刻啊。。呵呵。。另外这个CRACKME4nil大侠写过,所以有得罪之处敬请见谅!!

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

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
后面可以用 sprintf()
2009-8-9 03:07
0
雪    币: 390
活跃值: (15)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
sprintf和printf格式控制一样,就输出不一样吧。。一个是标准输出,一个是输到指定缓冲区。。所以应该没什么区别吧。。。
2009-8-9 11:14
0
雪    币: 88
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
好帖子,加油哦再接再厉!!!
2009-8-9 12:43
0
雪    币: 175
活跃值: (69)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
兄弟,进步很快呦。**~!~!
2009-8-9 20:44
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
好好学习  天天向上
2009-8-25 17:06
0
游客
登录 | 注册 方可回帖
返回
//