首页
社区
课程
招聘
[讨论]菜鸟练手的crackme,当然要写出算法
发表于: 2009-5-4 21:16 4861

[讨论]菜鸟练手的crackme,当然要写出算法

2009-5-4 21:16
4861
今天看了<密码学导引>第一章.写了个简单的crackme来给新手试试,算法不是很难,请写出注册机!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 115
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
先用PEID 查得Microsoft Visual C++ 6.0  用OD加载 断点bp GetWindowTextA 77D3216B 再F9运行输入用户名注册码确定停在77D3216B 现在是在USER32下面的 两次ctrl+f9跳到用户代码004015E1  再想想得到文本框个信息应该在点了确定以后吧 所以这里估计是确定按钮对应的事件代码 一直往上看在00401560断点 点击确定后 的确断在这里了 说明断点正确  分析如下:

00401560   .  83EC 5C       sub     esp, 5C
00401563   .  53            push    ebx
00401564   .  56            push    esi
00401565   .  8BF1          mov     esi, ecx
00401567   .  897424 14     mov     dword ptr ss:[esp+14], esi
0040156B   .  8D9E 98000000 lea     ebx, dword ptr ds:[esi+98]
00401571   .  8BCB          mov     ecx, ebx
00401573   .  E8 838C0100   call    仿射密码.0041A1FB                                     ;  length(name)
00401578   .  83F8 05       cmp     eax, 5
0040157B   .  0F8C 46010000 jl      仿射密码.004016C7                                     ;  length(name)<5 game over
00401581   .  8D4E 5C       lea     ecx, dword ptr ds:[esi+5C]
00401584   .  E8 728C0100   call    仿射密码.0041A1FB                                     ;  length(pwd)
00401589   .  85C0          test    eax, eax                                          ;  length(pwd)==0 game over
0040158B   .  0F84 36010000 je      仿射密码.004016C7
00401591   .  55            push    ebp
00401592   .  57            push    edi
00401593   .  B9 0F000000   mov     ecx, 0F
00401598   .  BE C4B04200   mov     esi, 仿射密码.0042B0C4                                ;  ASCII "0123456789abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
0040159D   .  8D7C24 2C     lea     edi, dword ptr ss:[esp+2C]
004015A1   .  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]       ;  str=0123456789abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
004015A3   .  8BCB          mov     ecx, ebx
004015A5   .  66:A5         movs    word ptr es:[edi], word ptr ds:[esi]
004015A7   .  E8 4F8C0100   call    仿射密码.0041A1FB                                     ;  length(name)
004015AC   .  8BF0          mov     esi, eax
004015AE   .  8D7E 01       lea     edi, dword ptr ds:[esi+1]
004015B1   .  57            push    edi
004015B2   .  E8 3D570100   call    仿射密码.00416CF4                                     ;  分配内存空间
004015B7   .  57            push    edi
004015B8   .  894424 18     mov     dword ptr ss:[esp+18], eax
004015BC   .  E8 33570100   call    仿射密码.00416CF4                                     ;  分配内存空间
004015C1   .  8BE8          mov     ebp, eax
004015C3   .  57            push    edi
004015C4   .  896C24 24     mov     dword ptr ss:[esp+24], ebp
004015C8   .  E8 27570100   call    仿射密码.00416CF4                                     ;  分配内存空间
004015CD   .  83C4 0C       add     esp, 0C
004015D0   .  894424 14     mov     dword ptr ss:[esp+14], eax
004015D4   .  8B4424 10     mov     eax, dword ptr ss:[esp+10]
004015D8   .  8BCB          mov     ecx, ebx
004015DA   .  57            push    edi
004015DB   .  50            push    eax
004015DC   .  E8 EB8B0100   call    仿射密码.0041A1CC                                     ;  length(name)
004015E1   .  8BC6          mov     eax, esi
004015E3   .  B9 3E000000   mov     ecx, 3E
004015E8   .  99            cdq
004015E9   .  F7F9          idiv    ecx                                               ;  length(name)/3E
004015EB   .  8BC1          mov     eax, ecx
004015ED   .  2BC6          sub     eax, esi
004015EF   .  8A5C14 2C     mov     bl, byte ptr ss:[esp+edx+2C]                      ;  num1=str[length(name)%3E]
004015F3   .  99            cdq
004015F4   .  F7F9          idiv    ecx                                               ;  (3E-length(name))%3E
004015F6   .  33C9          xor     ecx, ecx
004015F8   .  85F6          test    esi, esi
004015FA   .  8A5414 2C     mov     dl, byte ptr ss:[esp+edx+2C]                      ;  num2=str[(3E-length(name))%3E]
004015FE   .  7E 4E         jle     short 仿射密码.0040164E                               ;  num2<=0 game over
00401600   .  0FBEC3        movsx   eax, bl
00401603   .  894424 24     mov     dword ptr ss:[esp+24], eax                        ;  num1
00401607   .  8B4424 10     mov     eax, dword ptr ss:[esp+10]                        ;  name
0040160B   .  0FBED2        movsx   edx, dl                                           ;  num2
0040160E   .  2BC5          sub     eax, ebp
00401610   .  895424 28     mov     dword ptr ss:[esp+28], edx                        ;  num1
00401614   .  894424 20     mov     dword ptr ss:[esp+20], eax
00401618   .  EB 04         jmp     short 仿射密码.0040161E
0040161A   >  8B4424 20     mov     eax, dword ptr ss:[esp+20]
0040161E   >  8D1C29        lea     ebx, dword ptr ds:[ecx+ebp]                       ;  ecx=n
00401621   .  8B5424 28     mov     edx, dword ptr ss:[esp+28]                        ;  num1
00401625   .  BD 3E000000   mov     ebp, 3E
0040162A   .  0FBE0418      movsx   eax, byte ptr ds:[eax+ebx]                        ;  name[n]
0040162E   .  0FAF4424 24   imul    eax, dword ptr ss:[esp+24]                        ;  name[n]*num1
00401633   .  03C2          add     eax, edx                                          ;  name[n]*num1+num2
00401635   .  99            cdq
00401636   .  F7FD          idiv    ebp
00401638   .  8BC2          mov     eax, edx                                          ;  sum3=(name[n]*num1+num2)%3E
0040163A   .  03C1          add     eax, ecx                                          ;  sum3+n
0040163C   .  99            cdq
0040163D   .  F7FD          idiv    ebp                                               ;  (sum3+n)%3E
0040163F   .  8B6C24 18     mov     ebp, dword ptr ss:[esp+18]
00401643   .  41            inc     ecx
00401644   .  3BCE          cmp     ecx, esi                                          ;  for(n=0; n<length(name); n++)
00401646   .  8A4414 2C     mov     al, byte ptr ss:[esp+edx+2C]                      ;  pwd[n]=str[(sum3+n)%3E]
0040164A   .  8803          mov     byte ptr ds:[ebx], al
0040164C   .^ 7C CC         jl      short 仿射密码.0040161A
0040164E   >  8B5424 1C     mov     edx, dword ptr ss:[esp+1C]
00401652   .  C60429 00     mov     byte ptr ds:[ecx+ebp], 0
00401656   .  8B4C24 14     mov     ecx, dword ptr ss:[esp+14]
0040165A   .  57            push    edi                                               ;  以上循环生成字符串code
0040165B   .  51            push    ecx
0040165C   .  8D4A 5C       lea     ecx, dword ptr ds:[edx+5C]
0040165F   .  E8 688B0100   call    仿射密码.0041A1CC                                     ;  得到输入注册码的前面length(name)个字符
00401664   .  33C0          xor     eax, eax
00401666   .  33DB          xor     ebx, ebx
00401668   .  85F6          test    esi, esi                                          ;  length(name)<0 game over
0040166A   .  7E 3C         jle     short 仿射密码.004016A8
0040166C   .  8B4C24 14     mov     ecx, dword ptr ss:[esp+14]                        ;  pwd
00401670   .  8BFD          mov     edi, ebp                                          ;  code
00401672   .  2BCD          sub     ecx, ebp
00401674   .  894C24 28     mov     dword ptr ss:[esp+28], ecx
00401678   >  8A1439        mov     dl, byte ptr ds:[ecx+edi]                         ;  pwd[0]
0040167B   .  3A17          cmp     dl, byte ptr ds:[edi]                             ;  比较 pwd[0]和code[0] 是否相等  看到这里没有继续看了 看看下面的OK  可以猜想是不是生成的字符串就是注册码呢
0040167D   .  75 29         jnz     short 仿射密码.004016A8
0040167F   .  40            inc     eax
00401680   .  3BF0          cmp     esi, eax
00401682   .  894424 24     mov     dword ptr ss:[esp+24], eax
00401686   .  75 1A         jnz     short 仿射密码.004016A2
00401688   .  8B4C24 1C     mov     ecx, dword ptr ss:[esp+1C]
0040168C   .  6A 00         push    0
0040168E   .  6A 00         push    0
00401690   .  68 C0B04200   push    仿射密码.0042B0C0                                     ;  ASCII "OK!"
00401695   .  E8 88790100   call    仿射密码.00419022
0040169A   .  8B4C24 28     mov     ecx, dword ptr ss:[esp+28]
0040169E   .  8B4424 24     mov     eax, dword ptr ss:[esp+24]
004016A2   >  43            inc     ebx
004016A3   .  47            inc     edi
004016A4   .  3BDE          cmp     ebx, esi
004016A6   .^ 7C D0         jl      short 仿射密码.00401678
004016A8   >  8B4424 10     mov     eax, dword ptr ss:[esp+10]
004016AC   .  50            push    eax
004016AD   .  E8 6B560100   call    仿射密码.00416D1D
004016B2   .  55            push    ebp
004016B3   .  E8 65560100   call    仿射密码.00416D1D
004016B8   .  8B4C24 1C     mov     ecx, dword ptr ss:[esp+1C]
004016BC   .  51            push    ecx
004016BD   .  E8 5B560100   call    仿射密码.00416D1D
004016C2   .  83C4 0C       add     esp, 0C
004016C5   .  5F            pop     edi
004016C6   .  5D            pop     ebp
004016C7   >  5E            pop     esi
004016C8   .  5B            pop     ebx
004016C9   .  83C4 5C       add     esp, 5C
004016CC   .  C3            retn

大致分析就是这样了 在OD中第一次写的注释很详细但是不见了 比较郁闷 这次就简约写了。。

以下是算法:
在XP环境VC6下编译通过
#include<stdio.h>
#include<string.h>

int main(){
        char *str="0123456789abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char name[20];
        char pwd[20];
        char code[20];
        int len, n;

        memset(name, 0, sizeof(name));
        memset(pwd, 0, sizeof(pwd));
        memset(code, 0, sizeof(code));

        printf("请输入用户名:");
        scanf("%s", name);
       
        printf("请输入注册码:");
        scanf("%s", pwd);

        len=strlen(name);

        if(len<5)
                return 0;
        if(strcmp(pwd, "")==0)
                return 0;

        /*
                pwd[n]=str[(sum3+n)%3E]  
                sum3=(name[n]*num1+num2)%3E
                num2=str[(3E-length(name))%3E]
                num1=str[length(name)%3E]
  */
        for(n=0; n<len; n++){
                code[n]=str[(((name[n]*(str[len%0x3E])+(str[(0x3E-len)%0x3E]))%0x3E)+n)%0x3E];
                if(pwd[n]!=code[n])
                        return 0;
        }
       
        printf("ok!");

        getch();
        return 0;
}

以下是注册代码:
在XP环境VC6下编译通过
#include<stdio.h>
#include<string.h>

int main(){
        char *str="0123456789abcdefghjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char name[20];
        char pwd[20];
        int len, n;

        printf("请输入用户名(长度大于等于五位):");
        scanf("%s", name);

        len=strlen(name);

        /*
                pwd[n]=str[(sum3+n)%3E]  
                sum3=(name[n]*num1+num2)%3E
                num2=str[(3E-length(name))%3E]
                num1=str[length(name)%3E]
  */
        for(n=0; n<len; n++)
                pwd[n]=str[(((name[n]*(str[len%0x3E])+(str[(0x3E-len)%0x3E]))%0x3E)+n)%0x3E];
        pwd[n]='\0';

        printf("注册码:%s", pwd);

        getch();

        return 0;
}
2009-5-5 02:48
0
雪    币: 1596
活跃值: (30)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
厉害!厉害!能这么详细相信也不是菜鸟了.
以下是仿射密码的原理:

E(a,b,x)=(a*x1+b)%26,(a*x2+b)%26,(a*x3+b)%26,......,(a*x(n-1)+b)%26,(a*xn+b)%26



但希望,没有搞懂的,先搞懂再看


2009-5-5 07:24
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
厉害 膜拜下!!!!!
2009-5-5 13:04
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
注册机。。不错
2009-5-5 14:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
厉害,看来自己得用点时间好好学习一下
2009-5-8 11:34
0
雪    币: 1027
活跃值: (256)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
7
太厉害了哇!!高手
2009-5-8 13:27
0
游客
登录 | 注册 方可回帖
返回
//