selph
selph
发布于 2022-08-11 / 147 阅读
0
0

新160个CrackMe练习:039-eKH1

算法难度:⭐⭐⭐⭐

爆破难度:⭐

信息收集

运行情况:

image

查壳与脱壳:

无壳:

image

调试分析

首先看按钮的逻辑:

首先获取UserName,进行长度验证,然后获取Serial

接下来将获取的UserName和Serial作为参数,调用校验函数00427A20

如果得到的返回值是0x0BC614E则表示验证成功

image

接下来看这个校验函数:

首先是一些初始化操作,保存了参数到局部变量里

image

接下来对UserName进行处理:计算一个累加值

计算方法看注释,这里简述一下:

  • 取一个字符到ebx
  • ebx左移8位
  • ebx进行或操作,或一个数组中的字符
  • 如果ebx小于0了,则乘以-1
  • 循环

image

最终将刚刚计算的值转换成字符串,计算字符串长度

这里的字符串长度就是接下来循环的次数,也就是这个累加值的位数

接下来的校验流程大概是:

  1. 取ebx的最后一位作为索引,从新的数组中获取一个字符
  2. 将新得到的字符拼接到正确序列号的字符串里
  3. 然后删去最后一位,回到步骤1

image

注册机

注册码生成算法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

const char* arr = "LANNYDIBANDINGINANAKEKHYANGNGENTOT";
const char* arr2 = "LANNY5646521";
int main()
{
	//char name[100] = { 0 };
	char name[] = "selph";
	char serial[100] = { 0 };
	int len = 0;
	int ebx = 0;

	for (int i = 0;name[i]; i++)
	{
		ebx += name[i];
		ebx <<= 8;

		ebx |= arr[i];
		if (ebx < 0) {
			ebx *= -1;
		}
	}
	ebx ^= 0x12345678;

	for (int i = 0; ebx; i++)
	{
		serial[i] = arr2[ebx % 10];
		ebx /= 10;
	}

	std::cout << serial << std::endl;
}

效果:

image

总结

比上一节看VB舒服多了,感觉这一节的难点在于分析理解这些反汇编是在干嘛的


评论