本文作者:gncao
楼主目前是做渗透测试的,在看一些大神的文章时,有时会看到一些关于逆向方面的知识,无奈楼主不懂逆向。但是身为搞技术的嘛,不懂就学,学不懂就再学,所以就在前些日子看了一些基础的汇编视频入了个门,然后在看汇编的时候又对逆向破解比较感兴趣(有成就感),所以又看了破解相关的视频。
题外话(废话):但是楼主归根结底还是要做web安全的,还是要回到自己的路子上的,但是又怕时间长了,汇编的知识忘记了,所以在网上看到有一套CrackMe系列破解软件,故打算用这个来辅助记忆自己的汇编知识。楼主打算一周一破解,希望自己能够坚持下去。
废话不多说,下面就开始介绍并破解第一个小软件Acid_burn。
一、源程序介绍
首先了解下这个软件运行时的情况,记录下有哪几个需要破解的位置。
程序运行时会弹出一个NAG窗口,标题是"hello you have to kill me",这个窗口是要去除的。
然后点击确定后进入程序的主窗口
进去后发现有两个按钮,根据按钮上的字符串判断应该是需要输入序列号和名称的位置。
首先看下左边那个按钮,点击进去看下情况,发现有两个输入框,分别是输入用户名和序列号,然后点击Check it Baby,程序会进行校验,校验失败会弹出下面窗口,提醒你try again!
可以发现上面这个位置是一个需要破解的点。
然后点击I give up按钮返回到程序的主界面,看下右边那个按钮的情况。
点击进去后发现有一个输入框,提醒你输入序列号,然后点击Check it Baby,程序会进行校验,校验失败会弹出下面窗口,提醒你Failed!
记录下这个位置也是一个需要破解的点。
综上所述,我们可以看到这个程序有三个点需要破解:
1,程序主界面之前的一个NAG窗口
2,Serial/Name校验页面
3,Serial校验页面
二、NAG窗口去除
好,首先我们先要破解第一个NAG窗口,这个程序很小,用OD打开后可以F8单步调试一遍看下程序的调用情况。可以发现单步调试到 call Acid_bur.00429F8C时,第一个NAG窗口出现了,
很明显第一个NAG窗口的主函数在这个调用函数里面,所以在这个点F2下一个断点,然后ctrl+f2重新加载程序,F9运行到该位置时,F7进入该函数,然后再继续F8单步调试,在call dword ptr ds:[esi+0x24]这个位置NAG窗口又出来了
老方法,下断点、重新加载程序,F9运行到该位置,F7进入该函数继续F8单步调试,在call dword ptr ds:[ebx+0x1CC] 位置NAG窗口继续弹出
在这个位置我们需要注意一下,此处存在条件判断语句
0042562F /74 12 je XAcid_bur.00425643 00425631 . |8B5D FC mov ebx,dword ptr ss:[ebp-0x4] 00425634 . |8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00425637 . |8B83 D0010000 mov eax,dword ptr ds:[ebx+0x1D0] 0042563D . |FF93 CC010000 call dword ptr ds:[ebx+0x1CC] ; 第三次进入,弹窗函数 00425643 &;gt; \33C0 xor eax,eax
从这里我们可以看到,在执行到弹窗函数之前会做一个je判断,如果zf=1,则跳转;zf=0则不跳转,这里我们使用暴力破解的方式直接jmp过来,跳过弹窗函数,改完后的代码如下
0042562F /74 12 jmp 00425643 00425631 . |8B5D FC mov ebx,dword ptr ss:[ebp-0x4] 00425634 . |8B55 FC mov edx,dword ptr ss:[ebp-0x4] 00425637 . |8B83 D0010000 mov eax,dword ptr ds:[ebx+0x1D0] 0042563D . |FF93 CC010000 call dword ptr ds:[ebx+0x1CC] ; 第三次进入,弹窗函数 00425643 > \33C0 xor eax,eax
程序运行到0042562F处直接跳到00425643处,越过弹窗函数。修改完毕后我们右键-复制到可执行文件-所有修改,选择全部复制,然后跳到D窗口,右键-保存文件,将程序重命名为Acid_burn1.exe。
然后F3加载Acid_burn1.exe程序,F9直接运行可以发现没有了NAG窗口,第一个NAG窗口去除成功。
三、Serial/Name窗口破解
OD加载Acid_burn1.exe程序,我们在name和serial输入框随意输入一个字符串和序列号时,此时点击Check it Baby,会弹出try again窗口,内容是sorry,the serial is incorect。
记录下窗口的字符串内容,然后在OD的C窗口右键-查找-所有参考文本字串,在新窗口位置右键-查找文本,输入窗口内容字符串"the serial is incorect",然后找到对应的记录
在这里你可能会发现两个记录,没有关系,这个是两个函数窗口返回的一样的字符串内容(后面会分析到),双击第一条记录会自动切换到C窗口相应的汇编代码位置
然后向上面看代码会发现有个jge跳转指令,这个是大于等于指令,再往上看一点是一个cmp指令,联合这几条语句来看这个函数是将上一个call函数的结果eax跟数字4进行比对,如果小于4则不跳转,执行弹窗函数;如果大于等于4则跳转向下执行。这个函数是一个判断NAME字段长度是否小于4的函数,跟破解无关,有兴趣的可以在这个位置下断点,然后在name字段输入长度小于4的字符来看下,是否会发生跳转即可明白。
那这条记录不是我们想要的,我们就看下第二条记录
在这里我们可以看到有两块区域,下面这个是我们手动查找到的字符串,上面好像是一个成功的字符串。再往上看能看到有一个jnz条件跳转指令。
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC ; 关键函数;ZF=1则成功 0042FB03 75 1A jnz XAcid_bur.0042FB1F 0042FB05 6A 00 push 0x0 0042FB07 B9 CCFB4200 mov ecx,Acid_bur.0042FBCC ; ASCII "Congratz !!" 0042FB0C BA D8FB4200 mov edx,Acid_bur.0042FBD8 ; ASCII "Good job dude =)" 0042FB11 A1 480A4300 mov eax,dword ptr ds:[0x430A48] 0042FB16 8B00 mov eax,dword ptr ds:[eax] 0042FB18 E8 53A6FFFF call Acid_bur.0042A170 0042FB1D EB 18 jmp XAcid_bur.0042FB37 0042FB1F 6A 00 push 0x0 0042FB21 B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; ASCII "Try Again!" 0042FB26 BA 80FB4200 mov edx,Acid_bur.0042FB80 ; ASCII "Sorry , The serial is incorect !"
这个指令的意思是如果上一个call函数的返回结果ZF=1的话,则不跳转;ZF=0的话,则跳转。而跳转的位置恰好是在两块字符串中间,所以可以看出这个上面那个call函数是判断name和serial是否是正确的关键函数。
这里呢,我们仍然采用暴力破解的方式,这里呢不能让指令跳转,所以我们修改jnz指令,用nop指令覆盖,修改后的代码如下:
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC ; 关键函数;ZF=1则成功 0042FB03 90 nop 0042FB04 90 nop 0042FB05 6A 00 push 0x0 0042FB07 B9 CCFB4200 mov ecx,Acid_bur.0042FBCC ; ASCII "Congratz !!" 0042FB0C BA D8FB4200 mov edx,Acid_bur.0042FBD8 ; ASCII "Good job dude =)" 0042FB11 A1 480A4300 mov eax,dword ptr ds:[0x430A48] 0042FB16 8B00 mov eax,dword ptr ds:[eax] 0042FB18 E8 53A6FFFF call Acid_bur.0042A170 0042FB1D EB 18 jmp XAcid_bur.0042FB37 0042FB1F 6A 00 push 0x0 0042FB21 B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; ASCII "Try Again!" 0042FB26 BA 80FB4200 mov edx,Acid_bur.0042FB80 ; ASCII "Sorry , The serial is incorect !" 0042FB2B A1 480A4300 mov eax,dword ptr ds:[0x430A48]
修改完毕后,同样的右键-复制到可执行文件-全部赋值,保存该文件,重新命名为Acid burn2.exe。
程序保存完毕我们可以在OD内F3加载Acid burn2.exe程序F9运行改程序也可以直接运行Acid burn2.exe程序,在serial和name输入框内随意输入函数,点击check,都会弹出成功的信息。
四、serial窗口破解
最后一处破解就是serial输入框位置,这个位置破解同serial/name这个破解很类似,也是在C窗口右键-查找-所有参考文本字串,在新窗口位置右键-查找文本,输入窗口内容字符串"Failed",然后找到对应的记录。OD可能会给出多个记录,这时我们要根据记录的情况来判断下是否是我们窗口的记录,是我们想要的记录。(快捷键ctrl+n是找下一个记录)
找到记录后双击该记录,跳转到汇编代码处,同样的我们也看到了条件跳转指令,分析一下跟上一个窗口差不多一样的逻辑
0042F4D0 |. E8 2745FDFF call Acid_bur.004039FC ; 成功函数点;ZF=1成功0042F4D5 75 1A jnz XAcid_bur.0042F4F1 0042F4D7 |. 6A 00 push 0x0 0042F4D9 |. B9 64F54200 mov ecx,Acid_bur.0042F564 ; ASCII "Congratz!" 0042F4DE |. BA 70F54200 mov edx,Acid_bur.0042F570 ; ASCII "God Job dude !! =)" 0042F4E3 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48] 0042F4E8 |. 8B00 mov eax,dword ptr ds:[eax] 0042F4EA |. E8 81ACFFFF call Acid_bur.0042A170 0042F4EF |. EB 18 jmp XAcid_bur.0042F509 0042F4F1 |&;gt; 6A 00 push 0x0 0042F4F3 |. B9 84F54200 mov ecx,Acid_bur.0042F584 ; ASCII "Failed!" 0042F4F8 |. BA 8CF54200 mov edx,Acid_bur.0042F58C ; ASCII "Try Again!!" 0042F4FD |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
这里我们能够看到关键的函数就是call Acid_bur.004039FC,该函数执行后返回的结果ZF=1则不跳转,弹出成功的窗口;ZF=0则跳转弹出失败的窗口。
我们仍然选择暴力破解方式将jnz指令nop掉,不进行跳转,修改后的代码如下:
0042F4D0 |. E8 2745FDFF call Acid_bur.004039FC ; 成功函数点;ZF=1成功0042F4D5 90 nop 0042F4D6 90 nop 0042F4D7 |. 6A 00 push 0x0 0042F4D9 |. B9 64F54200 mov ecx,Acid_bur.0042F564 ; ASCII "Congratz!" 0042F4DE |. BA 70F54200 mov edx,Acid_bur.0042F570 ; ASCII "God Job dude !! =)" 0042F4E3 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48] 0042F4E8 |. 8B00 mov eax,dword ptr ds:[eax] 0042F4EA |. E8 81ACFFFF call Acid_bur.0042A170 0042F4EF |. EB 18 jmp XAcid_bur.0042F509 0042F4F1 |&;gt; 6A 00 push 0x0 0042F4F3 |. B9 84F54200 mov ecx,Acid_bur.0042F584 ; ASCII "Failed!" 0042F4F8 |. BA 8CF54200 mov edx,Acid_bur.0042F58C ; ASCII "Try Again!!" 0042F4FD |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
修改完毕后,同样的右键-复制到可执行文件-全部赋值,保存该文件,重新命名为Acid burn3.exe。
运行Acid burn3.exe程序,我们可以看到在serial窗口随便输入字符串都可以弹出成功的窗口。
至此,程序破解结束。
五、总结
1,程序破解的关键在于找到正确的条件跳转语句处,找到关键点则破解工作就完成了一大半;
2,限于楼主水平有限,在破解的过程中可能使用的方法不是最简单、最方便的,也希望有大佬指出更好的姿势;
3,Acid burn2.exe程序好像没有对name字段的长度小于4进行破解,当长度小于4仍然会弹出失败窗口。这里就不做笔记了,比较简单,有兴趣的可以试试;
4,程序破解除了使用暴力破解的方式也可以找到程序的关键函数写出算法出来进行破解,这里限于文章篇幅就不做分析了,后面有机会再分享。
最后,谢谢大家能够坚持看完这篇文章,同时呢也希望各位大佬指出文章的不足之处,后面文章会做出相应调整。再说一句谢谢。