软件破解简单上手 OllyDbg调试器应用

来源:互联网 发布:淘宝清理图片空间 编辑:程序博客网 时间:2024/06/07 02:38
现在破解者们可能都在用OllyDbg调试器对软件进行动态的分析,因为目前多数的软件都工作在WINDOWS XP的平台上,并且OllyDbg调试器结合了动态和静态调试的特性,简单易用。

         针对这次要破解的小程序,熟悉一下OllyDbg调试器的用法。

工作前的准备

         OllyDbg调试器的下载:
        http://www.pediy.com/tools/Debuggers/ollydbg/OllyICE.rar
         本次需要用到的软件:
         http://pickup.mofile.com/2970871204857600

OllyDbg调试器界面

        将下载的压缩包解压,打开目录,执行OllyICE.exe,这个是汉化修改版的,前人栽树后人凉,希望多了解的,可以看帮助文件或是在《看雪论坛》找相关的资料。
       选择“文件”,打开我们这次用到的软件TraceMe.exe。然后先了解一下OllyDbg调试器的界面。

1. 代码窗口
      代码窗口显示的是被调试程序的代码,现在我们看到的有三列,第一列是虚拟地址,第二列是机器码,第三列是汇编代码。
2. 信息窗口
      调试时,会显示相关的信息提示,如寄存器的值,函数调用等。
3. 数据窗口
      以十六进制显示的文件在内存中的数据。
4. 寄存器窗口
      显示各寄存器的值。
5. 堆栈窗口
      堆栈,一般函数或子程序都会用它来传递参数,变量,如果传递的参数是字符串,在这里可以直接显示出来。

操作基本快捷键

F2    设置断点
F9    运行程序
F7    单步跟踪,遇到CALL等跟进
F8    单步跟踪,遇到CALL等跳过,不跟进
CTRL+F9    直到出现RET指定时中断
ALT+F9     若进入系统领空,可回到应用程序领空

破解小程序

       我们先来运行一下TraceMe.exe程序,看看它的注册方式:



        输入用户名和假的序列号,提示“序列号错误,再来一次!”,转到我们刚才执行的OllyICE.exe界面。
       按F9,在OllyDBG调试器的监视下执行程序,不巧的是OllyDbg调试器不支持中文字符串,否则我们可以在代码窗口点右键→查找→所有参考文本字串,查找刚才我们看到错误提示,直接在相应的虚拟地址上下断点(你可以用W32dsm先查找,记下关键的地址,再在OllyDbg调试器用CTRL+G快捷键转到相应地址下断点)。

       这里我们再学习针对API函数下断点的方法:

       GetDlgItemTextA 是一个常用的API函数,它的作用是获得对话框文本,此函数在USER32.DLL用户模块,如果成功返回的是文本长度;失败返回0。      

       为什么这次要用它来下断点?我们执行小程序,在用户名和序列号输入完毕后,点“CHECK”按钮,WINDOWS系统会利用该函数获得我们输入的文本字符串,然后去运算,最后把运算结果送回来,即注册成功或是失败。在这里下断点,就是在注册运算前拦截了程序,用F8一步一步执行程序就可以找到关键点了~

        在OllyDbg调试器中按下快捷键CTRL+N,找到USER32.GetDlgItemTextA,选中后按回车键。


       打开参考对话窗口:


       双击,来到代码窗口的该地址处,按F2下断点(红色背景显示)。断点下好了,也就是说我们找到了很快让我们解决掉该软件的地点喽,剩下的就是在刚才运行的程序里输入用户名和序列号,点“CHECK”按钮,OllyDbg调试器拦截,我们一步步的观察了。


       点“CHECK”按钮后,软件拦截成功,这时我们看到了代码窗口的第四列,那是注释列。我们按F8,让程序一步一步地运行,同时注意观察:

004011D7   . 8D5424 4C     lea     edx, dword ptr [esp+4C]        程序执行到这一步,在信息窗口会出现我们输入的用户名:

堆栈地址=0012F930, (ASCII "76512")
edx=7C92EB94 (ntdll.KiFastSystemCallRet)

004011DC   . 8D8424 A00000>lea     eax, dword ptr [esp+A0]      程序执行到这一步,在信息窗口会出现我们输入的注册码:

堆栈地址=0012F980, (ASCII "987654321")
eax=00000037

       我们还能注意到,在寄存器窗口中,也会适时地显示两组数据放置在了哪个寄存器内。

004011E5   . E8 56010000   call    00401340

       经过这个CALL后,我们会在堆栈窗口看到下面的图:


       程序在用我们输入的序列号与“1088”做了对比,按F9执行完后面的程式,果然提示我们输入错误。这时候我们用户名不要改,可以再用“1088”输入试试?这个小程序用用户名计算出序列号,然后比较,但比较时序列号是明码的。

       我们再从头看一下关键部分:


004011A3   . 8B3D A0404000 mov     edi, dword ptr [<&USER32.GetDlgI>; 调用USER32.GetDlgItemTextA函数
004011A9   . 53            push    ebx
004011AA   . 8D4424 4C     lea     eax, dword ptr [esp+4C]
004011AE   . 6A 51         push    51
004011B0   . 50            push    eax
004011B1   . 6A 6E         push    6E
004011B3   . 56            push    esi
004011B4   . FFD7          call    edi    ; 返回输入的用户名长度
004011B6   . 8D8C24 9C0000>lea     ecx, dword ptr [esp+9C]
004011BD   . 6A 65         push    65
004011BF   . 51            push    ecx
004011C0   . 68 E8030000   push    3E8
004011C5   . 56            push    esi
004011C6   . 8BD8          mov     ebx, eax
004011C8   . FFD7          call    edi     ;返回输入的序列号长度
004011CA   . 8A4424 4C     mov     al, byte ptr [esp+4C] 把输入的用户名头一字节拿出来
004011CE   . 84C0          test    al, al 测试看用户名是不是空的
004011D0   . 74 76         je      short 00401248 空的就转到相应提示上
004011D2   . 83FB 05       cmp     ebx, 5 不是空的,再测试是否小于5位
004011D5   . 7C 71         jl      short 00401248 小于的话就转到相应提示上
004011D7   . 8D5424 4C     lea     edx, dword ptr [esp+4C]   将符合的用户名放入寄存器中
004011DB   . 53            push    ebx
004011DC   . 8D8424 A00000>lea     eax, dword ptr [esp+A0] 将输入的序列号放入寄存器中
004011E3   . 52            push    edx
004011E4   . 50            push    eax
004011E5   . E8 56010000   call    00401340 这里是计算部分,我们略过,喜欢研究算法的可以进入
004011EA   . 8B3D BC404000 mov     edi, dword ptr [<&USER32.GetDlgI> 获得对话框的句柄
004011F0   . 83C4 0C       add     esp, 0C 平衡堆栈(特有的调用约定)
004011F3   . 85C0          test    eax, eax    测试EAX中数值
004011F5   . 74 37         je      short 0040122E 等于0注册失败,跳到相应提示

       我们了解了这段关键的代码,费了半天劲,有嘛用呢?把它改成输入什么都注册成功,然后资源共享……罪过。
      

       我们重点看这一句:

004011F5   . 74 37         je      short 0040122E 等于0注册失败,跳到相应提示

       如果将汇编代码的je改成nop(空指令,也就是程序执行到这一步什么都不做),或是jne(不等于0注册失败,也就是任意序列号都成),这两种方法都可以实现程序的“暴破”。
       OllyDbg调试器很容易修改,在这句代码的汇编语句上双击或是按空格,就打开了汇编窗口。

      

       在文本框中输入nop,点汇编按钮,OllyDbg调试器自动补充指令代码。在代码窗口中点右键,选择复制到可执行文件→所有修改,确定复制。

       关闭弹出的的对话框时,确定保存到磁盘,自己取个新的文件名就好了~再执行TraceMe.exe文件,试试注册?