首页
社区
课程
招聘
[原创]Kostya's crackme 分析笔记
发表于: 2006-8-5 04:35 5904

[原创]Kostya's crackme 分析笔记

2006-8-5 04:35
5904

Crackme        名称        :KeygenMe #1 By Kostya
Cracker                :ainafeng
工具                :OllyDbg
声明:我是一个初学者,报着学习的目的来到这里希望大家多多指教!!!
     前一个被意外加精,受到鼓励,再发一个。
       
1.运行程序,注册名与注册码只允许输入一个字符,通过readme得知这个crackeme,只允许输入一个字符,我们要修改它;
使用olly载入,无意发现EM_LIMITTEXT这个 wparam=通过修改这个可以解除限制,或nop掉;
试运行可以了

00401315  |. 6A 00          PUSH 0                                   ; /lParam = 0
00401317  |. 6A 01          PUSH 1                                   ; |wParam = 1
00401319  |. 68 C5000000    PUSH 0C5                                 ; |Message = EM_LIMITTEXT
0040131E  |. 68 E9030000    PUSH 3E9                                 ; |ControlID = 3E9 (1001.)
00401323  |. 50             PUSH EAX                                 ; |hWnd => NULL
00401324  |. E8 A1000000    CALL <JMP.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA
00401329  |. 33C0           XOR EAX,EAX
0040132B  |. A1 14324000    MOV EAX,DWORD PTR DS:[403214]
00401330  |. 6A 00          PUSH 0                                   ; /lParam = 0
00401332  |. 6A 01          PUSH 1                                   ; |wParam = 1
00401334  |. 68 C5000000    PUSH 0C5                                 ; |Message = EM_LIMITTEXT
00401339  |. 68 EA030000    PUSH 3EA                                 ; |ControlID = 3EA (1002.)
0040133E  |. 50             PUSH EAX                                 ; |hWnd => NULL
0040133F  |. E8 86000000    CALL <JMP.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA
00401344  |. 58             POP EAX

在GetWindowTextLengthA上下断点,来到

004010C3  |. FF35 0C324000  PUSH DWORD PTR DS:[40320C]               ; /hWnd = NULL
004010C9  |. E8 F0020000    CALL <JMP.&USER32.GetWindowTextLengthA>  ; \GetWindowTextLengthA
004010CE  |. B9 00000000    MOV ECX,0
004010D3  |. 83F8 13        CMP EAX,13
004010D6  |. 7F 43          JG SHORT KeygenMe.0040111B                        ;>13则 over
004010D8  |. 83F8 03        CMP EAX,3
004010DB  |. 7E 3E          JLE SHORT KeygenMe.0040111B                        ;<3 则over
所以上面的注册名wparam可以改为13h

004011E7  |. 50             PUSH EAX                                 ; /hWnd => NULL
004011E8  |. E8 D1010000    CALL <JMP.&USER32.GetWindowTextLengthA>  ; \GetWindowTextLengthA
004011ED  |. B9 00000000    MOV ECX,0
004011F2  |. 83F8 18        CMP EAX,18
004011F5  |.^0F85 20FFFFFF  JNZ KeygenMe.0040111B

注册码的wparam可以改为18h
ReadMe 还说 "Patch it, to stop closing after the registration procedure".
手动F8一步一步地运行了几次,发现都从这个地方跳死;

00401148  |. B8 00000000    MOV EAX,0                        ; EAX清零
0040114D  |. 83F8 00        CMP EAX,0                        ;总是相等
00401150  |. 0F85 FF000000  JNZ KeygenMe.00401255        ;退出
00401156  |.^E9 CCFEFFFF    JMP KeygenMe.00401027        ;重开始

我们把 MOV EAX,0 改为 MOV EAX,1 .

输入试练码

                ainafeng
                123456789012345678901234

开始
Olly 断在GetWindowTextLength
F8.

0040110F  |. B8 0C304000    MOV EAX,KeygenMe.0040300C                ;  ASCII "ainafeng"
00401114  |. E8 B8010000    CALL KeygenMe.004012D1

关键call 004012D1

004012D1  /$ 8A10           MOV DL,BYTE PTR DS:[EAX]
004012D3  |. 6BC9 48        IMUL ECX,ECX,48
004012D6  |. 2BCA           SUB ECX,EDX
004012D8  |. 83E9 6F        SUB ECX,6F
004012DB  |. 8BD1           MOV EDX,ECX
004012DD  |. 81F1 AFAC0B00  XOR ECX,0BACAF
004012E3  |. 40             INC EAX
004012E4  |. 4B             DEC EBX
004012E5  |. 83FB 00        CMP EBX,0
004012E8  |.^75 E7          JNZ SHORT KeygenMe.004012D1
004012EA  \. C3             RETN

这个循环计算出注册码的一部分,继续往下走

0040116B  |. 68 00304000    PUSH KeygenMe.00403000                   ; /pBufCount =
00401170  |. 68 0C304000    PUSH KeygenMe.0040300C                   ; |Buffer =
00401175  |. E8 62020000    CALL <JMP.&ADVAPI32.GetUserNameA>        ; \GetUserNameA

这个原来是调用系统的登陆名

0040127A  /$ 55             PUSH EBP
0040127B  |. 8BEC           MOV EBP,ESP
0040127D  |. 33C0           XOR EAX,EAX
0040127F  |. 33DB           XOR EBX,EBX
00401281  |. 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]        ;上次的结果-〉eax
00401284  |. 8B5D 0C        MOV EBX,DWORD PTR SS:[EBP+C]        ;这次的结果-〉ebx
00401287  |. 8BD0           MOV EDX,EAX                                ;edx=eax
00401289  |. 33D3           XOR EDX,EBX                                ;edx=edx^ebx
0040128B  |. 81F2 ACFF0000  XOR EDX,0FFAC                        ;edx=edx^0xFFAC
00401291  |. 81F3 53050000  XOR EBX,553                                ;ebx=ebx^0x553
00401297  |. 03C3           ADD EAX,EBX                                ;eax=eax+ebx
00401299  |. 03DA           ADD EBX,EDX                                ;ebx=ebx+edx
0040129B  |. 4B             DEC EBX                                ;ebx--
0040129C  |. 03C3           ADD EAX,EBX                                ;eax=eax+ebx
0040129E  |. C9             LEAVE

00401346  /$ A1 1C324000    MOV EAX,DWORD PTR DS:[40321C]        ;第一个结果(r1)
0040134B  |. 8B1D 18324000  MOV EBX,DWORD PTR DS:[403218]        ;第二个结果(r2)
00401351  |. 3BC3           CMP EAX,EBX                                ;if(r1!=r2)
00401353  |. 75 0E          JNZ SHORT KeygenMe.00401363               
00401355  |. 81F3 8E000000  XOR EBX,8E                                ;r1==r2 ,ebx=ebx^0x8e
0040135B  |. 03D8           ADD EBX,EAX                                ;ebx=ebx+eax
0040135D  |. 891D 18324000  MOV DWORD PTR DS:[403218],EBX        ;保存 r2

三。总结
1。注册码的格式
   r2,x2,r1
2。注册码 的第三个四个和十四个字符的位置为“-”
     r1=(r1*48h-sn-6f)^0XBACAF
     r2=(r2*0x48-username-0x6f)^0XBACAF
        x=r1;
        x^=r2;
        x^=0x0FFAC;
        x1=r2^0x553;
        x2=r1+tmp1;
        x1=x1+x;
        x1--;
        x2=x2+x1;
   然后前三个字符替换为KOS
3。可用的注册码
   ainafeng
   KOSA-48A0B0167-9174B2665


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 115
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
#include<stdio.h>
#include<string.h>
#include<windows.h>

int main(){
        char name[15], pc[20], pwd[30];
        int i, cexName, cexPc, eax, edx, tmp;
        DWORD countPc = 20;

        memset(pwd, 0x00, sizeof(30));

        printf("请输入用户名(用户名长度为4-13):");
        scanf("%s", name);

        edx=name[0];
        for(i=0,cexName=0; i<strlen(name); i++){
                tmp=((((cexName*0x48)-edx)-0x6f)^0xbacaf);
                edx=(((cexName*0x48)-edx)-0x6f)&0xFFFFFF00|name[i+1];    //每次都要把下个name[n]放到DL中
                cexName=tmp;
        }

        GetUserName(pc, &countPc);

        edx=pc[0];
        for(i=0,cexPc=0; i<strlen(name); i++){                                                //以输入的用户名为长度循环 系统用户名+1(这一位是结束符)位长度还多出的 用相应的name来代替
                tmp=((((cexPc*0x48)-edx)-0x6f)^0xbacaf);
                if(strlen(pc)>i)
                        edx=(((cexPc*0x48)-edx)-0x6f)&0xFFFFFF00|pc[i+1];
                else
                        edx=(((cexPc*0x48)-edx)-0x6f)&0xFFFFFF00|name[i+1];
                cexPc=tmp;
        }

        eax=(((cexPc^0x553)+((cexName^cexPc)^0xffac))-1)+(cexName+(cexPc^0x553));

        if(strcmp(name, pc)==0)                                //输入的用户名和系统用户名相等时 执行
                cexName=(cexName^0x8e)+cexPc;

        sprintf(pwd, "%08X%08X%08X", cexPc, eax, cexName);       

        pwd[4]='-';
        pwd[14]='-';
        pwd[0]='K';
        pwd[1]='O';
        pwd[2]='S';

        printf("注册码:%s\n", pwd);
       
        getch();
        return 0;
}
2009-5-13 11:36
0
雪    币: 87
活跃值: (25)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
我也是想写这个注册机,但是发现有一个问题一直没有解决,请高手指点!
问题:不同的机器上(比如Xp sp2 和Xp sp3虚拟机),相同的用户名,却得到不同的注册码?这个是为什么?我认为是因为
00401100  |.  FF35 0C324000       PUSH DWORD PTR DS:[40320C]               ; /hWnd = 003A0396 (class='Edit',parent=004103FC)
00401106  |.  E8 B3020000         CALL <JMP.&USER32.GetWindowTextLengthA>  ; \GetWindowTextLengthA
0040110B  |.  33C9                XOR ECX,ECX
0040110D  |.  8BD8                MOV EBX,EAX
0040110F  |.  B8 0C304000         MOV EAX,KeygenMe.0040300C                ;  ASCII "guan"
00401114  |.  E8 B8010000         CALL KeygenMe.004012D1                   ;  第一次计算的值ecx=ec2ac3e5
00401119  |.  EB 40               JMP SHORT KeygenMe.0040115B

这一段中不同的机器上GetWindowLength操作对edx的值产生影响,而有的则不产生影响,而edx的值将会在CALL KeygenMe.004012D1 函数中用到因此产生了不同机器上相同用户名得到不同的注册码!这个分析是否正确?希望高手指点我这个菜鸟,不胜感激!(附件是我写的注册机源码)
上传的附件:
2009-5-24 14:52
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了,呵呵
2009-5-31 15:16
0
游客
登录 | 注册 方可回帖
返回
//