[Asm] 纯文本查看 复制代码
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
typedef unsigned char UINT8;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
typedef unsigned __int128 UINT128;
//typedef unsigned __int256 UINT256;
/// 001EE150 00 6C 6F 76 65 5F 77 69 74 68 5F 65 00 00 00 00 .love_with_e....
//const char * love = "love_with_e";
const char love_base[] = {0x00, 0x6C, 0x6F, 0x76, 0x65, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x5F, 0x65, 0x00, 0x00, 0x00, 0x00};
/// 001EE160 00 31 37 36 30 31 37 5E 35 32 70 6F 6A 69 65 00 .176017^52pojie.
const char name_base[] = {0x00, 0x31, 0x37, 0x36, 0x30, 0x31, 0x37, 0x5E, 0x35, 0x32, 0x70, 0x6F, 0x6A, 0x69, 0x65, 0x00};
/*
001EE170 32 33 34 36 37 39 41 43 44 45 46 47 48 4A 4B 4C 234679ACDEFGHJKL
001EE180 4D 4E 50 52 54 55 56 57 58 59 5A 61 63 64 65 66 MNPRTUVWXYZacdef
*/
const char key_base[] = {
0x32, 0x33, 0x34, 0x36, 0x37, 0x39, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C,
0x4D, 0x4E, 0x50, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x63, 0x64, 0x65, 0x66
};
const char idx_base[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// 234679
0x00, 0x06, 0x00, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, /// ACDEFGHJKLMN
0x12, 0x00, 0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, /// PRTUVWXYZ
0x00, 0x1B, 0x00, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// acdef
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
///9F7HA36XfHaNDDC7L77HEPeYZ4Z44672
///CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49
char * base32table = "234679ACDEFGHJKLMNPRTUVWXYZacdef";
struct _permute_box {
UINT8 idx1;
UINT8 idx2;
UINT8 data[256];
};
typedef _permute_box PBOX;
int GbkToUtf8(const char *src_str, char * dst_str, int length);
int base32encode(UINT8 * data, int size, char * result);
void logger(const char * title, UINT8 * logMsg, int rows, int cols);
int generate(char * name, int ver, char * key);
bool check(char * name, char * key);
int main(int argc, char** argv) {
char name[] = "solly@52pojie.cn";
char key1[] = "0123456789ABCDEF0123456789ABCDEF\0";
char key2[] = "0123456789ABCDEF0123456789ABCDEF\0";
//char name[] = "°®·ÉµÄè @52pojie";
//char key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49\0";
char pname[2048];
int n = GbkToUtf8(name, pname, 2048);
int m = generate(pname, 1, key1);
int k = generate(pname, 2, key2);
printf("\n\nYour name: %s\n Key pro: %s\n Key full: %s\n\n", name, key1, key2);
bool ret1 = check(pname, key1);
bool ret2 = check(pname, key2);
if(ret1 && ret2) {
printf("Check successful.\n");
} else {
printf("Check failure.\n");
}
/// 2A 88 C3 04 78 FB 37 14 20 E4 79 08 C4 CB D9 D0 B4 21 0C 80
//UINT8 data[] = {0x3C, 0x2F, 0xC3, 0x14, 0xFD, 0x44, 0x99, 0x70, 0xC5, 0x81, 0xEE, 0x76, 0x38, 0xA0, 0x89, 0x21, 0x8E, 0x4F, 0x4C, 0x45};
//char test_key[33];
//int k = base32encode(data, 20, test_key);
//printf("n = %d, key = %s\n", k, test_key);
return 0;
}
int base32encode(UINT8 * data, int size, char * result) {
char result_tmp[9];
UINT8 d0,d1,d2,d3,d4,d5,d6,d7;
result_tmp[8] = '\0';
int k=0;
for(int i=0; i<size; i+=5) {
d0 = (data[i+0]>>3) & 0x1F;
result_tmp[0] = base32table[d0];
d1 = ((data[i+0]<<2) & 0x1C) | ((data[i+1]>>6) & 0x03);
result_tmp[1] = base32table[d1];
d2 = (data[i+1]>>1) & 0x1F;
result_tmp[2] = base32table[d2];
d3 = ((data[i+1]<<4) & 0x10) | ((data[i+2]>>4) & 0x0F);
result_tmp[3] = base32table[d3];
d4 = ((data[i+2]<<1) & 0x1E) | ((data[i+3]>>7) & 0x01);
result_tmp[4] = base32table[d4];
d5 = (data[i+3]>>2) & 0x1F;
result_tmp[5] = base32table[d5];
d6 = ((data[i+3]<<3) & 0x18) | (data[i+4]>>5 & 0x07);
result_tmp[6] = base32table[d6];
d7 = (data[i+4]) & 0x1F;
result_tmp[7] = base32table[d7];
for(int j=0; j<8; j++) {
result[k+j] = result_tmp[j];
}
k+=8;
result[k] = '\0';
}
return k;
}
PBOX * permute(PBOX * result, char * data, int length) {
UINT8 key[1024];
//logger("permute1", NULL, 0, 0);
for(int i=0; i<16; i++) {
key[i] = name_base[i];
}
strncpy((char *)&key[16], data, length);
//logger("data_buff", data_buff, 3, 16);
result->idx1 = 0;
result->idx2 = 0;
for(int i=0; i<256; i++) {
result->data[i] = (i + 0x5C);
}
//logger("idx", &result->idx1, 1, 2);
//logger("base", result->data, 16, 16);
int len1 = length + 16; //// len + sizeof(name_base)
UINT8 i = 0, j = 0;
for(int i=0; i<256; i++) {
UINT8 tmp = result->data[i];
j = j + tmp - key[i % len1];
//// sawp()
result->data[i] = result->data[j];
result->data[j] = tmp;
}
//logger("idx", &result->idx1, 1, 2);
//logger("permute-1", result->data, 16, 16);
i=result->idx1;
j=result->idx2;
int len2 = len1 + 256; ///
//printf("len2 = %d\n", len2);
for(int k=0; k<len2; k++) {
i = i + 1;
j = j + result->data[i];
//// swap()
UINT8 tmp = result->data[i];
result->data[i] = result->data[j];
result->data[j] = tmp;
}
result->idx1 = i;
result->idx2 = j;
//logger("idx", &result->idx1, 1, 2);
//logger("permute-2", result->data, 16, 16);
return result;
}
bool check(char * name, char * key) {
UINT8 name_buff[60];
PBOX name_permuted;
UINT8 key_buff[32];
int len_name = strlen(name);
len_name = (len_name<60) ? len_name : 59;
for(int i=0; i<len_name; i++) {
name_buff[i] = name[i];
}
name_buff[len_name] = '\0';
//printf("name: %s\n", name_buff);
int len_key = strlen(key); /// 0x20
//printf("key length: %d\n", len_key);
permute(&name_permuted, (char*)name_buff, len_name);
//printf("permuted1\n");
if(len_key) {
//UINT32 shift_data = 0, shift_bits = 0;
UINT64 shift_data = 0;
//UINT128 shift_data = 0;
UINT8 shift_bits = 0;
int kk = 0;
UINT8 i = name_permuted.idx1;
UINT8 j = name_permuted.idx2;
for(int k=0; k<len_key; k++) {
int idx = key[k]; //// key[] = "CMWcA9CdDPHW3NH3dYa6ND7E7AC7eR49"
//printf("check idx: %02X\n", idx);
shift_bits += 5;
///
shift_data = (shift_data << 5) | idx_base[idx];
if(shift_bits>=8) {
i = i + 1;
j = j + name_permuted.data[i];
//// swap()
UINT8 tmp = name_permuted.data[i];
name_permuted.data[i] = name_permuted.data[j];
name_permuted.data[j] = tmp;
////
UINT8 t = name_permuted.data[i] + name_permuted.data[j];
////
shift_bits -= 8;
//printf("%d,", shift_bits); /// 2,4,1,3,0,2,4,1,3,0,2,4,1,3,0,2,4,1,3,0
UINT32 data = (shift_data >> shift_bits);
////
key_buff[kk++] = (t ^ (UINT8)data);
//printf("data =%08X, t=%02X, key_buff = %02X, ", data, t, key_buff[kk-1]);
}
//printf("\n");
}
name_permuted.idx1 = i;
name_permuted.idx2 = j;
}
logger("check_key_decoded", key_buff, 1, 20);
//logger("idx", &name_permuted.idx1, 1, 2);
//logger("name_permuted1", name_permuted.data, 16, 16);
char bl = 0;
char * ptrPWD = (char *)&love_base[1];
permute(&name_permuted, ptrPWD, 11);
//printf("permuted2\n");
//logger("generate name_permuted.idx", &name_permuted.idx1, 1, 2);
//logger("check name_permuted", name_permuted.data, 16, 16);
UINT8 dh = name_permuted.idx2;
UINT8 dl = name_permuted.idx1;
for(int i=0; i<18; i++) {
dl ++;
name_permuted.idx1 = dl;
UINT32 idx0 = dl;
dh += name_permuted.data[idx0];
name_permuted.idx2 = dh;
UINT8 idx1 = (unsigned)dh;
UINT8 idx2 = (unsigned)dl;
UINT8 a = name_permuted.data[idx1];
UINT8 c = name_permuted.data[idx2];
name_permuted.data[idx2] = a;
name_permuted.data[idx1] = c;
dh = name_permuted.idx2;
dl = name_permuted.idx1;
UINT8 idx3 = (unsigned)dh;
UINT8 idx4 = (unsigned)dl;
c = name_permuted.data[idx3];
c += name_permuted.data[idx4];
c ^= key_buff[i]; // c == key_buff[i], ok
bl |= c; //// result = 0, ok
}
//logger("key_permuted", key_buff, 2, 16);
//logger("idx", &name_permuted.idx1, 1, 2);
//logger("name_permuted2", name_permuted.data, 16, 16);
dl++;
name_permuted.idx1 = dl;
unsigned int idx0 = dl;
dh += name_permuted.data[idx0];
name_permuted.idx2 = dh;
unsigned int idx1 = dh;
unsigned int idx2 = dl;
char a = name_permuted.data[idx1];
char c = name_permuted.data[idx2];
name_permuted.data[idx2] = a;
name_permuted.data[idx1] = c;
unsigned int idx3 = name_permuted.idx2;
unsigned int idx4 = name_permuted.idx1;
dh = name_permuted.data[idx3];
dh += name_permuted.data[idx4];
dh ^= key_buff[18]; /// flag1 = 0x3E or 0x3D
//logger("key_permuted", key_buff, 2, 16);
//logger("idx", &name_permuted.idx1, 1, 2);
//logger("name_permuted3", name_permuted.data, 16, 16);
//// crc
dl = 0xFF; //dl |= 0xFF;
for(int i=0; i<19; i++) {
char al = key_buff[i];
dl = (dl>>5) | (dl<<3);
dl ^= al;
}
char al = key_buff[19]; /// flag2
al ^= dl; /// dl == al, ok
al |= bl; /// bl = 0, ok
/// al=0x8C, dl=0x5F, bl=0xFF, dh=0xFB
return (al == 0) && ((dh == 0x3E) || (dh == 0x3D));
}
int generate(char * name, int ver, char * key) {
UINT8 name_buff[60];
PBOX name_permuted;
UINT8 key_buff[32];
UINT8 key_final[36];
int len_name = strlen(name);
len_name = (len_name<60) ? len_name : 59;
for(int i=0; i<len_name; i++) {
name_buff[i] = name[i];
}
name_buff[len_name] = '\0';
//printf("name: %s\n", name_buff);
char bl = 0;
char * ptrPWD = (char *)&love_base[1];
permute(&name_permuted, ptrPWD, 11);
//printf("permuted2\n");
//logger("generate name_permuted.idx", &name_permuted.idx1, 1, 2);
//logger("generate name_permuted", name_permuted.data, 16, 16);
UINT8 i = name_permuted.idx1; /// dl
UINT8 j = name_permuted.idx2; /// dh
for(int k=0; k<18; k++) {
i += 1;
j += name_permuted.data[i];
UINT8 tmp = name_permuted.data[i];
name_permuted.data[i] = name_permuted.data[j];
name_permuted.data[j] = tmp;
key_buff[k] = name_permuted.data[i] + name_permuted.data[j];
}
name_permuted.idx1 = i;
name_permuted.idx2 = j;
//logger("key_permuted", key_buff, 1, 18);
//logger("idx", &name_permuted.idx1, 1, 2);
//logger("name_permuted2", name_permuted.data, 16, 16);
i += 1;
j += name_permuted.data[i];
UINT8 tmp = name_permuted.data[i];
name_permuted.data[i] = name_permuted.data[j];
name_permuted.data[j] = tmp;
UINT8 ver_xor = name_permuted.data[i] + name_permuted.data[j];
key_buff[18] = (ver == 1) ? (ver_xor ^ 0x3E) : (ver_xor ^ 0x3D); /// flag1 = 0x3E or 0x3D
//logger("key_permuted", key_buff, 2, 16);
//logger("idx", &name_permuted.idx1, 1, 2);
//logger("name_permuted3", name_permuted.data, 16, 16);
//// crc
UINT8 crc = 0xFF; //dl |= 0xFF;
for(int k=0; k<19; k++) {
char al = key_buff[k];
crc = (crc>>5) | (crc<<3);
crc ^= al;
}
key_buff[19] = crc;
key_buff[20] = '\0';
logger("generated key_binary[]", key_buff, 1, 20);
int len_key = 0x20;//strlen(key); /// 0x20
//printf("key length: %d\n", len_key);
permute(&name_permuted, (char*)name_buff, len_name);
//printf("permuted1\n");
i = name_permuted.idx1;
j = name_permuted.idx2;
//printf("i=%d, j=%d\n", i, j);
for(int k=0; k<20; k++) {
i = i + 1;
j = j + name_permuted.data[i];
//// swap()
UINT8 tmp = name_permuted.data[i];
name_permuted.data[i] = name_permuted.data[j];
name_permuted.data[j] = tmp;
}
name_permuted.idx1 = i;
name_permuted.idx2 = j;
UINT32 shift_data = 0;
UINT32 shift_data_next = 0;
int shift_bits = 0;
int shift_bits_orig[] = { 5, 10, 7, 12, 9, 6, 11, 8, 5, 10, 7, 12, 9, 6, 11, 8, 5, 10, 7, 12, 9, 6, 11, 8, 5, 10, 7, 12, 9, 6, 11, 8};
int shift_bits_sub8[] = {-3, 2, -1, 4, 1, -2, 3, 0, -3, 2, -1, 4, 1, -2, 3, 0, -3, 2, -1, 4, 1, -2, 3, 0, -3, 2, -1, 4, 1, -2, 3, 0};
int kk = 20; /// 0~19
for(int k=31; k>=0; k--) {
shift_bits += 5;
if(shift_bits_sub8[k] >= 0) {
key_buff[--kk] ^= name_permuted.data[i] + name_permuted.data[j];
//// key_buff[]: 2A 88 C3 04 78 FB 37 14 20 E4 79 08 C4 CB D9 D0 B4 21 0C 80
UINT8 tmp = name_permuted.data[j];
name_permuted.data[j] = name_permuted.data[i];
name_permuted.data[i] = tmp;
j = j - name_permuted.data[i];
i = i - 1;
}
}
base32encode(key_buff, 20, (char *)key_final);
key_final[32] = '\0';
name_permuted.idx1 = i;
name_permuted.idx2 = j;
//logger("generated key_final[]", key_final, 2, 16);
if(key) {
strcpy(key, (char *)key_final);
}
return strlen((char*)key_final);
}
void logger(const char * title, UINT8 * logMsg, int rows, int cols) {
if(title != NULL) {
printf("\n%s:\n", title);
} else {
printf("\nlogger:\n");
}
if(logMsg != NULL) {
for(int i=0; i<rows; i++) {
for(int j=0; j<cols; j++) {
printf(" %02X", (unsigned char)logMsg[i*cols+j]);
}
printf("\n");
}
printf("\n");
} else {
printf("log has no message!\n\n");
}
}
int GbkToUtf8(const char *src_str, char * dst_str, int length) {
wchar_t wstr[4096];
if(dst_str == NULL) {
return 0;
}
int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0);
if(len>4094) {
len = 4094;
}
memset(wstr, 0, len + 2);
MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
if(len>=length) {
len = length-1;
}
memset(dst_str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, dst_str, len, NULL, NULL);
return len;
}