程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 外掛的面紗

外掛的面紗

編輯:Delphi

在幾年前我看到別人玩網絡游戲用上了外掛,做為程序員的我心裡實在是不爽,想搞清楚這到底是怎麼回事。就拿了一些來研究,小有心得,拿出來與大家共享,外掛無非就是分幾種罷了(依制作難度):

  1、動作式,所謂動作式,就是指用API發命令給窗口或API控制鼠標、鍵盤等,使游戲裡的人物進行流動或者攻擊,最早以前的“石器”外掛就是這種方式。(這種外掛完全是垃圾,TMD,只要會一點點API的人都知道該怎麼做,不過這種外掛也是入門級的好東東,雖然不能提高你的戰斗力,但是可以提高你的士氣^_^)

  2、本地修改式,這種外掛跟傳統上的一些游戲修改器沒有兩樣,做這種外掛在編程只需要對內存地址有一點認識並且掌握API就可以實現,“精靈”的外掛這是這種方式寫成的,它的難點在於找到那些地址碼,找地址一般地要借助於別人的工具,有的游戲還有雙碼校驗,正正找起來會比較困難。(這種外掛,比上一種有一點點難度,但是這種外掛做起來能夠用,也是有一定難度的啦~~,這種外掛可以很快提升你對內存地址的理解及應用,是你編程技術提高的好東東)

  3、木馬式,這種外掛的目的是幫外掛制作者偷到用戶的密碼(TMD,“爛”就一個字,不過要知已知彼所以還是要談一下啦~~),做這種外掛有一定的難度,需要HOOK或鍵盤監視技術做底子,才可以完成,它的原理是先首截了用戶的帳號或密碼,然後發到指定郵箱。(我以前寫過這樣的東東,但是從來沒有用過,我知道這種東東很不道德,所以以後千萬別用呀!~~)

  4、加速式,這種外掛可以加快游戲的速度……(對不起大家,這種東東我沒有實際做過,所以不能妄自評,慚愧~~)

  5、封包式,這種外掛是高難度外掛,需要有很強的編程功力才可以寫得出來。它的原理是先截取封包,後修改,再轉發(Kao,說起來簡單,你做一個試試~~~~)。這種外掛適用於大多數網絡游戲,像WPE及一些網絡游戲外掛都是用這種方式寫成的,編寫這種外掛需要apihook技術,winsock技術…………

 這幾種外掛之中,前三種可以用VB,DELPHI等語言比較好實現,後兩種則要用VC等底層支持比較好的編程工具才好實現。(啪,請聽下回分解)

  (本人是個程序愛好者並不是專業制作外掛的,所以文中有什麼不當請大家海涵,以後的文章,我會對動作式,本地修改式,木馬式,封包式這4種東東的編寫過程做詳細解說)

  上回我們對動作式外掛做了一個解析,動作式是最簡單的外掛,現在我們帶來看看,比動作式外掛更進一步的外掛——本地修改式外掛的整個制作過程進行一個詳細的分解。

  具我所知,本地修改式外掛最典型的應用就是在“精靈”游戲上面,因為我在近一年前(“精靈”還在測試階段),我所在的公司裡有很多同事玩“精靈”,於是我看了一下游戲的數據處理方式,發現它所發送到服務器上的信息是存在於內存當中(我看後第一個感受是:修改這種游戲和修改單機版的游戲沒有多大分別,換句話說就是在他向服務器提交信息之前修改了內存地址就可以了),當時我找到了地址於是修改了內存地址,果然,按我的想法修改了地址,讓系統自動提交後,果然成功了~~~~~,後來“精靈”又改成了雙地址校檢,內存校檢等等,在這裡我就不廢話了~~~~,OK,我們就來看看這類外掛是如何制作的:

  在做外掛之前我們要對Windows的內存有個具體的認識,而在這裡我們所指的內存是指系統的內存偏移量,也就是相對內存,而我們所要對其進行修改,那麼我們要對幾個Windows API進行了解,OK,跟著例子讓我們看清楚這種外掛的制作和API的應用(為了保證網絡游戲的正常運行,我就不把找內存地址的方法詳細解說了):

  1、首先我們要用FindWindow,知道游戲窗口的句柄,因為我們要通過它來得知游戲的運行後所在進程的ID,下面就是FindWindow的用法:


HWND FindWindow(
LPCTSTR lpClassName, // pointer to class name
LPCTSTR lpWindowName // pointer to window name
);

  2、我們GetWindowThreadProcessId來得到游戲窗口相對應進程的進程ID,函數用法如下:

DWord GetWindowThreadProcessId(
HWND hWnd, // handle of window
LPDWord lpdwProcessId // address of variable for process identifIEr
);

  3、得到游戲進程ID後,接下來的事是要以最高權限打開進程,所用到的函數OpenProcess的具體使用方法如下:

HANDLE OpenProcess(
DWord dwDesiredAccess, // Access flag
BOOL bInheritHandle, // handle inheritance flag
DWord dwProcessId // process identifIEr
);

  在dwDesiredAccess之處就是設存取方式的地方,它可設的權限很多,我們在這裡使用只要使用PROCESS_ALL_Access 來打開進程就可以,其他的方式我們可以查一下MSDN。

  4、打開進程後,我們就可以用函數對存內進行操作,在這裡我們只要用到WriteProcessMemory來對內存地址寫入數據即可(其他的操作方式比如說:ReadProcessMemory等,我在這裡就不一一介紹了),我們看一下WriteProcessMemory的用法:

BOOL WriteProcessMemory(
HANDLE hProcess, // handle to process whose memory is written to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // pointer to buffer to write data to
DWord nSize, // number of bytes to write
LPDWord lpNumberOfBytesWritten // actual number of bytes written
);

  5、下面用CloseHandle關閉進程句柄就完成了。

 這就是這類游戲外掛的程序實現部份的方法,好了,有了此方法,我們就有了理性的認識,我們看看實際例子,提升一下我們的感性認識吧,下面就是XX游戲的外掛代碼,我們照上面的方法對應去研究一下吧:

const
ResourceOffset: dWord = $004219F4;
resource: dWord = 3113226621;
ResourceOffset1: dWord = $004219F8;
resource1: dWord = 1940000000;
ResourceOffset2: dWord = $0043FA50;
resource2: dWord = 1280185;
ResourceOffset3: dWord = $0043FA54;
resource3: dWord = 3163064576;
ResourceOffset4: dWord = $0043FA58;
resource4: dWord = 2298478592;
var
hw: HWND;
pid: dWord;
h: THandle;
tt: Cardinal;
begin
hw := FindWindow('XX', nil);
if hw = 0 then
Exit;
GetWindowThreadProcessId(hw, @pid);
h := OpenProcess(PROCESS_ALL_Access, false, pid);
if h = 0 then
Exit;
if flatcheckbox1.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset), @Resource, sizeof(Resource), tt);
WriteProcessMemory(h, Pointer(ResourceOffset1), @Resource1, sizeof(Resource1), tt);
end;
if flatcheckbox2.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset2), @Resource2, sizeof(Resource2), tt);
WriteProcessMemory(h, Pointer(ResourceOffset3), @Resource3, sizeof(Resource3), tt);
WriteProcessMemory(h, Pointer(ResourceOffset4), @Resource4, sizeof(Resource4), tt);
end;
MessageBeep(0);
CloseHandle(h);
close;

  這個游戲是用了多地址對所要提交的數據進行了校驗,所以說這類游戲外掛制作並不是很難,最難的是要找到這些地址。

 (方法大家已經看清楚了,具體實踐就看大家的了,呵呵~~~~~~,不過不要高興太早,這種網絡游戲畢竟占少數,所以我會在以後的文章中對其他類型外掛做詳細解說,對了,請跟一下貼子,鼓勵一下,不然我真的沒有信心寫下面的文章了,謝謝)

  上回對五種類型的外掛做了一個大體的概括,大家對這幾種外掛都有了一定的了解,現在就依次(制作難度)由淺到深談談我對外掛制作的一些認識吧~~~~

  首先,先來談一下動作式的外掛,這也是我第一次寫外掛時做的最簡單的一種。

  記得還在“石器”時代的時候,我看到別人掛著一種軟件(外掛)人物就可以四外游走(當時我還不知道外掛怎麼回事^_^),於是找了這種軟件過來研究(拿來後才聽別人說這叫外掛),發現這種東東其實實現起來並不難,仔佃看其實人物的行走無非就是鼠標在不同的地方點來點去而已,看後就有實現這功能的沖動,隨後跑到MSDN上看了一些資料,發現這種實現這幾個功能,只需要幾個簡單的API函數就可以搞定:

  1、首先我們要知道現在鼠標的位置(為了好還原現在鼠標的位置)所以我們就要用到API函數GetCursorPos,它的使用方法如下:

BOOL GetCursorPos(
LPPOINT lpPoint // address of structure for cursor position
);

  2、我們把鼠標的位置移到要到人物走到的地方,我們就要用到SetCursorPos函數來移動鼠標位置,它的使用方法如下:

BOOL SetCursorPos(
int X, // horizontal position
int Y // vertical position
);

  3、模擬鼠標發出按下和放開的動作,我們要用到mouse_event函數來實現,具休使用方法用下:

VOID mouse_event(
DWord dwFlags, // flags specifying various motion/click variants
DWord dx, // horizontal mouse position or position change
DWord dy, // vertical mouse position or position change
DWord dwData, // amount of wheel movement
DWord dwExtraInfo // 32 bits of application-defined information
);

  在它的dwFlags處,可用的事件很多如移動MOUSEEVENTF_MOVE,左鍵按下MOUSEEVENTF_LEFTDOWN,左鍵放開MOUSEEVENTF_LEFTUP,具體的東東還是查一下MSDN吧~~~~~


 好了,有了以前的知識,我們就可以來看看人物移走是怎麼實現的了:

getcursorpos(point);
setcursorpos(ranpoint(80,windowX),ranpoint(80,windowY));//ranpoint是個自制的隨機坐標函數
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
setcursorpos(point.x,point.y);

  看了以上的代碼,是不是覺得人物的游走很簡單啦~~,舉一仿三,還有好多好東東可以用這個技巧實現(我早就說過,TMD,這是垃圾外掛的做法,相信了吧~~~),接下來,再看看游戲裡面自動攻擊的做法吧(必需游戲中攻擊支持快捷鍵的),道理還是一樣的,只是用的API不同罷了~~~,這回我們要用到的是keybd_event函數,其用法如下:

VOID keybd_event(
BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWord dwFlags, // flags specifying various function options
DWord dwExtraInfo // additional data associated with keystroke
);

  我們還要知道掃描碼不可以直接使用,要用函數MapVirtualKey把鍵值轉成掃描碼,MapVirtualKey的具體使用方法如下:

UINT MapVirtualKey(
UINT uCode, // virtual-key code or scan code
UINT uMapType // translation to perform
);

  好了,比說此快接鍵是CTRL+A,接下來讓我們看看實際代碼是怎麼寫的:

keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),0,0);
keybd_event(65,mapvirtualkey(65,0),0,0);
keybd_event(65,mapvirtualkey(65,0),keyeventf_keyup,0);
keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),keyeventf_keyup,0);

  首先模擬按下了CTRL鍵,再模擬按下A鍵,再模擬放開A鍵,最後放開CTRL鍵,這就是一個模擬按快捷鍵的周期。

  (看到這裡,差不多對簡易外掛有了一定的了解了吧~~~~做一個試試?如果你舉一仿三還能有更好的東東出來,這就要看你的領悟能力了~~,不過不要高興太早這只是才開始,以後還有更復雜的東東等著你呢~~)





  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved