游戏安全实验室 首页 游戏漏洞 查看内容

【游戏漏洞】代码实现HOOK明文发包

发布于:2018-7-2 09:06   |    45567次阅读 作者: 外部投稿    |   原作者: 通化程序员

在一个游戏里得到明文发包函数以后

对于我们逆向最大的用处,就是去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[i]);

    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<