[轉貼] 遊戲外掛設計技術探討
轉貼至小新a家
遊戲外掛設計技術探討(上) | |||
一、 前言 所謂遊戲外掛,其實是一種遊戲 外輔程序,它可以協助玩家自動產生遊戲動作、修改遊戲網路封包以及修改遊戲記憶體資料等,以實現玩家用最少的時間和金錢去完成功力升級和過關斬將。雖然, 現在對遊戲外掛程序的「合法」身份眾說紛紜,在這裡我不想對此發表任何個人意見,讓時間去說明一切吧。 不管遊戲外掛程序是不是「合法」身份,但是它卻是具有一定的技術含量的,在這些小小程序中使用了許多高端技術,如攔截Sock技術、攔截API技術、模擬鍵盤與滑鼠技術、直接修改程序記憶體技術等等。本文將對常見的遊戲外掛中使用的技術進行全面剖析。 二、認識外掛 遊戲外掛的歷史可以追溯到單機版遊戲時代,只不過當時它使用了另一個更通俗易懂的名字??遊戲修改器。它可以在遊戲中追蹤鎖定遊戲主人公的各項能力數值。這樣玩家在遊戲中可以達到主角不掉血、不耗費魔法、不消耗金錢等目的。這樣降低了遊戲的難度,使得玩家更容易通關。 隨著網路遊戲的時代的來臨,遊戲外掛在原有的功能之上進行了新的發展,它變得更加多種多樣,功能更加強大,操作更加簡單,以至有些遊戲的外掛已經成為一 個體系,比如《石器時代》,外掛品種達到了幾十種,自動戰鬥、自動行走、自動練級、自動補血、加速、不遇敵、原地遇敵、快速增加經驗值、按鍵精靈……幾乎 無所不包。 遊戲外掛的設計主要是針對於某個遊戲開發的,我們可以根據它針對的遊戲的類型可大致可將外掛分為兩種大類。 一類是將遊戲中大量繁瑣和無聊的攻擊動作使用外掛自動完成,以幫助玩家輕鬆搞定攻擊對象並可以快速的增加玩家的經驗值。比如在《龍族》中有一種工作的設 定,玩家的工作等級越高,就可以駕馭越好的裝備。但是增加工作等級卻不是一件有趣的事情,毋寧說是重複枯燥的機械勞動。如果你想做法師用的杖,首先需要做 基本工作--?砍樹。砍樹的方法很簡單,在一棵大樹前不停的點滑鼠就可以了,每10000的經驗升一級。這就意味著玩家要在大樹前不停的點擊滑鼠,這種無 聊的事情通過"按鍵精靈"就可以解決。外掛的"按鍵精靈"功能可以讓玩家擺脫無趣的點擊滑鼠的工作。 另一類是由外掛程序產生欺騙性的 網路遊戲封包,並將這些封包發送到網路遊戲服務器,利用這些虛假信息欺騙服務器進行遊戲數值的修改,達到修改角色能力數值的目的。這類外掛程序針對性很 強,一般在設計時都是針對某個遊戲某個版本來做的,因為每個網路遊戲服務器與客戶端交流的封包各不相同,外掛程序必須要對欺騙的網路遊戲服務器的封包進行 分析,才能產生服務器識別的封包。這類外掛程序也是當前最流利的一類遊戲外掛程序。 另外,現在很多外掛程序功能強大,不僅實現了自動 動作代理和封包功能,而且還提供了對網路遊戲的客戶端程序的資料進行修改,以達到欺騙網路遊戲服務器的目的。我相信,隨著網路遊戲商家的反外掛技術的進 展,遊戲外掛將會產生更多更優秀的技術,讓我們期待著看場技術大戰吧...... 三、外掛技術綜述 可以將開發遊戲外掛程序的過程大體上劃分為兩個部分: 前期部分工作是對外掛的主體遊戲進行分析,不同類型的外掛分析主體遊戲的內容也不相同。如外掛為上述談到的外掛類型中的第一類時,其分析過程常是針對遊 戲的場景中的攻擊對象的位置和分佈情況進行分析,以實現外掛自動進行攻擊以及位置移動。如外掛為外掛類型中的第二類時,其分析過程常是針對遊戲服務器與客 戶端之間通訊包資料的結構、內容以及加密算法的分析。因網路遊戲公司一般都不會公佈其遊戲產品的通訊包資料的結構、內容和加密算法的信息,所以對於開發第 二類外掛成功的關鍵在於是否能正確分析遊戲包資料的結構、內容以及加密算法,雖然可以使用一些工具輔助分析,但是這還是一種堅苦而複雜的工作。 後期部分工作主要是根據前期對遊戲的分析結果,使用大量的程序開發技術編寫外掛程序以實現對遊戲的控制或修改。如外掛程序為第一類外掛時,通常會使用到 滑鼠模擬技術來實現遊戲角色的自動位置移動,使用鍵盤模擬技術來實現遊戲角色的自動攻擊。如外掛程序為第二類外掛時,通常會使用到擋截Sock和擋截 API函數技術,以擋截遊戲服務器傳來的網路封包並將封包修改後封包後傳給遊戲服務器。另外,還有許多外掛使用對遊戲客戶端程序記憶體資料修改技術以及遊 戲加速技術。 本文主要是針對開發遊戲外掛程序後期使用的程序開發技術進行探討,重點介紹的如下幾種在遊戲外掛中常使用的程序開發技術: ● 動作模擬技術:主要包括鍵盤模擬技術和滑鼠模擬技術。 ● 封包技術:主要包括擋截Sock技術和擋截API技術。 四、動作模擬技術 我們在前面介紹過,幾乎所有的遊戲都有大量繁瑣和無聊的攻擊動作以增加玩家的功力,還有那些數不完的迷宮,這些好像已經成為了角色遊戲的代名詞。現在, 外掛可以幫助玩家從這些繁瑣而無聊的工作中擺脫出來,專注於遊戲情節的進展。外掛程序為了實現自動角色位置移動和自動攻擊等功能,需要使用到鍵盤模擬技術 和滑鼠模擬技術。下面我們將重點介紹這些技術並編寫一個簡單的實例幫助讀者理解動作模擬技術的實現過程。 1. 滑鼠模擬技術 幾乎所有的遊戲中都使用了滑鼠來改變角色的位置和方向,玩家僅用一個小小的滑鼠,就可以使角色暢遊天下。那麼,我們如何實現在沒有玩家的參與下角色也可 以自動行走呢。其實實現這個並不難,僅僅幾個Windows API函數就可以搞定,讓我們先來認識認識這些API函數。 (1) 模擬滑鼠動作API函數mouse_event,它可以實現模擬滑鼠按下和放開等動作。 VOID mouse_event( DWORD dwFlags、// 滑鼠動作標識。 DWORD dx、// 滑鼠水平方向位置。 DWORD dy、// 滑鼠垂直方向位置。 DWORD dwData、// 滑鼠輪子轉動的數量。 DWORD dwExtraInfo // 一個關聯滑鼠動作輔加信息。 ); 其中,dwFlags表示了各種各樣的滑鼠動作和點擊活動,它的常用取值如下: MOUSEEVENTF_MOVE 表示模擬滑鼠移動事件。 MOUSEEVENTF_LEFTDOWN 表示模擬按下滑鼠左鍵。 MOUSEEVENTF_LEFTUP 表示模擬放開滑鼠左鍵。 MOUSEEVENTF_RIGHTDOWN 表示模擬按下滑鼠右鍵。 MOUSEEVENTF_RIGHTUP 表示模擬放開滑鼠右鍵。 MOUSEEVENTF_MIDDLEDOWN 表示模擬按下滑鼠中鍵。 MOUSEEVENTF_MIDDLEUP 表示模擬放開滑鼠中鍵。 (2)、設置和獲取當前滑鼠位置的API函數。獲取當前滑鼠位置使用GetCursorPos()函數,設置當前滑鼠位置使用SetCursorPos()函數。 BOOL GetCursorPos( LPPOINT lpPoint // 返回滑鼠的當前位置。 ); BOOL SetCursorPos( int X、// 滑鼠的水平方向位置。 int Y //滑鼠的垂直方向位置。 ); 通常遊戲角色的行走都是通過滑鼠移動至目的地,然後按一下滑鼠的按鈕就搞定了。下面我們使用上面介紹的API函數來模擬角色行走過程。 CPoint oldPoint,newPoint; GetCursorPos(&oldPoint); //保存當前滑鼠位置。 newPoint.x = oldPoint.x+40; newPoint.y = oldPoint.y+10; SetCursorPos(newPoint.x,newPoint.y); //設置目的地位置。 mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);//模擬按下滑鼠右鍵。 mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);//模擬放開滑鼠右鍵。 2. 鍵盤模擬技術 在很多遊戲中,不僅提供了滑鼠的操作,而且還提供了鍵盤的操作,在對攻擊對像進行攻擊時還可以使用快捷鍵。為了使這些攻擊過程能夠自動進行,外掛程序需要使用鍵盤模擬技術。像滑鼠模擬技術一樣,Windows API也提供了一系列API函數來完成對鍵盤動作的模擬。 模擬鍵盤動作API函數keydb_event,它可以模擬對鍵盤上的某個或某些鍵進行按下或放開的動作。 VOID keybd_event( BYTE bVk、// 虛擬鍵值。 BYTE bScan、// 硬體掃瞄碼。 DWORD dwFlags、// 動作標識。 DWORD dwExtraInfo // 與鍵盤動作關聯的輔加信息。 ); 其中,bVk表示虛擬鍵值,其實它是一個BYTE類型值的宏,其取值範圍為1-254。有關虛擬鍵值表請在MSDN上使用關鍵字「Virtual- Key Codes」查找相關資料。bScan表示當鍵盤上某鍵被按下和放開時,鍵盤系統硬體產生的掃瞄碼,我們可以MapVirtualKey()函數在虛擬鍵 值與掃瞄碼之間進行轉換。dwFlags表示各種各樣的鍵盤動作,它有兩種取值:KEYEVENTF_EXTENDEDKEY和 KEYEVENTF_KEYUP。 下面我們使用一段代碼實現在遊戲中按下Shift+R快捷鍵對攻擊對像進行攻擊。 keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),0,0); //按下CTRL鍵。 keybd_event(0x52,MapVirtualKey(0x52,0),0,0);//鍵下R鍵。 keybd_event(0x52,MapVirtualKey(0x52,0)、KEYEVENTF_KEYUP,0);//放開R鍵。 keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0)、 KEYEVENTF_KEYUP,0);//放開CTRL鍵。 3. 激活外掛 上面介紹的滑鼠和鍵盤模擬技術實現了對遊戲角色的動作部分的模擬,但要想外掛能工作於遊戲之上,還需要將其與遊戲的場景窗口聯繫起來或者使用一個激活 鍵,就像按鍵精靈的那個激活鍵一樣。我們可以用GetWindow函數來枚舉窗口,也可以用Findwindow函數來查找特定的窗口。另外還有一個 FindWindowEx函數可以找到窗口的子窗口,當遊戲切換場景的時候我們可以用FindWindowEx來確定一些當前窗口的特徵,從而判斷是否還 在這個場景,方法很多了,比如可以GetWindowInfo來確定一些東西,比如當查找不到某個按鈕的時候就說明遊戲場景已經切換了等等辦法。當使用激 活鍵進行關聯,需要使用Hook技術開發一個全局鍵盤鉤子,在這裡就不具體介紹全局鉤子的開發過程了,在後面的實例中我們將會使用到全局鉤子,到時將學習 到全局鉤子的相關知識。 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)
|
留言
張貼留言
留言請注意禮節與尊重他人,良好的交流環境需要你我共同維護。
VtigerCRM 相關留言討論,請改至FaceBook社團申請加入使用
https://www.facebook.com/groups/vTigerCRMtoTaiwan/