selph
selph
Published on 2022-07-30 / 224 Visits
0
0

新160个CrackMe练习:031-Cruehead.1

算法难度:⭐⭐⭐

爆破难度:⭐

信息收集

运行情况:

image

查壳与脱壳:

无壳:

image

调试分析

字符串提示信息:

image

直接从字符串提示信息找到验证点

这是一个自写的弹窗函数还…,继续向上交叉引用

image

到了上一层:看到的是个窗口过程函数,这里在比对消息码,这里弹窗往上有个DialogBoxParamA的调用,应该就是创建Register对话框的函数,所以跟进这里的窗口过程

image

跟进之后,可以看到这有两个明显的函数调用获取用户输入,分别保存在了两个全局变量里,然后就关闭窗口了,接下来还得从刚刚创建窗口的地方往下看

image

往下看就是使用获取的Name和Serial进行一个函数调用,然后用调用结果比对,选择是否弹窗成功

image

接下来看Name的校验计算:

首先是判断字符的合法性,必须是字母,如果是小写字母则转变成大写字母

然后累加每个字母的值,和5678h进行异或,得到用户名的校验值

image

接下来是序列号的校验:

循环遍历每一个字符,序列号如果说是纯数字,那么减去0x30就相当于是把字符数字变成整数类型的数字,然后每次操作一个数字累加到edi之前就先乘以一次10,那么这个逻辑就相当于是字符串转整型的操作

然后进行一个异或1234h,返回校验值

image

最后比较这两个校验值,相同则弹窗成功:

image

注册机

注册码生成算法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

int main()
{
    char name[100] = { 0 };
    char serial[100] = { 0 };
	int name_check = 0;

	std::cin >> name;

	for (int i = 0; name[i]; i++) {
		if (name[i] > 'Z')name[i] -= 0x20;
		name_check += name[i];
	}
	name_check ^= 0x5678;
	name_check ^= 0x1234;

	sprintf(serial, "%d", name_check);
	std::cout << serial << std::endl;
}

结果:

image


Comment