010破解(四)之注册机

010破解(四)之注册机

010破解(二)之算法分析一
010破解(三)之算法分析二

概述

算法总算分析完成了,接下来准备就编写注册机了,根据我们输入的用户名,计算出序列号

思路分析

方法一:暴力枚举,这种方式太费时间,能用技术解决的事不可能用这种方法的
方法二:

  • 根据输入用户名计算加密值
  • 加密值与密码对应关系可以得到 k4 k5 k6 k7,假设Ret是函数返回的加密值
    K[4]=Ret&0xFF
    k[5]=(Ret>>8)&0xFF
    k[6]=(Ret>>0x10)%0xFF
    k[7]=(Ret>>0x18)&0xFF
  • 根据分析得到的序列号相关计算函数,结合已知条件,枚举剩余的值

注册机

关键代码,两种算法计算方式,有几个关键的序列号计算CALL是直接从IDA拷贝出来的


VOID CalPassword::CrackKey1(CHAR* pUserName,CString& Password,DWORD arg)
{
	srand(time(NULL));
	BYTE Key[10] = { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA };
	BYTE k0 = 0;
	BYTE k1 = 0;
	BYTE k2 = 0;
	BYTE k3 = 0;
	BYTE k4 = 0;
	BYTE k5 = 0;
	BYTE k6 = 0;
	BYTE k7 = 0;
	BYTE k8 = 0;
	BYTE k9 = 0;

	//Key[3] = 0x9C 0xAC 0xFC
	//0x9C是8位序列号
	Key[3] = 0x9C;

	//计算用户名加密值与k4 k5 k6 k7有对应关系
	//k4 k5 k6 k7 逆用户名加密值
	//说明K[4]=Ret&0xFF
	//说明k[5]=(Ret>>8)&0xFF
	//说明k[6]=(Ret>>0x10)%0xFF
	//说明k[7]=(Ret>>0x18)&0xFF
	DWORD dwRetValue = rand() % 0x3e8 + 1;		//指定商的范围 0-0x3e8
	DWORD dwValue = sub_EncodeName(pUserName, 1, 0, dwRetValue);
	Key[4] = dwValue & 0xFF;
	Key[5] = (dwValue >> 8) & 0xFF;
	Key[6] = (dwValue >> 16) & 0xFF;
	Key[7] = (dwValue >> 24) & 0xFF;

	//计算k0和k6
	while (TRUE)
	{
		k0 = rand() % 0xFF;
		BYTE AL = ((k0 ^ Key[6] ^ 0x18) + 0x3D) ^ 0xA7;
		if (AL >= arg)
		{
			Key[0] = k0;
			//Key[6] = k6;
			break;
		}
	}
	while (TRUE)
	{
		k1 = rand() % 0xFF;
		k2 = rand() % 0xFF;
		//esi=((K[2]^k[5]&0xFF)+(K[1]^k[7]&0xFF)*0x100)&0xFFFF
		//EAX=((esi^0x7892+0x4D30)^0x3421&0xFFFF)/0xB
		//判断余数是否为0,为0返回商,不为0返回0
		//商<=0x3e8
		DWORD dwTemp1 = (k2 ^ Key[5]) & 0xFF;
		DWORD dwTemp2 = ((k1 ^ Key[7]) & 0xFF) * 0x100;
		DWORD dwESI = (dwTemp1 + dwTemp2) & 0xFFFF;
		DWORD dwEAX = ((((dwESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF);
		if (dwEAX % 0xB == 0 && dwEAX/0xB == dwRetValue)
		{
			Key[1] = k1;
			Key[2] = k2;
			break;
		}
	}
	Password.Format(L"%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", Key[0], Key[1],
		Key[2], Key[3], Key[4], Key[5], Key[6], Key[7], Key[8], Key[9]);
}

VOID CalPassword::CrackKey2(CHAR* pUserName, CString& Password, DWORD arg)
{
	srand(time(NULL));
	BYTE Key[10] = { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA };
	BYTE k0 = 0;
	BYTE k1 = 0;
	BYTE k2 = 0;
	BYTE k3 = 0;
	BYTE k4 = 0;
	BYTE k5 = 0;
	BYTE k6 = 0;
	BYTE k7 = 0;
	BYTE k8 = 0;
	BYTE k9 = 0;

	//Key[3] = 0x9C 0xAC 0xFC
	//0xAC是10位序列号   
	Key[3] = 0xAC;

	//计算用户名加密值与k4 k5 k6 k7有对应关系
	//k4 k5 k6 k7 逆用户名加密值
	//说明K[4]=Ret&0xFF
	//说明k[5]=(Ret>>8)&0xFF
	//说明k[6]=(Ret>>0x10)%0xFF
	//说明k[7]=(Ret>>0x18)&0xFF
	DWORD dwRetValue = rand() % 0x3e8 + 1;		//指定商的范围 0-0x3e8
	DWORD dwValue = sub_EncodeName(pUserName, 0xFF, 0, 1);
	Key[4] = dwValue & 0xFF;
	Key[5] = (dwValue >> 8) & 0xFF;
	Key[6] = (dwValue >> 16) & 0xFF;
	Key[7] = (dwValue >> 24) & 0xFF;

	while (TRUE)
	{
		k1 = rand() % 0xFF;
		k2 = rand() % 0xFF;
		//esi=((K[2]^k[5]&0xFF)+(K[1]^k[7]&0xFF)*0x100)&0xFFFF
		//EAX=((esi^0x7892+0x4D30)^0x3421&0xFFFF)/0xB
		//判断余数是否为0,为0返回商,不为0返回0
		//商<=0x3e8
		DWORD dwTemp1 = (k2 ^ Key[5]) & 0xFF;
		DWORD dwTemp2 = ((k1 ^ Key[7]) & 0xFF) * 0x100;
		DWORD dwESI = (dwTemp1 + dwTemp2) & 0xFFFF;

		DWORD dwEAX = ((((dwESI ^ 0x7892) + 0x4D30) ^ 0x3421) & 0xFFFF);
		if (dwEAX % 0xB == 0 && dwEAX / 0xB == dwRetValue)
		{
			Key[1] = k1;
			Key[2] = k2;
			break;
		}
	}
	while (TRUE)
	{
		k9 = rand() % 0xFF;
		k0 = rand() % 0xFF;
		DWORD dwTemp1 = k9 ^ Key[5];
		DWORD dwTemp2 = Key[4] ^ Key[5];
		DWORD dwTemp3 = k0 ^ Key[6];
		DWORD dwarg1 = (((dwTemp1 << 8 )+ dwTemp2) << 8) + dwTemp3;
		DWORD dwRet = Algorithm2(dwarg1, 0x005B8C27);
		if (dwRet != 0 && dwRet <= arg)
		{
			Key[9] = k9;
			Key[0] = k0;
			break;
		}
	}	
	Password.Format(L"%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", Key[0], Key[1],
		Key[2], Key[3], Key[4], Key[5], Key[6], Key[7], Key[8], Key[9]);
}

成品演示

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值