• 用OllyDbg做破解


    朋友所托,要帮忙破解一个MFC的小程序,他急等着用 (背景:几个人合伙创业,其中一个负责写这个有点小核心的项目,为了巩固自己的”地位“搞的小把戏,给加了密,要用必须通过他 - 我艹~~~)。

    虽说自己搞C++比较多,相对来讲native一点,但是对于汇编与破解,了解相当有限,去年这朋友也找过我,因为当时刚换公司比较忙,是求助另外一好友才搞定的。这次还是自己花点时间研究研究吧。工具吗,用windbg貌似只能看,softice与ollydbg之间,选择了ollydbg。

    一、基础知识

    ollydbg是一个动态反汇编分析调试工具,其功能强大的令人发指,而且居然还是免费的,其官方地址为:http://www.ollydbg.de/,下载与介绍都在上面。

    要用ollydbg做破解,最好先过一遍下面的知识点:

    1. 了解汇编语言的基本结构,特别是函数的调用与返回,参数传递等,可以参考这篇文章:反汇编深入分析函数调用, 简短却又清晰,切中要点,我配合visualstudio的反汇编窗口执行了几遍,基本掌握了其结构。(我自己也维护了一个分析:https://gist.github.com/2904354)
      另外,Intel这三大卷:Intel® 64 and IA-32 Architectures Software Developer Manuals也是非常经典的参考资料,没必要读,但不理解时可以查查,尤其是第一卷中的基本结构介绍和第二卷的指令集介绍。
    2. OllyDbg入门完全教程(完美排版), 非常详尽的介绍了ollydbg的各个组成部分及功能,40来页的内容,花一个小时过一遍就可以了。
    3. OD入门系列图文详细教程-破解做辅助起步,通过一个例子详细解释了破解的全过程,非常有用。其中文中用到的看雪《加密与解密》书中的程序crackme可以在这里下载到:http://download.csdn.net/detail/tokey003/3672236

    二、实例操作

    先是一个非常简单的helloworld程序,源码如下:

     1 #include <cstdio>
     2 #include <windows.h>
     3 
     4 #pragma comment(lib, "user32.lib")
     5 
     6 void printHelloWorld(int a)
     7 {
     8         MessageBox(NULL, "Hello, World", "Greetings", MB_ICONWARNING);
     9 }
    10 
    11 int main()
    12 {
    13         bool bMsgBox = false;
    14         if(bMsgBox)
    15         {
    16             printHelloWorld(10);
    17         }
    18         else
    19         {
    20             printf("Hello, World");
    21         }
    22 }

    该程序总是在console输出"Hello, World",现在要修改其binary,使其总是弹出一个MessageBox。

    编译并使用ollydbg打开,因为我知道要传一个参数10到printHelloWorld函数中去,可以肯定会有一个指令:PUSH 0A,关键代码在其附近,在反汇编窗口搜索定位:

    可以看到,在PUSH 0A前面是一个条件判断,对应源代码中的那个判断,于是不难推出,Mov BYTE PTR SS:[LOCAL.1+3],0就是给bool型变量bMsgBox赋值的指令,0就是false。

    于是,在这里双击该指令,把0改成1,运行便看到程序弹出了messagebox。

    注意,为了保存修改过的可执行文件,你需要:

    • 右键-Edit-Copy to executable, 弹出该二进制文件的内容窗口
    • 右键 - Save file

    三、破解

    需要破解的程序,其行为是:在任何一台机器上使用该程序,你需要输入一个授权码,该授权码由特定程序通过系统信息产生,其工作流程为:

    1. 在客户电脑上运行该程序,获取系统信息(一个字符串)
    2. 将该字符串发给授权人,他有一个工具会产生授权码,并发给使用者
    3. 使用者输入该授权码,程序验证,如通过则可使用。

    单从行为上分析,突破口在于授权验证这一步,该程序要验证输入的授权码是否正确,也就是说它肯定知道正确的验证码,也就是说由系统信息产生授权码的算法也是内置在客户程序这边的,我们只不过需要一个办法把它读出来。

    该验证步骤是:获取系统信息,并个根据该信息产生正确的授权码,然后从某文本文件读入用户输入的验证码,对两者进行对比,如果成功,则弹出一个messagebox:output(true), 否则就是output(false)。根据以上信息,设置以下断点:

    • 菜单View-executable modules - show names,找到ReadFile和MessageBoxA,打上断点
    • 在反汇编窗口右键,Search for - all referenced strings, 找到output字符串,并设断点

    有了这几个断点,你就可以在运行中观察寄存器/栈/内存等内容,以及汇编指令来了解整个程序的运作机理。多走几遍,多观察思考,适当添加断点与注释。特别注意哪些条件测试指令与call指令,确定其行为后继续跟进去。

    这样,就找到了其内部获取系统信息的函数调用,与根据系统信息算出授权码的函数调用,从而得到了正确的授权码,结束。

    当然,要做的好一点的话,还可以:

    • 分析其授权码产生函数的算法,自己写一个产生器
    • 或者,动态修改其可执行文件,将其产生的授权码用一个MessageBox输出。

    但对于第一项,这需要阅读很多汇编代码,我没时间;对于第二项,需要插入对windows API函数的调用,这比简单的修改一个指令要复杂,暂时还不会,也不打算仔细研究。毕竟,是朋友所托,完成任务即可,不打算仔细研究 - 我还有很多其他重要的事情要做。

    四、技巧总结

    • 你可以通过猜测可能调到的Windows API函数,设置断点作为突破口
    • 你也可以通过可能reference到的字符串设置断点
    • 查到指令也是一个方法,但估计不是很有用 - 在没有源代码的情况下你很难预测一个特殊的指令被调用到了
    • 选中指令后,你可以右键-help on command来查到汇编指令帮助
    • 你可以双击汇编指令进行修改
    • 你可以添加注释 - 在一个漫长的破解过程中,记下你发现的是蛮重要的
    • 选中指令后,你可以看到其跳转关系
    • 我还很初级,这个强大的工具有更多技巧去发现。
  • 相关阅读:
    软件项目开发典型风险一览
    删除数据库所有表数据
    今天愚人节,教大家一个真正的最强整人方法
    潘正磊谈微软研发团队管理之道(下)
    追MM与23种设计模式
    22个所见即所得在线 Web 编辑器
    神奇的js代码,图片全都飞起来了
    字体 小 中 大
    使用ODP.NET连接Oracle数据库一个OracleCommand运行多条SQL语句的方法
    删除SQL数据库中所有的表
  • 原文地址:https://www.cnblogs.com/baiyanhuang/p/2543997.html
Copyright © 2020-2023  润新知