-
-
[原创]看雪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编辑
,原因:
赞赏
他的文章
- 看雪CTF 2019总决赛 第六题 三道八佛 IDA脱壳脚本 5668
- [原创]看雪CTF2019Q3第四题WP 5933
- [原创]看雪CTF2019Q3 第二题WP 6759
- [2019看雪CTF晋级赛Q3第九题WP 12490
- [原创]看雪CTF2019晋级赛Q2第三题 5021
看原图
赞赏
雪币:
留言: