Crackme--Acid burn

这题共分为两个部分,一个是需要输入用户名和序列号才能过关的,另一个是只需要序列号就能过关的
image
只需要序列号就能过关的部分比较简单,下面的是分析过程
首先随便输入一个序列号,可以看到弹出了一个框,有错误提示信息
image
根据错误提示信息,使用字符串搜索的方法在当前用户模块中搜索,找到了三个地址,不确定哪个是我们需要的,先都打上断点
image
重新输入一个错误序列号后定位到地址
image
根据push 0的地址找到了跳转过来的地址0x0042F4D5,这条语句跳转条件是ZF=0,也就是不相等时跳转,上面三行分别是给eax,edx赋值,其中一个是我们输入的错误序列号,另一个是一个固定字符串,可以猜测出call调用的函数是比较两个字符串的函数。
image
测试一下输入序列号Hello Dude!发现成功了,看来这部分就是一和一个提前生成好的明文比较。

然后看下输入序列号和用户名的部分,首先还是老套路下断点在错误提示信息处,从错误提示信息处向上翻代码,可以看到和第一部分一样的比较字符串的函数,其中比较的是我们输入的序列号和程序生成的序列号
image
保持用户名不变,输入此序列号可以看到能够通关
image
image
换了一个用户名,再使用这个序列号的时候可以看到失败了,猜测有可能序列号是根据用户名生成的,那就得找一下生成算法
image
当我们用户名长度输入小于4的时候,会在另一个错误提示处触发断点,从代码中可以看到,我们的用户名输入后,经过计算出字符串的长度赋值给了eax,然后和4进行比较,如果小于4就会提示错误信息
image
根据之前得到的序列号格式可以看到,CW CRACKED这两部分都是固定的,只有中间四位是变化的。
通过在两个错误信息代码之间观察,定位到了序列算法(因为我们之前用hello得到的序列号是8528),调试这部分代码的时候,观察寄存器中寄存器eax的值发现了8528这个值,所以猜测此处为序列生成算法
image
这段代码的意思是,取用户名的第一个字节,然后和0x43175的值相乘,这个值是固定的0x29,相乘后的值再加上自身得到最终值,用c语言实现一个生成序列号的代码如下:

#include <stdio.h>
int main()
{
    char szBuffer[30] = {0};
    printf("请输入用户名:");
    scanf("%s", szBuffer);
    int result = szBuffer[0] * 0x29 *2;
    printf("序列号CW-%d-CRACKED", result);
    return 0;
}
posted @ 2023-07-28 14:48  墨宸  阅读(51)  评论(0)    收藏  举报