首页
社区
课程
招聘
[原创]菜鸟学crackme之壹只老虎
发表于: 2009-5-4 11:46 6164

[原创]菜鸟学crackme之壹只老虎

2009-5-4 11:46
6164

壹只老虎是PEDIY CrackMe 2007里面的一个crackme了  虽然已经有破解文章了 但是下面是自己写的 主要想叫大家帮我看看 思维上有什么可以注意或改进的 这样让我这个小菜成长得更快

用PEiD查出Borland Delphi 6.0 - 7.0  Delphi和BCB的可以用DEDE找按钮事件地址 所以用DEDE加载壹只老虎 找到Button1Click事件地址0048C6D4
用OD加载壹只老虎 Ctrl+g 找到0048C6D4地址断点 然后F9运行输入注册名 whatdayitis 注册码 111111111111111111 后 点击注册 就来到了刚才的断点处 说明断点正确了的 接下来开始分析代码

0048C6D4  /.  55            push    ebp                                                                                                                       
0048C6D5  |.  8BEC          mov     ebp, esp                                                                       
0048C6D7  |.  83C4 84       add     esp, -7C                                    
0048C6DA  |.  53            push    ebx                                         
0048C6DB  |.  56            push    esi                                         
0048C6DC  |.  57            push    edi                                         
0048C6DD  |.  33C9          xor     ecx, ecx                                    
0048C6DF  |.  894D 84       mov     dword ptr ss:[ebp-7C], ecx                  
0048C6E2  |.  894D FC       mov     dword ptr ss:[ebp-4], ecx                  
0048C6E5  |.  894D F8       mov     dword ptr ss:[ebp-8], ecx                  
0048C6E8  |.  894D F4       mov     dword ptr ss:[ebp-C], ecx                  
0048C6EB  |.  894D F0       mov     dword ptr ss:[ebp-10], ecx                  
0048C6EE  |.  894D EC       mov     dword ptr ss:[ebp-14], ecx                  
0048C6F1  |.  8BD8          mov     ebx, eax                                    
0048C6F3  |.  33C0          xor     eax, eax                                    
0048C6F5  |.  55            push    ebp                                         
0048C6F6  |.  68 67C84800   push    4nil_壹?0048C867                           
0048C6FB  |.  64:FF30       push    dword ptr fs:[eax]                          
0048C6FE  |.  64:8920       mov     dword ptr fs:[eax], esp                     
0048C701  |.  8D55 FC       lea     edx, dword ptr ss:[ebp-4]
0048C704  |.  8B83 04030000 mov     eax, dword ptr ds:[ebx+304]
0048C70A  |.  E8 E57EFAFF   call    4nil_壹?004345F4                  ;  get name
0048C70F  |.  8D55 F8       lea     edx, dword ptr ss:[ebp-8]
0048C712  |.  8B83 08030000 mov     eax, dword ptr ds:[ebx+308]
0048C718  |.  E8 D77EFAFF   call    4nil_壹?004345F4                                  ;  get pwd
0048C71D  |.  8D45 F4       lea     eax, dword ptr ss:[ebp-C]        
0048C720  |.  BA 80C84800   mov     edx, 4nil_壹?0048C880             ;  ASCII "i am Bin Laden"
0048C725  |.  E8 CA77F7FF   call    4nil_壹?00403EF4
0048C72A  |.  8D45 F0       lea     eax, dword ptr ss:[ebp-10]
0048C72D  |.  BA 98C84800   mov     edx, 4nil_壹?0048C898             ;  ASCII "i am yi zhi lao hu"
0048C732  |.  E8 BD77F7FF   call    4nil_壹?00403EF4
0048C737  |.  8B45 FC       mov     eax, dword ptr ss:[ebp-4]
0048C73A  |.  E8 DD79F7FF   call    4nil_壹?0040411C                  ;  get name length
0048C73F  |.  83F8 0A       cmp     eax, 0A
0048C742  |.  0F8C FC000000 jl      4nil_壹?0048C844                  ;  length of name <10 game over
0048C748  |.  8B45 FC       mov     eax, dword ptr ss:[ebp-4]
0048C74B  |.  E8 CC79F7FF   call    4nil_壹?0040411C                                  ;  get name length
0048C750  |.  83F8 10       cmp     eax, 10
0048C753  |.  0F8F EB000000 jg      4nil_壹?0048C844                  ;  length of name >16 game over
0048C759  |.  8B45 F8       mov     eax, dword ptr ss:[ebp-8]
0048C75C  |.  E8 BB79F7FF   call    4nil_壹?0040411C                  ;  get pwd length
0048C761  |.  83F8 11       cmp     eax, 11
0048C764  |.  0F8C DA000000 jl      4nil_壹?0048C844                  ;  length of pwd<17 game over
0048C76A  |.  8B45 F8       mov     eax, dword ptr ss:[ebp-8]
0048C76D  |.  E8 AA79F7FF   call    4nil_壹?0040411C                  ;  get pwd length
0048C772  |.  83F8 16       cmp     eax, 16
0048C775  |.  0F8F C9000000 jg      4nil_壹?0048C844                  ;  length of pwd >22 game over
0048C77B  |.  8D45 FC       lea     eax, dword ptr ss:[ebp-4]
0048C77E  |.  8B55 F4       mov     edx, dword ptr ss:[ebp-C]
0048C781  |.  E8 9E79F7FF   call    4nil_壹?00404124                  ;  str1=name+"i am Bin Laden"
                        {
                        00404124   $  85D2          test    edx, edx
                        00404126   .  74 3F         je      short 4nil_壹?00404167
                        00404128   .  8B08          mov     ecx, dword ptr ds:[eax]
                        0040412A   .  85C9          test    ecx, ecx
                        0040412C   .^ 0F84 7EFDFFFF je      4nil_壹?00403EB0
                        00404132   .  53            push    ebx
                        00404133   .  56            push    esi
                        00404134   .  57            push    edi
                        00404135   .  89C3          mov     ebx, eax
                        00404137   .  89D6          mov     esi, edx                                           ;  get "i am Bin Laden"
                        00404139   .  8B79 FC       mov     edi, dword ptr ds:[ecx-4]                          ;  get length of name
                        0040413C   .  8B56 FC       mov     edx, dword ptr ds:[esi-4]                          ;  get length of "i am Bin Laden"
                        0040413F   .  01FA          add     edx, edi                                           ;  两个长度相加的和
                        00404141   .  39CE          cmp     esi, ecx                                           ;  比较用户名和"i am Bin Laden"
                        00404143   .  74 17         je      short 4nil_壹?0040415C                                                           ;相等则返回
                        00404145   .  E8 5E030000   call    4nil_壹?004044A8                                    ;  get name
                        0040414A   .  89F0          mov     eax, esi                                           ;  str="i am Bin Laden"
                        0040414C   .  8B4E FC       mov     ecx, dword ptr ds:[esi-4]                          ;  length(str)
                        0040414F   >  8B13          mov     edx, dword ptr ds:[ebx]                            ;  name
                        00404151   .  01FA          add     edx, edi                                           ;  name后的第一个地址
                        00404153   .  E8 70E7FFFF   call    4nil_壹?004028C8                                    ;  name+str
                                                {
                                                004028C5      8D40 00       lea     eax, dword ptr ds:[eax]
                                                004028C8  /$  56            push    esi
                                                004028C9  |.  57            push    edi
                                                004028CA  |.  89C6          mov     esi, eax
                                                004028CC  |.  89D7          mov     edi, edx
                                                004028CE  |.  89C8          mov     eax, ecx
                                                004028D0  |.  39F7          cmp     edi, esi
                                                004028D2  |.  77 13         ja      short 4nil_壹?004028E7                                                           ;这个地方始终要跳到004028E7 所以004028D4-004028E6是做什么用的呢?
                                                004028D4  |.  74 2F         je      short 4nil_壹?00402905                                                           ;这个应该是检查是否已经拷贝了 拷贝了就不执行以下的了 但是前面一句已经跳了 这句话有用吗
                                                004028D6  |.  C1F9 02       sar     ecx, 2
                                                004028D9  |.  78 2A         js      short 4nil_壹?00402905
                                                004028DB  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]
                                                004028DD  |.  89C1          mov     ecx, eax
                                                004028DF  |.  83E1 03       and     ecx, 3
                                                004028E2  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr ds:[esi]
                                                004028E4  |.  5F            pop     edi
                                                004028E5  |.  5E            pop     esi
                                                004028E6  |.  C3            retn
                                                004028E7  |>  8D7431 FC     lea     esi, dword ptr ds:[ecx+esi-4]                      ;  &str(length-4)
                                                004028EB  |.  8D7C39 FC     lea     edi, dword ptr ds:[ecx+edi-4]                      ;  目标地址
                                                004028EF  |.  C1F9 02       sar     ecx, 2                                             ;  length/4=N个双字
                                                004028F2  |.  78 11         js      short 4nil_壹?00402905
                                                004028F4  |.  FD            std                                                        ;  窜拷贝反向
                                                004028F5  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr ds:[esi]        ;  复制N个双字
                                                004028F7  |.  89C1          mov     ecx, eax
                                                004028F9  |.  83E1 03       and     ecx, 3                                             ;  length mod 4=复制双字后剩下的字节数
                                                004028FC  |.  83C6 03       add     esi, 3
                                                004028FF  |.  83C7 03       add     edi, 3                                             ;  定位地址
                                                00402902  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr ds:[esi]          ;  复制剩下字节
                                                00402904  |.  FC            cld                                                        ;  恢复窜拷贝正向
                                                00402905  |>  5F            pop     edi
                                                00402906  |.  5E            pop     esi
                                                00402907  \.  C3            retn
                                                }
                        00404158   .  5F            pop     edi
                        00404159   .  5E            pop     esi
                        0040415A   .  5B            pop     ebx
                        0040415B   .  C3            retn
                        }           
0048C786  |.  BB 64000000   mov     ebx, 64
0048C78B  |.  8D45 88       lea     eax, dword ptr ss:[ebp-78]
0048C78E  |>  C600 2E       /mov     byte ptr ds:[eax], 2E
0048C791  |.  40            |inc     eax
0048C792  |.  4B            |dec     ebx
0048C793  |.^ 75 F9         \jnz     short 4nil_壹?0048C78E
0048C795  |.  8B45 FC       mov     eax, dword ptr ss:[ebp-4]
0048C798  |.  E8 7F79F7FF   call    4nil_壹?0040411C                  ;  get length of str1
0048C79D  |.  8BF8          mov     edi, eax                         ;  for(m=0; m<length(str1); m++)
0048C79F  |.  85FF          test    edi, edi
0048C7A1  |.  7E 47         jle     short 4nil_壹?0048C7EA
0048C7A3  |.  BB 01000000   mov     ebx, 1
0048C7A8  |>  8B45 F0       /mov     eax, dword ptr ss:[ebp-10]      ;  str2="i am yi zhi lao hu"
0048C7AB  |.  E8 6C79F7FF   |call    4nil_壹?0040411C                 ;  get length of str2
0048C7B0  |.  8BF0          |mov     esi, eax
0048C7B2  |.  85F6          |test    esi, esi
0048C7B4  |.  7E 30         |jle     short 4nil_壹?0048C7E6
0048C7B6  |.  B9 01000000   |mov     ecx, 1
0048C7BB  |>  8B45 FC       |/mov     eax, dword ptr ss:[ebp-4]      ;  for(n=0; n<length(str2); n++)
0048C7BE  |.  0FB64418 FF   ||movzx   eax, byte ptr ds:[eax+ebx-1]   ;  str1[0]
0048C7C3  |.  8B55 F8       ||mov     edx, dword ptr ss:[ebp-8]
0048C7C6  |.  0FB6540A FF   ||movzx   edx, byte ptr ds:[edx+ecx-1]   ;  pwd[n]
0048C7CB  |.  F7EA          ||imul    edx                            ;  str1[m]*pwd[n]
0048C7CD  |.  51            ||push    ecx
0048C7CE  |.  B9 1A000000   ||mov     ecx, 1A
0048C7D3  |.  33D2          ||xor     edx, edx
0048C7D5  |.  F7F1          ||div     ecx                            ;  str1[m]*pwd[n]/1a
0048C7D7  |.  59            ||pop     ecx
0048C7D8  |.  83C2 41       ||add     edx, 41                        ;  str1[m]*pwd[n]mod26+41
0048C7DB  |.  8D0419        ||lea     eax, dword ptr ds:[ecx+ebx]
0048C7DE  |.  885405 87     ||mov     byte ptr ss:[ebp+eax-79], dl         ; 把结果存到内存里面
0048C7E2  |.  41            ||inc     ecx
0048C7E3  |.  4E            ||dec     esi
0048C7E4  |.^ 75 D5         |\jnz     short 4nil_壹?0048C7BB
0048C7E6  |>  43            |inc     ebx
0048C7E7  |.  4F            |dec     edi
0048C7E8  |.^ 75 BE         \jnz     short 4nil_壹?0048C7A8
0048C7EA  |>  8D45 EC       lea     eax, dword ptr ss:[ebp-14]
0048C7ED  |.  E8 6A76F7FF   call    4nil_壹?00403E5C
0048C7F2  |.  8B45 F8       mov     eax, dword ptr ss:[ebp-8]
0048C7F5  |.  E8 2279F7FF   call    4nil_壹?0040411C                  ;  get pwd length
0048C7FA  |.  8BF8          mov     edi, eax
0048C7FC  |.  85FF          test    edi, edi
0048C7FE  |.  7E 1F         jle     short 4nil_壹?0048C81F
0048C800  |.  8D5D 8E       lea     ebx, dword ptr ss:[ebp-72]
0048C803  |>  8D45 84       /lea     eax, dword ptr ss:[ebp-7C]      ;  从str2第6位开始 反向复制每个字符 复制长度为输入的注册码长度(这个地方我没有跟进去 是观察结果得到的)
0048C806  |.  8A13          |mov     dl, byte ptr ds:[ebx]
0048C808  |.  E8 3778F7FF   |call    4nil_壹?00404044
0048C80D  |.  8B55 84       |mov     edx, dword ptr ss:[ebp-7C]
0048C810  |.  8D45 EC       |lea     eax, dword ptr ss:[ebp-14]
0048C813  |.  8B4D EC       |mov     ecx, dword ptr ss:[ebp-14]
0048C816  |.  E8 4D79F7FF   |call    4nil_壹?00404168
0048C81B  |.  43            |inc     ebx
0048C81C  |.  4F            |dec     edi
0048C81D  |.^ 75 E4         \jnz     short 4nil_壹?0048C803
0048C81F  |>  8B45 EC       mov     eax, dword ptr ss:[ebp-14]
0048C822  |.  8B55 F8       mov     edx, dword ptr ss:[ebp-8]
0048C825  |.  E8 3E7AF7FF   call    4nil_壹?00404268                                  ;  比较生成的注册码和输入的注册码
0048C82A  |.  75 18         jnz     short 4nil_壹?0048C844
0048C82C  |.  6A 40         push    40
0048C82E  |.  B9 ACC84800   mov     ecx, 4nil_壹?0048C8AC             ;  恭喜你
0048C833  |.  BA B4C84800   mov     edx, 4nil_壹?0048C8B4             ;  注册成功!请联系我!qq:609841314
0048C838  |.  A1 D0EB4800   mov     eax, dword ptr ds:[48EBD0]
0048C83D  |.  8B00          mov     eax, dword ptr ds:[eax]
0048C83F  |.  E8 F478FCFF   call    4nil_壹?00454138
0048C844  |>  33C0          xor     eax, eax
0048C846  |.  5A            pop     edx
0048C847  |.  59            pop     ecx
0048C848  |.  59            pop     ecx
0048C849  |.  64:8910       mov     dword ptr fs:[eax], edx
0048C84C  |.  68 6EC84800   push    4nil_壹?0048C86E
0048C851  |>  8D45 84       lea     eax, dword ptr ss:[ebp-7C]
0048C854  |.  E8 0376F7FF   call    4nil_壹?00403E5C
0048C859  |.  8D45 EC       lea     eax, dword ptr ss:[ebp-14]
0048C85C  |.  BA 05000000   mov     edx, 5
0048C861  |.  E8 1A76F7FF   call    4nil_壹?00403E80
0048C866  \.  C3            retn

以下是还原的C版本的算法
在XP环境下 VC6调试通过
#include<stdio.h>
#include<string.h>

int main(){
        char name[50];
        char pwd[50];
        char tmp[50];
        char tmp1[]="i am yi zhi lao hu";
        int m, n, pwdLen, tmpLen, tmp1Len;
        char tmp2[50];
        char result[50];
       
        printf("输入用户名:(长度10-16)");
        scanf("%s", name);
        printf("输入注册码(长度17-22):");
        scanf("%s", pwd);

        strcpy(tmp,name);
        strcat(tmp,"i am Bin Laden");
        tmp1Len=strlen(tmp1);        //这个长度是个定值
        pwdLen=strlen(pwd);
        tmpLen=strlen(tmp);

        if(pwdLen<tmp1Len){                        //当输入的注册码小于18 第18位用'A'补上
                pwd[pwdLen]='A';
                pwd[pwdLen+1]='\0';
        }

        for(m=0; m<tmpLen; m++)
                for(n=0; n<tmp1Len; n++)                //这里可以看出 注册码是17位或者18位 因为"i am yi zhi lao hu"这个长度为18 大于18位的注册码也不纳入计算中
                        tmp2[n+m]=tmp[m]*pwd[n]%26+65;

        for(m=0; m<pwdLen; m++)                                //从第六位开始颠倒复制
                result[m]=tmp2[pwdLen-1-m+5];

        result[m]='\0';

        printf("计算后的注册码:\n%s\n", result);

        getch();
        return 0;
}

以下是写的注册机
在XP环境下 VC6调试通过

#include<stdio.h>
#include<string.h>
/*
经过算法分析得出
当注册码为18位时:
pwd[17]=name[5]*pwd[0]%26+65
pwd[16]=name[6]*pwd[0]%26+65
pwd[15]=name[7]*pwd[0]%26+65
pwd[14]=name[8]*pwd[0]%26+65
pwd[13]=name[9]*pwd[0]%26+65
pwd[12]=name[10]*pwd[0]%26+65
pwd[11]=name[11]*pwd[0]%26+65
pwd[10]=name[12]*pwd[0]%26+65
pwd[9]=name[13]*pwd[0]%26+65
pwd[8]=name[14]*pwd[0]%26+65
pwd[7]=name[15]*pwd[0]%26+65
pwd[6]=name[16]*pwd[0]%26+65
pwd[5]=name[17]*pwd[0]%26+65
pwd[4]=name[18]*pwd[0]%26+65
pwd[3]=name[19]*pwd[0]%26+65
pwd[2]=name[20]*pwd[0]%26+65
pwd[1]=name[21]*pwd[0]%26+65
pwd[0]=name[22]*pwd[0]%26+65

当注册码为17位时:
pwd[16]=name[5]*pwd[0]%26+65
pwd[15]=name[6]*pwd[0]%26+65
pwd[14]=name[7]*pwd[0]%26+65
pwd[13]=name[8]*pwd[0]%26+65
pwd[12]=name[9]*pwd[0]%26+65
pwd[11]=name[10]*pwd[0]%26+65
pwd[10]=name[11]*pwd[0]%26+65
pwd[9]=name[12]*pwd[0]%26+65
pwd[8]=name[13]*pwd[0]%26+65
pwd[7]=name[14]*pwd[0]%26+65
pwd[6]=name[15]*pwd[0]%26+65
pwd[5]=name[16]*pwd[0]%26+65
pwd[4]=name[17]*pwd[0]%26+65
pwd[3]=name[18]*pwd[0]%26+65
pwd[2]=name[19]*pwd[0]%26+65
pwd[1]=name[20]*pwd[0]%26+65
pwd[0]=name[21]*pwd[0]%26+65
*/
void yizhilaohu(char * tmp, char * name, int len){
        int n,m;

        for(m=65; m<91; m++)
                if(m==name[22]*m%26+65)                //算出pwd[0] 如果这里不马上跳出 还可以算出更多注册码
                        break;

        printf("注册码:%c", m);

        for(n=1; n<len; n++)
                printf("%c", tmp[len+4-n]*m%26+65);        //根据上面推导算出其他位的注册码
                       
        printf("\n");
}
int main(){
        char name[50];
        char tmp[50];
        //char tmp1[]="i am yi zhi lao hu";
        int m, n, pwdLen, tmpLen, tmp1Len;
       
        printf("输入用户名:(长度10-16)");
        scanf("%s", name);
       
        strcpy(tmp,name);
        strcat(tmp,"i am Bin Laden");

        yizhilaohu(tmp, name, 18);                //当注册码为18位时
        yizhilaohu(tmp, name, 17);                //当注册码为17位时
        getch();
        return 0;
}

到此完毕 这个crackme的注册码不唯一 算法虽然看得懂 写相应的破解算法想好好一阵
最后我还有个疑问 为什么算出的2个注册码 有时候第一个正确 有时候第二个正确 有时候都正确的(都不正确的情况还没发现哈) 这是为什么呢


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我认真看下  只能懂一二
2009-5-4 17:47
0
雪    币: 45
活跃值: (55)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
学习思路了,第一次看不明白,自己调试多几次跟出一些东西来之后再看就懂了
2013-2-8 12:00
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
菜鸟学习阶段
2013-2-11 23:55
0
游客
登录 | 注册 方可回帖
返回
//