selph
selph
Published on 2022-07-19 / 246 Visits
0
0

新160个CrackMe练习:016-fly_crkme3

算法难度:⭐⭐⭐

爆破难度:⭐

信息收集

运行情况:

image

查壳与脱壳:

UPX壳,直接ESP定律脱壳即可

image

调试分析

Delphi程序,截图不方便注释,之后用IDR直接复制代码到everEdit里写注释了:

找到校验按钮,分析校验函数sub_00444B30

首先是判断用户是否有输入,无输入则弹窗,有输入则跳转到00444B78:

image

接下来校验输入的数据,输入的内容必须是0x30~0x39之间,也就是纯数字:

image

接下来校验字符串长度:这个cm允许的输入是9,10,11字符,对于每种输入都有单独的计算,这里以输入长度为9位为例:输入格式是xx-xxx-xx

image

接下来进行了一个取数字的操作:进行了7段,总之就是把字符串中间的-去掉,把数字拼接在一起

image

取完数字之后,转换成Int类型保存起来:

image

接下来又进行了7段运算,运算出结果累加起来:

image

这里调用了一个00444B20的函数,功能类似C的pow函数,对一个数(eax)求n(edx)次方,这里Delphi函数调用约定是fastcall:

image

累加完成之后会进行对比:累加的值和输入的数字是否一样

image

相同则跳转到成功提示上:

image

然后再往下就是10字节长度和11字节长度的运算对比了,方法类似,都是分别计算一个次方,然后和原数比较,相同则成

算法分析

注册码生成算法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <Windows.h>

int main()
{
	for (int i = 1000000; i < 9999999; i++)
	{
		int sum = 0;
		char tmp[8] = { 0 };
		_itoa(i, tmp, 10);

		for (int j = 0; j < 7; j++) sum += pow(tmp[j]-'0',7);
		if (i == sum)std::cout << i << std::endl;
	}
}

总结

难得一次性分析了这么长的反汇编,很多可以写成函数来方便调用的地方都直接内联了,可能是为了提高效率,这样一来就出现了大量重复代码段,分析花了挺多时间


Comment