CrackMe-005全破详解(图文+源码)--上篇
逆向破解 | 逆向 | 逆向分析 | CrackMe | Crack | CrackMe5 | CrackMe05
前言
CrackMe005,都说比较变态,很多人给放过去了,但是我还是决定上了它,既然变态就分两篇,上篇先实际说流程,到底应该怎么上它,下篇会告诉逆向分析的过程和方法
准备
【环境和工具】
-
win7/xp虚拟机环境
-
CrackMe005(ajj2.zip)
-
ollydbg
-
Dededark
-
peid
-
UPXEasyGUI.exe(upx专用脱壳器)
【学习层次】
-
爆破,但是这个CM作者声明了,爆破他是不认可的
-
解密流程,写注册机
-
积累Delphi程序逆向特点经验
实战图文
一.最终效果动图展示
二.查壳、脱壳
1.peid查壳
发现是upx壳,如下图
2.脱壳
-
peid通用脱壳可以脱(脱后492K)
-
手动OD脱可以脱(脱后492K)
-
UPXEasyGUI.exe(upx专用脱壳器)也可以脱,脱后(448K)
-
建议UPXEasyGUI脱,前两种脱法脱后,反汇编代码有些地方会有一定的错位,会影响逆向分析
-
具体原因是啥有高人可以指点的话请联系我
脱后如图
二.整个破解流程
注意:建议使用我已经修改过的原版,修改点只有一个字符X盘符改成了C盘符,否则你需要增加X分区或者改盘符,搁不住,所以我修改了程序,当然你也可以自己脱壳后,自己搜索字符串,自己再改盘符字符串
1.复制目录下ok.txt,到C:\ajj.126.c0m\j\o\j\o\ok.txt,这里我给原版的X盘改成C盘了,不然就改分区。
2.这时就应该可以显示出Edit2文本框,但是是禁用状态。
3.右键点击5次注册按钮(注意是右键)。
4.左键双击图框区空白处(不能点着图),Edit2文本框禁用解除。
5.用户名输入ajj
6.Edit2文本框内输入1_345,78后左键双击Edit2输入框中任何位置。
7.在图片是“性相近”的时候,鼠标从软件框右下脚移入软件框内。
8.在图片是“性本善”的时候,鼠标从软件框左下角移入软件框内。
9.这时候应该label3显示出数字,是0,1,2,3这四个当中的其中一个。
10.将数字输入我写的注册机,点击生成最终点击方案。
11.依照方案点击相应图片,注册成功
三、注册机源码
源码中,我求的是点击次数总和最小的方法,因为其实有很多组合,只求效率最高的方法,源码写的比较臃肿,为的是新手好读懂
1 void CCM002Dlg::OnOK() 2 { 3 // TODO: Add extra validation here 4 5 //CDialog::OnOK(); 6 7 char szKey[1024]={0}; 8 int n = 0; 9 GetDlgItemText(IDC_EDIT1,szKey,1024); 10 if(!strlen(szKey)) 11 { 12 13 MessageBox("请按照【前期步骤】获取正确数值后再生成方案!","友情提示"); 14 return; 15 } 16 n = GetDlgItemInt(IDC_EDIT1); 17 18 19 switch(n){ 20 case 1 : 21 n=0x3D; 22 break; 23 case 2 : 24 n=0x34; 25 break; 26 case 3 : 27 n=0xDF; 28 break; 29 30 default : // 可选的 31 n=0x41; 32 } 33 34 35 struct image 36 { 37 char szname[7]; 38 int nNumber ; 39 int nLef; 40 int nRight; 41 }; 42 image aImage[4]={0}; 43 44 sprintf(aImage[0].szname,"人之初"); 45 aImage[0].nNumber = 1; 46 aImage[0].nLef = 0x2; 47 aImage[0].nRight = 0x11; 48 49 sprintf(aImage[1].szname,"性本善"); 50 aImage[1].nNumber = 2; 51 aImage[1].nLef = 0x3; 52 aImage[1].nRight = 0x13; 53 54 sprintf(aImage[2].szname,"性相近"); 55 aImage[2].nNumber = 3; 56 aImage[2].nLef = 0x5; 57 aImage[2].nRight = 0x17; 58 59 sprintf(aImage[3].szname,"习相远"); 60 aImage[3].nNumber = 4; 61 aImage[3].nLef = 0x7; 62 aImage[3].nRight = 0x1B; 63 /************************************************************************/ 64 /* 设计原则,选择出点击次数最少的方案 65 /* iR作为大数数组下标,iL作为小数数组下标,j大数商,k小数商,求i+j最小值 66 /************************************************************************/ 67 int nRes = 112; 68 int nIL = 0; 69 int nIR = 0; 70 int nJ = 0; 71 int nK =0 ; 72 for (int iL=0;iL<4;iL++) 73 { 74 for (int iR=0;iR < 4;iR++) 75 { 76 77 for (int j=1;j<=14;j++) 78 { 79 for (int k =0;k<=112;k++) 80 { 81 82 if ((aImage[iR].nRight*j + aImage[iL].nLef*k == n) && (nRes> j+k)) 83 { 84 nIL = iL; 85 nIR = iR; 86 nJ = j; 87 nK = k; 88 nRes = j+k ; 89 } 90 91 } 92 } 93 } 94 95 } 96 97 sprintf(szKey,"在“%s”图片时左键点击图片%d次\r\n\r\n在“%s”图片时右键点击图片%d次\r\n\r\n即可注册成功!",aImage[nIL].szname,nK,aImage[nIR].szname,nJ); 98 SetDlgItemText(IDC_EDIT2,szKey); 99 100 101 }