百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

游戏外挂之进程钩子

bigegpt 2024-09-17 12:26 8 浏览

游戏外挂,首先要做的就是将我们的代码放到游戏进程中去,以此来达到“不可告人的目的”。这里我就介绍一种比较常用的方法。就是进程钩子的方式将DLL放到游戏进程中去。其实这也是一些木马盗取账号和密码的方式。我们这里只是讲解通过一个进程钩子实现代码注入游戏进程。由第二节我们知道怎么去写一个C++MFC的DLL。这里我们首先新建一个DLL。首先和大家说下这里我会用到4个Window AP函数。

HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName ); 

这个API是找到一个给定类名或者窗口名称的窗口句柄。参数就不用介绍了,顾名思义,第一个参数就是窗口类名称,第二个参数就是窗口名称。我们在这里只是用第二个参数。第一个参数放NULL。窗口名称我们可以通过Spy++去获取这是VS的一个工具:

打开这个工具。

将那个圆拖到游戏标题栏后松开我们就可以看到这个游戏窗口的标题了。我们根据这个标题去找窗口句柄。

DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId );

这个API返回创建指定窗口的线程ID,MSDN上这样说的 “This function retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process that created the window”

参数hWnd是窗口句柄。就是FindWindow函数返回的值。lpdwProcessId是创建窗口的进程标志ID,它是一个输出参数,也就是一个指针。就和C#中的out参数差不多。这个参数可以放NULL,如果不是NULL,它会返回创建指定窗口的进程标志。

HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn,HINSTANCE hMod, DWORD dwThreadId);

这个API就是设置钩子。第一个参数是钩子类型。钩子类型具体有哪些可以参照MSDN这里我们用到的是WH_KEYBOARD。第二个参数就是一个回调函数。回调函数的格式如下:

LRESULT CALLBACK KeyboardProc( int code,
 WPARAM wParam,
 LPARAM lParam
);

第三个参数就是DLL的模块句柄,我们可以通过API函数来获取

HMODULE GetModuleHandle( LPCTSTR lpModuleName);

这个时候大家就会疑惑了SetWindowsHookEx的第三个参数是HINSTANCE类型,但是GetModuleHandle返回的却是HMODULE,这个能对上吗?其实能对上。你可以看看定义它的头文件,我们能看到typedef HINSTANCE HMODULE 这样大家就很容易看出它们其实就是一个东西。这在Windows 核心编程中经常碰到这种情况。我们在写Windows游戏外挂的时候,最好要去研究下Windows 核心编程。推荐一本比较耐看的书《windows核心编程》,我的是最新版.这本书的作者绝对Windows系统有很高的研究。值得反复去看,去研究。不跑题了,继续……。GetModuleHandle的第一个参数就是要注入的DLL路径可以是相当也可以绝对,当然我推荐相对路径。SetWindowsHookEx的最后一个参数就是GetWindowThreadProcessId返回的值。通过这样的讲解大家应该了解了。

下面就是实实在在的编码。我们新建一个MFC DLL(我这个DLL的名称是GameHookDLL)。

///钩子回调函数
LRESULT CALLBACK KeyboardProc( int code, // hook code
 WPARAM wParam, // virtual-key code
 LPARAM lParam // keystroke-message information
 ){
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 if(wParam==VK_F1&&((lParam&(1<<31))==0)){
 AfxMessageBox(L"F1键在游戏窗口被按下了!");
 }
 return CallNextHookEx(0,code,wParam,lParam);
}
//(LPWSTR)"YB_OnlineClient"
void SetHook(LPWSTR prc_name){
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 HWND hd=FindWindow(NULL,prc_name);
 if(hd==NULL)
 {
 AfxMessageBox(L"请打开输入的程序进程");
 return;
 }
 DWORD dwid=GetWindowThreadProcessId(hd,NULL);
 //
 HINSTANCE hdll=::GetModuleHandleW(L"GameHookDLL.dll");
 
 SetWindowsHookEx(WH_KEYBOARD,&KeyboardProc,hdll,dwid);
}

这是我在DLL中添加的两个函数,上面是SetWindowsHookEx的回调处理函数。对了,这个回调函数一定别忘了最后一行

return CallNextHookEx(0,code,wParam,lParam);如果回调KeyboardProc 中的code值小于0它会跳过去然后call下一个消息MSDN中的原文是:If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx。所以我建议还是自己研究MSDN,比较我个人能力有限,说不定理解的有误,当然在这里如果有什不正确或者理解有偏差的地方希望大家谅解。这里我们DLL只需要对外暴露第二个函数void SetHook(LPWSTR prc_name)。至于怎么暴露,自己去看第二节。

if(wParam==VK_F1&&((lParam&(1<<31))==0)){
 AfxMessageBox(L"F1键在游戏窗口被按下了!");
 }
wParam==VK_F1表示我们按下的F1键。(lParam&(1<<31))==0对lParam参数不熟悉的就不好理解了。lParam的第31位如果是0表示按下,如果是1表示按键弹起。我们这里是判断F1按键被按下。
如果没有(lParam&(1<<31))==0我们按下F1键将会弹出两次,一次是按下时弹出,一次是F1弹起式弹出。所以要保证lParam的第31位是0我们才弹出对话框。1<<31是10000000000000000000
0000000000后面有31个0而lParam的0~30位我们不确定但是我们&一下肯定都是0,然后第31位是0最后结果肯定是0这样就实现了判断。

MSDN中远英文是:

lParam[in] Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. For more information about the lParam parameter, see Keystroke Message Flags. This parameter can be one or more of the following values.

0-15.Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.

16-23.Specifies the scan code. The value depends on the OEM.

24.Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.

25-28.Reserved.

29.Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.

30.Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.

31.Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.

接下来我们去新建一个MFC exe程序。在这个程序中去调用这个void SetHook(LPWSTR prc_name)函数。把窗口名称作为参数传过去。这里我添加的是MFC 简单对话框。对话框的布局如图:

然后给文本框关联上CString类型的变量txt_prc_name。在按钮事件中添加注册钩子代码:

void CGameWGClientDlg::OnBnClickedOk()
{
 UpdateData(true);
 LPWSTR s1=(LPWSTR)(LPCTSTR)txt_prc_name;
 SetHook(s1);
 // TODO: 在此添加控件通知处理程序代码
 //CDialogEx::OnOK();
}

这些只需要你掌握一点MFC知识。LPWSTR s1=(LPWSTR)(LPCTSTR)txt_prc_name;这个经过两次装换,主要是CString类型没法直接装换成LPWSTR类型。所以就这样处理了。好代码搞定,来看效果:

在MFC客户程序中输入我们用Spy++找出的游戏窗口名称,然后点击确定这样钩子就被注册到了游戏进程中。这时候我们在登陆框中随便输入,直到我们输入F1弹出对话框。这样通过键盘钩子注入进程的原型就搞定了。这一节就到这里。

作者:egojit

原文:https://www.cnblogs.com/egojit/archive/2013/06/16/3138266.html

相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...