Tencent2016A 注册过程分析
1. 查找注册函数
使用OD进行调试,发现无壳无反调试。
在 GetWindowTextW GetDlgItemTextW SetWindowTextW 设置断点无法拦截,在ctrl+n发现有SendMessage导入函数,猜测使用的消息方式,WM_GETTEXT。
通过 SendMessage 可以顺利定位到注册函数。
2. 分析注册流程
用户名预处理
*(DWORD *)v9 += name_length * (DWORD)(20160126+i) * name_buffer[j];
可以借助IDA 处理一下。
用户名 长度为 6-20个字符之间
用户名 二次处理
name_[i] = (*(int*)&buf[i * 4]) / 10;
基本上是 除10 被VC 优化过也不是那么好看出来。
00292100 . 33F6 XOR ESI,ESI
00292102 > 8B8C34 8800000>MOV ECX,DWORD PTR SS:[ESP+ESI+88] ; name_b/10
00292109 . B8 67666666 MOV EAX,66666667
0029210E . F7E9 IMUL ECX
00292110 . C1FA 02 SAR EDX,2
00292113 . 8BCA MOV ECX,EDX
00292115 . C1E9 1F SHR ECX,1F
00292118 . 03CA ADD ECX,EDX
0029211A . 8B5424 24 MOV EDX,DWORD PTR SS:[ESP+24]
0029211E . 2BD7 SUB EDX,EDI
00292120 . 894C34 2C MOV DWORD PTR SS:[ESP+ESI+2C],ECX
00292124 . 3BF2 CMP ESI,EDX
00292126 . 72 09 JB SHORT Tencent2.00292131
用户名与KEY比较
这里的key值被处理过,后面再谈
00292140 . 8B4C24 2C MOV ECX,DWORD PTR SS:[ESP+2C] ; name_begin+0
00292144 . 8B4424 50 MOV EAX,DWORD PTR SS:[ESP+50] ; key_4
00292148 . 8D1408 LEA EDX,DWORD PTR DS:[EAX+ECX] ; add (name_0+key_4)
0029214B . 8B4C24 48 MOV ECX,DWORD PTR SS:[ESP+48] ; key_2
0029214F . 3BD1 CMP EDX,ECX ; cmp(key_2)
00292151 . 75 58 JNZ SHORT Tencent2.002921AB
00292153 . 8B5424 30 MOV EDX,DWORD PTR SS:[ESP+30] ; name_1
00292157 . 03D1 ADD EDX,ECX ; add(name_1,key_2)
00292159 . 03C0 ADD EAX,EAX ; key_4+key_4
0029215B . 3BD0 CMP EDX,EAX ; cmp(key_4+key4)
0029215D . 75 4C JNZ SHORT Tencent2.002921AB
0029215F . 8B4C24 4C MOV ECX,DWORD PTR SS:[ESP+4C] ; key_3
00292163 . 8B4424 34 MOV EAX,DWORD PTR SS:[ESP+34] ; name_2
00292167 . 8B5424 40 MOV EDX,DWORD PTR SS:[ESP+40] ; key_0
0029216B . 8D3401 LEA ESI,DWORD PTR DS:[ECX+EAX] ; add(name_2,key_3)
0029216E . 3BF2 CMP ESI,EDX ; cmp(key_0)
00292170 . 75 39 JNZ SHORT Tencent2.002921AB
00292172 . 8B7424 38 MOV ESI,DWORD PTR SS:[ESP+38] ; name_3
00292176 . 03F2 ADD ESI,EDX ; add(name_3,key_0)
00292178 . 03C9 ADD ECX,ECX ; key_3+key_3
0029217A . 3BF1 CMP ESI,ECX ; cmp(key_3+key_3)
0029217C . 75 2D JNZ SHORT Tencent2.002921AB
0029217E . 8B5424 3C MOV EDX,DWORD PTR SS:[ESP+3C] ; name_4
00292182 . 8B4C24 44 MOV ECX,DWORD PTR SS:[ESP+44] ; key_1
00292186 . 03CA ADD ECX,EDX ; add(name_4,key_1)
00292188 . 8D1440 LEA EDX,DWORD PTR DS:[EAX+EAX*2] ; name_2*3
0029218B . 3BCA CMP ECX,EDX ; cmp(name_2*3)
通过分析得出用户名与key关系的公式
// k1 = n2*3 – n4
// n3+k0 = k3*2
// n2+k3 = k0
// n0+k4 = k2
// n1+k2 = 2k4
KEY值得变换
const char* ch_index = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@%";
将输入key通过ch_index 获取索引
之后通过 下面方式将索引去除前2比特合成新的key值
00291A8D |. 8B4C24 18 |MOV ECX,DWORD PTR SS:[ESP+18]
00291A91 |. 8AC1 |MOV AL,CL
00291A93 |. 02C0 |ADD AL,AL ; key[0]+key[0]
00291A95 |. 8AD5 |MOV DL,CH
00291A97 |. C0EA 04 |SHR DL,4
00291A9A |. 80E2 03 |AND DL,3
00291A9D |. 02C0 |ADD AL,AL
00291A9F |. 02D0 |ADD DL,AL
00291AA1 |. 8A4424 1A |MOV AL,BYTE PTR SS:[ESP+1A] ; key[2]
00291AA5 |. 885424 14 |MOV BYTE PTR SS:[ESP+14],DL
00291AA9 |. 8AD0 |MOV DL,AL
00291AAB |. C0EA 02 |SHR DL,2
00291AAE |. 8ACD |MOV CL,CH
00291AB0 |. C0E0 06 |SHL AL,6
00291AB3 |. 024424 1B |ADD AL,BYTE PTR SS:[ESP+1B] ; key[3]
00291AB7 |. 80E2 0F |AND DL,0F
00291ABA |. C0E1 04 |SHL CL,4
00291ABD |. 32D1 |XOR DL,CL
00291ABF |. 885424 15 |MOV BYTE PTR SS:[ESP+15],DL
00291AC3 |. 884424 16 |MOV BYTE PTR SS:[ESP+16],AL
Y为索引缓冲区,x为新key值,每4字节一组。
unsigned char a0 = y[i + 0] * 4;
unsigned char a1 = (y[i+1] >> 4) & 0x03;
unsigned char a2 = a0 + a1; // x[0]
x[j+0] = a2;
unsigned char b0 = (y[i + 1] << 4);
unsigned char b1 = (y[i+2] >> 2) & 0x0f;
unsigned char b2 = b0^b1; // x[1]
x[j+1] = b2;
unsigned char c0 = (y[i+2] << 6)+y[i+3]; // x[2]
x[j+2] = c0;
keygen.7z
Tencent2016A.7z
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课