https://www.52pojie.cn/thread-709699-1-1.html
将上面链接中的160个CrackMe的打包文件下载下来之后, 打开该chm, 选择第一个Acid burn, 下载保存到本地, 然后解压, 运行其中的 exe 程序
0x00 查壳
壳是啥? 为啥要查壳脱壳? 不懂, 先跳过!
程序是使用delphi编写的无壳
0x01 分析程序
首先了解下这个软件运行时的情况,记录下有哪几个需要破解的位置。
程序运行时会弹出一个NAG窗口, 标题是hello you have to kill me,这个窗口是要去除的
NAG窗口: 软件未注册或软件的试用版经常会弹出一些提示窗口要求注册,这些窗口被称为nag窗口
然后点击确定后进入程序的主窗口
进去后发现有两个按钮, 根据按钮上的字符串判断应该是需要输入序列号和名称的位置。
首先看下左边那个按钮,点击进去看下情况,发现有两个输入框,分别是输入用户名和序列号,然后点击Check it Baby,程序会进行校验,校验失败会弹出下面窗口,提醒你Try Again!!
可以发现上面这个位置是一个需要破解的点。
然后点击I give up按钮返回到程序的主界面,看下右边那个按钮的情况。
点击进去后发现有一个输入框,提醒你输入序列号,然后点击Check it Baby,程序会进行校验,校验失败会弹出下面窗口,提示你Failed!
记录下这个位置也是一个需要破解的点。
综上所述,我们可以看到这个程序有三个点需要破解:
- 程序主界面之前的一个NAG窗口
- Serial/Name校验页面
- Serial校验页面
0x02 NAG窗口去除
首先我们先要破解第一个NAG窗口, 启动OllyDbg软件, 选择菜单的文件-> 打开-> 选择Acid burn.exe
此时文件会停留在如下位置, 双击注释位置能添加自定义注释
用OD打开后可以按F8单步步过, 调试一遍看下程序的调用情况. 可以发现单步调试到 call Acid_bur.00429F8C 时, 第一个NAG窗口出现了
每按一次
F8, 将执行反汇编窗口中的一条指令, 遇到CALL等子程序不进入其代码
很明显第一个NAG窗口的主函数在这个调用函数里面, 所以在这个点按F2下一个断点, 断点下成功会变红
按
F2之后, 程序运行到此处会暂停, 再按一次F2键会删除断点
然后按Ctrl+F2重新加载程序, 按F9运行到断点call Acid_bur.00429F8C处, 按F7单步步入 进入该函数, 然后再继续按F8单步步过调试,在call dword ptr ds:[esi+0x24] 这个位置NAG窗口又出来了
Ctrl+F2: 重新运行程序.F9: 如果没有设置断点, 被调试的程序会直接开始运行; 如果设置了断点, 程序会停在断点处.F7: 单步步入, 功能和单步步过F8类似, 区别是遇到CALL等子程序时会进入其中
老方法, 按F2下断点、Ctrl+F2重新加载程序,按F9运行到第一个断点call Acid_bur.00429F8C处, F7进入函数, 按F9运行到第二个断点call dword ptr ds:[esi+0x24], 按F7进入该函数, 继续F8单步调试,在call dword ptr ds:[ebx+0x1CC]位置NAG窗口继续弹出
老规矩, F2下断点, Ctrl+F2重新运行, 不断使用F9和F7使得程序运行到call dword ptr ds:[ebx+0x1CC]
然后我们直接按F7单步步入进去, F7进入call Acid_bur.0042A170
此时我们可以看到熟悉的字眼MessageBoxA, 显然这个第四次进入的函数call dword ptr ds:[ebx+0x1CC], 就是调用弹出对话框的函数. 所以, 不应该继续往下分析了, 应该往回看.
按Esc, 回到第四次进入, 调用弹框的地方, 没啥好分析的, 就是一些赋值, 应该是对话框的标题, 内容之类的
再按几次Esc, 回到第三次进入的地方
在这个位置我们需要注意一下, 此处存在比较语句cmp和跳转语句je
cmp: 用第一个操作减去第二个操作数, 若执行指令后,ZF=1, 则说明两个数相等, 因为zero为1说明结果为0.zf代表Zero Flag, 表示零标志位je代表jmp equal, 表示等于就跳转, 是否等于可以看zf的值,zf=1, 则跳转;zf=0则不跳转
我们将代码重新执行一次, F8运行到这个je语句这里, 留意到右边寄存器窗口, 此时的zf=0, 说明不会跳转, 因为不跳转, 所以执行了弹框函数call dword ptr ds:[ebx+0x1CC]
注意左边的线, 白色说明不跳, 红色则会跳
因此这里我们可以使用暴力破解的方式直接jmp过来, 跳过弹窗函数
双击je short Acid_bur.00425643, 将弹框内的je short 00425643改成jmp 00425643, 点击汇编
这样修改是为了程序运行到0042562F处直接跳到00425643处, 越过弹窗函数
修改完毕后我们右键->复制到可执行文件->所有修改->全部复制
然后自动跳到D窗口,右键->保存文件, 将程序重命名为Acid_burn1.exe
然后按F3加载Acid burn1.exe程序,按F9直接运行可以发现没有了NAG窗口, 至此, 第一个NAG窗口去除成功
0x03 分析Serial
随便输入一组错误的序列号, 程序弹出一个失败的提示框
可以从这个字符串入手, 启动OllyDbg软件,选择菜单的文件-> 打开-> 选择Acid burn.exe
此时文件会停留在如下位置, 双击注释位置能添加自定义注释
在反汇编窗口右键鼠标,选择查找->所有参考文本字串
弹出如下图所示的对话框
右键选择查找文本-> 输入Try定位Try Again!!位置
接着右键鼠标,点击反汇编窗口中跟随
接着定位到如下图所示位置
可以看到, 除了Try Agained!!, Failed之外, 上面还有Congratz!和God Job dude!!
我们先看看Try Again!!在哪先, 选中该语句右键查找参考->选定地址(快捷键Ctrl+R)
弹出如下图所示的参考页面
双击上面的地址(0042F4F8), 去到对应的位置
然后我们按Esc返回, 再查看其他的位置, 在反汇编窗口加上注释如下:
注意查看此时的反汇编窗口的汇编代码
JNZ=jump if not zero运算结果不为零则跳转, 即ZF不为1时跳转
简单讲一下这里的逻辑: 先调用一个函数call Acid_bur.004039FC, 如果返回结果不为0, 则jnz short Acid_bur.0042F4F1, 即跳转到下面的失败弹框; 如果返回结果为0, 则不跳转, 执行成功的弹框.
成功弹框执行完成之后, 会有一个jmp short Acid_bur.0042F509, 跳过失败弹框的逻辑, 因为前面已经执行完成功弹框的逻辑了, 当然要跳过失败弹框的逻辑啦!
走到这一步就很好解决了, 得出方法一: 修改上面的JNZ改为NOP, 让他直接往下执行就行了呗
NOP是英语No Operation的缩写。
NOP无操作数,所以称为空操作。
方法一
双击jnz short Acid_bur.0042F4F1, 改成nop
修改完毕后我们右键->复制到可执行文件->所有修改->全部复制
然后自动跳到D窗口,右键->保存文件, 将程序重命名为Acid_burn2.exe
然后按F3加载Acid burn2.exe程序, 按F9直接运行, 此时随便输入一个序列号, 如下图:
方法二
方法一的思路是, 不管前面的函数返回啥, 我将jnz short Acid_bur.0042F4F1, 改成nop, 直接不跳转, 让程序继续往下执行.
这里我们不妨在这个jnz前面的函数call Acid_bur.004039FC上按F2插入一个断点, 看看发生了这个函数发生了啥
插入断点后, Ctrl+F2重新运行, F9运行, 然后打开Serial窗口, 随便输入一个序列号, 比如我输入了sdfsdf, 然后点击Check it Baby!
切换OD, 程序自动停到当前断点处, 此时注意右边寄存器窗口中出现了两个值, EAX的值是我们输入的sdfsdf, 而EDX的值是Hello Dude!, 很可能这个值就是真正的序列号
验证的方法很简单, Ctrl+F2重新运行 ->F9运行, 输入该字符串Hello Dude!->F9继续运行, 弹框如下:
发现Hello Dude!就是正确的序列号
秉着严谨的态度, 我们按F7进去该函数看一下, 看到了熟悉的cmp, 以及下面的je
这里的je跳转没有实现, 所以, 我们可以参考上面的NAG窗口去除, 直接修改成jmp, 直接跳到00403A9A, 以达到随便输入都弹出正确的框框, 具体操作此处不再重复.
0x04 分析Serial/Name
F3 加载解决Serial之后保存的的Acid burn2.exe, F9直接运行, 然后随便输入, 点击Check it Baby!, 此时的错误弹框先不要关
回到OD, 按F12暂停, 点击堆栈K小图标(Ctrl+K), 如下图:
这里有两个MessageBox的地址,第一个地址为77D5082F这个地址明显太大, 不在模块的领空, 不是的。第二个地址为0042A1AE, 和00400100地址非常接近,十有八九就是它了。
关于
程序领空和系统领空, 具体请查看 https://www.52pojie.cn/thread-75582-1-1.html , 我们只需要明白00400000这个基址开始的地址,一直到00488000结束的基址都是程序领空
右键-> 显示调用
注意观察弹框开始的 push ebp左边, 那里有一根线, 可以帮助我们定界
在头部push ebp下按F2下断点, Ctrl+F2重新运行, F9运行, 重新随便输入序列号和名字, 点击Check it baby!! 按钮, 程序停在断电处, 此时在右下角堆栈处找到最近一条Return语句
0012F974 0042FB37 返回到 Acid_bur.0042FB37 来自 Acid_bur.0042A170
右键->反汇编窗口中跟随
0042FAD5 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; UNICODE "-"
0042FADA |. FF75 F8 push [local.2] ; Acid_bur.0042FBB8
0042FADD |. 8D45 F4 lea eax,[local.3]
0042FAE0 |. BA 05000000 mov edx,0x5
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC
0042FAEA |. 8D55 F0 lea edx,[local.4]
0042FAED |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3 |. E8 60AFFEFF call Acid_bur.0041AA58
0042FAF8 |. 8B55 F0 mov edx,[local.4]
0042FAFB |. 8B45 F4 mov eax,[local.3]
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC
0042FB03 |. 75 1A jnz short Acid_bur.0042FB1F ; 这是个关键的判断
0042FB05 |. 6A 00 push 0x0
0042FB07 |. B9 CCFB4200 mov ecx,Acid_bur.0042FBCC
0042FB0C |. BA D8FB4200 mov edx,Acid_bur.0042FBD8
0042FB11 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB16 |. 8B00 mov eax,dword ptr ds:[eax] ; Acid_bur.00424090
0042FB18 |. E8 53A6FFFF call Acid_bur.0042A170
0042FB1D |. EB 18 jmp short Acid_bur.0042FB37 ; 这个跳转跳过了错误弹框
0042FB1F |> 6A 00 push 0x0
0042FB21 |. B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; ASCII 54,"ry Again!"
0042FB26 |. BA 80FB4200 mov edx,Acid_bur.0042FB80 ; ASCII 53,"orry , The serial is incorect !"
0042FB2B |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB30 |. 8B00 mov eax,dword ptr ds:[eax] ; Acid_bur.00424090
0042FB32 |. E8 39A6FFFF call Acid_bur.0042A170 ; 错误弹框
0042FB37 |> 33C0 xor eax,eax ; 返回到了这里
简单分析一下上面的代码: jnz short Acid_bur.0042FB1F会通过它上面的call Acid_bur.004039FC 判断我们的输入是否正确,判断的结果存在EAX中,如果EAX不等于就跳转到错误提示信息框那里
我们的目的是无论输入是否正确都通过验证, 所以最简单的办法就是将jnz short Acid_bur.0042FB1F这句使用NOP填充
我们尝试一下:选择JNZ这句,右键->二进制->用NOP填充. 按F9继续运行程序
回到原始程序,再次点击Check it baby!, 发现它卡住了, 莫慌, 是因为我们之前在push ebp下了一个断点, 切换回OD, 再按F9运行, 如下图:
此时我们重新打开未修改过的Acid burn2.exe, 再让它弹出错误窗口, 切换OD, 再按F12暂停一下, 按堆栈k小图标(Ctrl+K)窗口, 看一下最后一个调用, 是不是发现什么特殊的地方?
对啦!那个CALL就是调用MessageBox的地方,所以,下次我们就不用在MessageBox处下断跟踪了,直接最后一个地址->右键->显示调用
得知这个小技巧之后, 我们还需要处理最后一个小问题, 如果输入的Serial的长度小于4, 就会弹出错误的窗口.
我们保持当前错误窗口别关掉, 回到OD, 按F12暂停->点堆栈k小图标->最后一个地址->显示调用
显然, 我们的目的就是让它无论如何都要跳, 所以直接将jge short Acid_bur.0042FA79改成jmp 0042FA79即可
F9运行->切换程序->再点一下Check it Baby!, 如下:
最后, 按照上面讲过的流程, 保存下来即可
0x05 总结
至此, 这个程序的破解工作已经全部完成!
我们大概学了如下内容:
- OD的一些快捷键, 如F7, F8, F9, F12等等
- 字符串搜索定位
- F12暂停法分析程序
- 修改完后怎么保存
- 取消类似
jnz的跳转, 即改成NOP; 强制跳转, 即改成jmp - 还有复习了一些汇编语法
欢迎大家访问我的博客: https://fengwenhua.top , 虽然博客上面没啥东西!
来源:CSDN
作者:江南小虫虫
链接:https://blog.csdn.net/A807296772/article/details/104302577