selph
selph
Published on 2022-07-10 / 253 Visits
1
0

新160个CrackMe练习:003-CrueheadCM3

爆破难度:⭐⭐

算法难度:⭐⭐

信息收集

运行情况:是一个空白界面,可能要经过某些操作才能让内容显示出来

image.png

查壳:无壳

image.png

查字符串:看到了一些提示语

image.png

查导入表:除去窗口绘制,消息循环用到的函数,这里还出现了文件操作相关函数,可能跟文件有关,结合上面的字符串搜索信息,应该需要一个CRACKME3.KEY的文件

image.png

逆向分析

根据之前对文件进行静态的信息收集之后,这个文件操作很可疑,就从文件操作函数CreateFileA去搜索交叉引用看看这里在干嘛

首先打开名为CRACKME3.KEY的文件,然后读取其中的内容保存到缓冲区

image.png

然后判断读取的字节数如果是0x12就往下走,对读取到的内容进行一顿操作,然后通过某种计算方法进行校验,然后把校验结果保存在al里入栈了

image.png

然后经过一段窗口创建的操作之后,在进入消息循环之前,做了这样一个校验,校验文件内容是否正确,正确就弹框提示,正是通过刚刚push的al进行校验的

image.png

暴力破解

整个校验流程最后还是通过判断+跳转进行执行的,暴力破解老样子,直接修改跳转条件即可:

image.png

前面还有个判断读取到的内容是否为0x12字节,把那个跳转也nop改掉即可,这里就不演示了

算法分析

这里的校验算法主要是这几行:

image.png

这里调用了两个自写的函数,首先是sub_401311:这里计算一个前14字节的校验和,然后对前14字节依次与ABCD…进行异或操作,将异或的结果保存起来,校验和也保存起来

image.png

然后是下一个函数sub_40133C:就是取后4字节出来

image.png

现在这个校验算法已经清晰了起来:

  • 计算一个校验和,校验和与0x12345678进行异或,得到的结果与输入里的最后4字节进行比较
  • 对输入的前14字节进行异或操作,异或后的结果作为参数去调用显示验证成功提示框

那么序列号的生成就是:

  1. 随便输入一个14字节的字符串作为用户名
  2. 对这14字节依次异或ABCD…,保存起来
  3. 对校验和异或0x12345678,然后拼接到异或结果后面,即可完成生成

注册码生成算法:

#include <iostream>
#include <windows.h>

void generateSeriesFile(const char* in_pwd) {
    char pwd[0x13] = { 0 };
    int i;
    char var_bl = 'A';
    unsigned int sum = 0;

    memcpy(pwd, in_pwd, 0x13);

    i = 0;
    do {
        sum += pwd[i];
        pwd[i] ^= var_bl;
        i++;
        var_bl++;
        if (!pwd[i])break;
    } while (var_bl != 'O');

    sum ^= 0x12345678;
    *(unsigned int *)&pwd[0xE] = sum;

    for (int k = 0; k < 18; k++)
    {
        unsigned char* tmp = (unsigned char*) & pwd;
        printf("%02x ",tmp[k]);
    }

    HANDLE hFile = CreateFileA("CRACKME3.KEY", GENERIC_ALL, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD retNum = 0;
    WriteFile(hFile, pwd, sizeof(pwd), &retNum, NULL);
    CloseHandle(hFile);
}

int main()
{
    const char *pwd= "helloworld@qqq.com";
    generateSeriesFile(pwd);
    system("pause");
    return 0;
}

效果:

image.png

总结

序列号算法和校验依然很简单,这里有意思的是:这个程序的校验逻辑位于窗口进入消息循环之前,校验行为发生在了软件正常运行之前,根据校验结果再选择是否正常运行程序

参考资料


Comment