前言
这是160个CreakMe系列的第004个CM,难度:☆;
这个程序是Delphi编写的,要完成这次的逆向分析需要了解Delphi程序的运行过程。
本次分析使用到的环境和工具如下:
- 操作系统:Windows 10 2004(物理机)
- 工具:x32dbg,DelphiDecompiler
- IDE:Visual Studio 2019
软件分析
依旧是用户名+序列号的验证,那么这次的分析目标也依旧是:实现验证的破解,以及分析出来序列号的算法
这是没有确认按钮,应该是用户名和注册码验证成功后会自动显示图片,第一次见这种情况
分析目标1:暴力破解
拖入x32dbg,依然是先查字符串,这个软件是中文的,猜测这个软件的提示也是中文的,搜索成功两个字:
直接定位到显示注册成功的地方:
这里有个可疑的跳转,会跳过这个注册成功,那就让这个跳转失效试试:
验证成功:
到这里暴力破解就完成了
分析目标2:注册机
用户名abcd,注册码1234,用这个去进行测试:
上面这段do-while循环算了半天,算出来34abcd18,但丝毫没有影响到最终做判断的esi+30c也就是0x022b1c00这个地址的值,所以目前还不知道这算的是啥玩意,也不是注册码。
这是一个Delphi程序,反汇编分析的手感怪怪的,应该是有什么姿势不太对,我去查了关于Delphi反汇编相关的资料,参考某大佬的基础讲解(参考资料链接在下方),仿佛有所顿悟
参考资料:用实例讲解如何读懂DELPHI程序的反编译
大概浏览之后,这里印象比较深刻的有如下三点:
-
我们了解到Delphi程序是基于事件的,可通过专门的工具(dede、IDR)来辅助分析和定位,我们对这些控件的操作都是一个事件
-
Delphi反汇编里,函数调用参数大多都放在eax里,返回值放在edx里
-
通过观察call所在地址,可以判断是否是用户函数,如果是用户函数需要进去看看
到这里我们分析这个CM所需要的前置知识应该是够了,可以继续分析了:
工具可以从52破解上下载,这里我用的是DelphiDecompiler
拖入exe一键分析:
我们发现这个exe有个可疑事件叫做chkcode,双击点进去:
大概看了一下,静态分析也看不出个啥玩意,记下地址到x32dbg里下断点动态分析去:
随便下了个断点,当我输入注册码的时候,断点中断了,说明这里跟我们输入的注册码有关
这里自动注释冒出来了个“黑头Sun Bird”和“desloffc-012-OK”
这里很可能是用来拼接正确注册码的
再次进入断点,这里似乎显示出来了正确的注册码:
拿去试一试:
果然正确了,来观察一下这个注册码的结构:
"黑头Sun Bird" + 一个数字 +“desloffc-012-OK”+ 用户名
问题在于中间的这个数字要怎么计算
再次中断一步一步走看一看:
可以轻易发现,这里的esi里装的是用户名长度,将这个长度+5,然后转换成字符串,然后进行拼接
关于转换int到str这个call是怎么发现是转换的呢,就按照这个地址去DelphiDecompiler里查看:
这里提示说是IntToStr
那么到此,这个注册码的生成规则就很明确了
编写注册机
源代码:
据说C++可以用中文变量名,赶紧尝试一下
----啊这真的敲得好累啊,真就一个变量敲大半天,还是老老实实敲英文变量名吧
#include<stdio.h>
#include<string.h>
int main() {
char 用户名[12] = { 0 };
char 序列号[100] = { 0 };
char 中间数字[10] = { 0 };
printf("请输入用户名:");scanf_s("%s",用户名,12);
sprintf_s(中间数字, "%d", strlen(用户名)+5);
strcpy_s(序列号, "黑头Sun Bird");
strcat_s(序列号, 中间数字);
strcat_s(序列号, "dseloffc-012-OK");
strcat_s(序列号, 用户名);
printf("序列号是:%s\r\n", 序列号);
return 0;
}
效果演示
总结
刚开始做这个的时候,我看反汇编看的有点懵,经过搜索发现,Delphi程序是基于事件来运行的,需要借助相关辅助工具去进行事件的定位,了解了这个之后,一切都变得如此的简单。
这次的教训是,要分析一个程序,需要先了解这个编程语言编写的程序有什么特点,是否需要什么辅助工具来协助。