void test(unsigned char *ptr, unsigned char *key)
{
int addr = (int)ptr;
for (int i = 0; i < sizeof(rsa_n); i += 2)
{
int P1 = (addr + i) & 0xFFFF;
int P2 = ((addr + i) >> 4) & 0xFFFF;
int A = ~(~(*(unsigned short *)&rsa_n[i]) + P1);
int K = A ^ (*(unsigned short *)&ptr[i]);
int X = K - P2 - 0x37;
int vk = P2 + X + 0x37;
printf("%04X->%04X, ", (unsigned short)K, (unsigned short)X);
if (i % 8 == 0)
printf("\n");
}
for (int i = 0; i < 20; i++)
{
printf("%02X ", key[i]);
}
printf("\n");
}
#define STACK_SIZE 0x18C
unsigned char *find_key(void *stack, DWORD addr)
{
int first = 0;
unsigned char *key = 0;
unsigned char *ptr = (unsigned char *)stack;
for (int i = 0; i < STACK_SIZE; i+=4)
{
if (addr == *(DWORD *)&ptr[i])
{
if (first != 0)
{
if (*(DWORD *)&ptr[i + 4] != 0x80)
{
key = &ptr[i + 4];
break;
}
}
if (*(DWORD *)&ptr[i + 4] == 0x80)
{
first = 1;
}
}
}
return key;
}
6. 解密序列号
必须先拥有一份序列号从中获取product code 和usr data
解密序列号
首先使用BASE64 进行解码,再使用N进行解密找到product code 和usr data
0x00B9B630 00 02 6b 64 b8 f2 d3 f7 e7 f0 79 65 b8 00 01 01 ..kd??????ye?...
0x00B9B640 02 04 74 65 73 74 03 11 74 65 73 74 40 73 65 6e ..test..test@sen
0x00B9B650 73 65 2e 63 6f 6d 2e 63 6e 05 1a 0a e4 07 07 59 se.com.cn...?..Y
0x00B9B660 51 24 25 a4 d1 bd 51 ff 38 fb 3f 2e 69 88 02 c1 Q$%???Q.8??.i?.?
0x00B9B670 e9 72 48 26 5b 84 1c c4 6e bf 53 af 3d e3 75 df ?rH&[?.?n?S?=?u?
0x00B9B680 2e cc c1 26 1a 01 71 65 af 8b 3f 00 13 03 27 8f .??&..qe???...'?
0x00B9B690 ca ef 6f d7 da 4f e5 f8 2d 72 68 e7 36 0e a9 1f ??o??O??-rh?6.?.
0x00B9B6A0 d8 90 33 94 83 b1 a9 e9 a0 4a 4f e2 2f 69 cc 1c ??3??????JO?/i?.
0x00B9B6B0 ae a4 2f fc 3d ad 2f e5 01 27 b7 ae c6 b8 a2 53 ??/?=?/?.'?????S
0x00B9B6C0 e8 60 c3 ea 73 09 28 d9 89 5f 9f 47 04 e1 7a d0 ?`??s.(??_?G.?z?
0x00B9B6D0 5d 38 90 7d cd c8 84 f3 b1 86 4a ea 33 09 e6 e1 ]8?}??????J?3.??
0x00B9B6E0 27 e3 77 10 33 31 75 9f 33 71 37 15 db 94 b8 13 '?w.31u?3q7.???.
0x00B9B6F0 9e 54 9a 42 cf c8 6b 8a 07 36 28 85 c6 28 ff 33 ?T?B??k?.6(??(.3
0x00B9B700 5d c2 59 ef 0b 52 18 a1 66 29 1d 36 fc aa 0e 4d ]?Y?.R.?f).6??.M
0x00B9B710 3b a0 56 33 8e d5 6d 12 c9 e0 59 65 c7 3e 75 af ;?V3??m.??Ye?>u?
0x00B9B720 51 a4 71 6d 42 94 9a 49 e9 2f 5b 90 af 4a 04 e6 Q?qmB??I?/[??J.?
Tag定义如下:
enum eChunks
{
SERIAL_CHUNK_VERSION = 0x01, // 1 byte of data - version
SERIAL_CHUNK_USER_NAME = 0x02, // 1 + N bytes - length + N bytes of customer's name (without enging \0).
SERIAL_CHUNK_EMAIL = 0x03, // 1 + N bytes - length + N bytes of customer's email (without ending \0).
SERIAL_CHUNK_HWID = 0x04, // 1 + N bytes - length + N bytes of hardware id (N % 4 == 0)
SERIAL_CHUNK_EXP_DATE = 0x05, // 4 bytes - (year << 16) + (month << 8) + (day)
SERIAL_CHUNK_RUNNING_TIME_LIMIT = 0x06, // 1 byte - number of minutes
SERIAL_CHUNK_PRODUCT_CODE = 0x07, // 8 bytes - used for decrypting some parts of exe-file
SERIAL_CHUNK_USER_DATA = 0x08, // 1 + N bytes - length + N bytes of user data
SERIAL_CHUNK_MAX_BUILD = 0x09, // 4 bytes - (year << 16) + (month << 8) + (day)
SERIAL_CHUNK_END = 0xFF // 4 bytes - checksum: the first four bytes of sha-1 hash from the data before that chunk
};
#define KEY 0x01
if (key[0] == KEY && key[1] == KEY)
{
for (int i = 0; i < sizeof(rsa_n); i+=2)
{
int P1 = (addr + i) & 0xFFFF;
int P2 = ((addr + i) >> 4) & 0xFFFF;
unsigned short K = P2 + KEY + 0x37;
unsigned short C = *(unsigned short *)&ptr[i];
unsigned short M = ~(~(C^K) - P1);
*(unsigned short *)&rsa_n[i] = M;
}
write_rsa_n(rsa_n, sizeof(rsa_n));
}
得到的RSA-N (BigNum)如下:
解密后的结果:
7. 替换RSA-N
通过对KEY 进行修改并且对RSA-N 进行加密进行替换:
#define KEY 0x01
for (int i = 0; i < sizeof(rsa_n); i+=2)
{
int P1 = (addr + i) & 0xFFFF;
int P2 = ((addr + i) >> 4) & 0xFFFF;
unsigned short K = P2 + KEY + 0x37;
unsigned short M = *(unsigned short *)&rsa_n[i];
unsigned short A = ~M + P1;
unsigned short C = (~A) ^ K;
*(unsigned short *)&ptr[i] = C;
}
// SHA1-SIZE
memset(key, KEY, 20);