aaa教育 这是一篇适合初学者并且非常简单的软件破解过程。如果读者希望从中学习到高深的破解技术,那估计要另你失望了,本文主要采用暴破伎俩来破解一些常规的软件,即没有使用反调试、加密、加壳 、虚拟机等相关技术。其目的主要叙述一下软件的采用爆破的简单过程。

  作者假设读者熟悉一下相关知识

  1. 了解汇编,能看懂简单汇编代码.

  2.熟悉最少一门调试工具 这里我们采用Ollydbg。

  4.知道一些常用用语,比如 什么时爆破、对API下断等。

  3.对破解有浓厚的兴趣。认识到破解时一门艺术,而非商业利益(....)

 

声明:对本文使用的软件,我们只是拿来练习,只是为了更好的学习破解这门艺术,并未侵犯原作者的版权及其他事宜。再次声明。

 

下面让我们来一步步走完我们这次的爆破之旅吧!

实验对象: 飞秋(FeiQ) 一款局域网既是通讯工具。这里我们的版本是ver2.4

 

首先让我们先感谢老卢为我们提供这款功能强大的软件。怎么也得先感谢一下,因为我们将要对他的作品开刀做手术啊。飞秋有着和QQ非常炫的功能,至于其他的就不说了,用了就知道. 郑州软件测试培训班

 begin:

这里我们提的是飞秋的等级设置功能。将自己的头像设置为一个太阳是否很帅啊。是很帅,但不能想设就设。因为老卢。。。。。!需要授权码,随便输入一个 肯定不对 “授权码不正确”

蹬蹬。。 该我们出场了吧。

拿出OD 因为弹出对话框所以我们先对MessageBoxA下断。

 (下断会吧。插件下 输入bp MessageBoxA)

在输入,断点后到 user32模块中 , F8 步步执行 到弹出注册失败对话框后 回到程序领空发现了什么?

 就是先分析一下目标是用什么语言编写,程序有没有加壳等。在这里我们分析一下,我们工具是PEiD.exe。

分析一下飞秋。效果如图。

PEID 查看飞秋结果

可知飞秋用VC6++编写,没有加壳,这当然是最方便的。

在对飞秋depends一下。看看飞秋都导入了什么DLL。请自己查看。

上一篇 我们说到当我们断点到MessageBoxA 回到应用程序领空后看到效果图 如下:

注册失败 返回飞秋领空代码

上面弹出授权码错误对话框后,接着就JMP走,当然就注册失败了,但我们发现飞秋下面就是正确的授权码。于是我们想如果改一下流程会怎么样。改是肯定改因为要爆破吗!不过不要急先看一下代码。分析一下流程。

以下是OD copy的部分代码。 结合上图

TEST EAX,EAX                         ;测试eax

JE SHORT 飞秋FeiQ.0046352A  ;ZF =1跳转

请留意跳转语句 00463503处代码 每次输入授权码 他都不跳,接着执行下面代码,结果弹出错误对话框,为了让其跳转我们将je改为jne 接着看效果。哈哈 授权码正确。接着看头像,哇有星星了。恩 在改一个太阳。感觉是否很爽?

 

》不过你先等一下,你先试一下将飞秋退出在打开!

》干什么呢?我正爽呢?

》你先退出在打开 试.. 一 ..下. 嘛 我实在不忍看你这样。

》吼。什么,我的太阳没了?

》这个。。。 别打我啊。不是我啊。

哈哈 给大家开个玩笑。软件注册和未注册版本都有标示,一般通过注册表、配置文件等手段。这个相必大家都知道。飞秋则通过配置文件来保存注册信息,在目录下打开FeiqCfg.xml文件 找到SerialNo节点 其是保存授权码。(同时请留意一下其下的另外两个节点UserDenji和ShowDenji 后面用到 标示用户等级和显示等级)当飞秋在启动时会用他。这个是错误的,所以我们的太阳没了,怎么办呢?聪明的你肯定立刻想到,只要我们找到和授权吗比较代码并将其修改,那不就。。。。 嘿嘿。不错,寻找比较代码就是我们所要做的工作。去那找呢?这可难不到聪明的你吧!

》找什么找,我每次设置一下不行吗?

》啊。。。。你太。。聪明啦,这也行。 不过不专业。

》我喜欢。我就每次改。

》汗。只要你愿意。

对。我们当然要专业。岂能每次手工修改,这可不是我们作风。

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

在上一篇中我们修改了一个跳转JE XXXX语句。很自然的我们可以这样认为,即是将输入的授权码和正确的授权码做比较。我们看看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 39 41 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 很简单不是吗?

 

最后让我们总结一下:

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

 

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

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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐