Quantcast
Channel: 看雪安全论坛
Viewing all articles
Browse latest Browse all 9556

【原创】一枚CrackMe分析

$
0
0
大牛都 在发驱动源码,而我连他们的源码都看不懂,
:eek::eek::eek::eek::eek::eek:
只会玩CrackMe,哪位好心的大牛收留我吧。
:3::3::3::3::3::3::3::3::3::3::3:
代码:

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,就得到正确的注册码。

上传的附件
文件类型: rar CrackMe.rar (25.7 KB)

Viewing all articles
Browse latest Browse all 9556

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>