lgjxj 发表于 2007-1-27 01:11:20

破解一个骗新手的 CM(全世界高手飘过)

【文章标题】: 破解一个骗新手的 CM(全世界高手飘过)
【文章作者】: KAN [ DCG ]
【作者邮箱】: tom7411@163.com
【作者主页】: 我都想有,可惜。。。。
【作者QQ号】: 看雪说不要留
【软件名称】: CrackMe2.exe
【软件大小】: 很小
【下载地址】: https://www.chinapyg.com/viewthread.php?tid=11454&extra=page%3D1
【加壳方式】: UPX
【编写语言】: Delphi 6.0 - 7.0
【使用工具】: 当然是 0D 了
【操作平台】: WIN XP
【软件介绍】: 在飘云阁下的一个 CM
【作者声明】: 只是感兴趣,为解密而学破解
--------------------------------------------------------------------------------
【详细过程】
今天在飘云阁下了一个 CM,打开一看,随意输入了用户名和假码后,下了各种断点都断不下来,烦了,打开 WIN 任务
管理器见到这个 CM 有两个进程,看来有一个是假的(也因为这样才写这篇破文(很破的文)给新手直到一些假象)

于是就到程序载入点看看它的启动,原来问题就在开头
   
00454EB8 <模> $55            PUSH EBP                           ; 程序启动停在这里
00454EB9   .8BEC          MOV EBP,ESP
00454EBB   .83C4 F0       ADD ESP,-10
00454EBE   .B8 D84C4500   MOV EAX,CrackMe2.00454CD8
00454EC3   .E8 380FFBFF   CALL CrackMe2.00405E00
00454EC8   .E8 83FDFFFF   CALL CrackMe2.00454C50            ;这个 CALL 启动了骗人的 CM 框架,靠
00454ECD   .A1 70604500   MOV EAX,DWORD PTR DS:
00454ED2   .8B00          MOV EAX,DWORD PTR DS:
00454ED4   .E8 2FE0FFFF   CALL CrackMe2.00452F08
00454ED9   .A1 70604500   MOV EAX,DWORD PTR DS:
00454EDE   .8B00          MOV EAX,DWORD PTR DS:
00454EE0   .BA 1C4F4500   MOV EDX,CrackMe2.00454F1C         ;ASCII "CrackMe #2"
00454EE5   .E8 2EDCFFFF   CALL CrackMe2.00452B18
00454EEA   .8B0D A05F4500 MOV ECX,DWORD PTR DS:       ;CrackMe2.00457BFC
00454EF0   .A1 70604500   MOV EAX,DWORD PTR DS:
00454EF5   .8B00          MOV EAX,DWORD PTR DS:
00454EF7   .8B15 A8444500 MOV EDX,DWORD PTR DS:       ;CrackMe2.004544F4
00454EFD   .E8 1EE0FFFF   CALL CrackMe2.00452F20
00454F02   .A1 70604500   MOV EAX,DWORD PTR DS:
00454F07   .8B00          MOV EAX,DWORD PTR DS:
00454F09   .E8 92E0FFFF   CALL CrackMe2.00452FA0       ;老兄,这个 才是真命天子啊 ,F8 过 启动 CM
00454F0E   .E8 E9EFFAFF   CALL CrackMe2.00403EFC

——————————————————————————————————————————————

F7 进入 454EBE 处把下面这条指令宰了,“痛快”

00454C7D    |. /75 05         JNZ SHORT CrackMe2.00454C84         ;把 JZ 改为 jnz 就可以了

——————————————————————————————————————————————
看,这样它就不会启动那个骗我们的假货了,杀 ,然后 CTRL + B 输入 错误对话框中的 Bad Code! 关键字
就可以很容易找到下面了

0045481E    |.8B45 E4       MOV EAX,DWORD PTR SS:       ;用户名地址送入 EAX,F2 下个断点吧
00454821    |.E8 86FAFAFF   CALL CrackMe2.004042AC            ;得到了用户名的位数
00454826    |.8BD8          MOV EBX,EAX                         ;将位数送入 EBX
00454828    |.85DB          TEST EBX,EBX                        ;看看你大哥有没有输入用户名
0045482A    |.7E 3F         JLE SHORT CrackMe2.0045486B         ;没有就不给你玩,死了吧
0045482C    |.BE 01000000   MOV ESI,1
   

00454831    |>8D55 DC       /LEA EDX,DWORD PTR SS:      ;循环开始
00454834    |.8B87 04030000 |MOV EAX,DWORD PTR DS:   ;用户名地址重新还给了 EAX,
                                                                                 本来就是它的
0045483A    |.E8 09F0FDFF   |CALL CrackMe2.00433848
0045483F    |.8B45 DC       |MOV EAX,DWORD PTR SS:
00454842    |.8A4430 FF   |MOV AL,BYTE PTR DS:   ;用户名第一字节送入了 AL
00454846    |.50            |PUSH EAX                           ; /Char
00454847    |.E8 AC20FBFF   |CALL <JMP.&user32.VkKeyScanA>      ; \这个CALL 就把用户名字符加
                                                                            工成注册码的各位数值
0045484C    |.0FBFC0      |MOVSX EAX,AX
0045484F    |.8D4D E0       |LEA ECX,DWORD PTR SS:      ;除了上面的一个 CALL 是由于外,
                                                                      其它的基本是假货,不理
00454852    |.BA 03000000   |MOV EDX,3
00454857    |.E8 4837FBFF   |CALL CrackMe2.00407FA4
0045485C    |.8B55 E0       |MOV EDX,DWORD PTR SS:
0045485F    |.8D45 F8       |LEA EAX,DWORD PTR SS:
00454862    |.E8 4DFAFAFF   |CALL CrackMe2.004042B4
00454867    |.46            |INC ESI
00454868    |.4B            |DEC EBX
00454869    |.^ 75 C6         \JNZ SHORT CrackMe2.00454831      ;看看 EBX 是否为 0,不是就跳回

0045486B    |>8B45 F8       MOV EAX,DWORD PTR SS:
0045486E    |.E8 39FAFAFF   CALL CrackMe2.004042AC
00454873    |.83F8 14       CMP EAX,14
00454876    |.7E 0D         JLE SHORT CrackMe2.00454885
00454878    |.8D45 F8       LEA EAX,DWORD PTR SS:
0045487B    |.BA 14000000   MOV EDX,14
00454880    |.E8 B3FDFAFF   CALL CrackMe2.00404638
00454885    |>8B45 F8       MOV EAX,DWORD PTR SS:
00454888    |.E8 1FFAFAFF   CALL CrackMe2.004042AC
0045488D    |.83F8 14       CMP EAX,14
00454890    |.7D 22         JGE SHORT CrackMe2.004548B4
00454892    |.8B45 F8       MOV EAX,DWORD PTR SS:
00454895    |.E8 12FAFAFF   CALL CrackMe2.004042AC
0045489A    |.8BF0          MOV ESI,EAX
0045489C    |.83FE 13       CMP ESI,13
0045489F    |.7F 13         JG SHORT CrackMe2.004548B4
004548A1    |>8D45 F8       /LEA EAX,DWORD PTR SS:
004548A4    |.BA 90494500   |MOV EDX,CrackMe2.00454990
004548A9    |.E8 06FAFAFF   |CALL CrackMe2.004042B4             //这里看看你上面的注册码几位,不够20位的后面用0来补上
004548AE    |.46            |INC ESI
004548AF    |.83FE 14       |CMP ESI,14
004548B2    |.^ 75 ED         \JNZ SHORT CrackMe2.004548A1
004548B4    |>8D55 D8       LEA EDX,DWORD PTR SS:
004548B7    |.8B87 F8020000 MOV EAX,DWORD PTR DS:
004548BD    |.E8 86EFFDFF   CALL CrackMe2.00433848
004548C2    |.8B55 D8       MOV EDX,DWORD PTR SS:
004548C5    |.8B45 F8       MOV EAX,DWORD PTR SS:
004548C8    |.E8 2BFBFAFF   CALL CrackMe2.004043F8
004548CD    |.74 52         JE SHORT CrackMe2.00454921       ;关键跳转,改为 JMP 你就无敌了
                                                               ;在我心中这比算法注册还完美破解,强
004548CF    |.FF87 08030000 INC DWORD PTR DS:
004548D5    |.83BF 08030000>CMP DWORD PTR DS:,3
004548DC    |.75 05         JNZ SHORT CrackMe2.004548E3
004548DE    |.E8 19F6FAFF   CALL CrackMe2.00403EFC
004548E3    |>B8 03000000   MOV EAX,3
004548E8    |.2B87 08030000 SUB EAX,DWORD PTR DS:
004548EE    |.83F8 02       CMP EAX,2
004548F1    |.75 17         JNZ SHORT CrackMe2.0045490A
004548F3    |.6A 00         PUSH 0
004548F5    |.66:8B0D 94494>MOV CX,WORD PTR DS:
004548FC    |.33D2          XOR EDX,EDX
004548FE    |.B8 A0494500   MOV EAX,CrackMe2.004549A0            ;ASCII "Bad Code!"
                                                                  ,CR,"2 attempt(s) remaining..."
00454903    |.E8 582BFDFF   CALL CrackMe2.00427460
00454908    |.EB 38         JMP SHORT CrackMe2.00454942
0045490A    |>6A 00         PUSH 0
0045490C    |.66:8B0D 94494>MOV CX,WORD PTR DS:
00454913    |.33D2          XOR EDX,EDX
                     
00454915    |.B8 CC494500   MOV EAX,CrackMe2.004549CC             ;ASCII "Bad Code!",
                                                                     CR,"1 attempt remaining..."
0045491A    |.E8 412BFDFF   CALL CrackMe2.00427460
0045491F    |.EB 21         JMP SHORT CrackMe2.00454942
00454921    |>6A 00         PUSH 0
00454923    |.66:8B0D 94494>MOV CX,WORD PTR DS:
0045492A    |.B2 02         MOV DL,2
0045492C    |.B8 F8494500   MOV EAX,CrackMe2.004549F8          ;ASCII "Code is OK!",CR,"
                                                                   Thanks for solving this CrackMe..."
00454931    |.E8 2A2BFDFF   CALL CrackMe2.00427460
00454936    |.A1 70604500   MOV EAX,DWORD PTR DS:
0045493B    |.8B00          MOV EAX,DWORD PTR DS:
0045493D    |.E8 4AE7FFFF   CALL CrackMe2.0045308C




--------------------------------------------------------------------------------
【经验总结】

总结一下,它的注册过程:
   
                        用户名长度有 1 位也通过
                     
                        你输入的用户名小写的,它硬把它改为大写(没道理)

                        注册码只是用妳的用户名的 ASCII 码连在一起,当然如果你输入的如果是
                        小写的话,它会在每位前头加一个 0 ,输入的是大写的话就加个 1

                                 你输入一百个用户名字符,它就帮你算前七个,所以你可以省些力气

                        没了。。。。。。。。。。结束
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
main()
{
      cout<<"请输入你的用户名,程序结束计算在前第七位,你看着办吧!\n";
      char temp;
      char name;
      cin>>temp;
      int i;
      for(i=0;temp!='\0';i++) // 获取长度,也可以用 strlen 函数来代替
      {
          if(temp=='\0')
          break;
      }
      int v=0,j,b;
      for(j=0;j<i;j++)
      {

          v=temp;
          b=v;
          if(v>90)
          {
         v-=32;   //如果输入的是小写就把它转换为大写
          }
          name=v;
          if(b>90)
          cout<<"0";//输入用户名字符是小写的插入 0
          else
          cout<<"1";   //输入用户名字符是大写的插入 1
          if(j==6)
          {
            if(b>90)
            cout<<"4\n";
            else
            cout<<"5\n";
            return 0;
          }
          printf("%0X",name);
      }
          switch(j)
          {
            case 1:cout<<"00000000000000000\n";
            break;
            case 2:cout<<"00000000000000\n";
            break;
            case 3:cout<<"00000000000\n";
            break;
            case 4:cout<<"00000000\n";
            break;
            case 5:cout<<"00000\n";
            break;
            case 6:cout<<"00\n";
            break;
          }
      cout<<endl;
}                     //修改了一下,昨天看漏眼了,第七位也在计算之内
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年01月27日 1:06:57

[ 本帖最后由 lgjxj 于 2007-1-27 10:38 编辑 ]

xuhw 发表于 2007-1-27 11:04:23

分析的不错啊!继续进行CM3

coolpeople 发表于 2007-1-27 21:45:25

真假窗口是怎么样传递注册码的..有点搞不明白...:L

wan 发表于 2007-1-28 00:36:26

漂亮…学习了!!!

avel 发表于 2007-1-29 11:05:41

不错不错~~~
呵呵!
页: [1]
查看完整版本: 破解一个骗新手的 CM(全世界高手飘过)