您的位置:首页精文荟萃破解文章 → 算法分析: <献给初学者> 之三

算法分析: <献给初学者> 之三

时间:2004/10/15 0:55:00来源:本站整理作者:蓝点我要评论(3)

 
▲软件名称▲ CRACKME.EXE

▲下载地址▲ http://ddcrack.myetang.com/crackit/crackme/ctm-cm2.zip

▲破解难度▲
应该说无论从破解角度,还是算法角度,它都可以算作较难级别。其本身推荐级别就为2级。特别是它的破解,如果单纯地从动态调试角度去看的话,恐怕作为一名初学者来讲,会被搞得一头雾水。所以,它的破解与算法比较起来则更为困难和复杂。

▲破解思路▲
首先,我们要找到那个Key File文件名和文件类型。然后,正确设置断点:Bpx CreatefileA。此断点的含义是:确定文件是否存在;打开文件并获得句柄。再后,我们就要用16进制编辑器来建立一个假的KEYFILE文件,推荐使用HexWorkshop。而且,本例也必须使用HexWorkshop这样的16进制编辑器方可。建立好假的钥匙文件后,就要在文件里面先随便地写入一些东东,保存并退出该钥匙文件。接下来,再重新运行待破解程序,按照正常破解思路去寻找突破口,争取找到其文件中的内容,以便正确构造这个KEYFILE。
好了,让我们一起出发吧!Let's go!!!!!!

▲破解过程▲
首先,我们来找到Key File的名称及类型。使用反汇编(先脱去其UPX壳)、动态跟踪或者使用 Filemon,这三种方法均可准确找到其钥匙文件的名称类型信息,这个比较简单,不详细叙述了。它的钥匙文件为:CTM_CM02.KEY。是个注册表类型文件,存入路径为安装目录下。所以,我们就可以用HexWorkshop来建立这样一个文件,然后再编辑它,在里面随便写入一些东东。(关于HexWorkshop的使用方法,这里也不详述,请大家参照看雪及相关教程)
好了,准备工作已经做好了,让我们来看看到底这个CRACKME有哪些与众不同之处吧?!

如上面所提设断,然后运行程序(或者先运行程序,在程序还未弹出错误提示前,快速启动SI也可以),程序被成功拦截。然后按2次F12,然后按F10到达下面这里…………
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00426570(C)
|
:00426553 8D85F4FFFEFF lea eax, dword ptr [ebp+FFFEFFF4]
:00426559 BA40674200 mov edx, 00426740
:0042655E E839CEFDFF call 0040339C
:00426563 FE85FBFFFEFF inc byte ptr [ebp+FFFEFFFB]
:00426569 80BDFBFFFEFF00 cmp byte ptr [ebp+FFFEFFFB], 00
:00426570 75E1 jne 00426553

* Possible StringData Ref from Code Obj ->"ctm_cm02.key"=============>可见钥匙文件名称
及文件类型信息。
|
:00426572 BA4C674200 mov edx, 0042674C
:00426577 8D85A8FEFEFF lea eax, dword ptr [ebp+FFFEFEA8]
:0042657D E83FD8FDFF call 00403DC1
:00426582 BA01000000 mov edx, 00000001
:00426587 8D85A8FEFEFF lea eax, dword ptr [ebp+FFFEFEA8]
:0042658D E81EDCFDFF call 004041B0
:00426592 E84DC1FDFF call 004026E4
:00426597 85C0 test eax, eax
:00426599 0F8566010000 jne 00426705
:0042659F 8D85A8FEFEFF lea eax, dword ptr [ebp+FFFEFEA8]
:004265A5 E85AD9FDFF call 00403F04=====================>EAX=你输入的字符 长度值
:004265AA E8F9C0FDFF call 004026A8
:004265AF 8945FC mov dword ptr [ebp-04], eax=======>[ebp-04]=字符长度004265B2 837DFC00 cmp dword ptr [ebp-04], 00000000===>钥匙文件内的字符长度与00比较
:004265B6 7515 jne 004265CD======================>不是00就跳到下边。
* Possible StringData Ref from Code Obj ->"Key file is empty!"======>提示钥匙文件为空!
|
:004265B8 BA64674200 mov edx, 00426764
:004265BD 8B83B0010000 mov eax, dword ptr [ebx+000001B0]
:004265C3 E8CCB6FEFF call 00411C94
:004265C8 E928010000 jmp 004266F5

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004265B6(C)
|
:004265CD 817DFC00000100 cmp dword ptr [ebp-04], 00010000===>钥匙文件内的字符
长度与0x10000比较
:004265D4 7E07 jle 004265DD=======================>不大于则跳!
:004265D6 C745FC00000100 mov [ebp-04], 00010000=============>大于则置[ebp-04]为0x10000。
以上过程是在对钥匙文件内你输入的字符串长度进行比较定位,如果不大于0x10000,就跳走,继续执行下面,如果字符串长度超出0x010000范围,则置[ebp-04]为0x10000。呵呵。。。。
以下是真正要进入关键了。我将以******符号把我的破解中的想法及破解方法标明出来。希望大家可以看得清楚些。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004265D4(C)
|
:004265DD 6A00 push 00000000
:004265DF 8D95FCFFFEFF lea edx, dword ptr [ebp+FFFEFFFC]
:004265E5 8B4DFC mov ecx, dword ptr [ebp-04]=======>字符串长度送ECX
:004265E8 8D85A8FEFEFF lea eax, dword ptr [ebp+FFFEFEA8]
:004265EE E871D8FDFF call 00403E64

:004265F3 E8B0C0FDFF call 004026A8
:004265F8 53 push ebx
:004265F9 57 push edi
:004265FA 56 push esi
:004265FB 8D75FC lea esi, dword ptr [ebp-04]
:004265FE 8B0E mov ecx, dword ptr [esi]
:00426600 8DB5FCFFFEFF lea esi, dword ptr [ebp+FFFEFFFC]
:00426606 8DBDFBFFFEFF lea edi, dword ptr [ebp+FFFEFFFB]
:0042660C 31C0 xor eax, eax======================>EAX=0
:0042660E 83CAFF or edx, FFFFFFFF
:00426611 31DB xor ebx, ebx======================>EBX=0
:00426613 40 inc eax===========================>EAX=01
:00426614 F7D2 not edx===========================>EDX=0

************************关键部分之一******************************

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00426636(U)
|
:00426616 8A1C16 mov bl, byte ptr [esi+edx]******依次取你输入的字符放入
BL中。
:00426619 84DB test bl, bl*********************测试BL是否为0
:0042661B 7429 je 00426646***************** ①测试结果是0就跳到下边
:0042661D E816000000 call 00426638 ▲
:00426622 52 push edx
:00426623 F7E3 mul ebx**************EAX=EBX*EAX,相乘的结果放在EAX中
在前面,EBX已经被初始赋值为0。
:00426625 5A pop edx
:00426626 35326D5463 xor eax,63546D32******执行计算:EAXxor63546D32,并且把相异或的结果存入EAX中。而进一步查看的话,你可以发现:63546D32=“cTm2”。呵呵。。。。

:0042662B FEC2 inc dl===========>DL加1,作为循环的计数器。DL初始为0。
:0042662D 39CA cmp edx, ecx=====>比较循环次数与字符长度
:0042662F 7442 je 00426673********** ②循环完毕跳走

:00426631 80FAFF cmp dl, FF***********比较循环次数与FF(10进制的255)。如果相等,则跳走。这里实际上是一个限制,其作用后面说。
:00426634 743D je 00426673********** ③相等就跳走

:00426636 EBDE jmp 00426616==============>跳回去循环,直到循环完毕。

那么,也许有人会问:这部分代码写的不是很清楚吗?有什么问题吗?事实上,代码的意思是清楚的,只是如果单纯在动态下分析时,会让人一头雾水,因为这一小段代码中,包含的跳转命令太多太复杂,稍微疏忽一点儿,就会搞不清楚它的跳转目标了。所以,我还是把我破解的过程全如实地写出来,供大家参考。
好了,为了弄清楚到底这些跳转做什么用,我们就来看看。按照从下向上的顺序,先看③和②。

★如果②③处的跳转成立,那么,它们都将会跳到以下地方:

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0042662F(C), :00426634(C), :00426651(C)***************************重点!要害!往下看!
| ▲ ▲ ▲
:00426673 B802000000 mov eax, 00000002******************跳到了这里。它跳过来后做什么呢?呵呵,它使EAX=02。那又怎么样啊?呵呵,请往下看!!!

:00426678 8907 mov dword ptr [edi], eax==========>[edi]=EAX
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00426668(U), :00426671(U)
|
:0042667A 5E pop esi
:0042667B 5F pop edi
:0042667C 5B pop ebx
:0042667D 8A85FBFFFEFF mov al, byte ptr [ebp+FFFEFFFB]****使AL=02
:00426683 2C01 sub al, 01*************************AL=AL-01
:00426685 7208 jb 0042668F=======================>小于0则跳
:00426687 744A je 004266D3=======================>等于0则跳
:00426689 FEC8 dec al*****************************AL=AL-01
:0042668B 7458 je 004266E5************************等于0则跳
:0042668D EB66 jmp 004266F5

由于我们的EAX=02,因此,我们只会在 je 004266E5 处跳转。看看它跳到了哪里??

* Possible StringData Ref from Code Obj ->"Key file is not valid!"
| ▲▲▲▲▲▲▲▲▲▲

:004266E5 BAE0674200 mov edx, 004267E0***************此处下命令D,可以看见
上面的出错提示信息。
:004266EA 8B83B0010000 mov eax, dword ptr [ebx+000001B0]
:004266F0 E89FB5FEFF call 00411C94
因此,我们必须做到不能让②③跳转,也就是要做到不能让EAX=02。(最为关键之处!!!)
大家再往前面看看,先后共有三个跳转会到EAX=02的地方。因此,我们都要保证其跳转命令不能跳过来方可。如果能够做到这一点,那么,我们就可以从唯一剩下的可供选择的①处顺利往下运行了。
呵呵。那么就接着来!先来看看:如何才能做到程序必须在①处顺利往下运行呢?

****************************关键部分之二******************************

让我们回过头再来研究研究①处的代码吧。(此处真是关键中的关键啊!!!!)

:00426616 8A1C16 mov bl, byte ptr [esi+edx]******依次取你输入的字符放入
BL中。
:00426619 84DB test bl, bl*********************测试BL是否为0
:0042661B 7429 je 00426646***************** ①测试结果是0就跳到下边
:0042661D E816000000 call 00426638 ▲

仔细分析,可以看出:如果能够让BL为0,就会成功跳转;否则,玩完!呵呵,怎样才能为0?说实话,现在想来是挺简单,但是当时可真是感觉无从下手!其实说穿了,就是必须让所取到的字符中含有00!!!呵呵,看看后面的解释----“依次取你输入的字符放入BL中”。因此,只要让程序所取到的字符是00就能够满足跳转条件啦。不过千万别弄错了,这个00是指你输入的字符中含有00!这里就有一个问题了,就是前面提到的那个使用FF进行比较的限制条件,它的作用就是如果程序取FF位时,还没有出现00的话,它就会跳到出错的地方了。由此,我们在此可以获得重大突破:我们输入的字符串的字节中,要含有00,且它一定要出现在255位之前!就是最多只可有254位!那么,还犹豫什么呀?快把KeyFile改过来吧?记住,要用16进制编辑器改哟?

好了,现在我们可以顺利地在①处跳转了。万岁!!!!接着往下看看吧…………★如果①处的跳转成立,那么,它将跳到以下地方:

****************************关键部分之三*****************************

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0042661B(C)
|
:00426646 E8EDFFFFFF call 00426638===========>我们跳到了这里。此处我们可以
得到如下信息:EAX=计算结果;ECX=字符长度;EDX=循环次数
:0042664B 42 inc edx******************EDX=循环次数+1
:0042664C 83C204 add edx, 00000004********EDX=EDX+04
:0042664F 39D1 cmp ecx, edx*************比较EDX与你输入的字符长度
:00426651 7520 jne 00426673*************不相等则跳!跳到哪里去了?
天哪!这个跳转正是能够使得EAX=02的第三个跳转!!!!因此,我们无论如何不能够让它跳!

怎样才能不让它跳?就是要让最后那个EDX与你输入的字符长度相等!!!!如何能够保证这一点呢?(非常关键!)我们来看:EDX=循环的次数。什么含义?就是00前面的字符长度,因为循环取你所输入的字符时,程序是遇到00才跳转过来的。因此,循环的次数,也就是00前面的字符的个数。那么我们就不难看出,EDX+1 则就是字串00所处的位置。然后呢?程序又让EDX加上了04。什么意思?就是说字符串00后面还有4位字符嘛!!!!!如果不是这样的话,ECX岂不与EDX不等啦?
因此,我们至此可以得出结论:不论前面如何,00后面必须保证有4个字符,方可使得上面的那个跳转指令失效!!!!还等什么,快改过来吧?

好了,我们又过了一关!一鼓作气,接着来!我们上面不跳,则会到达这里了………

****************************关键部分之四*****************************

:00426653 83EA04 sub edx, 00000004=========>EDX=EDX-04
:00426656 85C0 test eax, eax=============>测试EAX。此时,EAX中为前面
我们进行循环并计算的结果。
:00426658 7602 jbe 0042665C==============>不跳
:0042665A D1E8 shr eax, 1================>EAX逻辑右移1,即EAX/2。结果
保存在EAX中。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00426658(C)
|
:0042665C 3B0416 cmp eax, dword ptr [esi+edx]******[esi+edx]与EAX比较
[esi+edx]为你输入的00后的那四位字符!!!
:0042665F 7509 jne 0042666A**********************不等则跳!
后面的就简单了,不再具体陈述。其结果是,如果EAX与你输入的那后半部分字符串不相等,则会跳到出错的地方。所以,我们必须使得EAX与你输入的那后半部分字符串相等。这样,程序会执行下面的那条 JMP 0042667A 的跳转命令,最终跳到成功的地方!!!!!

:00426661 B800000000 mov eax, 00000000
:00426666 8907 mov dword ptr [edi], eax
:00426668 EB10 jmp 0042667A

还等什么?快改吧?(千万记住哟?你在寄存器中看到的EAX的显示数据,可是与实际应该输入的数据是反向的哟?为什么是这样子,就不用过多解释了吧?呵呵。。。。。)

▲破解及算法总结▲
其KeyFiles应该是这样子的:
1、你输入的字符中必须含有00,而且其后面必须保证只有4个字符。
2、这4个字符就是00前面那些字符依次相乘,并与63546D32=cTm2相异或后的结果除以2。
3、将除以2后的结果反转。
结果就是这样子:用户名+00+4位的计算后的结果。那么输入中文也是可以的,只不过计算时多了几步计算罢了。不会有人想偷懒直接在第一个字符的地方就输入00吧??哈哈!那样因为没有前面的循环,也就不会有后面的4位字符存在,自然也就会……………………

收工喽…………………………@!@

--------------------------------------------------------------------------------
  



    
    
     
    
    
     

相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 去除winrar注册框方法

最新文章 比特币病毒怎么破解 比去除winrar注册框方法 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)通过Access破解MSSQL获得数据

人气排行 华为无线路由器HG522-C破解教程(附超级密码JEB格式文件京东电子书下载和阅读限制破解教UltraISO注册码全集(最新)qq相册密码破解方法去除winrar注册框方法(适应任何版本)怎么用手机破解收费游戏华为无线猫HG522破解如何给软件脱壳基础教程