首页
社区
课程
招聘
[原创]一枚CrackMe分析
2013-8-15 17:10 24780

[原创]一枚CrackMe分析

2013-8-15 17:10
24780
大牛都 在发驱动源码,而我连他们的源码都看不懂,

只会玩CrackMe,哪位好心的大牛收留我吧。

00401140  /[        DISCUZ_CODE_5        ]nbsp; 81EC C8000000 sub     esp, 0C8
00401146  |.  57            push    edi
00401147  |.  B9 09000000   mov     ecx, 9
0040114C  |.  33C0          xor     eax, eax
0040114E  |.  8D7C24 2D     lea     edi, dword ptr [esp+2D]
00401152  |.  C64424 2C 30  mov     byte ptr [esp+2C], 30
00401157  |.  68 70804000   push    00408070                         ;  请输入你的用户名啊:\n
0040115C  |.  F3:AB         rep     stos dword ptr es:[edi]
0040115E  |.  66:AB         stos    word ptr es:[edi]
00401160  |.  AA            stos    byte ptr es:[edi]
00401161  |.  E8 01010000   call    00401267                         ;  puts
00401166  |.  8D4424 58     lea     eax, dword ptr [esp+58]          ;  存放用户名的地址
0040116A  |.  50            push    eax
0040116B  |.  68 6C804000   push    0040806C                         ;  %s
00401170  |.  E8 DB000000   call    00401250                         ;  scanf
00401175  |.  68 54804000   push    00408054                         ;  请输入你的注册码啊:\n
0040117A  |.  E8 E8000000   call    00401267                         ;  puts
0040117F  |.  8D4C24 14     lea     ecx, dword ptr [esp+14]          ;  存放注册码的地址
00401183  |.  51            push    ecx
00401184  |.  68 6C804000   push    0040806C                         ;  %s
00401189  |.  E8 C2000000   call    00401250                         ;  scanf
0040118E  |.  8D9424 940000>lea     edx, dword ptr [esp+94]
00401195  |.  8D4424 6C     lea     eax, dword ptr [esp+6C]          ;  取用户名
00401199  |.  52            push    edx
0040119A  |.  50            push    eax
0040119B  |.  E8 60FEFFFF   call    00401000                         ;  计算用户名长度并将用户名加密,加密其实就是把ascii换位
004011A0  |.  8D8C24 C40000>lea     ecx, dword ptr [esp+C4]
004011A7  |.  8D9424 9C0000>lea     edx, dword ptr [esp+9C]          ;  加密后的用户名
004011AE  |.  51            push    ecx
004011AF  |.  8D4424 78     lea     eax, dword ptr [esp+78]          ;  加密前的用户名
004011B3  |.  52            push    edx
004011B4  |.  50            push    eax
004011B5  |.  E8 96FEFFFF   call    00401050                         ;  进行第二次加密
004011BA  |.  8D4C24 58     lea     ecx, dword ptr [esp+58]
004011BE  |.  8D9424 D00000>lea     edx, dword ptr [esp+D0]          ;  第二次加密后的数据
004011C5  |.  51            push    ecx
004011C6  |.  8D8424 AC0000>lea     eax, dword ptr [esp+AC]          ;  第一次加密后的数据
004011CD  |.  52            push    edx
004011CE  |.  8D8C24 880000>lea     ecx, dword ptr [esp+88]          ;  原用户名
004011D5  |.  50            push    eax
004011D6  |.  51            push    ecx
004011D7  |.  E8 A4FEFFFF   call    00401080                         ;  再一次进行处理
004011DC  |.  8D7C24 40     lea     edi, dword ptr [esp+40]          ;  读取注册码
004011E0  |.  83C9 FF       or      ecx, FFFFFFFF
004011E3  |.  33C0          xor     eax, eax
004011E5  |.  83C4 3C       add     esp, 3C
004011E8  |.  F2:AE         repne   scas byte ptr es:[edi]           ;  读取注册码到一个数组
004011EA  |.  F7D1          not     ecx                              ;  其实就是计算注册码长度
004011EC  |.  49            dec     ecx
004011ED  |.  5F            pop     edi
004011EE  |.  85C9          test    ecx, ecx
004011F0  |.  7E 0F         jle     short 00401201
004011F2  |>  8A5404 00     /mov     dl, byte ptr [esp+eax]          ;  依次读取注册码
004011F6  |.  FEC2          |inc     dl
004011F8  |.  885404 00     |mov     byte ptr [esp+eax], dl          ;  注册码ascii加 1
004011FC  |.  40            |inc     eax
004011FD  |.  3BC1          |cmp     eax, ecx
004011FF  |.^ 7C F1         \jl      short 004011F2
00401201  |>  8D5424 00     lea     edx, dword ptr [esp]
00401205  |.  8D4424 28     lea     eax, dword ptr [esp+28]
00401209  |.  52            push    edx
0040120A  |.  50            push    eax
0040120B  |.  E8 F0FEFFFF   call    00401100
00401210  |.  83C4 08       add     esp, 8
00401213  |.  83F8 01       cmp     eax, 1
00401216  |.  75 19         jnz     short 00401231
00401218  |.  68 40804000   push    00408040                         ;  你输入的是真码:
0040121D  |.  E8 45000000   call    00401267
00401222  |.  83C4 04       add     esp, 4
00401225  |.  E8 7C580000   call    00406AA6
0040122A  |.  81C4 C8000000 add     esp, 0C8
00401230  |.  C3            retn
00401231  |>  68 30804000   push    00408030                         ;  你要努力啊~:
00401236  |.  E8 2C000000   call    00401267
0040123B  |.  83C4 04       add     esp, 4
0040123E  |.  E8 63580000   call    00406AA6
00401243  |.  81C4 C8000000 add     esp, 0C8
00401249  \.  C3            retn

下面依次看各个加密 CALL
第一个加密 部分
00401000  /[        DISCUZ_CODE_19        ]nbsp; 53            push    ebx
00401001  |.  57            push    edi
00401002  |.  8B7C24 0C     mov     edi, dword ptr [esp+C]           ;  edi=用户名
00401006  |.  33DB          xor     ebx, ebx
00401008  |.  8A07          mov     al, byte ptr [edi]               ;  测试第一个字符是否为空
0040100A  |.  84C0          test    al, al
0040100C  |.  74 3D         je      short 0040104B
0040100E  |.  56            push    esi
0040100F  |.  8B7424 14     mov     esi, dword ptr [esp+14]          ;  data
00401013  |>  0FBEC0        /movsx   eax, al
00401016  |.  8BC8          |mov     ecx, eax
00401018  |.  81E1 0F000080 |and     ecx, 8000000F
0040101E  |.  79 05         |jns     short 00401025                  ;  判断 是否为正数
00401020  |.  49            |dec     ecx
00401021  |.  83C9 F0       |or      ecx, FFFFFFF0
00401024  |.  41            |inc     ecx
00401025  |>  99            |cdq
00401026  |.  83E2 0F       |and     edx, 0F                         ;  交换ascii的值,如56变65
00401029  |.  03C2          |add     eax, edx
0040102B  |.  C0E1 04       |shl     cl, 4                           ;  左移4位
0040102E  |.  C1F8 04       |sar     eax, 4                          ;  右移4位
00401031  |.  02C8          |add     cl, al                          ;  相加
00401033  |.  880E          |mov     byte ptr [esi], cl
00401035  |.  79 04         |jns     short 0040103B                  ;  判断是否为正数
00401037  |.  F6D9          |neg     cl                              ;  不为正数则取反加1
00401039  |.  880E          |mov     byte ptr [esi], cl              ;  存放起来
0040103B  |>  8A47 01       |mov     al, byte ptr [edi+1]            ;  继续取下一位
0040103E  |.  47            |inc     edi
0040103F  |.  46            |inc     esi


第二次加密 部分
其实就是再与用户名进行异或

00401050  /[        DISCUZ_CODE_20        ]nbsp; 57            push    edi
00401051  |.  8B7C24 08     mov     edi, dword ptr [esp+8]           ;  edi=用户名
00401055  |.  8A0F          mov     cl, byte ptr [edi]               ;  取第一位判断是否为空
00401057  |.  84C9          test    cl, cl
00401059  |.  74 20         je      short 0040107B                   ;  若第一位为空则退出这个计算
0040105B  |.  8B5424 10     mov     edx, dword ptr [esp+10]
0040105F  |.  56            push    esi
00401060  |.  8B7424 10     mov     esi, dword ptr [esp+10]          ;  取加密后的用户名
00401064  |>  8A06          /mov     al, byte ptr [esi]
00401066  |.  32C1          |xor     al, cl                          ;  与加密前的用户名进行异或运算
00401068  |.  8802          |mov     byte ptr [edx], al
0040106A  |.  7F 04         |jg      short 00401070                  ;  判断是否小于等于0
0040106C  |.  04 60         |add     al, 60                          ;  如果是,则加上0x60
0040106E  |.  8802          |mov     byte ptr [edx], al              ;  取放得到 的数据
00401070  |>  8A4F 01       |mov     cl, byte ptr [edi+1]            ;  继续取下一位数据
00401073  |.  47            |inc     edi
00401074  |.  46            |inc     esi
00401075  |.  42            |inc     edx


再进行一次处理

00401080  /[        DISCUZ_CODE_21        ]nbsp; 55            push    ebp
00401081  |.  8B6C24 08     mov     ebp, dword ptr [esp+8]           ;  ebp=用户名
00401085  |.  8A4D 00       mov     cl, byte ptr [ebp]               ;  取第一个用户名,判断是否为空
00401088  |.  84C9          test    cl, cl
0040108A  |.  74 6C         je      short 004010F8
0040108C  |.  8B5424 14     mov     edx, dword ptr [esp+14]
00401090  |.  53            push    ebx
00401091  |.  56            push    esi
00401092  |.  8B7424 18     mov     esi, dword ptr [esp+18]          ;  第二次加密后的数据
00401096  |.  57            push    edi
00401097  |.  8B7C24 18     mov     edi, dword ptr [esp+18]          ;  第一次加密后的数据
0040109B  |.  74 0E         je      short 004010AB
0040109D  |>  8A07          mov     al, byte ptr [edi]               ;  依次取第一次加密后的数据
0040109F  |.  C74424 14 010>mov     dword ptr [esp+14], 1
004010A7  |.  84C0          test    al, al
004010A9  |.  75 08         jnz     short 004010B3
004010AB  |>  C74424 14 000>mov     dword ptr [esp+14], 0
004010B3  |>  803F 00       cmp     byte ptr [edi], 0                ;  用第一次加密后的数据作为条件结束依据
004010B6  |.  75 09         jnz     short 004010C1
004010B8  |.  803E 00       cmp     byte ptr [esi], 0                ;  比较第二次加密 后的数据 该 位是否为0
004010BB  |.  75 04         jnz     short 004010C1
004010BD  |.  33DB          xor     ebx, ebx
004010BF  |.  EB 05         jmp     short 004010C6
004010C1  |>  BB 01000000   mov     ebx, 1
004010C6  |>  8A06          mov     al, byte ptr [esi]               ;  依次取第二次加密后的数据
004010C8  |.  32C1          xor     al, cl                           ;  将第二次加密后的数据与原用户名进行异或运算
004010CA  |.  32C3          xor     al, bl                           ;  再与数字1进行异或运算
004010CC  |.  8A5C24 14     mov     bl, byte ptr [esp+14]
004010D0  |.  32C3          xor     al, bl                           ;  再与bl进行异或运算
004010D2  |.  3C 30         cmp     al, 30                           ;  比较是否小于0x30
004010D4  |.  8802          mov     byte ptr [edx], al
004010D6  |.  7D 04         jge     short 004010DC
004010D8  |.  34 45         xor     al, 45                           ;  若小于,则与0x45进行异或运算
004010DA  |.  8802          mov     byte ptr [edx], al
004010DC  |>  8A02          mov     al, byte ptr [edx]
004010DE  |.  3C 5B         cmp     al, 5B                           ;  比较是否5B<x<5F
004010E0  |.  7C 08         jl      short 004010EA
004010E2  |.  3C 5F         cmp     al, 5F
004010E4  |.  7F 04         jg      short 004010EA
004010E6  |.  04 08         add     al, 8                            ;  若满足条件 ,则+0x8
004010E8  |.  8802          mov     byte ptr [edx], al               ;  继续取下一位数据,准备进行计算
004010EA  |>  8A4D 01       mov     cl, byte ptr [ebp+1]
004010ED  |.  45            inc     ebp
004010EE  |.  47            inc     edi

注册 码的处理部分:
00401100  /[        DISCUZ_CODE_22        ]nbsp; 8B5424 04     mov     edx, dword ptr [esp+4]           ;  edx=加密转换过后的用户名
00401104  |.  53            push    ebx
00401105  |.  56            push    esi
00401106  |.  8A0A          mov     cl, byte ptr [edx]               ;  取第一个用户名加密后的数据
00401108  |.  84C9          test    cl, cl
0040110A  |.  74 28         je      short 00401134
0040110C  |.  8B7424 10     mov     esi, dword ptr [esp+10]          ;  esi=转换过后的注册码
00401110  |.  8B4424 0C     mov     eax, dword ptr [esp+C]           ;  eax=加密转换过后的用户名
00401114  |>  8A1E          /mov     bl, byte ptr [esi]              ;  依次取转换过后的注册码
00401116  |.  84DB          |test    bl, bl
00401118  |.  74 1E         |je      short 00401138
0040111A  |.  3ACB          |cmp     cl, bl                          ;  比较是否一样,一样则继续比较
0040111C  |.  75 11         |jnz     short 0040112F
0040111E  |.  8A4A 01       |mov     cl, byte ptr [edx+1]            ;  取下一位数据
00401121  |.  42            |inc     edx
00401122  |.  46            |inc     esi

帖上注册机:
#include <stdio.h>
int main(){
        char name[20];
        char name1[20];
        char name2[20];
        char name3[20];
        int i,a,b,c;
        printf("请输入你的用户名啊::\n");
        scanf("%s",name);
        printf("这就是你的注册码啊:\n");
        for(i=0;name[i];i++)
        {
                a=name[i]<<4&0x000000F0;
                b=name[i]>>4&0x0000000F;
                c=a+b;
                name1[i]=c;
                if(name1[i]&0x80)
                        name1[i]=~name1[i]+0x1;
        }//完成第一次加密
        for(i=0;name[i];i++)
        {
                name2[i]=name[i]^name1[i];
                if(name2[i]<=0)
                        name2[i]+=0x60;
        }//完成第二次加密
        for(i=0;name[i];i++)
        {
                name3[i]=name2[i]^name[i];
                if(name3[i]<=0x30)
                {
                        name3[i]=name3[i]^0x45;
                }
                if(name3[i]>0x5B&&name3[i]<0x5F)
                        name3[i]=name3[i]+8;
                name3[i]=name3[i]-0x1;
                printf("%c",name3[i]);
        }
        printf("\n");
        getchar();
        getchar();
}


可用注册码如:speday   6AUERh
注册思路:
1、       依次取各位用户名的ascii值,将十六进制格式的ascii值十位于个位进行对换,如 3F变为F3,2D变成D2,如果变换的结果出现负数,则取它的补码。补码=原码取反+1
2、       将第一步得到的数据与原用户名各字符对应进行异或运算,若得到的结果中有值小于等于0,则将该值加上0x60
3、       将第二步得到的数据,与原用户名进行异或运算,得到的值按以下步骤处理。(1)若小于等于0x30,则与0x45进行异或运算。(2)若0x5B<X<0X5F,则将该值加上0x8
4、      将第三步得到的数据减0x1,就得到正确的注册码。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 5
打赏
分享
最新回复 (20)
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Tartar 2013-8-15 17:32
2
0
稍微复杂点的CrackMe都玩不明白的纯水货 路过
求楼主指点
雪    币: 62
活跃值: (881)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
wonderzdh 1 2013-8-15 17:33
3
0
nice
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
muyiqiusuo 2013-8-15 20:19
4
0
看不懂算法的路过
雪    币: 19
活跃值: (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
破九 2013-8-15 20:29
5
0
return 0;
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-8-15 21:23
6
0
哦,忘了返回一个值了。
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-8-15 21:25
7
0
若哪里没写明白,欢迎提出来。。
雪    币: 45
活跃值: (55)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
shenger 2013-8-15 22:09
8
0
CRACKME大神 哈哈哈
雪    币: 87142
活跃值: (198939)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 2013-8-15 22:15
9
0
+1
雪    币: 2063
活跃值: (1752)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
陈林00007 2013-8-16 07:14
10
0
[QUOTE][/QUOTE]
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cxlongcxl 2013-8-16 19:47
11
0
我也是刚学的,顶楼主!
雪    币: 10301
活跃值: (16596)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhczf 2013-8-17 15:29
12
0
来支持一下楼主发表帖子
雪    币: 680
活跃值: (68)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
稻草人Z 2 2013-8-17 19:55
13
0
前排一个
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Tartar 2013-8-17 21:44
14
0
这个比较简单,还能明白要是稍微复杂点的就
所以说求楼主指点,求带
雪    币: 116
活跃值: (275)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
lpcdma 2013-8-18 19:48
15
0
涛哥最近高产啊,跟你学了。
雪    币: 198
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dingk 2013-8-19 12:31
16
0
混了好长时间了,也就只会欺负一些简单的CrackMe,唉唉唉
最近很长时间都没认真学点东西了,向楼主学习!
雪    币: 35
活跃值: (139)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
JoyFei 2 2013-8-19 22:38
17
0
楼主最近高产,
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
Speeday 8 2013-8-19 23:09
18
0
汗。都 是些简单的,大牛莫笑。
雪    币: 645
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
怕天亮 2013-8-21 15:36
19
0
顶大牛 好文章 菜鸟飞过
雪    币: 5471
活跃值: (2660)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
山民 2013-8-22 08:52
20
0
介绍全面,最后作出注册机。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
困惑灵魂 2013-8-26 10:32
21
0
oyoyoyoy
游客
登录 | 注册 方可回帖
返回