首页
社区
课程
招聘
[原创]看雪CTF.TSRC 2018 团队赛 第八题 二向箔分析
发表于: 2018-12-17 12:33 2769

[原创]看雪CTF.TSRC 2018 团队赛 第八题 二向箔分析

2018-12-17 12:33
2769

         卡在最后一步,时间来不及了。。。。

         整个程序要求输入72个字符分成: 32 +  32 + 8 = 72 
         头32个字节由check1(401AC0)校验,返回1 才进入后部分校验 后40个字符进入到check2401710校验返回1,则注册码成功。
一 check1 401AC0)
       前32个sn 为“76474B2B1926009C452B0062720019” 则返回成功。
       实际上就是解方程。下面是将其还原算法代码(C++)
unsigned char g_sn[0x48] =
{
	0x76, 0x47, 0x4b, 0x2b, 0x19, 0x26, 0x00, 0x9c,
	0x45, 0x2b, 0x00, 0x62, 0x72, 0x00, 0x19, 0x02,
	//0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	//0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
	0x11, 0x22, 0x33, 0x44
};


/*****************************************************************
用途:输出sn进行字节交换
******************************************************************/
void SnSwap(unsigned char *sn, unsigned char *newSn)
{
	for (int i = 0; i < 16; i++)
	{
		int index = (7 * (i / 4) + 2 * (i % 4)) % 4;
		int location = (i / 4 + i % 4 + 2 * (i / 4)) % 4;
		newSn[4 * index + location] = sn[i];
	}
}
unsigned char g_const2[256] = 
{
	0x10, 0x57, 0x02, 0x39, 0xac, 0xa8, 0x37, 0x40, 0x72, 0xac, 0xb9, 0x94, 0xf9, 0x30, 0x42, 0x40,
	0x14, 0xfd, 0xeb, 0xbc, 0x29, 0x01, 0x68, 0xc0, 0x9e, 0x40, 0x1b, 0x51, 0xbd, 0xa2, 0x3b, 0x40,
	0x0a, 0x64, 0x78, 0x4f, 0xbc, 0x94, 0x33, 0x40, 0x7a, 0xaf, 0x12, 0x4b, 0x96, 0xa6, 0x41, 0x40,
	0x24, 0x7f, 0x12, 0x1f, 0xf1, 0xb5, 0x62, 0x40, 0x47, 0x34, 0x42, 0x79, 0x4e, 0xef, 0x55, 0x40,
	0xe4, 0x68, 0x23, 0x75, 0x16, 0x09, 0x57, 0xc0, 0xa0, 0x0e, 0x7e, 0x03, 0x1b, 0x5a, 0x03, 0xc0,
	0xe1, 0x58, 0x3b, 0x08, 0xbb, 0x5f, 0x66, 0x40, 0x43, 0xa9, 0xe4, 0xc7, 0x1a, 0x68, 0x45, 0x40,
	0x4e, 0x05, 0x8f, 0x75, 0x0d, 0xe8, 0x4f, 0x40, 0x84, 0xb8, 0x8d, 0xfb, 0xa7, 0x09, 0x2d, 0xc0,
	0x88, 0x62, 0xc9, 0xba, 0xc4, 0x2d, 0x6c, 0x40, 0x57, 0xfc, 0x71, 0x2c, 0x8a, 0x9e, 0x3c, 0x40,
	0xc0, 0x48, 0xde, 0x90, 0xc3, 0xc5, 0x63, 0x40, 0x2e, 0x6f, 0xea, 0xff, 0x7a, 0x47, 0x49, 0x40,
	0x00, 0x9a, 0x80, 0x4f, 0xf2, 0xbf, 0xe6, 0x3f, 0xa3, 0x3e, 0x95, 0x71, 0x33, 0x71, 0x4b, 0x40,
	0x5c, 0xbe, 0x88, 0x7a, 0xf9, 0xc6, 0x56, 0x40, 0xed, 0x5f, 0x6b, 0x3d, 0xf4, 0xf1, 0x59, 0x40,
	0xe8, 0xa1, 0xf8, 0x94, 0xd8, 0xe6, 0x43, 0x40, 0x4c, 0x3c, 0xb5, 0xa8, 0xa4, 0x56, 0x3b, 0x40,
	0x53, 0xf5, 0x6e, 0x7f, 0x83, 0x51, 0x70, 0x40, 0xcd, 0xfb, 0x5f, 0xed, 0x0e, 0x09, 0x57, 0x40,
	0xca, 0x13, 0xbb, 0x54, 0x2a, 0x42, 0x58, 0x40, 0xfe, 0x3a, 0x53, 0x73, 0xd1, 0x60, 0x39, 0x40,
	0xf0, 0x2d, 0xb0, 0x58, 0x6f, 0x46, 0x6a, 0x40, 0xdc, 0xc8, 0x2f, 0x33, 0x3b, 0x90, 0x3f, 0x40,
	0x1b, 0xf8, 0x44, 0x94, 0xdc, 0x50, 0x50, 0x40, 0x79, 0x6e, 0x1c, 0x4c, 0xa6, 0xb3, 0x39, 0x40,
};
unsigned char g_const[256] = 
{
	0xEE, 0xB9, 0x17, 0x1C, 0x0B, 0x53, 0x56, 0x40, 0xB0, 0x8F, 0x20, 0x7B, 0x1F, 0xCB, 0x53, 0xC0,
	0x3E, 0xDE, 0xDA, 0xB2, 0xD8, 0xCD, 0x5B, 0xC0, 0xC2, 0xE0, 0x4F, 0x80, 0x24, 0xB8, 0x01, 0x40,
	0x28, 0xD9, 0xAE, 0x09, 0x1D, 0x45, 0x4D, 0x40, 0xBC, 0xBF, 0xB0, 0xBA, 0xA4, 0x10, 0x3D, 0x40,
	0x59, 0x3D, 0x04, 0xF9, 0x44, 0x0D, 0x49, 0x40, 0x79, 0xF8, 0x57, 0x7F, 0x3F, 0xE8, 0x45, 0x40,
	0x2A, 0x3E, 0xB7, 0x6F, 0x3D, 0x49, 0x43, 0xC0, 0x90, 0x47, 0xA1, 0x02, 0x41, 0x03, 0x18, 0xC0,
	0xFE, 0x3C, 0xD8, 0x6E, 0x3F, 0xD2, 0x57, 0x40, 0x74, 0xE5, 0x05, 0xB8, 0x4F, 0xEE, 0x37, 0x40,
	0x93, 0x55, 0xC6, 0x7F, 0xA9, 0x8D, 0x5F, 0x40, 0xCC, 0x05, 0x2B, 0xFE, 0xD1, 0x91, 0x4B, 0xC0,
	0x48, 0xD3, 0x63, 0xE2, 0xEE, 0x42, 0x44, 0x40, 0x40, 0x09, 0xC7, 0x44, 0xAB, 0x39, 0x35, 0x40,
	0x50, 0xB7, 0xF3, 0x1A, 0xDC, 0xAB, 0x0F, 0x40, 0x54, 0xCC, 0x0B, 0x4B, 0x2B, 0xA0, 0x2B, 0x40,
	0x30, 0x9F, 0xBB, 0xE1, 0xD4, 0x2C, 0x50, 0x40, 0x18, 0xCF, 0x21, 0x80, 0x1F, 0x70, 0x26, 0xC0,
	0x0A, 0x5D, 0x83, 0xEA, 0x86, 0x55, 0x51, 0x40, 0x94, 0xB7, 0xE2, 0x65, 0xF3, 0xE2, 0x42, 0x40,
	0xB1, 0x21, 0x5C, 0x03, 0x15, 0xE7, 0x48, 0x40, 0xC0, 0x01, 0xF6, 0xC3, 0x5A, 0xAE, 0xF0, 0x3F,
	0x34, 0xEE, 0x29, 0xD0, 0x23, 0x42, 0x1F, 0x40, 0x84, 0x01, 0x69, 0x25, 0xDD, 0x93, 0x3D, 0x40,
	0x58, 0xE4, 0xB8, 0x8B, 0x3C, 0x46, 0x20, 0x40, 0x38, 0xF8, 0x7B, 0x85, 0x84, 0x07, 0x27, 0x40,
	0x70, 0x16, 0x1F, 0x32, 0x58, 0x23, 0x18, 0xC0, 0xB8, 0xD5, 0x58, 0x08, 0xC3, 0x2F, 0x20, 0xC0,
	0x54, 0x6B, 0x43, 0x4A, 0xF2, 0x89, 0x39, 0x40, 0xD8, 0x9E, 0x2F, 0xD1, 0x0F, 0xA4, 0xFA, 0x3F,
};
typedef struct doubleInfo
{
	double d1;
	double d2;
}doubleInfo;
vector<doubleInfo> g_snDoube;
vector<doubleInfo> g_newVector;
doubleInfo g_key[16];
/*****************************************************************
用途:创建sn浮点向量
******************************************************************/
void sn2DoubleVector(unsigned char * sn)
{
	doubleInfo d;
	d.d2 = 0;
	for (int i = 0; i < 16; i++)
	{
		d.d1 = (double)sn[i];
		
		g_snDoube.push_back(d);
	}
}

/*****************************************************************
用途:将g_snDoube进行二元一次方程变换
******************************************************************/
void  SnF1(int index)
{
	int i;
	double d11, d12;
	double c11, c12;
	doubleInfo strDoubleInfo;
	double DoubleConst[32][2];
	DoubleConst[16][0] = 0.8872448700399544;
	DoubleConst[16][1] = 0.4612987541580665;
	DoubleConst[17][0] = 1.0;
	DoubleConst[17][1] = -2.449293598294706e-16;
	DoubleConst[18][0] = 1.0;
	DoubleConst[18][1] = 0.0;
	DoubleConst[19][0] = 0.8661842563768242;
	DoubleConst[19][1] = 0.4997247582469054;
	DoubleConst[20][0] = 1.0;
	DoubleConst[20][1] = -2.449293598294706e-16;
	DoubleConst[21][0] = 0.8661842563768242;
	DoubleConst[21][1] = 0.4997247582469054;
	DoubleConst[22][0] = 0.9985971885883369;
	DoubleConst[22][1] = 0.052949550927931;
	DoubleConst[23][0] = 0.9953266793156615;
	DoubleConst[23][1] = -0.09656501148168593;
	DoubleConst[24][0] = 1.0;
	DoubleConst[24][1] = 0.0;
	DoubleConst[25][0] = 0.9985971885883369;
	DoubleConst[25][1] = 0.052949550927931;
	DoubleConst[26][0] = 0.9945026452220342;
	DoubleConst[26][1] = 0.1047114542272076;
	DoubleConst[27][0] = 0.9878936003329053;
	DoubleConst[27][1] = 0.1551329572376227;
	DoubleConst[28][0] = 0.8661842563768242;
	DoubleConst[28][1] = 0.4997247582469054;
	DoubleConst[29][0] = 0.9953266793156615;
	DoubleConst[29][1] = -0.09656501148168593;
	DoubleConst[30][0] = 0.9878936003329053;
	DoubleConst[30][1] = 0.1551329572376227;
	DoubleConst[31][0] = 0.7738490104360864;
	DoubleConst[31][1] = 0.6333701201091585;
	DoubleConst[0][0] = 0.6276739465982339;
	DoubleConst[0][1] = -0.7784763430970766;
	DoubleConst[1][0] = -0.963553239351518;
	DoubleConst[1][1] = 0.2675166442208714;
	DoubleConst[2][0] = 1.0;
	DoubleConst[2][1] = -2.449293598294706e-16;
	DoubleConst[3][0] = 1.0;
	DoubleConst[3][1] = 0.0;
	DoubleConst[4][0] = -0.963553239351518;
	DoubleConst[8][1] = -2.449293598294706e-16;
	DoubleConst[4][1] = 0.2675166442208714;
	DoubleConst[5][0] = 1.0;
	DoubleConst[5][1] = 0.0;
	DoubleConst[6][0] = 0.7316273320795593;
	DoubleConst[6][1] = -0.6817048092496827;
	DoubleConst[7][0] = 0.9954095040352869;
	DoubleConst[7][1] = -0.09570746719156305;
	DoubleConst[8][0] = 1.0;
	DoubleConst[9][0] = 0.7316273320795593;
	DoubleConst[9][1] = -0.6817048092496827;
	DoubleConst[10][0] = 0.9393388792184448;
	DoubleConst[10][1] = 0.3429904809009076;
	DoubleConst[11][0] = 0.9993790498804485;
	DoubleConst[11][1] = 0.03523513388724686;
	DoubleConst[12][0] = 1.0;
	DoubleConst[12][1] = 0.0;
	DoubleConst[13][0] = 0.9954095040352869;
	DoubleConst[13][1] = -0.09570746719156305;
	DoubleConst[14][0] = 0.9993790498804485;
	DoubleConst[14][1] = 0.03523513388724686;
	DoubleConst[15][0] = 0.933838571018358;
	DoubleConst[15][1] = -0.357694734764703;

	for (i = 0; i < 16; i++)
	{
		strDoubleInfo = g_snDoube.at(i);
		d11 = strDoubleInfo.d1;
		d12 = strDoubleInfo.d2;
		c11 = DoubleConst[index+ i][0];
		c12 = DoubleConst[index+ i][1];
		strDoubleInfo.d1 = c11 * d11 - c12 * d12;
		strDoubleInfo.d2 = d11 * c12 + d12 * c11;
		g_snDoube[i] = strDoubleInfo;
	}
}
/*****************************************************************
用途:取0 4 8 12  或1 5 9 13 或 2 6 10 14 或3 7 11 15
******************************************************************/
void  Fecth4ByIndex(int index, int max)
{
	if (false == g_newVector.empty())
	{
		g_newVector.erase(g_newVector.begin(), g_newVector.end());
	}
	for (int i = 0; i < max; i++)
	{
		g_newVector.push_back(g_snDoube[i * 4 + index]);
	}

}

/*****************************************************************
用途:取0 1 2 3 或4 5 6 7或8 9 10 11或12 13 14 15
******************************************************************/
void  Fecth1ByIndex(int index, int max)
{
	if (false == g_newVector.empty())
	{
		g_newVector.erase(g_newVector.begin(), g_newVector.end());
	}
	for (int i = 0; i < max; i++)
	{
		g_newVector.push_back(g_snDoube[index * 4 + i]);
	}

}

/*****************************************************************
用途:设置0 4 8 12  或1 5 9 13 或 2 6 10 14 或3 7 11 15
******************************************************************/
void Set4ByIndex(int index, int max)
{
	for (int i = 0; i < max; i++)
	{
		g_snDoube[i * 4 + index] = g_newVector[i];
	}
}

/*****************************************************************
用途:设置0 1 2 3 或4 5 6 7或8 9 10 11或12 13 14 15
******************************************************************/
void Set1ByIndex(int index, int max)
{
	for (int i = 0; i < max; i++)
	{
		g_snDoube[index * 4 + i] = g_newVector[i];
	}
}

/*****************************************************************
用途:创建用于计算的常量向量
******************************************************************/
void  CreateConstVetor(vector<doubleInfo> *tempVector)
{
	int cnt = 4;
	int deta = 0;
	double doubleValue;
	doubleInfo constInfo;
	double DoubleCnt = (double)cnt;

	for (int i = 0; i < 4; i++)
	{
		doubleValue = (double)deta * 3.14159265354 / DoubleCnt;
		constInfo.d1 = cos(doubleValue);
		constInfo.d2 = sin(doubleValue);
		tempVector->push_back(constInfo);
		deta -= 2;
	}

}

/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  SnF2ByIndex(int index1, int index2, int constIndex)
{
	double d11, d12;
	double d21, d22;
	double c11, c12;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor(&DoubleConst);


	d11 = g_newVector[index1].d1;
	d12 = g_newVector[index1].d2;
	d21 = g_newVector[index2].d1;
	d22 = g_newVector[index2].d2;
	c11 = DoubleConst[constIndex].d1;
	c12 = DoubleConst[constIndex].d2;
	g_newVector[index2].d1 = (d11 - d21)*c11 - (d12 - d22)*c12;
	g_newVector[index2].d2 = (d11 - d21)*c12 + (d12 - d22)*c11;
	g_newVector[index1].d1 = d11 + d21;
	g_newVector[index1].d2 = d12 + d22;


}
/*****************************************************************
用途:向量索引交换
******************************************************************/
void  SnSwap(int index1, int index2)
{
	doubleInfo strDoubleInfo1;
	doubleInfo strDoubleInfo2;

	strDoubleInfo1 = g_newVector[index1];
	strDoubleInfo2 = g_newVector[index2];
	g_newVector[index1] = strDoubleInfo2;
	g_newVector[index2] = strDoubleInfo1;
}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  SnF2AndSwap(void)
{
	SnF2ByIndex(0, 2, 0);
	SnF2ByIndex(1, 3, 1);
	SnF2ByIndex(0, 1, 0);
	SnF2ByIndex(2, 3, 0);
	SnSwap(1, 2);

	int xxxx = 1;
	
}
/*****************************************************************
用途:创建用于计算的常量向量
******************************************************************/
void  CreateConstVetor2(vector<doubleInfo> *tempVector)
{
	int cnt = 4;
	int deta = 0;
	double doubleValue;
	doubleInfo constInfo;
	double DoubleCnt = (double)cnt;

	for (int i = 0; i < 4; i++)
	{
		doubleValue = (double)deta * 3.14159265354 / DoubleCnt;
		constInfo.d1 = cos(doubleValue);
		constInfo.d2 = sin(doubleValue);
		tempVector->push_back(constInfo);
		deta += 2;
	}

}
/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  SnF2ByIndex2(int index1, int index2, int constIndex)
{
	double d11, d12;
	double d21, d22;
	double c11, c12;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor2(&DoubleConst);


	d11 = g_newVector[index1].d1;
	d12 = g_newVector[index1].d2;
	d21 = g_newVector[index2].d1;
	d22 = g_newVector[index2].d2;
	c11 = DoubleConst[constIndex].d1;
	c12 = DoubleConst[constIndex].d2;
	g_newVector[index2].d1 = (d11 - d21)*c11 - (d12 - d22)*c12;
	g_newVector[index2].d2 = (d11 - d21)*c12 + (d12 - d22)*c11;
	g_newVector[index1].d1 = d11 + d21;
	g_newVector[index1].d2 = d12 + d22;
}
/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void DivLoop(int loopCnt)
{
	double doubleCnt = loopCnt;
	for (int i = 0; i < loopCnt; i++)
	{
		g_newVector[i].d1 = g_newVector[i].d1 / doubleCnt;
		g_newVector[i].d2 = g_newVector[i].d2 / doubleCnt;
	}

}
/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  SnF2AndSwap2(void)
{
	SnF2ByIndex2(0, 2, 0);
	SnF2ByIndex2(1, 3, 1);
	SnF2ByIndex2(0, 1, 0);
	SnF2ByIndex2(2, 3, 0);
	SnSwap(1, 2);
	DivLoop(4);

	int xxxx = 1;
}

bool encrypt(char* sn)
{
	//第一步进行sn字节交换
	unsigned char newSn[16];
	SnSwap(g_sn, newSn);

	//第二步,将newSn转换到g_snDoube
	sn2DoubleVector(newSn);

	//第三步,进行二元一次方程变换
	SnF1(0);

	//第四步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth4ByIndex(i, 4);
		SnF2AndSwap();
		Set4ByIndex(i, 4);
	}

	//第五步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth1ByIndex(i, 4);
		SnF2AndSwap();
		Set1ByIndex(i, 4);
	}

	//第六步
	SnF1(16);

	//第七步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth1ByIndex(i, 4);
		SnF2AndSwap2();
		Set1ByIndex(i, 4);
	}

	//第八步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth4ByIndex(i, 4);
		SnF2AndSwap2();
		Set4ByIndex(i, 4);
	}
	//============================================================
	memcpy((unsigned char*)g_key, g_const, 0x100);
	bool flag = 0;
	for (int i = 0; i < 16; i++)
	{
		if ((g_snDoube[i].d1 != g_key[i].d1) || (g_snDoube[i].d2 != g_key[i].d2))
		{
			flag = true;
			break;
		}
	}
	return false;
}

unsigned char g_sn[0x48] =
{
	0x76, 0x47, 0x4b, 0x2b, 0x19, 0x26, 0x00, 0x9c,
	0x45, 0x2b, 0x00, 0x62, 0x72, 0x00, 0x19, 0x02,
	//0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	//0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
	0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
	0x11, 0x22, 0x33, 0x44
};


/*****************************************************************
用途:输出sn进行字节交换
******************************************************************/
void SnSwap(unsigned char *sn, unsigned char *newSn)
{
	for (int i = 0; i < 16; i++)
	{
		int index = (7 * (i / 4) + 2 * (i % 4)) % 4;
		int location = (i / 4 + i % 4 + 2 * (i / 4)) % 4;
		newSn[4 * index + location] = sn[i];
	}
}
unsigned char g_const2[256] = 
{
	0x10, 0x57, 0x02, 0x39, 0xac, 0xa8, 0x37, 0x40, 0x72, 0xac, 0xb9, 0x94, 0xf9, 0x30, 0x42, 0x40,
	0x14, 0xfd, 0xeb, 0xbc, 0x29, 0x01, 0x68, 0xc0, 0x9e, 0x40, 0x1b, 0x51, 0xbd, 0xa2, 0x3b, 0x40,
	0x0a, 0x64, 0x78, 0x4f, 0xbc, 0x94, 0x33, 0x40, 0x7a, 0xaf, 0x12, 0x4b, 0x96, 0xa6, 0x41, 0x40,
	0x24, 0x7f, 0x12, 0x1f, 0xf1, 0xb5, 0x62, 0x40, 0x47, 0x34, 0x42, 0x79, 0x4e, 0xef, 0x55, 0x40,
	0xe4, 0x68, 0x23, 0x75, 0x16, 0x09, 0x57, 0xc0, 0xa0, 0x0e, 0x7e, 0x03, 0x1b, 0x5a, 0x03, 0xc0,
	0xe1, 0x58, 0x3b, 0x08, 0xbb, 0x5f, 0x66, 0x40, 0x43, 0xa9, 0xe4, 0xc7, 0x1a, 0x68, 0x45, 0x40,
	0x4e, 0x05, 0x8f, 0x75, 0x0d, 0xe8, 0x4f, 0x40, 0x84, 0xb8, 0x8d, 0xfb, 0xa7, 0x09, 0x2d, 0xc0,
	0x88, 0x62, 0xc9, 0xba, 0xc4, 0x2d, 0x6c, 0x40, 0x57, 0xfc, 0x71, 0x2c, 0x8a, 0x9e, 0x3c, 0x40,
	0xc0, 0x48, 0xde, 0x90, 0xc3, 0xc5, 0x63, 0x40, 0x2e, 0x6f, 0xea, 0xff, 0x7a, 0x47, 0x49, 0x40,
	0x00, 0x9a, 0x80, 0x4f, 0xf2, 0xbf, 0xe6, 0x3f, 0xa3, 0x3e, 0x95, 0x71, 0x33, 0x71, 0x4b, 0x40,
	0x5c, 0xbe, 0x88, 0x7a, 0xf9, 0xc6, 0x56, 0x40, 0xed, 0x5f, 0x6b, 0x3d, 0xf4, 0xf1, 0x59, 0x40,
	0xe8, 0xa1, 0xf8, 0x94, 0xd8, 0xe6, 0x43, 0x40, 0x4c, 0x3c, 0xb5, 0xa8, 0xa4, 0x56, 0x3b, 0x40,
	0x53, 0xf5, 0x6e, 0x7f, 0x83, 0x51, 0x70, 0x40, 0xcd, 0xfb, 0x5f, 0xed, 0x0e, 0x09, 0x57, 0x40,
	0xca, 0x13, 0xbb, 0x54, 0x2a, 0x42, 0x58, 0x40, 0xfe, 0x3a, 0x53, 0x73, 0xd1, 0x60, 0x39, 0x40,
	0xf0, 0x2d, 0xb0, 0x58, 0x6f, 0x46, 0x6a, 0x40, 0xdc, 0xc8, 0x2f, 0x33, 0x3b, 0x90, 0x3f, 0x40,
	0x1b, 0xf8, 0x44, 0x94, 0xdc, 0x50, 0x50, 0x40, 0x79, 0x6e, 0x1c, 0x4c, 0xa6, 0xb3, 0x39, 0x40,
};
unsigned char g_const[256] = 
{
	0xEE, 0xB9, 0x17, 0x1C, 0x0B, 0x53, 0x56, 0x40, 0xB0, 0x8F, 0x20, 0x7B, 0x1F, 0xCB, 0x53, 0xC0,
	0x3E, 0xDE, 0xDA, 0xB2, 0xD8, 0xCD, 0x5B, 0xC0, 0xC2, 0xE0, 0x4F, 0x80, 0x24, 0xB8, 0x01, 0x40,
	0x28, 0xD9, 0xAE, 0x09, 0x1D, 0x45, 0x4D, 0x40, 0xBC, 0xBF, 0xB0, 0xBA, 0xA4, 0x10, 0x3D, 0x40,
	0x59, 0x3D, 0x04, 0xF9, 0x44, 0x0D, 0x49, 0x40, 0x79, 0xF8, 0x57, 0x7F, 0x3F, 0xE8, 0x45, 0x40,
	0x2A, 0x3E, 0xB7, 0x6F, 0x3D, 0x49, 0x43, 0xC0, 0x90, 0x47, 0xA1, 0x02, 0x41, 0x03, 0x18, 0xC0,
	0xFE, 0x3C, 0xD8, 0x6E, 0x3F, 0xD2, 0x57, 0x40, 0x74, 0xE5, 0x05, 0xB8, 0x4F, 0xEE, 0x37, 0x40,
	0x93, 0x55, 0xC6, 0x7F, 0xA9, 0x8D, 0x5F, 0x40, 0xCC, 0x05, 0x2B, 0xFE, 0xD1, 0x91, 0x4B, 0xC0,
	0x48, 0xD3, 0x63, 0xE2, 0xEE, 0x42, 0x44, 0x40, 0x40, 0x09, 0xC7, 0x44, 0xAB, 0x39, 0x35, 0x40,
	0x50, 0xB7, 0xF3, 0x1A, 0xDC, 0xAB, 0x0F, 0x40, 0x54, 0xCC, 0x0B, 0x4B, 0x2B, 0xA0, 0x2B, 0x40,
	0x30, 0x9F, 0xBB, 0xE1, 0xD4, 0x2C, 0x50, 0x40, 0x18, 0xCF, 0x21, 0x80, 0x1F, 0x70, 0x26, 0xC0,
	0x0A, 0x5D, 0x83, 0xEA, 0x86, 0x55, 0x51, 0x40, 0x94, 0xB7, 0xE2, 0x65, 0xF3, 0xE2, 0x42, 0x40,
	0xB1, 0x21, 0x5C, 0x03, 0x15, 0xE7, 0x48, 0x40, 0xC0, 0x01, 0xF6, 0xC3, 0x5A, 0xAE, 0xF0, 0x3F,
	0x34, 0xEE, 0x29, 0xD0, 0x23, 0x42, 0x1F, 0x40, 0x84, 0x01, 0x69, 0x25, 0xDD, 0x93, 0x3D, 0x40,
	0x58, 0xE4, 0xB8, 0x8B, 0x3C, 0x46, 0x20, 0x40, 0x38, 0xF8, 0x7B, 0x85, 0x84, 0x07, 0x27, 0x40,
	0x70, 0x16, 0x1F, 0x32, 0x58, 0x23, 0x18, 0xC0, 0xB8, 0xD5, 0x58, 0x08, 0xC3, 0x2F, 0x20, 0xC0,
	0x54, 0x6B, 0x43, 0x4A, 0xF2, 0x89, 0x39, 0x40, 0xD8, 0x9E, 0x2F, 0xD1, 0x0F, 0xA4, 0xFA, 0x3F,
};
typedef struct doubleInfo
{
	double d1;
	double d2;
}doubleInfo;
vector<doubleInfo> g_snDoube;
vector<doubleInfo> g_newVector;
doubleInfo g_key[16];
/*****************************************************************
用途:创建sn浮点向量
******************************************************************/
void sn2DoubleVector(unsigned char * sn)
{
	doubleInfo d;
	d.d2 = 0;
	for (int i = 0; i < 16; i++)
	{
		d.d1 = (double)sn[i];
		
		g_snDoube.push_back(d);
	}
}

/*****************************************************************
用途:将g_snDoube进行二元一次方程变换
******************************************************************/
void  SnF1(int index)
{
	int i;
	double d11, d12;
	double c11, c12;
	doubleInfo strDoubleInfo;
	double DoubleConst[32][2];
	DoubleConst[16][0] = 0.8872448700399544;
	DoubleConst[16][1] = 0.4612987541580665;
	DoubleConst[17][0] = 1.0;
	DoubleConst[17][1] = -2.449293598294706e-16;
	DoubleConst[18][0] = 1.0;
	DoubleConst[18][1] = 0.0;
	DoubleConst[19][0] = 0.8661842563768242;
	DoubleConst[19][1] = 0.4997247582469054;
	DoubleConst[20][0] = 1.0;
	DoubleConst[20][1] = -2.449293598294706e-16;
	DoubleConst[21][0] = 0.8661842563768242;
	DoubleConst[21][1] = 0.4997247582469054;
	DoubleConst[22][0] = 0.9985971885883369;
	DoubleConst[22][1] = 0.052949550927931;
	DoubleConst[23][0] = 0.9953266793156615;
	DoubleConst[23][1] = -0.09656501148168593;
	DoubleConst[24][0] = 1.0;
	DoubleConst[24][1] = 0.0;
	DoubleConst[25][0] = 0.9985971885883369;
	DoubleConst[25][1] = 0.052949550927931;
	DoubleConst[26][0] = 0.9945026452220342;
	DoubleConst[26][1] = 0.1047114542272076;
	DoubleConst[27][0] = 0.9878936003329053;
	DoubleConst[27][1] = 0.1551329572376227;
	DoubleConst[28][0] = 0.8661842563768242;
	DoubleConst[28][1] = 0.4997247582469054;
	DoubleConst[29][0] = 0.9953266793156615;
	DoubleConst[29][1] = -0.09656501148168593;
	DoubleConst[30][0] = 0.9878936003329053;
	DoubleConst[30][1] = 0.1551329572376227;
	DoubleConst[31][0] = 0.7738490104360864;
	DoubleConst[31][1] = 0.6333701201091585;
	DoubleConst[0][0] = 0.6276739465982339;
	DoubleConst[0][1] = -0.7784763430970766;
	DoubleConst[1][0] = -0.963553239351518;
	DoubleConst[1][1] = 0.2675166442208714;
	DoubleConst[2][0] = 1.0;
	DoubleConst[2][1] = -2.449293598294706e-16;
	DoubleConst[3][0] = 1.0;
	DoubleConst[3][1] = 0.0;
	DoubleConst[4][0] = -0.963553239351518;
	DoubleConst[8][1] = -2.449293598294706e-16;
	DoubleConst[4][1] = 0.2675166442208714;
	DoubleConst[5][0] = 1.0;
	DoubleConst[5][1] = 0.0;
	DoubleConst[6][0] = 0.7316273320795593;
	DoubleConst[6][1] = -0.6817048092496827;
	DoubleConst[7][0] = 0.9954095040352869;
	DoubleConst[7][1] = -0.09570746719156305;
	DoubleConst[8][0] = 1.0;
	DoubleConst[9][0] = 0.7316273320795593;
	DoubleConst[9][1] = -0.6817048092496827;
	DoubleConst[10][0] = 0.9393388792184448;
	DoubleConst[10][1] = 0.3429904809009076;
	DoubleConst[11][0] = 0.9993790498804485;
	DoubleConst[11][1] = 0.03523513388724686;
	DoubleConst[12][0] = 1.0;
	DoubleConst[12][1] = 0.0;
	DoubleConst[13][0] = 0.9954095040352869;
	DoubleConst[13][1] = -0.09570746719156305;
	DoubleConst[14][0] = 0.9993790498804485;
	DoubleConst[14][1] = 0.03523513388724686;
	DoubleConst[15][0] = 0.933838571018358;
	DoubleConst[15][1] = -0.357694734764703;

	for (i = 0; i < 16; i++)
	{
		strDoubleInfo = g_snDoube.at(i);
		d11 = strDoubleInfo.d1;
		d12 = strDoubleInfo.d2;
		c11 = DoubleConst[index+ i][0];
		c12 = DoubleConst[index+ i][1];
		strDoubleInfo.d1 = c11 * d11 - c12 * d12;
		strDoubleInfo.d2 = d11 * c12 + d12 * c11;
		g_snDoube[i] = strDoubleInfo;
	}
}
/*****************************************************************
用途:取0 4 8 12  或1 5 9 13 或 2 6 10 14 或3 7 11 15
******************************************************************/
void  Fecth4ByIndex(int index, int max)
{
	if (false == g_newVector.empty())
	{
		g_newVector.erase(g_newVector.begin(), g_newVector.end());
	}
	for (int i = 0; i < max; i++)
	{
		g_newVector.push_back(g_snDoube[i * 4 + index]);
	}

}

/*****************************************************************
用途:取0 1 2 3 或4 5 6 7或8 9 10 11或12 13 14 15
******************************************************************/
void  Fecth1ByIndex(int index, int max)
{
	if (false == g_newVector.empty())
	{
		g_newVector.erase(g_newVector.begin(), g_newVector.end());
	}
	for (int i = 0; i < max; i++)
	{
		g_newVector.push_back(g_snDoube[index * 4 + i]);
	}

}

/*****************************************************************
用途:设置0 4 8 12  或1 5 9 13 或 2 6 10 14 或3 7 11 15
******************************************************************/
void Set4ByIndex(int index, int max)
{
	for (int i = 0; i < max; i++)
	{
		g_snDoube[i * 4 + index] = g_newVector[i];
	}
}

/*****************************************************************
用途:设置0 1 2 3 或4 5 6 7或8 9 10 11或12 13 14 15
******************************************************************/
void Set1ByIndex(int index, int max)
{
	for (int i = 0; i < max; i++)
	{
		g_snDoube[index * 4 + i] = g_newVector[i];
	}
}

/*****************************************************************
用途:创建用于计算的常量向量
******************************************************************/
void  CreateConstVetor(vector<doubleInfo> *tempVector)
{
	int cnt = 4;
	int deta = 0;
	double doubleValue;
	doubleInfo constInfo;
	double DoubleCnt = (double)cnt;

	for (int i = 0; i < 4; i++)
	{
		doubleValue = (double)deta * 3.14159265354 / DoubleCnt;
		constInfo.d1 = cos(doubleValue);
		constInfo.d2 = sin(doubleValue);
		tempVector->push_back(constInfo);
		deta -= 2;
	}

}

/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  SnF2ByIndex(int index1, int index2, int constIndex)
{
	double d11, d12;
	double d21, d22;
	double c11, c12;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor(&DoubleConst);


	d11 = g_newVector[index1].d1;
	d12 = g_newVector[index1].d2;
	d21 = g_newVector[index2].d1;
	d22 = g_newVector[index2].d2;
	c11 = DoubleConst[constIndex].d1;
	c12 = DoubleConst[constIndex].d2;
	g_newVector[index2].d1 = (d11 - d21)*c11 - (d12 - d22)*c12;
	g_newVector[index2].d2 = (d11 - d21)*c12 + (d12 - d22)*c11;
	g_newVector[index1].d1 = d11 + d21;
	g_newVector[index1].d2 = d12 + d22;


}
/*****************************************************************
用途:向量索引交换
******************************************************************/
void  SnSwap(int index1, int index2)
{
	doubleInfo strDoubleInfo1;
	doubleInfo strDoubleInfo2;

	strDoubleInfo1 = g_newVector[index1];
	strDoubleInfo2 = g_newVector[index2];
	g_newVector[index1] = strDoubleInfo2;
	g_newVector[index2] = strDoubleInfo1;
}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  SnF2AndSwap(void)
{
	SnF2ByIndex(0, 2, 0);
	SnF2ByIndex(1, 3, 1);
	SnF2ByIndex(0, 1, 0);
	SnF2ByIndex(2, 3, 0);
	SnSwap(1, 2);

	int xxxx = 1;
	
}
/*****************************************************************
用途:创建用于计算的常量向量
******************************************************************/
void  CreateConstVetor2(vector<doubleInfo> *tempVector)
{
	int cnt = 4;
	int deta = 0;
	double doubleValue;
	doubleInfo constInfo;
	double DoubleCnt = (double)cnt;

	for (int i = 0; i < 4; i++)
	{
		doubleValue = (double)deta * 3.14159265354 / DoubleCnt;
		constInfo.d1 = cos(doubleValue);
		constInfo.d2 = sin(doubleValue);
		tempVector->push_back(constInfo);
		deta += 2;
	}

}
/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  SnF2ByIndex2(int index1, int index2, int constIndex)
{
	double d11, d12;
	double d21, d22;
	double c11, c12;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor2(&DoubleConst);


	d11 = g_newVector[index1].d1;
	d12 = g_newVector[index1].d2;
	d21 = g_newVector[index2].d1;
	d22 = g_newVector[index2].d2;
	c11 = DoubleConst[constIndex].d1;
	c12 = DoubleConst[constIndex].d2;
	g_newVector[index2].d1 = (d11 - d21)*c11 - (d12 - d22)*c12;
	g_newVector[index2].d2 = (d11 - d21)*c12 + (d12 - d22)*c11;
	g_newVector[index1].d1 = d11 + d21;
	g_newVector[index1].d2 = d12 + d22;
}
/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void DivLoop(int loopCnt)
{
	double doubleCnt = loopCnt;
	for (int i = 0; i < loopCnt; i++)
	{
		g_newVector[i].d1 = g_newVector[i].d1 / doubleCnt;
		g_newVector[i].d2 = g_newVector[i].d2 / doubleCnt;
	}

}
/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  SnF2AndSwap2(void)
{
	SnF2ByIndex2(0, 2, 0);
	SnF2ByIndex2(1, 3, 1);
	SnF2ByIndex2(0, 1, 0);
	SnF2ByIndex2(2, 3, 0);
	SnSwap(1, 2);
	DivLoop(4);

	int xxxx = 1;
}

bool encrypt(char* sn)
{
	//第一步进行sn字节交换
	unsigned char newSn[16];
	SnSwap(g_sn, newSn);

	//第二步,将newSn转换到g_snDoube
	sn2DoubleVector(newSn);

	//第三步,进行二元一次方程变换
	SnF1(0);

	//第四步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth4ByIndex(i, 4);
		SnF2AndSwap();
		Set4ByIndex(i, 4);
	}

	//第五步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth1ByIndex(i, 4);
		SnF2AndSwap();
		Set1ByIndex(i, 4);
	}

	//第六步
	SnF1(16);

	//第七步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth1ByIndex(i, 4);
		SnF2AndSwap2();
		Set1ByIndex(i, 4);
	}

	//第八步,执行二元一次方程变换
	for (int i = 0; i < 4; i++)
	{
		Fecth4ByIndex(i, 4);
		SnF2AndSwap2();
		Set4ByIndex(i, 4);
	}
	//============================================================
	memcpy((unsigned char*)g_key, g_const, 0x100);
	bool flag = 0;
	for (int i = 0; i < 16; i++)
	{
		if ((g_snDoube[i].d1 != g_key[i].d1) || (g_snDoube[i].d2 != g_key[i].d2))
		{
			flag = true;
			break;
		}
	}
	return false;
}

       下面是解密算法代码
/*****************************************************************
用途:乘以4.0
******************************************************************/
void MulLoop(int loopCnt)
{
	double doubleCnt = loopCnt;
	for (int i = 0; i < loopCnt; i++)
	{
		g_newVector[i].d1 = g_newVector[i].d1 * doubleCnt;
		g_newVector[i].d2 = g_newVector[i].d2 * doubleCnt;
	}

}


/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  DecodeSnF2ByIndex2(int index1, int index2, int constIndex)
{
	double x11, x12;
	double x21, x22;
	double y11, y12;
	double y21, y22;
	double c1, c2;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor2(&DoubleConst);


	y11 = g_newVector[index1].d1;
	y12 = g_newVector[index1].d2;
	y21 = g_newVector[index2].d1;
	y22 = g_newVector[index2].d2;
	c1 = DoubleConst[constIndex].d1;
	c2 = DoubleConst[constIndex].d2;

	double m1 = (y21 *c1 + y22*c2) / (c1*c1 + c2*c2);
	double m2 = (y22 *c1 - y21*c2) / (c1*c1 + c2*c2);
	//x21 = (y11 - m1) / 2;
	//x22 = (y12 - m2) / 2;
	//x11 = y11 - x21;
	//x12 = y12 - x22;
	x11 = (y11 + m1) / 2.0;
	x12 = (y12 + m2) / 2.0;
	x21 = (y11 - m1) / 2.0;
	x22 = (y12 - m2) / 2.0;
	g_newVector[index1].d1 = x11;
	g_newVector[index1].d2 = x12;
	g_newVector[index2].d1 = x21;
	g_newVector[index2].d2 = x22;

}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  DecodeSnF2AndSwap2(void)
{
	MulLoop(4);
	SnSwap(2, 1);
	DecodeSnF2ByIndex2(2, 3, 0);
	DecodeSnF2ByIndex2(0, 1, 0);
	DecodeSnF2ByIndex2(1, 3, 1);
	DecodeSnF2ByIndex2(0, 2, 0);


	int xxxx = 1;

}


/*****************************************************************
用途:将g_snDoube进行二元一次方程变换
******************************************************************/
void  decodeSnF1(int index)
{
	int i;
	double x1, x2;
	double y1, y2;
	double c1, c2;
	double DoubleConst[32][2];
	DoubleConst[16][0] = 0.8872448700399544;
	DoubleConst[16][1] = 0.4612987541580665;
	DoubleConst[17][0] = 1.0;
	DoubleConst[17][1] = -2.449293598294706e-16;
	DoubleConst[18][0] = 1.0;
	DoubleConst[18][1] = 0.0;
	DoubleConst[19][0] = 0.8661842563768242;
	DoubleConst[19][1] = 0.4997247582469054;
	DoubleConst[20][0] = 1.0;
	DoubleConst[20][1] = -2.449293598294706e-16;
	DoubleConst[21][0] = 0.8661842563768242;
	DoubleConst[21][1] = 0.4997247582469054;
	DoubleConst[22][0] = 0.9985971885883369;
	DoubleConst[22][1] = 0.052949550927931;
	DoubleConst[23][0] = 0.9953266793156615;
	DoubleConst[23][1] = -0.09656501148168593;
	DoubleConst[24][0] = 1.0;
	DoubleConst[24][1] = 0.0;
	DoubleConst[25][0] = 0.9985971885883369;
	DoubleConst[25][1] = 0.052949550927931;
	DoubleConst[26][0] = 0.9945026452220342;
	DoubleConst[26][1] = 0.1047114542272076;
	DoubleConst[27][0] = 0.9878936003329053;
	DoubleConst[27][1] = 0.1551329572376227;
	DoubleConst[28][0] = 0.8661842563768242;
	DoubleConst[28][1] = 0.4997247582469054;
	DoubleConst[29][0] = 0.9953266793156615;
	DoubleConst[29][1] = -0.09656501148168593;
	DoubleConst[30][0] = 0.9878936003329053;
	DoubleConst[30][1] = 0.1551329572376227;
	DoubleConst[31][0] = 0.7738490104360864;
	DoubleConst[31][1] = 0.6333701201091585;
	DoubleConst[0][0] = 0.6276739465982339;
	DoubleConst[0][1] = -0.7784763430970766;
	DoubleConst[1][0] = -0.963553239351518;
	DoubleConst[1][1] = 0.2675166442208714;
	DoubleConst[2][0] = 1.0;
	DoubleConst[2][1] = -2.449293598294706e-16;
	DoubleConst[3][0] = 1.0;
	DoubleConst[3][1] = 0.0;
	DoubleConst[4][0] = -0.963553239351518;
	DoubleConst[8][1] = -2.449293598294706e-16;
	DoubleConst[4][1] = 0.2675166442208714;
	DoubleConst[5][0] = 1.0;
	DoubleConst[5][1] = 0.0;
	DoubleConst[6][0] = 0.7316273320795593;
	DoubleConst[6][1] = -0.6817048092496827;
	DoubleConst[7][0] = 0.9954095040352869;
	DoubleConst[7][1] = -0.09570746719156305;
	DoubleConst[8][0] = 1.0;
	DoubleConst[9][0] = 0.7316273320795593;
	DoubleConst[9][1] = -0.6817048092496827;
	DoubleConst[10][0] = 0.9393388792184448;
	DoubleConst[10][1] = 0.3429904809009076;
	DoubleConst[11][0] = 0.9993790498804485;
	DoubleConst[11][1] = 0.03523513388724686;
	DoubleConst[12][0] = 1.0;
	DoubleConst[12][1] = 0.0;
	DoubleConst[13][0] = 0.9954095040352869;
	DoubleConst[13][1] = -0.09570746719156305;
	DoubleConst[14][0] = 0.9993790498804485;
	DoubleConst[14][1] = 0.03523513388724686;
	DoubleConst[15][0] = 0.933838571018358;
	DoubleConst[15][1] = -0.357694734764703;

	for (i = 0; i < 16; i++)
	{
		y1 = g_snDoube[i].d1;
		y2 = g_snDoube[i].d2;
		c1 = DoubleConst[index + i][0];
		c2 = DoubleConst[index + i][1];
		x1 = (y1*c1 + y2*c2) / (c1*c1 + c2*c2);
		x2 = (y2*c1 - y1*c2) / (c1*c1 + c2*c2);
		g_snDoube[i].d1 = x1;
		g_snDoube[i].d2 = x2;
	}
}
/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  DecodeSnF2ByIndex(int index1, int index2, int constIndex)
{
	double x11, x12;
	double x21, x22;
	double y11, y12;
	double y21, y22;
	double c1, c2;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor(&DoubleConst);


	y11 = g_newVector[index1].d1;
	y12 = g_newVector[index1].d2;
	y21 = g_newVector[index2].d1;
	y22 = g_newVector[index2].d2;
	c1 = DoubleConst[constIndex].d1;
	c2 = DoubleConst[constIndex].d2;

	double m1 = (y21 *c1 + y22*c2) / (c1*c1 + c2*c2);
	double m2 = (y22 *c1 - y21*c2) / (c1*c1 + c2*c2);
	//x21 = (y11 - m1) / 2;
	//x22 = (y12 - m2) / 2;
	//x11 = y11 - x21;
	//x12 = y12 - x22;
	x11 = (y11 + m1) / 2.0;
	x12 = (y12 + m2) / 2.0;
	x21 = (y11 - m1) / 2.0;
	x22 = (y12 - m2) / 2.0;
	g_newVector[index1].d1 = x11;
	g_newVector[index1].d2 = x12;
	g_newVector[index2].d1 = x21;
	g_newVector[index2].d2 = x22;

}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  DecodeSnF2AndSwap(void)
{
	SnSwap(2, 1);
	DecodeSnF2ByIndex(2, 3, 0);
	DecodeSnF2ByIndex(0, 1, 0);
	DecodeSnF2ByIndex(1, 3, 1);
	DecodeSnF2ByIndex(0, 2, 0);
	int xxxx = 1;

}

int round_double(double number)
{
	return (number > 0.0) ? (number + 0.5) : (number - 0.5);
}

/*****************************************************************
用途:创建sn浮点向量
******************************************************************/
void DecodeSn2DoubleVector(unsigned char * sn)
{
	doubleInfo d;
	d.d2 = 0;
	for (int i = 0; i < 16; i++)
	{
		sn[i] = round_double(g_snDoube[i].d1);
	}

	sn[16] = 0;
}

/*****************************************************************
用途:输出sn进行字节交换
******************************************************************/
void DecodeSnSwap(unsigned char *sn, unsigned char *newSn)
{    //0 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
	//00 bb 22 99 55 cc 77 ee aa 11 88 33 ff 66 dd 44
	//00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff
	sn[0] = newSn[0];
	sn[1] = newSn[9];
	sn[2] = newSn[2];
	sn[3] = newSn[11];
	sn[4] = newSn[15];
	sn[5] = newSn[4];
	sn[6] = newSn[13];
	sn[7] = newSn[6];
	sn[8] = newSn[10];
	sn[9] = newSn[3];
	sn[10] = newSn[8];
	sn[11] = newSn[1];
	sn[12] = newSn[5];
	sn[13] = newSn[14];
	sn[14] = newSn[7];
	sn[15] = newSn[12];

}

void decrypt(void)
{
	//为解密后字符
	unsigned char newSn[16];

	memcpy((unsigned char*)g_key, g_const, 0x100);
	int flag = 0;
	for (int i = 0; i < 16; i++)
	{
		if ((g_snDoube[i].d1 != g_key[i].d1) || (g_snDoube[i].d2 != g_key[i].d2))
		{
			flag = 1;
			break;
		}
	}

	//第八步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth4ByIndex(i, 4);
		DecodeSnF2AndSwap2();
		Set4ByIndex(i, 4);
	}

	//第七步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth1ByIndex(i, 4);
		DecodeSnF2AndSwap2();
		Set1ByIndex(i, 4);
	}

	//第六步
	decodeSnF1(16);

	//第五步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth1ByIndex(i, 4);
		DecodeSnF2AndSwap();
		Set1ByIndex(i, 4);
	}


	//第四步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth4ByIndex(i, 4);
		DecodeSnF2AndSwap();
		Set4ByIndex(i, 4);
	}

	//第三步,进行二元一次方程变换
	decodeSnF1(0);

	//第二步,将newSn转换到g_snDoube
	unsigned char decodeNewSn[17];
	DecodeSn2DoubleVector(decodeNewSn);

	//第一步进行sn字节交换
	DecodeSnSwap(newSn, decodeNewSn);
}
   二、check2(401710)
       1、TEA算法 
          sub_403A30函数为TEA算法,同时要求解密后最后一个int为0x10 实际上是前面的size。
        2、sub_401330貌似是AES算法 卡在这里。
        3、虚拟机代码
               sub_401330函数里面有一段虚拟机代码其主要功能如下:
     
unsigned char gvmConst[16][16] =
{
	0x01, 0x0E, 0x9A, 0x22, 0x59, 0x81, 0x58, 0x9A, 0xE7, 0x5A, 0x3E, 0x86, 0x62, 0xEB, 0x57, 0xD2,
	0x00, 0x55, 0xC6, 0x7F, 0xA9, 0x8D, 0x5F, 0x40, 0xE8, 0x99, 0x31, 0xE8, 0x9D, 0x60, 0x00, 0x08,
	0x7E, 0x6E, 0xCF, 0xD4, 0x92, 0xBC, 0x4B, 0x27, 0xC0, 0xCF, 0xF2, 0x65, 0x6D, 0x3C, 0x49, 0xD1,
	0xAA, 0xB1, 0x45, 0xA8, 0x6D, 0x75, 0x9B, 0xC1, 0xDF, 0x75, 0x60, 0xDD, 0x8D, 0xDD, 0x13, 0xDA,
	0xD3, 0x98, 0x3E, 0xEF, 0x41, 0x24, 0x75, 0xC8, 0x81, 0xEB, 0x87, 0xAD, 0xEC, 0xD7, 0xCE, 0x7C,
	0xE6, 0x49, 0xA1, 0xF5, 0x8B, 0x3C, 0x3A, 0x34, 0x54, 0x49, 0x5A, 0xE9, 0xD9, 0x94, 0x49, 0x33,
	0xD4, 0x58, 0x36, 0xB7, 0x95, 0x7C, 0x43, 0x7F, 0x14, 0x97, 0xC4, 0xD2, 0xF8, 0x40, 0x0A, 0xAE,
	0x20, 0xEC, 0x91, 0x39, 0xAB, 0xD0, 0xAB, 0x0D, 0xFF, 0x99, 0xF1, 0xE4, 0x26, 0x0D, 0xB8, 0xD7,
	0x60, 0xAF, 0xCE, 0x10, 0xF5, 0xD3, 0x8D, 0x6F, 0xE1, 0x44, 0x49, 0xBD, 0x19, 0x04, 0x43, 0x13,
	0xB8, 0x25, 0x88, 0xCF, 0x13, 0xF5, 0x23, 0xC2, 0xEC, 0x6C, 0xD2, 0x26, 0xCA, 0x61, 0x6A, 0xF1,
	0x07, 0x61, 0x83, 0xB4, 0xF2, 0xB2, 0x0E, 0xDB, 0x13, 0xF6, 0x47, 0x66, 0x0A, 0xF2, 0x04, 0x75,
	0x88, 0x41, 0x41, 0x69, 0x9B, 0xB4, 0x62, 0xAB, 0x77, 0xD8, 0xB0, 0x8D, 0xBD, 0xB9, 0xDA, 0x7C,
	0x94, 0x90, 0xDE, 0x5D, 0x66, 0x22, 0xD0, 0x86, 0x75, 0xD4, 0x97, 0xE0, 0x7F, 0x26, 0x93, 0x95,
	0x0C, 0xE6, 0xDE, 0x8C, 0x97, 0x52, 0xBC, 0x27, 0xE0, 0x8A, 0x0C, 0xAA, 0x5D, 0x33, 0xD6, 0xD6,
	0xBC, 0x38, 0x76, 0x17, 0xDA, 0x1A, 0xA6, 0x91, 0xAF, 0xCE, 0x31, 0x71, 0xD0, 0xE8, 0xA2, 0xE4,
	0xB7, 0x36, 0xC5, 0x56, 0x20, 0x64, 0x79, 0x71, 0xC0, 0xEE, 0x75, 0xDB, 0x9D, 0xDD, 0xA3, 0x0D,

};

void vmEncrypt(void)
{
	unsigned char sn[4][4] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, };
	unsigned char temSn[4][4] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, };
	sn[0][0] = temSn[0][0];
	sn[0][1] = temSn[1][0];
	sn[0][2] = temSn[2][0];
	sn[0][3] = temSn[3][0];
	sn[1][0] = temSn[0][1];
	sn[1][1] = temSn[1][1];
	sn[1][2] = temSn[2][1];
	sn[1][3] = temSn[3][1];
	sn[2][0] = temSn[0][2];
	sn[2][1] = temSn[1][2];
	sn[2][2] = temSn[2][2];
	sn[2][3] = temSn[3][2];
	sn[3][0] = temSn[0][3];
	sn[3][1] = temSn[1][3];
	sn[3][2] = temSn[2][3];
	sn[3][3] = temSn[3][3];

	int k = 0;
        int index = 15;
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			sn[j][i] = sn[j][i] ^ gvmConst[index][k];
			k++;
		}
	}
	
	int xxxx = 1;

}

   
/*****************************************************************
用途:乘以4.0
******************************************************************/
void MulLoop(int loopCnt)
{
	double doubleCnt = loopCnt;
	for (int i = 0; i < loopCnt; i++)
	{
		g_newVector[i].d1 = g_newVector[i].d1 * doubleCnt;
		g_newVector[i].d2 = g_newVector[i].d2 * doubleCnt;
	}

}


/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  DecodeSnF2ByIndex2(int index1, int index2, int constIndex)
{
	double x11, x12;
	double x21, x22;
	double y11, y12;
	double y21, y22;
	double c1, c2;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor2(&DoubleConst);


	y11 = g_newVector[index1].d1;
	y12 = g_newVector[index1].d2;
	y21 = g_newVector[index2].d1;
	y22 = g_newVector[index2].d2;
	c1 = DoubleConst[constIndex].d1;
	c2 = DoubleConst[constIndex].d2;

	double m1 = (y21 *c1 + y22*c2) / (c1*c1 + c2*c2);
	double m2 = (y22 *c1 - y21*c2) / (c1*c1 + c2*c2);
	//x21 = (y11 - m1) / 2;
	//x22 = (y12 - m2) / 2;
	//x11 = y11 - x21;
	//x12 = y12 - x22;
	x11 = (y11 + m1) / 2.0;
	x12 = (y12 + m2) / 2.0;
	x21 = (y11 - m1) / 2.0;
	x22 = (y12 - m2) / 2.0;
	g_newVector[index1].d1 = x11;
	g_newVector[index1].d2 = x12;
	g_newVector[index2].d1 = x21;
	g_newVector[index2].d2 = x22;

}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  DecodeSnF2AndSwap2(void)
{
	MulLoop(4);
	SnSwap(2, 1);
	DecodeSnF2ByIndex2(2, 3, 0);
	DecodeSnF2ByIndex2(0, 1, 0);
	DecodeSnF2ByIndex2(1, 3, 1);
	DecodeSnF2ByIndex2(0, 2, 0);


	int xxxx = 1;

}


/*****************************************************************
用途:将g_snDoube进行二元一次方程变换
******************************************************************/
void  decodeSnF1(int index)
{
	int i;
	double x1, x2;
	double y1, y2;
	double c1, c2;
	double DoubleConst[32][2];
	DoubleConst[16][0] = 0.8872448700399544;
	DoubleConst[16][1] = 0.4612987541580665;
	DoubleConst[17][0] = 1.0;
	DoubleConst[17][1] = -2.449293598294706e-16;
	DoubleConst[18][0] = 1.0;
	DoubleConst[18][1] = 0.0;
	DoubleConst[19][0] = 0.8661842563768242;
	DoubleConst[19][1] = 0.4997247582469054;
	DoubleConst[20][0] = 1.0;
	DoubleConst[20][1] = -2.449293598294706e-16;
	DoubleConst[21][0] = 0.8661842563768242;
	DoubleConst[21][1] = 0.4997247582469054;
	DoubleConst[22][0] = 0.9985971885883369;
	DoubleConst[22][1] = 0.052949550927931;
	DoubleConst[23][0] = 0.9953266793156615;
	DoubleConst[23][1] = -0.09656501148168593;
	DoubleConst[24][0] = 1.0;
	DoubleConst[24][1] = 0.0;
	DoubleConst[25][0] = 0.9985971885883369;
	DoubleConst[25][1] = 0.052949550927931;
	DoubleConst[26][0] = 0.9945026452220342;
	DoubleConst[26][1] = 0.1047114542272076;
	DoubleConst[27][0] = 0.9878936003329053;
	DoubleConst[27][1] = 0.1551329572376227;
	DoubleConst[28][0] = 0.8661842563768242;
	DoubleConst[28][1] = 0.4997247582469054;
	DoubleConst[29][0] = 0.9953266793156615;
	DoubleConst[29][1] = -0.09656501148168593;
	DoubleConst[30][0] = 0.9878936003329053;
	DoubleConst[30][1] = 0.1551329572376227;
	DoubleConst[31][0] = 0.7738490104360864;
	DoubleConst[31][1] = 0.6333701201091585;
	DoubleConst[0][0] = 0.6276739465982339;
	DoubleConst[0][1] = -0.7784763430970766;
	DoubleConst[1][0] = -0.963553239351518;
	DoubleConst[1][1] = 0.2675166442208714;
	DoubleConst[2][0] = 1.0;
	DoubleConst[2][1] = -2.449293598294706e-16;
	DoubleConst[3][0] = 1.0;
	DoubleConst[3][1] = 0.0;
	DoubleConst[4][0] = -0.963553239351518;
	DoubleConst[8][1] = -2.449293598294706e-16;
	DoubleConst[4][1] = 0.2675166442208714;
	DoubleConst[5][0] = 1.0;
	DoubleConst[5][1] = 0.0;
	DoubleConst[6][0] = 0.7316273320795593;
	DoubleConst[6][1] = -0.6817048092496827;
	DoubleConst[7][0] = 0.9954095040352869;
	DoubleConst[7][1] = -0.09570746719156305;
	DoubleConst[8][0] = 1.0;
	DoubleConst[9][0] = 0.7316273320795593;
	DoubleConst[9][1] = -0.6817048092496827;
	DoubleConst[10][0] = 0.9393388792184448;
	DoubleConst[10][1] = 0.3429904809009076;
	DoubleConst[11][0] = 0.9993790498804485;
	DoubleConst[11][1] = 0.03523513388724686;
	DoubleConst[12][0] = 1.0;
	DoubleConst[12][1] = 0.0;
	DoubleConst[13][0] = 0.9954095040352869;
	DoubleConst[13][1] = -0.09570746719156305;
	DoubleConst[14][0] = 0.9993790498804485;
	DoubleConst[14][1] = 0.03523513388724686;
	DoubleConst[15][0] = 0.933838571018358;
	DoubleConst[15][1] = -0.357694734764703;

	for (i = 0; i < 16; i++)
	{
		y1 = g_snDoube[i].d1;
		y2 = g_snDoube[i].d2;
		c1 = DoubleConst[index + i][0];
		c2 = DoubleConst[index + i][1];
		x1 = (y1*c1 + y2*c2) / (c1*c1 + c2*c2);
		x2 = (y2*c1 - y1*c2) / (c1*c1 + c2*c2);
		g_snDoube[i].d1 = x1;
		g_snDoube[i].d2 = x2;
	}
}
/*****************************************************************
用途:进行二元一次方程第二次变换
******************************************************************/
void  DecodeSnF2ByIndex(int index1, int index2, int constIndex)
{
	double x11, x12;
	double x21, x22;
	double y11, y12;
	double y21, y22;
	double c1, c2;

	//创建常量向量
	vector<doubleInfo> DoubleConst;
	CreateConstVetor(&DoubleConst);


	y11 = g_newVector[index1].d1;
	y12 = g_newVector[index1].d2;
	y21 = g_newVector[index2].d1;
	y22 = g_newVector[index2].d2;
	c1 = DoubleConst[constIndex].d1;
	c2 = DoubleConst[constIndex].d2;

	double m1 = (y21 *c1 + y22*c2) / (c1*c1 + c2*c2);
	double m2 = (y22 *c1 - y21*c2) / (c1*c1 + c2*c2);
	//x21 = (y11 - m1) / 2;
	//x22 = (y12 - m2) / 2;
	//x11 = y11 - x21;
	//x12 = y12 - x22;
	x11 = (y11 + m1) / 2.0;
	x12 = (y12 + m2) / 2.0;
	x21 = (y11 - m1) / 2.0;
	x22 = (y12 - m2) / 2.0;
	g_newVector[index1].d1 = x11;
	g_newVector[index1].d2 = x12;
	g_newVector[index2].d1 = x21;
	g_newVector[index2].d2 = x22;

}

/*****************************************************************
用途:二元一次方程第二次变换以及进行向量切换
******************************************************************/
void  DecodeSnF2AndSwap(void)
{
	SnSwap(2, 1);
	DecodeSnF2ByIndex(2, 3, 0);
	DecodeSnF2ByIndex(0, 1, 0);
	DecodeSnF2ByIndex(1, 3, 1);
	DecodeSnF2ByIndex(0, 2, 0);
	int xxxx = 1;

}

int round_double(double number)
{
	return (number > 0.0) ? (number + 0.5) : (number - 0.5);
}

/*****************************************************************
用途:创建sn浮点向量
******************************************************************/
void DecodeSn2DoubleVector(unsigned char * sn)
{
	doubleInfo d;
	d.d2 = 0;
	for (int i = 0; i < 16; i++)
	{
		sn[i] = round_double(g_snDoube[i].d1);
	}

	sn[16] = 0;
}

/*****************************************************************
用途:输出sn进行字节交换
******************************************************************/
void DecodeSnSwap(unsigned char *sn, unsigned char *newSn)
{    //0 1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
	//00 bb 22 99 55 cc 77 ee aa 11 88 33 ff 66 dd 44
	//00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff
	sn[0] = newSn[0];
	sn[1] = newSn[9];
	sn[2] = newSn[2];
	sn[3] = newSn[11];
	sn[4] = newSn[15];
	sn[5] = newSn[4];
	sn[6] = newSn[13];
	sn[7] = newSn[6];
	sn[8] = newSn[10];
	sn[9] = newSn[3];
	sn[10] = newSn[8];
	sn[11] = newSn[1];
	sn[12] = newSn[5];
	sn[13] = newSn[14];
	sn[14] = newSn[7];
	sn[15] = newSn[12];

}

void decrypt(void)
{
	//为解密后字符
	unsigned char newSn[16];

	memcpy((unsigned char*)g_key, g_const, 0x100);
	int flag = 0;
	for (int i = 0; i < 16; i++)
	{
		if ((g_snDoube[i].d1 != g_key[i].d1) || (g_snDoube[i].d2 != g_key[i].d2))
		{
			flag = 1;
			break;
		}
	}

	//第八步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth4ByIndex(i, 4);
		DecodeSnF2AndSwap2();
		Set4ByIndex(i, 4);
	}

	//第七步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth1ByIndex(i, 4);
		DecodeSnF2AndSwap2();
		Set1ByIndex(i, 4);
	}

	//第六步
	decodeSnF1(16);

	//第五步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth1ByIndex(i, 4);
		DecodeSnF2AndSwap();
		Set1ByIndex(i, 4);
	}


	//第四步,执行二元一次方程变换
	for (int i = 3; i >= 0; i--)
	{
		Fecth4ByIndex(i, 4);
		DecodeSnF2AndSwap();
		Set4ByIndex(i, 4);
	}

	//第三步,进行二元一次方程变换
	decodeSnF1(0);

	//第二步,将newSn转换到g_snDoube
	unsigned char decodeNewSn[17];
	DecodeSn2DoubleVector(decodeNewSn);

	//第一步进行sn字节交换
	DecodeSnSwap(newSn, decodeNewSn);
}
   二、check2(401710)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-12-17 12:57 被oooAooo编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//