首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

破解是击败、绕过或清除各种拷贝保护机制的“暗黑艺术(dark art)”。最初,破解主要是针对注册序列号、硬件密钥(dongles,加密狗)等的软件保护方案。近来,破解也被应用于数字版权管理技术——数字版权管理技术致力于保护电影、音乐唱片和书籍等受版权保护的资料。毋庸置疑,破解与逆向工程有着密切的联系,因为想要攻击任何一种基于软件的保护机制,破解者首先必须要准确地了解这种保护机制是如何工作的。

本章提供了一些生动的破解范例。我将分析一些程序,并试着去破解它们。我还将讲述各种各样有趣的破解技术,随着我们学习的不断深入,我讲的破解技术的难度也会循序渐进地增加。

为什么要学习并理解破解技术呢?当然,我们不是为了盗用软件!我认为关于拷贝保护和破解的整个思想都很有趣,我个人就非常喜欢在其中斗智斗勇。而且,如果想要保护自己的程序免遭破解,你自己就必须掌握破解技术。这是很重要的一点:没有尝试过破解别人程序的人是不可能开发出有效的拷贝保护技术的。

真的去破解拷贝保护技术在大多数国家都被认为是非法的。是的,这一章确实要讲解如何进行破解,但并不会去破解真正的拷贝保护技术,因为这不仅是非法的,而且也是不

道德的。相反,我会以一些特殊的程序为例讲解破解技术,这些程序我们称其为crackme。Crackme程序专门用来向破解者提出智力挑战,并向新手教授破解的基础知识。在数个不同的逆向工程网站上你可以下载到成千上百个crachme程序。

11.1  修补程序(Patching)

让我们迈出练习破解的第一步。我将从一个非常简单crackme程序开始——由Bengaly开发的KeygenMe-3程序。当你第一次运行KeygenMe-3时,你会看到一个好看(尽管在某种程度上有点儿吓人)的界面,要求你输入两个值,当然,没有任何关于这两个值是什么的提示信息。图11.1是KeygenMe-3程序的对话框。

在这个界面上的两个文本框中随意输入两个值,然后点击“OK”按钮会弹出如图11.2所示的消息框。要经过一定的专业训练才能注意到这个消息框可能是一个“备用的(stock)”Windows消息框,很可能是调用某个标准的Windows消息框API函数生成的。这一点很重要,因为如果这真的是一个常规的Windows消息框,你就可以用调试器为消息框API函数设置一个断点。从这个断点出发,你可以试着找到程序中提示你输入的序列号不正确的代码。这是一种基本的破解技术——找出程序中提示你未被授权运行该程序的代码部分。你一旦找到了这部分代码,接着找程序中确定你是否被授权所使用的逻辑就变得容易多了。

图11.1  KeygenMe-3的主界面

图11.2  KeygenMe-3 的无效序列号的消息框。

不幸的是,对破解者来说,完善的保护机制通常不会使用这种容易找到的消息框。例如,开发人员可以使用其他方式创建从视觉上看上去一模一样的消息框,而不使用内建的Windows消息框工具(译注:如API等),这样一来要找到判定逻辑的代码就困难多了。这种情况下,你可以让程序运行至显示消息框的地方,然后用调试器跟踪此进程,并检查调用堆栈,以找到有关程序在什么地方决定要显示这个特别的消息框的线索。

我们现在来弄清楚KeygenMe-3是如何显示它的消息框的。通常,可以试着把OllyDbg用作逆向工具。考虑到这里要破解的是一个相对简单的程序,Olly就足够了。

在OllyDbg中打开程序后,直接进入“Executable Modules”窗口,看有哪些模块(DLLs)静态链接到了这个程序。图11.3显示了KeygenMe-3的“Executable Modules”视图。

图11.3  OllyDbg的“Executable Modules”窗口,显示了Key4.exe 程序中所加载的模块

这一视图直接告诉我们Key4.exe是一个“孤独的枪手——显然,除系统DLLs外再也没有别的DLLs链接到其上了。因为除了Key4.exe模块外,其余的模块全都是操作系统组件。这一点很清楚,因为它们全都位于C:\WINDOWS\SYSTEM32目录下,而且有时候你还可以根据常用的操作系统组件的名字来辨认它们。当然,如果不能确定的话,你还可以在Windows系统中查看二进制可执行文件的属性来获得一些细节信息,比如说是谁创建这个程序等诸如此类的信息。例如,你不能确定lpk.dll,就可去C:\WINDOWS\SYSTEM32目录下(鼠标右键)查看它的属性。在“Version(版本)”标签中你可以看到它的版本信息,这就告诉了我们一些关于可执行文件的基本情况(假定这些信息已被此模块的创建者放在应有的位置上了)。图11.4显示Windows XP Service Pack 2操作系统下“lpk.”的“Version(版本)”标签,你可以清楚地看到它是一个操作系统组件。

你在“Executable Modules”窗口中可以直接在Key4.exe上点击“View Names”,就可以查看Key4.exe直接调用的APIs函数了。这个操作完成后你看到的是从Key4.exe中导入和导出的函数列表。这一界面见图11.5。

图11.4  lpk.dll的版本信息

图11.5  从Key4导入和导出的函数(由OllyDbg给出)

这时,你可能会对名为USER32.MessageBoxA的导入项感兴趣,因为很可能就是这个调用生成了图11.2中所示的消息框。OllyDbg允许你对这样的导入项进行多种操作,但是我最喜欢的OllyDbg特性(特别是对付像crackme这样的小程序时)是它可以显示调用导入函数的所有代码。这是帮助我们找到显示注册失败消息框(即图11.2)的代码的一种最佳的方法,同样也很有可能帮我们找到显示注册成功消息框的代码。你可以选取MessageBoxA项,点击鼠标右键,然后选择“Find References”,就会进入显示所有对MessageBoxA函数的调用的对话框,这个对话框如图11.6所示。

在这里你可以看到Key4.exe中所有调用MessageBoxA API函数的代码。注意最后一项使用的是JMP而不是CALL指令。这正是这个API函数的导入项,实质上所有其他调用都要通过JMP来实现。不过这与我们目前的讨论无关,我们只讨论前四个使用CALL指令的调用。选择任一项,按回车,就会显示出调用这个API函数的反汇编代码。在这里你还可以看到有哪些参数传给了这个API函数,凭着这些参数,你就可以很快判断出这里是不是你要找的正确位置(即显示消息框的代码所在的位置)。

图11.6  调用MessageBoxA函数的代码

第一项将你带到了“About”消息框(从OllyDbg中的消息文本可以看出)的代码。第二项对应的是参数合法性校验的消息框,显示“Please Fill In 1 Char to Continue!!”(请键入一个字符再继续!!)。第三项看上去好像就是我们要找的东西。这里是OllyDbg显示的第三个调用MessageBoxA的代码:

好了,看上去好像你已经找到正确的地方了!这是一个典型的if-else代码序列,用来显示两个消息框中的一个。如果“EAX == EST”,程序将显示“Great, You are ranked as Level-3 at Keygening now”消息(太棒了,你现在已经达到Keygening三级水平了),否则,将显示“You Have Entered A Wrong Serial,Please Try Again”消息(你输入了一个错误的序列号,请重试)。我们要做的第一件事就是试着修补一下这个程序,使得它总是执行“EAX==ESI”成立时才会执行的代码,然后再来看我们是否能得到那条成功的消息。

我们可以这样做:双击JNZ指令,你将进入OllyDbg的“Assemble(汇编)”对话框,如图11.7所示。

Assemble对话框允许你修改程序中的代码,在这里只需要键入你所想要的汇编语言指令就可以了。如果新的指令比原来的指令短,只要你勾选了对话框上的“Fill with NOPs”选项,OllyDbg就会用NOP指令(no operation,空操作指令)来补充。这一点很重要,修改机器码可不同于处理word文档,可以插入、删除文字,只需要随之移动其后面的所有材料就可以了。如果要移动机器码,哪怕只是移动1个字节,都是一件非常复杂的任务,因为在汇编语言代码中许多引用(references)都是相对的,移动代码会使导致这些相对引用失效。Olly决不会试着这样去做。如果你的指令比原来的指令短,Olly会用添加NOP指令的办法来补齐。而如果你输入的指令比原来的指令长的话,在原指令后面的指令就会被覆

盖掉。这种情况下,你肯定不想在Key4.00401358处出现错误消息,所以你还是干脆彻底地从程序中清除掉这个跳转吧。你可以在Assemble对话框中键入NOP,并勾选上“Fill with NOPs”选项。这样就可以保证Olly会用NOP指令完全覆盖掉这个JNZ指令了。

修补完程序后,你就可以运行程序并看看会发生什么了。你要记住,修补只应用到了调试程序上,还没有写回到原来的可执行文件中去,这一点很重要。这也就是说,此刻唯一可以运行修补程序的办法就是在调试器内运行它。在调试器内运行你只需要按F9就可以了。和开始的时候一样,你看到的是正常的KeygenMe-3对话框(就是图11.1所示的对话框),在两个文本框内任意输入两个值,并点击“OK”。好,成功了!程序此时显示的是成功对话框,如图11.8所示。

到这里我们就结束了修补的第一课。,用一个if语句来控制程序功能可用性的简单程序事实上很普遍,我们这里讲的这一方法可以适用于大多数这样的程序。这一方法唯一有点复杂的地方是查找这些if语句的过程。KeygenMe-3是一个很小的程序,在一些较大的程序中可能不会使用备用(stock)MessageBox API函数,或者会有数百条这样的API调用,这就会使得修补变得复杂多了。

你要牢记的是,到目前为止,你只是在调试器内对程序进行了修补。也就是说,要享受你的破解成果,你必须在OllyDbg中运行这个程序。为此,你必须永久地修补程序的二进制可执行文件,使程序得以永久破解。要实现这一点,你需要在CPU窗口中的代码区域单击右键,并选择“Copy to Executable(复制到可执行文件)”菜单,然后在子菜单中选择“All Modifications(所有修改)”。这个操作将会创建一个新的窗口,里面是做过修补的新的可执行文件。现在你要做只是右键单击这个窗口,选择“Save File(保存文件)”,并在OllyDbg中为这个做过修补的可执行文件命个名。就是这样!对于简单的破解和修补任务,OllyDbg确实是一款非常好的工具。程序通常为了确保自己未被修改过而进行校验和校验(checksum verification),如果你遇到这样的破解情景的话,修补会在某种程度上变得复杂一点。在这种情况下,要正确地修补程序你需要做更多的工作,不过别担心:总是能做到的。

图11.7  OllyDbg中的Assemble对话框

图11.8  KeygenMe-3的成功消息框

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论