首页
社区
课程
招聘
[原创]2016腾讯的游戏安全竞赛题PC第一题分析
发表于: 2016-3-20 10:35 7891

[原创]2016腾讯的游戏安全竞赛题PC第一题分析

2016-3-20 10:35
7891

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

上传的附件:
收藏
免费 3
支持
分享
最新回复 (6)
雪    币: 3053
活跃值: (891)
能力值: ( LV13,RANK:1300 )
在线值:
发帖
回帖
粉丝
2
下面的题不做了,没啥意思。
2016-3-20 10:46
0
雪    币: 284
活跃值: (250)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
谢谢分享,简单明了
2016-3-20 14:45
0
雪    币: 6
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢楼主分享
2016-3-20 15:27
0
雪    币: 1042
活跃值: (470)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
表示跟到关键部分就被代码恶心了.楼主分析的不错~666
2016-3-20 21:52
0
雪    币: 12
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
关键代码定位不到啊
2017-4-24 15:14
0
雪    币: 28
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2017-5-2 21:31
0
游客
登录 | 注册 方可回帖
返回
//