首页
社区
课程
招聘
[原创]破解某keyfile CM
发表于: 2009-8-31 19:36 5552

[原创]破解某keyfile CM

2009-8-31 19:36
5552

【标题】:破解某keyfile CM
【作者】:riusksk(泉哥)
【主页】:http://riusksk.blogbus.com
【软件】: CM.rar
【加壳】:无
【邮箱】:riusksk@qq.com
【时间】:2009/8/30
【声明】:纯属兴趣而已,无其它目的,如果失误之处望赐教!
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
【详细过程】:
用OD载入后,下断点:bpx CreateFileA, 运行后断在如下地址:
0040415A    6A 00           PUSH 0
0040415C    68 80000000     PUSH 80
00404161    51              PUSH ECX
00404162    6A 00           PUSH 0
00404164    52              PUSH EDX
00404165    50              PUSH EAX
00404166    8D43 48         LEA EAX,DWORD PTR DS:[EBX+48]                            ; fcrackme.key
00404169    50              PUSH EAX
0040416A    E8 9DD0FFFF     CALL <JMP.&KERNEL32.CreateFileA>                          ;断在这里
0040416F    83F8 FF         CMP EAX,-1                                                  ;打开失败则跳转
00404172    74 29           JE SHORT crme.0040419D
00404174    8903            MOV DWORD PTR DS:[EBX],EAX                               ; 保存文件句柄
00404176    5F              POP EDI
00404177    5E              POP ESI
00404178    5B              POP EBX
00404179    C3              RETN
因此我们这里先建立一个名为“fcrackme.key”的文件名作为keyfile,
F8下去,执行RETN后,来到下列地址:
00426592    E8 4DC1FDFF     CALL crme.004026E4
00426597    85C0            TEST EAX,EAX
00426599    0F85 66010000   JNZ crme.00426705
0042659F    8D85 A8FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA8]
004265A5    E8 5AD9FDFF     CALL crme.00403F04
004265AA    E8 F9C0FDFF     CALL crme.004026A8
004265AF    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
004265B2    837D FC 00      CMP DWORD PTR SS:[EBP-4],0                               ; 判断文件内容是否为空,不为空则跳转
004265B6    75 15           JNZ SHORT crme.004265CD
004265B8    BA 64674200     MOV EDX,crme.00426764                                    ; ASCII "Key file is empty!"
004265BD    8B83 B0010000   MOV EAX,DWORD PTR DS:[EBX+1B0]
004265C3    E8 CCB6FEFF     CALL crme.00411C94                                        ;设置窗口中的文本内容
004265C8    E9 28010000     JMP crme.004266F5
004265CD    817D FC 0000010>CMP DWORD PTR SS:[EBP-4],10000                           ; 比较fcrackme.key文件中的字符串长度
004265D4    7E 07           JLE SHORT crme.004265DD
004265D6    C745 FC 0000010>MOV DWORD PTR SS:[EBP-4],10000
004265DD    6A 00           PUSH 0
004265DF    8D95 FCFFFEFF   LEA EDX,DWORD PTR SS:[EBP+FFFEFFFC]
004265E5    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-4]                             ; 保存keyfile中字符串的长度
004265E8    8D85 A8FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA8]
004265EE    E8 71D8FDFF     CALL crme.00403E64
004265F3    E8 B0C0FDFF     CALL crme.004026A8
004265F8    53              PUSH EBX
004265F9    57              PUSH EDI
004265FA    56              PUSH ESI
004265FB    8D75 FC         LEA ESI,DWORD PTR SS:[EBP-4]
004265FE    8B0E            MOV ECX,DWORD PTR DS:[ESI]                               ; 字符串长度
00426600    8DB5 FCFFFEFF   LEA ESI,DWORD PTR SS:[EBP+FFFEFFFC]                      ; 字符串
00426606    8DBD FBFFFEFF   LEA EDI,DWORD PTR SS:[EBP+FFFEFFFB]
0042660C    31C0            XOR EAX,EAX
0042660E    83CA FF         OR EDX,FFFFFFFF
00426611    31DB            XOR EBX,EBX
00426613    40              INC EAX
00426614    F7D2            NOT EDX
00426616    8A1C16          MOV BL,BYTE PTR DS:[ESI+EDX]                             ; 依次取keyfile中的字符进行以下计算
00426619    84DB            TEST BL,BL                                               ; 为0则跳转,注意这里是十六进制00,应用十六进制编辑器编辑
0042661B    74 29           JE SHORT crme.00426646
0042661D    E8 16000000     CALL crme.00426638
00426622    52              PUSH EDX                                                 ; 字符位数,从0开始
00426623    F7E3            MUL EBX                                                  ; 字符与上一循环中的值相乘
00426625    5A              POP EDX
00426626    35 326D5463     XOR EAX,63546D32                                         ; 与63546D32异或
0042662B    FEC2            INC DL                                                   ; 计数器
0042662D    39CA            CMP EDX,ECX                                              ; 执行完所有字符则跳转
0042662F    74 42           JE SHORT crme.00426673                                   ; 这里让它跳转就失败了,我就是在这边卡住的,如果不跳转那么就必须执行到00426646,于是我就在这边下断点,但发现OD根本就没执行到这边,由此推断,在此之前应该有个分支跳转语句来判断是否应该执行到00426646,因此我就借助了一下IDA的交叉参考功能,终于发现在00426619就有此判断语句,如下图所示:


00426631    80FA FF         CMP DL,0FF                                               ; 如果DL=FF就跳转
00426634    74 3D           JE SHORT crme.00426673
00426636  ^ EB DE           JMP SHORT crme.00426616                                  ; 循环以上操作
00426638    57              PUSH EDI
00426639    8DBD F4FFFEFF   LEA EDI,DWORD PTR SS:[EBP+FFFEFFF4]
0042663F    8B3F            MOV EDI,DWORD PTR DS:[EDI]
00426641    881C17          MOV BYTE PTR DS:[EDI+EDX],BL
00426644    5F              POP EDI
00426645    C3              RETN
00426646    E8 EDFFFFFF     CALL crme.00426638
0042664B    42              INC EDX                                                  ; EDX=EDX+1
0042664C    83C2 04         ADD EDX,4                                                ; EDX=EDX+4
0042664F    39D1            CMP ECX,EDX                                              ; 将EDX与文件内容长度比较
00426651    75 20           JNZ SHORT crme.00426673                                  ; 不相等则跳转,跳了就完蛋了,因此必须在00之后再加四个字符
00426653    83EA 04         SUB EDX,4                                                ; EDX=EDX-4
00426656    85C0            TEST EAX,EAX
00426658    76 02           JBE SHORT crme.0042665C
0042665A    D1E8            SHR EAX,1                                                ; 将之前EAX的运算结果右移一位
0042665C    3B0416          CMP EAX,DWORD PTR DS:[ESI+EDX]                           ; 将右移后的EAX与00之后的四位字符相比较,也就是说00之后就是经00前面的用户名计算出来的注册码
0042665F    75 09           JNZ SHORT crme.0042666A                                  ; 相等则注册成功
00426661    B8 00000000     MOV EAX,0
00426666    8907            MOV DWORD PTR DS:[EDI],EAX
00426668    EB 10           JMP SHORT crme.0042667A
0042666A    B8 01000000     MOV EAX,1
0042666F    8907            MOV DWORD PTR DS:[EDI],EAX
00426671    EB 07           JMP SHORT crme.0042667A
00426673    B8 02000000     MOV EAX,2
00426678    8907            MOV DWORD PTR DS:[EDI],EAX
0042667A    5E              POP ESI
0042667B    5F              POP EDI
0042667C    5B              POP EBX
0042667D    8A85 FBFFFEFF   MOV AL,BYTE PTR SS:[EBP+FFFEFFFB]
00426683    2C 01           SUB AL,1
00426685    72 08           JB SHORT crme.0042668F
00426687    74 4A           JE SHORT crme.004266D3
00426689    FEC8            DEC AL
0042668B    74 58           JE SHORT crme.004266E5
0042668D    EB 66           JMP SHORT crme.004266F5
0042668F    BA 80674200     MOV EDX,crme.00426780                                    ; ASCII "Valid Key file found!"
00426694    8B83 B0010000   MOV EAX,DWORD PTR DS:[EBX+1B0]
0042669A    E8 F5B5FEFF     CALL crme.00411C94
0042669F    BA A0674200     MOV EDX,crme.004267A0                                    ; ASCII "Registered to: "
004266A4    8D85 A4FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA4]
004266AA    E8 05CCFDFF     CALL crme.004032B4
004266AF    8D85 A4FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA4]
004266B5    8B95 F4FFFEFF   MOV EDX,DWORD PTR SS:[EBP+FFFEFFF4]
004266BB    E8 DCCCFDFF     CALL crme.0040339C
004266C0    8B95 A4FEFEFF   MOV EDX,DWORD PTR SS:[EBP+FFFEFEA4]
004266C6    8B83 C0010000   MOV EAX,DWORD PTR DS:[EBX+1C0]
004266CC    E8 C3B5FEFF     CALL crme.00411C94
004266D1    EB 22           JMP SHORT crme.004266F5
004266D3    BA B8674200     MOV EDX,crme.004267B8                                    ; ASCII "Key file contains wrong serial!"
004266D8    8B83 B0010000   MOV EAX,DWORD PTR DS:[EBX+1B0]
004266DE    E8 B1B5FEFF     CALL crme.00411C94
004266E3    EB 10           JMP SHORT crme.004266F5
004266E5    BA E0674200     MOV EDX,crme.004267E0                                    ; ASCII "Key file is not valid!"
004266EA    8B83 B0010000   MOV EAX,DWORD PTR DS:[EBX+1B0]
004266F0    E8 9FB5FEFF     CALL crme.00411C94
004266F5    8D85 A8FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA8]
004266FB    E8 C8D7FDFF     CALL crme.00403EC8
00426700    E8 A3BFFDFF     CALL crme.004026A8
00426705    33C0            XOR EAX,EAX
00426707    5A              POP EDX
00426708    59              POP ECX
00426709    59              POP ECX
0042670A    64:8910         MOV DWORD PTR FS:[EAX],EDX
0042670D    68 30674200     PUSH crme.00426730
00426712    8D85 A4FEFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFEA4]
00426718    E8 03CBFDFF     CALL crme.00403220
0042671D    8D85 F4FFFEFF   LEA EAX,DWORD PTR SS:[EBP+FFFEFFF4]
00426723    E8 F8CAFDFF     CALL crme.00403220
00426728    C3              RETN
00426729  ^ E9 56C7FDFF     JMP crme.00402E84
0042672E  ^ EB E2           JMP SHORT crme.00426712
00426730    5F              POP EDI
00426731    5E              POP ESI
00426732    5B              POP EBX
00426733    8BE5            MOV ESP,EBP
00426735    5D              POP EBP
00426736    C3              RETN

【算法总结】:
1.        先读取文件名为“fcrackme.key”的keyfile
2.        计算keyfile中00之前的用户名(其实也可不写,直接用十六进制编辑器写个00 00 00 00 00五字节的内容即可),
serial=1;
for (i=0;i<lstrlen(username);i++)
{
serial=(username[i]*serial)^ 63546D32h
}
serial=serial >> 1
3.        文件中00之后的注册码即是上面计算出来值,这里提供两组正确的keyfile(十六进制编辑器下的情况):
[第一组]00000000:00 00 00 00 00
[第二组]00000000:72 69 75 73 6B 73 6B 00 C8 CB DB 79  (“riusksk 人踶”)

【注册机】:
#include "stdio.h"
#include "string.h"

void main()
{
        unsigned long temp=1;
        char serial[5];
        char username[50];
        int i;
        int userlen;
        FILE *keyfile;

        printf("please input your name:\n");
        gets(username);
        userlen=strlen(username);
        for (i=0;i<userlen;i++)
        {
                temp=(username[i]*temp)^0x63546D32;
        }
        temp=temp >> 1;
        strcat(username," ");
        if((keyfile=fopen("fcrackme.key","wt"))==NULL)
        {
            printf("keyfile creating errer!");
            return;
        }
    else
        {
                        fwrite(username,userlen,1,keyfile);
                        serial[0]=0;
                        serial[1]=temp;
                        serial[2]=temp>>8;
                        serial[3]=temp>>16;
                        serial[4]=temp>>24;
                        for(i=0;i<5;i++)
                        fputc(serial[i],keyfile);
                        printf("\nkeyfile has created successful!!\n");
                        printf("Make By riusksk\n");
        }
        return;
}


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
2
刚看到逍遥风版主分析的一个CM与此CM类似,不过他分析不完全正确,他只分析出全为0的情况,而忽略了用户名的存在的情况:http://bbs.pediy.com/showthread.php?threadid=23444
2009-9-1 15:55
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
3
下回去看看,分析很详细。。。顶下
2009-9-1 17:13
0
游客
登录 | 注册 方可回帖
返回
//