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

【游戏漏洞】HOOK原理以及在游戏逆向中的应用

发布于:2018-3-15 10:24   |    117361次阅读 作者: 外部投稿    |   原作者: 通化程序员

HOOk的意思是拦截, 也称钩子。

大家可以打开PCHunter 这个工具  看看任意的网游或则 游戏辅助程序,都纯在着大量的钩子。

无论是对数据的拦截还是对游戏代码的篡改还是游戏安全的被动防护,钩子都是必须的。

 

 

钩子的作用

①获取执行到某条代码的时候,所有寄存器的值 。

例如HOOK 明文包,HOOK 收包,我们可以拦截到所有的封包内容及包长,从而可以更加方便的分析封包协议。

 

②在某条代码处加入我们想处理的内容,例如某些变态功能 ,例如DXF扣血CALL ,判断是怪物对象直接赋值0将血量扣为0实现秒怪,而判断是人物对象直接不扣血,实现无敌的效果。

 

 

 

hook明文包代码实例如下:

函数,变量名 全部中文修改标注

 

void Call_Hook明文包()

{

DWORD Hook地址 = Addr_明文包-15;

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=0xE8;

WriteProcessMemory(hProcess,(LPDWORD)(Hook地址 + 0x00),&Temp,1,&WriteSize);

DWORD Temp1=跳转值;

WriteProcessMemory(hProcess,(LPDWORD)(Hook地址 + 0x01),&Temp1,4,&WriteSize);

byte Temp2=0x90;

WriteProcessMemory(hProcess,(LPDWORD)(Hook地址 + 0x05),&Temp2,1,&WriteSize);

}

__except (1)

{

Call_输出调试信息("YYC3D   Hook明文包异常\r\n");

}

}

 

 

 

在退出的时候一定要还原HOOK

否则找不到HOOK的函数,游戏程序会直接崩溃

以下是还原HOOK代码:

 

void Call_UnHook明文包()

{

__try

{

DWORD Hook地址 = Addr_明文包-15;

DWORD WriteSize=NULL;

byte Temp []={0x8B,0x88,0xAC,0x0A,0x01,0x00};

WriteProcessMemory(hProcess,(LPDWORD)Hook地址,&Temp,6,&WriteSize);

}

__except (1)

{

Call_输出调试信息("YYC3D   UnHook明文包异常\r\n");

}

}

 

 

 

 

 

基本原理

 

修改代码,让他跳转到我们想要的位置(DLL)中执行,执行我们想执行的代码以后再跳转回来。

本的原则是,这个过程不修改他原本任何的堆栈和寄存器值。

当然除了修变态修改的情况!因为变态修改目的就是为了改变他的值。

 

那么有人会问 ,那为什么不直接在游戏进程中修改成我们想要执行的代码

唯一的原因就是,该处的代码空间不够我们用的。

当然我们也可以在游戏进程里 ,找一块空内存或者申请一块内存出来, 把代码写进去然后让他跳转过去执行。

这样的办法,也可以用作远程HOOK。

所以说不注入DLL也可以HOOK。

 

因为本的原则是不破坏堆栈和寄存器

所以对于大家不是十分熟练HOOK之前 尽量不要去HOOK PUSH POP CALL RETN 等操作堆栈的代码。

这样不会影响我们什么,因为你把代码HOOK的位置调整一下,想要得到的值或者修改的值也会变

例如

mov  eax,[edx+C]

mov  ecx,[edx+10]

push eax

我们想知道EAX的值,我们可以不hook push eax  ,可以去HOOK上一句,因为2句的EAX值是相同的,也可以HOOK  mov eax,[edx+c]  

[edx+c]  因为 [edx+c] 就是我们后面想得到的值。

 

 

HOOK的时候, 我们选大于5字节的代码可以一句或则多句,因为我们要修改的代码为JMP XXXX 是需要5字节的。

① 记录下我们要HOOK的代码

②修改成 jmp XXXX  多余的字节  我们NOP 填充  

③跳到我们的DLL里,我们最好用裸函数,这样不会生成多余的代码,生成多余的代码会影响我们。

然后我们要  PUSHAD ,  然后可以随意执行我们 ,做完我们的操作以后,我们就POPAD ,

最后执行原来被我们HOOK的代码   , JMP  XXXX 跳转回去。

④这样 ,对于游戏进程来说, 代码执行过这里,什么都没有变化  ,只是多执行了我们想要硬插进去的代码而已。

 

 

 

 

 

 

来源:通化程序员-公众号投稿

*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)

 

分享到:
踩0 赞0

收藏

最新评论
B Color Image Link Quote Code Smilies

发表评论

top 问题反馈

返回顶部