本帖最后由 Sendige 于 2019-12-11 23:11 编辑
大家好,我是Sendige,很久没有给大家带来算法分析了,今天闲来没事做,想玩一下桌球,但是自己技术不行,所以想找一个辅助来辅助下我的技术,记得之前自己破解过一款,
时隔多年,我又亲自对他开刀,惊喜的是,这个辅助更新了,好了,废话不多说,走起!
下面因为我注册的账号是用了自己的qq号进行注册,为了避免有打广告的嫌疑,下面的账号用了wuaipojie进行脱敏处理,实际上不是这个的,所以你们要验证我的md5加密结果和教程里的是否一样是行不通的,望知悉。
VB写的验证,不多说,可以跑VB按钮事件脚本下断点。
开始之前请自己注册好一个账号,后面用来进行数据分析使用,我们直接来到按钮事件
前面一大段都是在判断账号密码有没有输入,版本号是不是最新之类的,所以我们可以忽略,我们来到发送封包那里。
很明显了,这里是发送封包的call
这是封包数据:-----------shi-yong---------------//-zhanghao-aa// wuaipojie //un-zhanghao-//<br>//-daoqi-aa// 2019-12-10 //un-daoqi-//<br>//-key-aa// 666501d89d672cd0a05f96dfd060bc29 //un-key-//<br>www.xxxxx.com
走到这里返回了一个key,我们记为Key1
这里记为key2,是封包里的那个key。
上图这里是关键判断,判断本地的key1和返回封包的key2是不是一样
Key1=66650e7e5ff72cd0a05f96dfd060bc29
Key2=666501d89d672cd0a05f96dfd060bc29
经过分析,他是对比个大概,只要大概相似就行了。
[Asm] 纯文本查看 复制代码 009C16DD . 50 push eax ; /var18
009C16DE . 8D85 14FFFFFF lea eax,dword ptr ss:[ebp-0xEC] ; |
009C16E4 . 50 push eax ; |var28
009C16E5 . FF15 00104000 call dword ptr ds:[<&MSVBVM60.__vbaVarTs>; \__vbaVarTstGt
上网找到vbaVarTstGt ->检验指定变量大于 bpx vbaVarTstGe ->检验指定变量大于或等于
所以我们可以这样,将本地算法得出的结果,即得出的key1填写在返回的封包里面的key2里,经过测试,这个跳转也是不跳的。所以我们只要逆出算法就可以进行本地验证了。
现在我们开始逆出本地key1的算法
[Asm] 纯文本查看 复制代码 009C1375 . E8 B6220000 call 星空qq桌.009C3630 ; 取出key1
009C137A . 8BD0 mov edx,eax ;
009C137C . 8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
我们每次断在009C1375这个地址之前先下这个断点
[Asm] 纯文本查看 复制代码 009C11F0 . 50 push eax
009C11F1 . 68 5CE54000 push 星空qq桌.0040E55C ; [url=http://www.xxxxxx.com/login/login2015.php]http://www.xxxxxx.com/login/login2015.php[/url]
009C11F6 . 8D55 84 lea edx,dword ptr ss:[ebp-0x7C]
009C11F9 . 52 push edx
009C11FA . E8 B12B0000 call 星空qq桌.009C3DB0 ; 发送封包
k=oyo7fpltd9esyktg77rcjmva8t44bn1e
记下这个k值,因为计算key1的算法call需要用到这个值
[Asm] 纯文本查看 复制代码 009C3733 . 8B3D 30104000 mov edi,dword ptr ds:[<&MSVBVM60.__vbaSt>; MSVBVM60.__vbaStrVarMove
009C3739 . 8D55 B8 lea edx,dword ptr ss:[ebp-0x48]
009C373C . 52 push edx
009C373D . FFD7 call edi ; <&MSVBVM60.__vbaStrVarMove>
009C373F . 8B1D E4114000 mov ebx,dword ptr ds:[<&MSVBVM60.__vbaSt>;
009C3745 . 8BD0 mov edx,eax
009C3747 . 8D4D E4 lea ecx,dword ptr ss:[ebp-0x1C]
这个call 进行了这个操作 从K值的第9位开始取,取长度为8,记为K1
K1= oyo7fpltd9esyktg77rcjmva8t44bn1e(标记为红色部分)
[Asm] 纯文本查看 复制代码 009C374C . 8D45 E4 lea eax,dword ptr ss:[ebp-0x1C]
009C374F . 8D4D A8 lea ecx,dword ptr ss:[ebp-0x58]
009C3752 . 50 push eax
009C3753 . 51 push ecx
009C3754 . E8 87020000 call 星空qq桌.009C39E0 ; 将K1进行md5操作
这个call其实就是一个md5操作的函数,看下图这个数据就可以看出来了,不确定的话可以拿工具调试一下。
K1(md5)=578898cb2b2ac47708d0e7e4d19eedaf
[Asm] 纯文本查看 复制代码 009C377C . 8D4D 88 lea ecx,dword ptr ss:[ebp-0x78]
009C377F . 51 push ecx
009C3780 . FFD7 call edi ; <&MSVBVM60.__vbaStrVarMove>
009C3782 . 8BD0 mov edx,eax ; 取K值前10位 记为K2
009C3784 . 8D4D E0 lea ecx,dword ptr ss:[ebp-0x20]
K2=oyo7fpltd9
[Asm] 纯文本查看 复制代码 009C3789 . 8D55 E0 lea edx,dword ptr ss:[ebp-0x20]
009C378C . 8D85 78FFFFFF lea eax,dword ptr ss:[ebp-0x88]
009C3792 . 52 push edx
009C3793 . 50 push eax
009C3794 . E8 47020000 call 星空qq桌.009C39E0 ; 将k2 md5操作
这里也是同理,和上面一样的操作。
K2(md5)=91d2c5aa02f27174038bbd9036b0c56c
[Asm] 纯文本查看 复制代码 009C37D5 . BA C4CC4000 mov edx,星空qq桌.0040CCC4 ; qqzq
009C37DA . 8D4D DC lea ecx,dword ptr ss:[ebp-0x24]
009C37DD . FF15 78114000 call dword ptr ds:[<&MSVBVM60.__vbaStrCopy>] ; MSVBVM60.__vbaStrCopy
009C37E3 . 8D55 DC lea edx,dword ptr ss:[ebp-0x24]
009C37E6 . 8D85 08FFFFFF lea eax,dword ptr ss:[ebp-0xF8]
009C37EC . 52 push edx
009C37ED . 50 push eax
009C37EE . E8 ED010000 call 星空qq桌.009C39E0 ; qqzq md5
这里把qq桌球的简写拼音(qqzq)进行md5操作
qqzq(md5)=5ae623031acc47df1d5f6f4228d8bd88
下面是开始进行合并字符串
[Asm] 纯文本查看 复制代码 009C37F3 . 8B0D 2C509C00 mov ecx,dword ptr ds:[0x9C502C]
009C37F9 . 8B35 4C114000 mov esi,dword ptr ds:[<&MSVBVM60.__vbaVarCat>] ; MSVBVM60.__vbaVarCat
009C37FF . 8D55 C8 lea edx,dword ptr ss:[ebp-0x38]
009C3802 . 898D 90FEFFFF mov dword ptr ss:[ebp-0x170],ecx
009C3808 . 8D45 A8 lea eax,dword ptr ss:[ebp-0x58]
009C380B . 52 push edx
009C380C . 8D4D 98 lea ecx,dword ptr ss:[ebp-0x68]
009C380F . 50 push eax
009C3810 . 51 push ecx
009C3811 . C785 88FEFFFF>mov dword ptr ss:[ebp-0x178],0x8
009C381B . FFD6 call esi ; k值前5个+md5(k1); <&MSVBVM60.__vbaVarCat>
k=oyo7fpltd9esyktg77rcjmva8t44bn1e
oyo7f578898cb2b2ac47708d0e7e4d19eedaf (k值前5个+md5(k1))
[Asm] 纯文本查看 复制代码 009C381D . 50 push eax
009C381E . 8D95 78FFFFFF lea edx,dword ptr ss:[ebp-0x88]
009C3824 . 8D85 68FFFFFF lea eax,dword ptr ss:[ebp-0x98]
009C382A . 52 push edx
009C382B . 50 push eax
009C382C . FFD6 call esi ; k值前5个+md5(k1)+md5(k2); <&MSVBVM60.__vbaVarCat>
oyo7f578898cb2b2ac47708d0e7e4d19eedaf91d2c5aa02f27174038bbd9036b0c56c
[Asm] 纯文本查看 复制代码 009C382E . 8D8D 58FFFFFF lea ecx,dword ptr ss:[ebp-0xA8]
009C3834 . 50 push eax
009C3835 . 8D95 48FFFFFF lea edx,dword ptr ss:[ebp-0xB8]
009C383B . 51 push ecx
009C383C . 52 push edx
009C383D . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位; <&MSVBVM60.__vbaVarCat>
oyo7f578898cb2b2ac47708d0e7e4d19eedaf91d2c5aa02f27174038bbd9036b0c56cktg
[Asm] 纯文本查看 复制代码 009C383F . 50 push eax
009C3840 . 8D85 28FFFFFF lea eax,dword ptr ss:[ebp-0xD8]
009C3846 . 8D8D 18FFFFFF lea ecx,dword ptr ss:[ebp-0xE8]
009C384C . 50 push eax
009C384D . 51 push ecx
009C384E . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位+未知值; <&MSVBVM60.__vbaVarCat>
oyo7f578898cb2b2ac47708d0e7e4d19eedaf91d2c5aa02f27174038bbd9036b0c56cktg5a8dd11b9c99
[Asm] 纯文本查看 复制代码 009C3850 . 50 push eax
009C3851 . 8D95 08FFFFFF lea edx,dword ptr ss:[ebp-0xF8]
009C3857 . 8D85 F8FEFFFF lea eax,dword ptr ss:[ebp-0x108]
009C385D . 52 push edx
009C385E . 50 push eax
009C385F . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位+未知值+md5(qqzq); <&MSVBVM60.__vbaVarCat>
oyo7f578898cb2b2ac47708d0e7e4d19eedaf91d2c5aa02f27174038bbd9036b0c56cktg5a8dd11b9c995ae623031acc47df1d5f6f4228d8bd88
[Asm] 纯文本查看 复制代码 009C3861 . 8D8D 88FEFFFF lea ecx,dword ptr ss:[ebp-0x178]
009C3867 . 50 push eax
009C3868 . 8D95 E8FEFFFF lea edx,dword ptr ss:[ebp-0x118]
009C386E . 51 push ecx
009C386F . 52 push edx
009C3870 . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位+未知值+md5(qqzq)+登录账号; <&MSVBVM60.__vbaVarCat>
oyo7f578898cb2b2ac47708d0e7e4d19eedaf91d2c5aa02f27174038bbd9036b0c56cktg5a8dd11b9c995ae623031acc47df1d5f6f4228d8bd88wuaipojie
上面就差一个未知值是哪里来的,其实这个值慢慢调试也能找到,不过你第一次调试的时候比较难发现到,所以我会用另一种思路来找出来。
我们知道这个辅助作者比较“喜欢”用md5来进行加密,所以,我们找到md5加密的call,进入里面下个断点,再重新运行软件调试,就能找到那个未知值的是来自于哪里了。
[Asm] 纯文本查看 复制代码 009C3754 . E8 87020000 call 星空qq桌.009C39E0 ; 将K1进行md5操作
比如我们找到这句,进入这个call
[Asm] 纯文本查看 复制代码 009C39E0 $ 55 push ebp ; md5操作
009C39E1 . 8BEC mov ebp,esp
009C39E3 . 83EC 0C sub esp,0xC
009C39E6 . 68 C6194000 push <jmp.&MSVBVM60.__vbaExceptHandler> ; SE 处理程序安装
009C39EB . 64:A1 0000000>mov eax,dword ptr fs:[0]
009C39F1 . 50 push eax
009C39F2 . 64:8925 00000>mov dword ptr fs:[0],esp
009C39F9 . 83EC 68 sub esp,0x68
009C39FC . 53 push ebx
009C39FD . 56 push esi
009C39FE . 57 push edi
009C39FF . 8965 F4 mov dword ptr ss:[ebp-0xC],esp
009C3A02 . C745 F8 58194>mov dword ptr ss:[ebp-0x8],星空qq桌.0040195>
009C3A09 . 33C0 xor eax,eax
009C3A0B . 8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
这段就是md5操作的call,我们在头部下个断点,重新运行软件,我们要重新记录下发送封包里的K值。
第二次调试:k=0kmwvead9gha9devgzjhwfola0sovphx
刚才下的md5断点断下来了
这个就是未知值了0kmwvead9gha9dev
k=0kmwvead9gha9devgzjhwfola0sovphx
0kmwvead9gha9dev
通过对比,可以看出未知值是取k值前16位 并进行md5操作
[Asm] 纯文本查看 复制代码 009C36E9 . E8 F2020000 call 星空qq桌.009C39E0 ; 取k值16位 并进行md5操作
上图就是0kmwvead9gha9dev的md5结果,我们来验证一下。
看来我们的猜测是正确的,我们把这个值记为K3
k=0kmwvead9gha9devgzjhwfola0sovphx
K3=0kmwvead9gha9dev
K3(md5)= e811e7c7f665bb4c2461c07f2155da2e
K1、k2怎么来,上面已经写了,所以这次不给出加密过程
K1= 9gha9dev
K1(md5)= 02a6befe6e7ff5dc7f335ebf20b36e98K2= 0kmwvead9g
K2(md5)= 2f17263be17be77472f796abae0006b1
qqzq(md5)=5ae623031acc47df1d5f6f4228d8bd88
合并字符:
[Asm] 纯文本查看 复制代码 009C381B . FFD6 call esi ; k值前5个+md5(k1); <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e98
[Asm] 纯文本查看 复制代码 009C382C . FFD6 call esi ; k值前5个+md5(k1)+md5(k2); <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e982f17263be17be77472f796abae0006b1
[Asm] 纯文本查看 复制代码 009C383D . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位; <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e982f17263be17be77472f796abae0006b1dev
[Asm] 纯文本查看 复制代码 009C384E . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位++md5(k3)前12个; <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e982f17263be17be77472f796abae0006b1deve811e7c7f665
[Asm] 纯文本查看 复制代码 009C385F . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位++md5(k3)前12个+md5(qqzq); <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e982f17263be17be77472f796abae0006b1deve811e7c7f6655ae623031acc47df1d5f6f4228d8bd88
[Asm] 纯文本查看 复制代码 009C3870 . FFD6 call esi ; k值前5个+md5(k1)+md5(k2)+k1后三位+md5(k3)前12个+md5(qqzq)+登录账号; <&MSVBVM60.__vbaVarCat>
结果:0kmwv02a6befe6e7ff5dc7f335ebf20b36e982f17263be17be77472f796abae0006b1deve811e7c7f6655ae623031acc47df1d5f6f4228d8bd88wuaipojie
[Asm] 纯文本查看 复制代码 009C387C . 8D45 D8 lea eax,dword ptr ss:[ebp-0x28]
009C387F . 8D8D D8FEFFFF lea ecx,dword ptr ss:[ebp-0x128]
009C3885 . 50 push eax
009C3886 . 51 push ecx
009C3887 . E8 54010000 call 星空qq桌.009C39E0 将上面的结果再进行md5操作
最后结果得出:ea03e585c65565639fb6aabf3a2031fb
至于本地方法,我这里只提供思路,源码这些就不提供了,为了防止伸手党或者别有用心的人用来倒卖,看到这里,动手能力强的人,基本上可以写出本地源码了。
本地验证的方法请参考珈蓝夜雨大神的文章【吾爱动画大赛2019参赛作品】- 逆向分析某网络验证通信算法https://www.52pojie.cn/thread-1022758-1-1.html(出处: 吾爱破解论坛)
讲真的,我之前也是不懂怎么把网络验证转本地,我只知道思路,但是至于怎么操作真的不清楚,有幸能拜读珈蓝夜雨大神的文章,还有视频教程,视频做的不错,我也一步一步跟着调试,算是大概知道了飘零金盾的算法
这是我做的笔记:https://docs.qq.com/doc/DV01hRXFhT0ZwQWhj (写的不是很好,献丑了!!)
这个辅助本地思路:
[Asm] 纯文本查看 复制代码 009C11F1 . 68 5CE54000 push 星空qq桌.0040E55C ; [url=http://www.xxxx.com/login/login2015.php]http://www.xxxx.com/login/login2015.php[/url] //将这里的地址修改为本地地址 即127.0.0.1/login/login2015.php
然后用易语言,添加一个服务器组件,创建一个_服务器1_数据到达的事件,然后截取到登录的封包,拿出k值,进行上面的加密操作得出key1,最后把返回登录成功的封包里面的key2替换,这样就可以了。
对了,虽然本地成功,登录进去,但是你进入游戏后,辅助检测不到你所玩的桌球是哪个模式,模式有8,9球和斯诺克两种,但是可以搜索字符串,找到选择模式那里,强行跳转到你所玩对应的模式,功能一样可以用的。 |