当前位置:   article > 正文

crackme用来测试程序设计人员的逆向工程技能的小程序。

crackme

Crackme

crackme(通常简称CM)是用来测试程序设计人员的逆向工程技能的小程序。 
KeygenMe、ReverseMe、UnpackMe,KeygenMe是要求别人做出程序对应的 keygen (序号产生器)。 
ReverseMe 要求别人把它的算法做出逆向分析。 
UnpackMe 是则是要求别人把它成功脱壳 。

分析这些程序都能提高个人的程序分析能力,这些程序都有各自侧重的知识点。 
下面就以一个验证序列号的crackme小程序作为例子进行破解,得到正确的序列号。 
直接运行程序是这样的 
这里写图片描述

开始破解程序,首先用IDA打开文件 
这里写图片描述

在函数(Function name)窗口中看见CWinApp,CCmdTarget更类,熟悉的同学已经知道该程序使用MFC编写,结合自己的开发经验,就能猜到获取编辑框中的内容用的函数是GetDlgItemText(),定位到调用该函数的位置0×00401557。在之前有三个指令, 
这里写图片描述

在调用GetDlgItemText()之前有三个push指令,

.text:00401549 push 0Ah ; int //字符串最大长度 
.text:0040154B lea edx, [ebp+String] 
.text:0040154E push edx ; char * //字符串缓存区 
.text:0040154F push 3E8h ; int //指向输入框控件 
.text:00401554 mov ecx, [ebp+var_20] ;

注意到刚才弹框的提示内容“Incorrect try again!!”,可以在IDA字符串窗口中找到,定位到使用该字符串的位置 
这里写图片描述

细心的同学已经发现了,在上面loc_401585代码段处有字符串比较(lstrcmpA),比较完成后有两个分支,一个提示输入正确“Correct way to go!!”,另一个提示输入错误 “Incorrect try again!!”,结合上面获取文本输入框内容的代码段信息可以判断,lpString2和lpString1中有一个存储正确的验证码,另一个存储输入的内容,接下来我们用两种方法让我们的验证码通过验证。

获取正确的验证码

在0040158D call ds:lstrcmpA处设置断点,点击Debugger->Start Process或按F9开始动态调试,在程序输入框中随便输入一串字符,实验中输入的是‘1qaz2wsx’,然后点击“Check”控件,程序停在我们设置的断点处,然后查看寄存器ecx和edx中的值,所示如下: 
这里写图片描述

这里写图片描述

如图所示,ecx寄存器存放的是lpString2:‘’,edx寄存器存放的是lpString1:‘1qaz2wsx’,获得正确验证码”’”’,接下来在程序中试验一下: 
这里写图片描述

结果正确!

修改二进制代码

修改PE文件,使输入的内容显示正确。在上一小节,程序比较完lpString1和lpString2有两个分支,一个是正确输入的提示框,另一个是错误输入提示框。修改代码跳转,只要跳转到弹出“Correct way to go!!”代码段就可以了,结合代码,当两个字符串不同时会执行jnz short loc_4015AD指令,跳转到loc_4015AD代码段,将jnz指令改为jz,可在两个字符串不同时跳转到“Correct way to go!!”代码段。jnz的十六进制码为75,jz的十六进制码为74,只需将可执行程序中的75改为74就可以。

通过IDA Pro查看十六进制文件窗口找到该跳转指令 
这里写图片描述

用Hedit打开程序,找到该跳转指令

这里写图片描述

在二进制的文件中该跳转指令在0×00001595处,而不是IDA显示的0×00401595,发生了什么?这涉及到PE文件内存映射方面的基础知识,童鞋们可查阅相关资料。

将跳转指令75修改为74,保存修改后运行,随意输入一段字符串看运行结果: 
这里写图片描述 
结果正确!那么,如果输入原来程序的验证码‘’,结果会是什么?为什么会是这样?

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/907471
推荐阅读
相关标签
  

闽ICP备14008679号