鑫郁飞

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 518|回复: 0

任鸟飞谈逆向----QQ西游 HOOK明文发包

[复制链接]

管理员

Rank: 9Rank: 9Rank: 9

阅读权限
200
积分
109503
精华
71
主题
156
帖子
176
分享
0
日志
0
在线时间
57 小时
最后登录
2018-7-19
注册时间
2016-11-22
听众
0
收听
0
发表于 2018-6-17 16:51:20 | 显示全部楼层 |阅读模式
微信公众号  任鸟飞逆向

在一个游戏里得到明文发包函数以后
对于我们逆向最大的用处,就是去HOOK,然后分析封包
因为如果在OD等调试软件中下断分析是很难的,封包的种类很多很频繁,单一的动作也不一定只是一个封包,所以HOOK明文包进行分析是必然的
也有一些工具例如WPE等,也是做此类事情的,不过他只是HOOK的发包函数,对于加密的封包,还要去找解密函数,HOOK明文函数就相当于直接省去了解密过程。


我们要HOOK的位置

首先我们要在明文发包CALL上面找5字节或则大于5字节的空间就行HOOK

这5字节即可

然后将去修改成JMP xxxx 跳转到我们自己DLL的子程序里
执行我们想执行的过程(调试输出封包信息)
然后再跳转回去
此过程不能对游戏代码产生任何影响,包括寄存器的值和堆栈。

代码如下

void Call_Hook明文包()
{
        DWORD Hook地址 = Addr_hook明文包;
        DWORD Hook子程序指针 = (DWORD)Hook明文包子程序;
        DWORD 跳转值=Hook子程序指针-Hook地址-5;

        Call_提升权限(TRUE);//提升EXE权限
        DWORD pid=NULL;
        DWORD WriteSize=NULL;
        GetWindowThreadProcessId(Call_获取窗口句柄(),&pid);//获得进程ID
        hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);//打开进程

        __try
        {
                byte Temp=0xE9;//写内存有三种方式  不同情况进行不同应用
                WriteProcessMemory(hProcess,(LPDWORD)(Hook地址 + 0x00),&Temp,1,&WriteSize);
                DWORD Temp1=跳转值;
                WriteProcessMemory(hProcess,(LPDWORD)(Hook地址 + 0x01),&Temp1,4,&WriteSize);

        }
        __except (1)
        {
                Call_输出调试信息("QQ西游    Hook明文包异常\r\n");
        }
}


在不用HOOK的时候我们要对其进行还原,否则直接卸载DLL 游戏会因为找不到跳转子程序而崩溃的

void Call_UnHook明文包()
{        
        __try
        {
                DWORD Hook地址 = Addr_hook明文包;
                DWORD WriteSize=NULL;
                byte Temp []={0x8B,0x44,0x24,0x08,0x50};
                WriteProcessMemory(hProcess,(LPDWORD)Hook地址,&Temp,5,&WriteSize);
        }
        __except (1)
        {
                Call_输出调试信息("QQ西游    UnHook明文包异常\r\n");
        }
}


跳转过去的子程序员任意输出我们想要的信息
同样用 pushad 和popad 保存和还原寄存器 防止我们的代码对游戏产生影响



void Call_输出明文包信息()
        {
                p =new byte[g_包长];
                ReadProcessMemory(hProcess,(LPCVOID)g_包地址,p,g_包长,0);
                for (int i=0;i<(int)g_包长;i++)
                {
                        sprintf(s,"%02X",p);
                            strcat_s(a,s);
                 }
                Call_输出调试信息("QQ西游    flag1:%x    flag2:%x    flag3:%x    包长:%x  %s\r\n",g_flog1,g_flog2,g_flog3,g_包长,a);

                sprintf(a,"%s","");//格式化
                delete p;
        }



__declspec(naked) void Hook明文包子程序()
{
        __asm
        {
                pushad
                        mov eax,[esp+0x28]//由于有 pushad 相当于sub  esp,20  +0x8 变+0x28
                    mov ecx,[eax]
                        mov g_flog1,ecx
                        mov ecx,[eax+4]
                        mov g_flog2,ecx
                        mov ecx,[eax+8]
                        mov g_flog3,ecx
                        mov ecx,[eax+0xC]
                        mov g_包地址,ecx
                        mov edx,[eax+0x10]
            mov ebx,[eax+0x14]
                        sub edx,ecx
                        mov g_包长,edx

        }

        Call_输出明文包信息();



        __asm
        {
                popad
                mov eax,[esp+8]
                push eax
                jmp Addr_hook明文包返回
        }
}


那么我们来看一下 调试输出的效果



可以捕捉到游戏里所有的封包了
进行随意分析了


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|鑫郁飞网络科技有限公司 ( 渝ICP备16011958号-1 )

GMT+8, 2018-7-23 13:58 , Processed in 0.063616 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表