很多新人同学都有过这样的疑问
登录这一块的逆向数据为什么一定要单独讲解?为什么一般都是采用控件登录?
那么在这里给大家做一个统一的答复
第一点,登录的协议往往比较复杂,不是你心里想的一两个封包就可以实现的,所以分析起来,比较麻烦。
第二点,出于对账号安全的考虑,账号密码的加密解密也是比较复杂的。
第三点,出于对脱机挂的防范,此处也会困难重重。
那么综上所述,直接分析协议登录视乎是一件劳民伤财,事倍攻半的事情
所以,往往采取控件登录的方式,同样可以达到不错的效果
当然还有另外一种登录的方式就是模拟登录,这种方法效率低,错误率高,不是一个很好的选择。
在这里借用腾讯公司的各登录端进行讲解分析
这些登录端看上去 形形色色
其实实际核心代码都是差不多的
其中最为典型的 QQ炫舞和QQ仙侠传代码几乎未变 其他客户端多少有一定的VM混淆和一定的调用修改等等
基本上可以说除了代码混淆以外,你分析1.2个游戏的登录程序,其他的也都了解了
其中最值得一提的是
有一些同学说有的游戏 去分析控件扫描不出来任何数据
是做了什么新的反调试?经过测试发现并非如此
而心细的同学发现在你启动腾讯统一登录器的时候,他还偷偷启动了一个进程
如下图
那么这个进程是负责什么的呢,就是负责你输入账号密码,账号密码加密解密的,然后和统一登录器进行跨进程通信
这个情况,我是在3年前勇者大冒险第一次测试的时候发现的,目前已经有好多游戏更新成这个样子
知道了原因,该怎么处理怎么处理喽
那么进入正题
拿QQ仙侠传的登录端进行登录分析(QQ炫舞等游戏一模一样),其他游戏有混淆和修改
首先我们通过控件的属性例如编辑框的字符串长度 找到控件输入CALL
因为控件输入CALL必然会改变编辑框字符串长度
只要我们在字符串长度上下写入断 通过调用关系返回即可找到控件输入CALL
而编辑框字符串长度很容易找了,用CE不断扫描字符长度即可
033A8D71 8B4B 58 mov ecx, dword ptr [ebx+58]
033A8D74 8B01 mov eax, dword ptr [ecx]
033A8D76 8B5424 10 mov edx, dword ptr [esp+10]
033A8D7A 8B00 mov eax, dword ptr [eax] ; 0785EE44 078606FC
033A8D7C 52 push edx ; 控件输入CALL
033A8D7D FFD0 call eax
033A8D7F 5F pop edi ; 033AD1F0
033A8D80 5E pop esi
033A8D81 33C0 xor eax, eax
033A8D83 5B pop ebx
033A8D84 C2 0800 retn 8
这个函数很简单
一个参数 就是输入的字符
当然我们说 他应该还有另外一个参数代表他在哪一个编辑框中输入,那根据函数约定他只能在ECX中了,经过测试,证明是对的
而该ECX就应该是控件对象
那我们第2步 需要去找到 登陆端的所有控件,往上追ECX的来源即可
通过调用关系返回
0348F123 /74 03 je short 0348F128
0348F125 |8300 01 add dword ptr [eax], 1
0348F128 \8B4424 50 mov eax, dword ptr [esp+50]
0348F12C 3BC6 cmp eax, esi
0348F12E 897424 38 mov dword ptr [esp+38], esi
0348F132 897424 14 mov dword ptr [esp+14], esi
0348F136 897424 1C mov dword ptr [esp+1C], esi
0348F13A 0F84 CC010000 je 0348F30C
0348F140 8B55 00 mov edx, dword ptr [ebp]
0348F143 50 push eax
0348F144 8B42 64 mov eax, dword ptr [edx+64]
0348F147 8BCD mov ecx, ebp
0348F149 FFD0 call eax ; 控件遍历的CALL
0348F14B 8BF8 mov edi, eax ; dd eax-30+4ac+58
0348F14D 3BFE cmp edi, esi
0348F14F 0F84 B0010000 je 0348F305
0348F155 8B5C24 40 mov ebx, dword ptr [esp+40]
0348F159 81FB 03020000 cmp ebx, 203
0348F15F 74 08 je short 0348F169
0348F161 81FB 06020000 cmp ebx, 206
0348F167 75 20 jnz short 0348F189
0348F169 8B17 mov edx, dword ptr [edi]
0348F16B 8B42 74 mov eax, dword ptr [edx+74]
0348F16E 8BCF mov ecx, edi
0348F170 FFD0 call eax
遍历过程只是结构嵌套 不在这里过多介绍
继续追寄存器
03489080 8B51 04 mov edx, dword ptr [ecx+4] ; [ebp+8] [esp+4]
03489083 8B42 04 mov eax, dword ptr [edx+4]
03489089 8078 39 00 cmp byte ptr [eax+39], 0 ; [esp+14]
0348908D 56 push esi
0348908E 57 push edi
0348908F 8B7C24 20 mov edi, dword ptr [esp+20] ; [esp+1c]
03489095 8B37 mov esi, dword ptr [edi]
03489097 3970 0C cmp dword ptr [eax+C], esi
0348909A 73 05 jnb short 034890A1
0348909C 8B40 08 mov eax, dword ptr [eax+8]
0348909F EB 04 jmp short 034890A5
034890A1 8BD0 mov edx, eax
034890A3 8B00 mov eax, dword ptr [eax]
034890A5 8078 39 00 cmp byte ptr [eax+39], 0
034890AB 8B41 04 mov eax, dword ptr [ecx+4]
034890AE 3BD0 cmp edx, eax
034890B0 895424 0C mov dword ptr [esp+C], edx
034890B4 894C24 08 mov dword ptr [esp+8], ecx
034890B8 74 0D je short 034890C7
034890BA 8B37 mov esi, dword ptr [edi]
034890BC 3B72 0C cmp esi, dword ptr [edx+C]
034890BF 72 06 jb short 034890C7
034890C1 8D4C24 08 lea ecx, dword ptr [esp+8]
034890C5 EB 0C jmp short 034890D3
034890C7 894C24 10 mov dword ptr [esp+10], ecx
034890CB 894424 14 mov dword ptr [esp+14], eax
034890CF 8D4C24 10 lea ecx, dword ptr [esp+10]
034890D3 8B11 mov edx, dword ptr [ecx]
034890D5 8B4424 1C mov eax, dword ptr [esp+1C]
eax 就是外层的第一个参数
034890D9 8B49 04 mov ecx, dword ptr [ecx+4]
034890DC 5F pop edi
034890DD 8910 mov dword ptr [eax], edx ; [ecx+20]-30+4ac+58
034890DF 8948 04 mov dword ptr [eax+4], ecx ; ecx
034890E2 5E pop esi
034890E3 83C4 10 add esp, 10
034890E6 C2 0800 retn 8
最后来源 GetWindowLong 的返回值
GetWindowLong返回我们的一个类的地址
这样就成功的追到了
控件的遍历
领取专属 10元无门槛券
私享最新 技术干货