破解艺术 三

来源:互联网 发布:mac运行windows软件 编辑:程序博客网 时间:2024/04/28 22:12

 破解软件不仅需要扎实得编程功底,更需要灵活善变得思维,要懂得揣摩作者得意图。要引发蝴蝶效应。

在上一篇中我们修改了一个跳转JEXXXX语句。很自然的我们可以这样认为,即是将输入的授权码和正确的授权码做比较。我们看看JE XXXX以上的代码。

Copy OD 部分代码调试时请结合OD 他的强大和反汇编就不用我说了吧!

MOV ESI,DWORD PTR DS:[EDI+64] ;寄存器显示是我们自己输入的授权码

MOV EAX,DWORD PTR SS:[ESP+C] ;寄存器显示一字符串 推测为正确的授权码

MOV DWORD PTR SS:[ESP+1C],0

MOV DL,BYTE PTR DS:[EAX] ;取eax第一个字符

MOV BL,BYTE PTR DS:[ESI]  ;取esi第一个字符

MOV CL,DL                           ;cl     

CMP DL,BL                            ;比较

JNZ SHORT 飞秋FeiQ.004634FC ;不等跳

TEST CL,CL                   ;结束?

JE SHORT 飞秋FeiQ.004634F8   ;结束跳

MOV DL,BYTE PTR DS:[EAX+1] ;取下个字符

MOV BL,BYTE PTR DS:[ESI+1] ;取下个字符

MOV CL,DL                           ; cl

CMP DL,BL                                   ;比较

JNZ SHORT 飞秋FeiQ.004634FC ;不等跳

ADD EAX,2               ;下个字符地址

ADD ESI,2                             ;下个字符地址

TEST CL,CL

JNZ SHORT 飞秋FeiQ.004634D4   ;典型的循环比较 由此证实eax为正确授权码!

XOR EAX,EAX

JMP SHORT 飞秋FeiQ.00463501 

SBB EAX,EAX

SBB EAX,-1                                   //

TEST EAX,EAX                             //

JE SHORT 飞秋FeiQ.0046352A我们修改得跳转指令其上是比较结果

 

终于找到了的授权码,让我们测试一下,拷贝授权码重新注册(在没有修改的目标运行)

果然正确。退出在打开。太阳已然在。哈哈。

》我爽歪歪。

》不过你先等一下,你先试一下。。。(被打断)

》吼,又怎么啦?

》不好意思,你在修改一下级别。

》改什么改,我注册成功了,什么。怎么又不正确?靠

》郁闷 又打我!

哈哈 让大家开心一下而已。

还是拿处OD 断点到MOV EAX,DWORD PTR SS:[ESP+C] 恩?发现一个问题 不同的级别授权码不一样 怪不得呢?怎么办呢?

 

大家想没想这样一个问题,授权码随便输入一个我照样能设置级别,为什么还费这劲找正确的授权码呢?不错这样确实可以设置,但我们要找的是在程序启动的时候比较授权码部分,这个怎么找呢?方式有很多种

1.你可以单步执行  分析逻辑流程,理论上可以找到,但相当困难

2.可以根据程序类型推测位置 MFC程序可以在 APP::InitInstance,CMainFrame::OnCreatezh中。以及其他可能认为初始化地方。

3. 授权码在文件,所以可以对文件API下断。分析相关程序

4. …….

 当然还有有一些其他的,只不过笔者不知道而已,不过就上述几个而言工作量已是相当大了,软件破解就像做题一样,计算出来的结果大家都正确,但是采用的方法不同,那么工作量、复杂度也不同。一个好方法和坏方法所引发的蝴蝶效应可大不同。如灯泡的容量计算,人脸的识别系统,空肥皂盒的检查。。。。

》喂喂,干什么呢?

》啊  不好意思跑题了。

意思是告诉大家,采用正确的方法,可以使问题简单化。

分析一下我们用的方法。一般授权码不可能明文出现在程序中,都是经过某种复杂算法计算出来的,很显然我们可以利用这一点。在注册时候程序要计算出正确授权码,以便和输入的授权码做比较,那么在初始启动时也必然要和配置文件中的授权码做比较。但他要先得到正确的输入吗,一般这两块计算是相同的,我们建立这种假设。

 看看比较输入码之前都做了些什么?

注意这两句代码

MOV ESI,DWORD PTR DS:[EDI+64]//输入的授权码

MOV EAX,DWORD PTR SS:[ESP+C] //正确的授权码

可知在比较之前授权码已存在堆栈中。那就看一下什么时候产生,

我们只要注意赋值给eax之前的代码,F8单步跟踪,注意OD的堆栈窗口,我们发现当执行完CALL 飞秋FeiQ.004938D0 堆栈中出现授权码。由此断定该函数计算授权码。

缩小范围 看看CALL 飞秋FeiQ.004938D0都做了些什么、(代码太多,就不在copy 免的占地方 请在OD中查看)

这么多怎么看呢?其实我们不必仔细分析每个指令用途,(当然你也可以分析,不过增加工作量而已)这里我们用查看堆栈/寄存器方法来缩小范围,而不是分析指令。从上面分析我们得知该函数返回之前堆栈中已存在正确输入吗,所以在跟踪时只要注意堆栈就行,看什么时候其被填值的。以下是跟踪过程

a.      CALL 飞秋FeiQ.00493B60 指令后堆栈中出现授权码.

b.      CALL 飞秋FeiQ.00568C0E 后将授权码全部转换为大写。

c.      继续跟踪a 步骤出来的地址 缩小范围。

d.      00493D87 LEA ECX,DWORD PTR SS:[ESP+30]  ecx 中显示授权码。

 到这里基本上算跟踪完成了,授权码在[ESP+30]中,由此可推测其以上代码为计算授权码代码,粗略看一下,fxxx指令 乘法 除法 循环,关键字有 30 3941 5a 61 7a 也有点像。先不管是不是,试一下便知。

对可疑地址下断。这时你可能会问对谁下断呢?00493B60是计算授权码地方 他的断点肯定的有,有因为他是从004938D0开始调用的,即当我们注册的时候是先调用004938D0,又经过几层调用,最后来到00493B60 处,所以可以认为004938D0做了一些其他的操作,(实时也如此其中将授权码全部转换为大写就是在004938D0中调用另一个函数做的)而00493B60才是真实计算授权码地方。所以也对004938D0也下断。

 

重新启动程序看是否调用,嘿嘿 果然断到了,先走004938D0 后来到00493B60计算授权码码的地方。恩接着我们看看是谁调用。来到调用处。我们推断这是初始化地方 代码很多我们大致看一下。多亏了OD 其已经给我们列出了 前面提到配置文件FeiqCfg.xml中所有节点,当然我们所关心的级别ShowDenji也在之中,(在编程过程中起一个意义名字,对大家都有好处不是吗?)也肯定了程序根据配置文件来初始化的,

找到ShowDenji节点。如下代码

PUSH 飞秋FeiQ.005E7F5C      ; ASCII "ShowDenji" // OD显示

CALL 飞秋FeiQ.00507C90             ;判断操作

CMP DWORD PTR DS:[ESI],EBX  ebx 0

JE 飞秋FeiQ.00408F87                  zf=1 跳。即授权码不正确跳,正确则显示等级。

 

到这里大家应该都知道怎么弄了把。JE修改为JNE 很简单不是吗?

 

最后让我们总结一下:

整个过程只修改了两个命令,第一个是在注册时候,为了显示授权成功并且初始级别,我们修改一跳指令,这时级别可以随意设置,但是下次启动时候,程序通过配置文件会再次比较授权码,这时我们的级别就没了,所以我们就有修改了比较授权码指令!到此为止你可以随意改变级别,且下次启动时级别依然在。

 

我承认我骗了你,本文所述方法并没有什么艺术可言,也没有高深技术。他只演示了爆破软件一些思路、一些小伎俩,讲一些爆破软件的思路,怎么找可疑地址,希望对大家有一些帮助。

  当然在实际破解过程中,不可能如此简单,一切是不会这么容易的,必然回遇到各种各样障碍,加密、加壳、反调试、虚拟机等各种技术,但万变不离其总,只要具备扎实的编程功底,不灭的毅力,良好的思维,平时多动手,多积累经验,相信都不是问题,这篇文章就当给我们新手打打气把。相信我们自己。我们能行。

 

PS我们找到了生成授权码的地方,有兴趣的朋友可以写个注册机,对自己应该是个很大的提高,同时也希望讲自己的心得体会分给大家,谢谢!)

 

 

笔者也是个大大的菜鸟,错误不对之出在所难免,敬请见谅。

                                                                                                                完!

原创粉丝点击