先Mark:附上序列号的逆运算过程(RC6),当然这是假设已经在内存中已经寻找到该sn的编码后的结果,见下面g_data
此代码中分别附有正向编码和逆向编码过程,剩余分析后续补充:)
// calc_sn.cpp : Defines the entry point for the console application.
//
#include <Windows.h>
typedef struct _context
{
unsigned int unkonwn1;
unsigned int *sn;
int len;
unsigned int key_a;
unsigned int key_b;
unsigned int key_table[32];
unsigned int key_d;
unsigned int key_e;
}context;
unsigned int shrl(unsigned int a1, char a2)
{
return (a1 << a2) | (a1 >> (32 - a2));
}
unsigned int __stdcall inner_log(int a1)
{
return (unsigned int)(a1 << (32 - (unsigned __int64)(signed __int64)(5))) >> (32- (unsigned __int64)(signed __int64)(5));
}
unsigned int shlr(unsigned int a1, char a2)
{
return (a1 >> a2) | (a1 << (32 - a2));
}
unsigned char data[] = {
0xFC, 0x42, 0x43, 0xA4, 0x54, 0x76, 0x72, 0xB2, 0x9F, 0x11, 0xF9, 0xD3, 0x52, 0x4F, 0xF0, 0x8C,
0xBE, 0x64, 0x65, 0x44, 0x2E, 0x0A, 0xD4, 0xB4, 0x67, 0x64, 0x96, 0x02, 0xA5, 0xBA, 0xF2, 0xA3,
0x40, 0x30, 0xD9, 0x89, 0x8C, 0x36, 0x4B, 0xDC, 0xAB, 0x2F, 0x4D, 0x45, 0xD7, 0x95, 0x07, 0xC4,
0x3B, 0xFD, 0x98, 0xE1, 0x02, 0x2F, 0x7D, 0x2F, 0xDB, 0xAA, 0x09, 0x37, 0xD2, 0x2B, 0x88, 0xAC,
0xF5, 0x9B, 0x55, 0x20, 0xF6, 0x01, 0xB5, 0x69, 0x98, 0x4F, 0xD1, 0xA9, 0x70, 0x40, 0x9E, 0xDC,
0x2B, 0x7D, 0xB9, 0x1F, 0x1F, 0xB2, 0xA0, 0x14, 0x5F, 0x49, 0xE1, 0xEA, 0x50, 0x1E, 0x41, 0xD8,
0xEA, 0x22, 0xD6, 0x94, 0xE5, 0x8F, 0x56, 0xCD, 0x36, 0x63, 0x10, 0x32, 0x1F, 0xF0, 0xF7, 0x09,
0xD9, 0xF6, 0x5C, 0x5E, 0xA0, 0x25, 0x2F, 0xBE, 0x92, 0x63, 0x9C, 0x2E, 0xD1, 0x6D, 0xEA, 0xBB
};
/*
0xF5, 0x9B, 0x55, 0x20, 0xF6, 0x01, 0xB5, 0x69, 0x98, 0x4F, 0xD1, 0xA9,
0x70, 0x40, 0x9E, 0xDC, 0x2B, 0x7D, 0xB9, 0x1F, 0x1F, 0xB2, 0xA0, 0x14, 0x5F, 0x49, 0xE1, 0xEA,
0x50, 0x1E, 0x41, 0xD8, 0xEA, 0x22, 0xD6, 0x94, 0xE5, 0x8F, 0x56, 0xCD, 0x36, 0x63, 0x10, 0x32,
0x1F, 0xF0, 0xF7, 0x09, 0xD9, 0xF6, 0x5C, 0x5E, 0xA0, 0x25, 0x2F, 0xBE, 0x92, 0x63, 0x9C, 0x2E,
0xD1, 0x6D, 0xEA, 0xBB, 0x6D, 0x07, 0xAF, 0x7F, 0x4C, 0xFA, 0xD7, 0x9B
};
*/
void encrypt(context *ctx, bool encrypt)
{
int *cur_dword; // esi@2
unsigned int *tmp_key; // ebx@2
int fourth_dword; // eax@3
unsigned int v10; // ST28_4@3
unsigned int v14; // eax@3
bool v18; // zf@3
signed int block_size; // [sp+24h] [bp-Ch]@2
unsigned int offset = 0;
if (ctx->len)
{
if (encrypt)
{
do
{
cur_dword = (int *)((unsigned char*)ctx->sn + offset);
tmp_key = &ctx->key_table[31];
block_size = 16;
*cur_dword -= ctx->key_d;
cur_dword[2] -= ctx->key_e;
do
{
fourth_dword = cur_dword[3];
cur_dword[3] = cur_dword[2];
cur_dword[2] = cur_dword[1];
cur_dword[1] = *cur_dword;
*cur_dword = fourth_dword;
v10 = shrl(cur_dword[1] * (2 * cur_dword[1] + 1), 5); // 调换前5个比特与后27个比特
v14 = shrl((DWORD)cur_dword[3] * (2 * (DWORD)(cur_dword[3]) + 1), 5);
*cur_dword = v10 ^ shlr(*cur_dword - *(tmp_key - 1), inner_log(v14));
cur_dword[2] = ((DWORD)v14) ^ shlr(cur_dword[2] - *tmp_key, inner_log(v10));;
tmp_key -= 2;
v18 = block_size-- == 1;
} while (!v18);
offset += 16;
cur_dword[1] -= ctx->key_a;
cur_dword[3] -= ctx->key_b;
} while (offset < ctx->len);
}
else
{
do
{
cur_dword = (int *)((unsigned char*)ctx->sn + offset);
tmp_key = &ctx->key_table[-1];
block_size = 16;
cur_dword[1] += ctx->key_a;
cur_dword[3] += ctx->key_b;
do
{
tmp_key += 2;
v10 = shrl(cur_dword[1] * (2 * cur_dword[1] + 1), 5); // 调换前5个比特与后27个比特
v14 = shrl((DWORD)cur_dword[3] * (2 * (DWORD)(cur_dword[3]) + 1), 5);
int y = *cur_dword ^v10;
int x = shrl(y, inner_log(v14));
*cur_dword = x + *(tmp_key - 1);
int n = cur_dword[2] ^ ((DWORD)v14);
int m = shrl(n, inner_log(v10));
cur_dword[2] = m + *tmp_key;
fourth_dword = *cur_dword;
*cur_dword = cur_dword[1];
cur_dword[1] = cur_dword[2];
cur_dword[2] = cur_dword[3];
cur_dword[3] = fourth_dword;
v18 = block_size-- == 1;
} while (!v18);
*cur_dword += ctx->key_d;
cur_dword[2] += ctx->key_e;
offset += 16;
} while (offset < ctx->len);
}
}
}
char sn[33] = "11111111111111111111111111111111";
unsigned char g_data[32] = {
0x4B, 0x7D, 0x6F, 0x22, 0xBD, 0xEA, 0x61, 0xC3, 0x0B, 0xE7, 0xB2, 0xD9, 0x2C, 0x6B, 0x41, 0x88,
0x5D, 0x71, 0x27, 0x85, 0xBA, 0x71, 0xF0, 0xB9, 0x23, 0x77, 0x28, 0x6C, 0xFC, 0x36, 0xA6, 0xD0
};
int main(int argc, char* argv[])
{
context ctx = { 0 };
ctx.sn = (unsigned int*)sn;
ctx.len = 32;
ctx.key_a = 0x5bf76637;
ctx.key_b = 0x4748da7a;
memcpy(ctx.key_table, data, 4 * 32);
ctx.key_d = 0x7faf076d;
ctx.key_e = 0x9bd7fa4c;
encrypt(&ctx, 1);
encrypt(&ctx, 0);
ctx.sn = (unsigned int*)g_data;
encrypt(&ctx, 0);
return 0;
}
[峰会]看雪.第八届安全开发者峰会10月23日上海龙之梦大酒店举办!