CrackMe_02分析

介绍

该程序是一个面试题,主要目的是分析该软件做算法还原并且实现一个注册机。
注册机
话不多说,开始分析。

找到关键点

找关键点之前先观察软件,发现账号最高为8位,密码最高为24位。输入后点击注册没有提示信息及任何的反应。这时候,首先使用字符串搜索大法。找找是否有关键的字符串
在这里插入图片描述
有一个很明显的注册成功。
在这里插入图片描述
直接回车到该地址,找到函数头然后下断点。
在这里插入图片描述
在这里插入图片描述

关键算法预览

非常明显的三段算法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

详细分析

关键点已经找全,接下来做细致的分析。然后写出对应的代码做出注册机

第一段

在这里插入图片描述
在这里插入图片描述

  • 第一段总结:从0x30、0x42、0x62开始循环,每次按进制+1,循环26次。并且保存数组中(内存部分的值):str0_9[26]、stra_z[26]、strA_Z[26]
  • 记好这三组值数组首地址。分别:ebp-0x864、ebp-0x844、ebp-0x884
  • 后面算法取值的时候需要做一个偏移计算

判断账号和密码长度分析

在这里插入图片描述
在这里插入图片描述

第二段

第二段算法两个地址分别存放了两串奇怪的值,分别取出来做了异或计算的操作。这个地方很容易放过去。:xoruser[8]
在这里插入图片描述
在这里插入图片描述

  • 第二段详细算法
    在这里插入图片描述

第三段

第三段分为两个部分

  • 第一个部分计算出三个下标。:key[3]
  • 第二个部分又细分为3个小部分,从前面循环出的三组数据中取值。:passwd[24]
    三个下标值
  • 3.1部分
    循环次数除以3取余,判断余数是否为2
    在这里插入图片描述
  • 3.2部分
    判断余数是否为1
    在这里插入图片描述
  • 3.3部分
    判断余数是否为0
    在这里插入图片描述

代码实现

定义好数组
在这里插入图片描述

第一部分

按初始值0x30、0x42、0x62开始遍历26次。将结果分别存入数组内
在这里插入图片描述

第二部分

取两组奇怪的值做计算,结果放到xoruser[8]数组中。
在这里插入图片描述

第三部分

  • 利用前面计算出的xoruser数组中的值计算出三个下标存入key[3]中
  • 3.1-3.3根据key[]分别在三个数组中取值。循环8次每次取三个值放入passwd[]中
    在这里插入图片描述
  • 3.1部分
    在这里插入图片描述
  • 3.2部分
    在这里插入图片描述
  • 3.3部分
    在这里插入图片描述

完整代码

#include <iostream>
#include <Windows.h>
char user[9] = {};		//账号

char str1 = 0x30;
char str2 = 0x42;
char str3 = 0x62;

char str0_9[26] = {};		//ebp - 0x864
char strA_Z[26] = {};		//ebp - 0x844
char stra_z[26] = {};		//ebp - 0x884

//奇怪字符
char str_temp[8] = {0x00,0x00,0x88, 0x85, 0xBB, 0xF7, 0xFF, 0xFF };		//00 00 88 85 BB F7 FF FF		第一串奇怪值
char str_temp1[8] = { 0xB8, 0x04, 0xFA, 0x42, 0x00, 0xE8, 0xAD, 0x13 };		//B8 04 FA 42 00 E8 AD 13		第二串奇怪值


//按账号计算出一组值
char xoruser[8] = {};

//根据前面计算结果,算出一个三位的下标
char key[3] = {};

char passwd[24] = {};		//密码存放数组		ebp - 8A0

int main()
{
	printf("请输入一个8位账号:\n");
	scanf_s("%s",&user,9);

	for (int i = 0; i < 26; i++)
	{
		str0_9[i] = str1 + i;
		strA_Z[i] = str2 + i;
		stra_z[i] = str3 + i;
	}

	for (int i = 0; i < 8; i++)
	{
		char temp,temp1;
		temp = user[i] ^ i;
		temp1 = temp ^ str_temp[i];
		xoruser[i] = str_temp1[i] ^ temp1;		//ecx = temp ^ str_temp[i]
	}

	for (int j = 0; j < 8; j++)
	{
		char temp, temp1, temp2;

		temp = xoruser[j] & 0xE0;
		temp1 = (temp) & 0x1F;
		temp2 = temp + temp1;
		key[0] = ((temp2 & 0xff) >> 0x5);	//	key[0] = ((xoruser[i]&0xE0) + ((xoruser[i] & 0xE0)&0x1F)) >> 5

		temp = xoruser[j] & 0x1C;
		temp1 = ((temp) & 0x3);
		key[2] = ((temp + temp1) & 0xFF) >> 2;	//key[2] =  (((xoruser[i] & 0x1C) & 0x3) + (xoruser[i] & 0x1C)) >> 2

		key[1] = xoruser[j] & 0x3;		//key[1] = xoruser[i] & 0x3

		char count_temp1, count_temp2;	//临时变量

		if (j % 3 == 2)
		{
			count_temp1 = str0_9[0] + key[1];
			count_temp2 = (j * 3);
			passwd[count_temp2] = count_temp1;		//passwd[0] + i*3 = str0_9[key[1]]

			count_temp1 = strA_Z[8 + key[0]];
			count_temp2 = (1 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[1]+i*3 = strA_Z[8] + key[0]

			count_temp1 = stra_z[16 + key[2]];
			count_temp2 = (2 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[2] + i *3 =stra_z[16] + key[2]
		}
		else if (j % 3 == 1) {

			count_temp1 = strA_Z[16 + key[0]];
			count_temp2 = j * 3;
			passwd[count_temp2] = count_temp1;		//passwd[i*3]=strA_Z[16 + key[0]]

			count_temp1 = stra_z[8 + key[2]];
			count_temp2 = (1 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[1] + i*3 = stra_z[8] + key[2]

			count_temp1 = str0_9[key[1]];
			count_temp2 = (2 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[2] + i*3 = str0_9[key[1]]
		}
		else if (j % 3 == 0) {

			count_temp1 = strA_Z[16 + key[2]];
			count_temp2 = j * 3;
			passwd[count_temp2] = count_temp1;		//passwd[0] + i *3 = strA_Z[16] + key[2]

			count_temp1 = stra_z[8 + key[1]];
			count_temp2 = (1 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[1] + i *3 =stra_z[8] + key[1]

			count_temp1 = str0_9[key[0]];
			count_temp2 = (2 + (j * 3));
			passwd[count_temp2] = count_temp1;		//passwd[2] + i * 3 = str0_9[0] + key[0]
		}
	}
	printf("密钥为:%s\n",passwd);
	system("pause");
}

验证

在这里插入图片描述
在这里插入图片描述

总结

  • 总的算法:对三个初始值做循环,遍历出三组数据分别存入三个数组内。取两组奇怪的值分别做异或运算将结果保存。利用异或的结果计算出三个下标,拿这三个值又做三次运算。将运算的结果去前面三个数组内取值。最终生成一个24位密钥
  • 在逆向这种环环相扣的算法时,每个关键数据和数组的起始地址位置都该记录下来。逆向的耐心很重要,一些地方该逆还得逆。躲不了…
  • Crack地址:https://pan.baidu.com/s/1MfEAt4ydCXNriBLOL3JL8A
    提取码:6lv6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值