4. 实例实现
通过上面的学习,我们已经基本具备了编写动作式游戏外挂的能力了。下面我们将创建一个画笔程序外挂,它实现自动移动画笔字光标的位置并写下一个红色的“R”字。以这个实例为基础,加入相应的游戏动作规则,就可以实现一个完整的游戏外挂。这里作者不想使用某个游戏作为例子来开发外挂(因没有游戏商家的授权啊!),如读者感兴趣的话可以找一个游戏试试,最好仅做测试技术用。
首先,我们需要编写一个全局钩子,使用它来激活外挂,激活键为F10。创建全局钩子步骤如下:
(1).选择MFC AppWizard(DLL)创建项目ActiveKey,并选择MFC Extension DLL(共享MFC拷贝)类型。
(2).插入新文件ActiveKey.h,在其中输入如下代码:
| #ifndef _KEYDLL_H #define _KEYDLL_H class AFX_EXT_CLASS CKeyHook:public CObject { public: CKeyHook(); ~CKeyHook(); HHOOK Start(); //安装钩子 BOOL Stop(); //卸载钩子 }; #endif |
(3).在ActiveKey.cpp文件中加入声明"#include ActiveKey.h"。
(4).在ActiveKey.cpp文件中加入共享数据段,代码如下:
| //Shared data section #pragma data_seg("sharedata") HHOOK glhHook=NULL; //钩子句柄。 HINSTANCE glhInstance=NULL; //DLL实例句柄。 #pragma data_seg() |
(5).在ActiveKey.def文件中设置共享数据段属性,代码如下:
| SETCTIONS shareddata READ WRITE SHARED |
(6).在ActiveKey.cpp文件中加入CkeyHook类的实现代码和钩子函数代码:
| //键盘钩子处理函数。 extern "C" LRESULT WINAPI KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam) { if( nCode >= 0 ) { if( wParam == 0X79 )//当按下F10键时,激活外挂。 { //外挂实现代码。 CPoint newPoint,oldPoint; GetCursorPos(&oldPoint); newPoint.x = oldPoint.x+40; newPoint.y = oldPoint.y+10; SetCursorPos(newPoint.x,newPoint.y); mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);//模拟按下鼠标左键。 mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);//模拟放开鼠标左键。 keybd_event(VK_SHIFT,MapVirtualKey(VK_SHIFT,0),0,0); //按下SHIFT键。 keybd_event(0x52,MapVirtualKey(0x52,0),0,0);//按下R键。 keybd_event(0x52,MapVirtualKey(0x52,0),KEYEVENTF_KEYUP,0);//放开R键。 keybd_event(VK_SHIFT,MapVirtualKey(VK_SHIFT,0),KEYEVENTF_KEYUP,0);//放开SHIFT键。 SetCursorPos(oldPoint.x,oldPoint.y); } } return CallNextHookEx(glhHook,nCode,wParam,lParam); } CKeyHook::CKeyHook(){} CKeyHook::~CKeyHook() { if( glhHook ) Stop(); } //安装全局钩子。 HHOOK CKeyHook::Start() { glhHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);//设置键盘钩子。 return glhHook; } //卸载全局钩子。 BOOL CKeyHook::Stop() { BOOL bResult = TRUE; if( glhHook ) bResult = UnhookWindowsHookEx(glhHook);//卸载键盘钩子。 return bResult; } |
(7).修改DllMain函数,代码如下:
| extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { //如果使用lpReserved参数则删除下面这行 UNREFERENCED_PARAMETER(lpReserved); if (dwReason == DLL_PROCESS_ATTACH) { TRACE0("NOtePadHOOK.DLL Initializing!\n"); //扩展DLL仅初始化一次 if (!AfxInitExtensionModule(ActiveKeyDLL, hInstance)) return 0; new CDynLinkLibrary(ActiveKeyDLL); //把DLL加入动态MFC类库中 glhInstance = hInstance; //插入保存DLL实例句柄 } else if (dwReason == DLL_PROCESS_DETACH) { TRACE0("NotePadHOOK.DLL Terminating!\n"); //终止这个链接库前调用它 AfxTermExtensionModule(ActiveKeyDLL); } return 1; } |
(8).编译项目ActiveKey,生成ActiveKey.DLL和ActiveKey.lib。
接着,我们还需要创建一个外壳程序将全局钩子安装了Windows系统中,这个外壳程序编写步骤如下:
(1).创建一个对话框模式的应用程序,项目名为Simulate。
(2).在主对话框中加入一个按钮,使用ClassWizard为其创建CLICK事件。
(3).将ActiveKey项目Debug目录下的ActiveKey.DLL和ActiveKey.lib拷贝到Simulate项目目录下。
(4).从“工程”菜单中选择“设置”,弹出Project Setting对话框,选择Link标签,在“对象/库模块”中输入ActiveKey.lib。
(5).将ActiveKey项目中的ActiveKey.h头文件加入到Simulate项目中,并在Stdafx.h中加入#include ActiveKey.h。
(6).在按钮单击事件函数输入如下代码:
| void CSimulateDlg::OnButton1() { // TODO: Add your control notification handler code here if( !bSetup ) { m_hook.Start();//激活全局钩子。 } else { m_hook.Stop();//撤消全局钩子。 } bSetup = !bSetup; } |
(7).编译项目,并运行程序,单击按钮激活外挂。
(8).启动画笔程序,选择文本工具并将笔的颜色设置为红色,将鼠标放在任意位置后,按F10键,画笔程序自动移动鼠标并写下一个红色的大写R。图一展示了按F10键前的画笔程序的状态,图二展示了按F10键后的画笔程序的状态。

图一:按F10前状态(001.jpg)

图二:按F10后状态(002.jpg)
更多内容请看PCdog.com--程序设计 游戏策划专题
