1. 程式人生 > >簡單遊戲外掛製作教程

簡單遊戲外掛製作教程

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

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

2、本地修改式,這種外掛跟傳統上的一些遊戲修改器沒有兩樣,做這種外掛在程式設計只需要對記憶體地址有一點認識並且掌握

API就可以實現,精靈的外掛這是這種方式寫成的,它的難點在於找到那些地址碼,找地址一般地要藉助於別人的工具,有的遊戲還有雙碼校驗,正正找起來會比較困難。(這種外掛,比上一種有一點點難度,但是這種外掛做起來能夠用,也是有一定難度的啦~~,這種外掛可以很快提升你對記憶體地址的理解及應用,是你程式設計技術提高的好東東) 

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

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

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

  這幾種外掛之中,前三種可以用VB,DELPHI等語言比較好實現,後兩種則要用VC等底層支援比較好的程式設計工具才好實現。 

現在就依次(製作難度)由淺到深談談我對外掛製作的一些認識吧~~~~ 


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

VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要VB API函式:
FindWindow                              ←尋找視窗列表中第一個符合指定條件的頂級視窗 
GetWindowThreadProcessId       ←獲取與指定視窗關聯在一起的一個程序和執行緒識別符號
--------------------------------------------------------------------------------------------------------------------------------------------------------
相關API宣告:
FindWindow

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

GetWindowThreadProcessId 

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) 
As Long
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要的控制元件:LabelTimer
--------------------------------------------------------------------------------------------------------------------------------------------------------   自定義函式:
Dim hwnd As Long
--------------------------------------------------------------------------------------------------------------------------------------------------------   原始碼:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long)As Long
Private Sub Timer1_Timer()
Dim hwnd As Long' 儲存 FindWindow 函式返回的控制代碼
hwnd = FindWindow(vbNullString, "Windows Media Player")' 取得程序識別符號
'只要把Windows Media Player換成遊戲的名稱就可了!
If hwnd = 0 Then
Label1.Caption = "遊戲未執行"
Else
Label1.Caption = "遊戲已執行"
End If
End Sub


VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
相信大家,在製作遊戲外掛的時候,都會用到FPE、金山遊俠、GE修改器、Game Master8.0等等這些軟體,但是如今的網路遊戲基本上都加了NP,下面來了解一下NP。知己知彼,百戰不殆嘛!
什麼是nProtect
nProtect是設計用於保護個人電腦終端不被病毒和黑客程式感染的新概念的基於網路的反黑客和反病毒的工具。他幫助確保所有輸入個人電腦終端的資訊在網路上不落入黑客手中。在終端使用者在執行電子貿易時,可以通過將nProtect配置在那些提供電子商務、進口貿易,電子貿易的金融機構的網站上,來提高安全等級。nProtect怎樣工作?nProtect是一種基於伺服器端的解決方案並且當那些需要保護的任何網路應用被執行時而自動啟動。nProtect被載入記憶體,所以終端使用者不需要安裝任何應用程式,只要nProtect啟動,就開始拒絕黑客工具和病毒的入侵!
--------------------------------------------------------------------------------------------------------------------------------------------------------
下面介紹它如何工作:
使用者登陸時nProtect自動啟動。
瀏覽器確認和自動安裝安全模組到使用者的個人電腦。掃描黑客工具和病毒通知使用者目前的安全狀態如果有黑客工具和病毒嘗試刪除在被入侵時端駐留記憶體來鎖定黑客工具直到電腦或者nProtect關閉。
可惡的韓國人,把這個加進了網路遊戲。我只能說:呸!” 
-------------------------------------------------------------------------------------------------------------------------------------------------------- 
下面講講躲過NP的掃描的幾個方法:
一、FPE
臺灣人開發的東西,哎。出名了的,沒辦法誰叫它這麼好呢!
1.先裝一個FPE把,呵呵這個是廢話! 
2.不要把安裝程式刪除,按照:開始執行→regedit→HEKY_LOCAL_MACHINE→SOFTWARE
→jaw→FPE 開啟!(問:有什麼用? 答:修改呀!)
3.執行FPE,然後在搜尋裡面輸入 'jaw'(一定要家'')一般是6個地址,然後全部都選中輸入:
313131c313131(意思就是111,兩邊多輸入31就是1111!)不要關FPE!(關了就完了!)
4.修改登錄檔,把登錄檔裡面的jawFPEFPE的是全改)關閉FPE出現對話方塊。(什麼鳥語不認識!呵呵)
5.將現在FPE的資料夾修改為1112000(原來是FPE2000撒),把FPE.exe修改為111.exe
6.然後重新安裝一次FPE也把那個DLL檔案複製到你修改過的FPE檔案目錄下!(呵呵!)
7.FPE進遊戲裡面亂來拉!哈哈
--------------------------------------------------------------------------------------------------------------------------------------------------------



二、工作管理員篇
比爾·蓋茨那崽兒設計的東西,還可以在這上面派上用場!(問:是什麼東西?答WINDOWS自帶的撒!呵呵!)
1.首先用快捷鍵Ctrl+Alt+Delete/.開啟工作管理員
2.檢視程序,一般垃圾點的網路遊戲會出現多的程序。你就殺了就行了!
3.沒有多的程序怎麼辦?BIN這個是大多數網路遊戲都有的把,官方的登陸器和私服的登陸器一樣的,都是呼叫BIN進入遊戲。登陸器開啟後,更新完畢。點選運行遊戲,間隔幾秒殺掉登陸器的程序(這個要看你自己的計算機配置如何了,可能是2秒、可能是10秒!反正不超過15秒)這樣就可以閉屏NP拉!
呵呵又可以亂來了!
--------------------------------------------------------------------------------------------------------------------------------------------------------


三、直接篇
直接篇說白了就不用任何東西!怎麼做?跟著我眼鏡來撒!
《封神榜》知道把?(答:不知道!反答:去死!)它的保護是有的,官方都已經公佈了
但是有些人說《封神榜》沒NP,(注意:NP現在就是保護的代名詞了!)別聽那些人的!
首先,執行登陸器(更新的那個)進入遊戲。關閉用登陸器進入的遊戲馬上執行Game.exe
呵呵,沒NP了。FPE等東西可以亂來了。魔法疊加、免負重等等都可以實現!
還有一種就是DAT檔案或者BIN檔案直接修改為EXE。呵呵!
--------------------------------------------------------------------------------------------------------------------------------------------------------


四、程式設計篇(VBVCDELPHI等等!)
怎麼辦呢?呵呵,我不懂怎麼編VCDELPHI的。***我就喜歡VB怎麼著?
VB可以簡單的實現虛擬nProtect的訊息傳送。具體的就不說了!
一句話虛擬nProtect訊息(你不等於沒說嘛!)-_-!呵呵這個嘛......
程式碼就不寫了,麻煩。就像用WPE這些發包一樣的原理




VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
躲避了NP的掃描現在就可以模擬了!
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要VB API函式:
keybd_event                             ←函式模擬了鍵盤行動
--------------------------------------------------------------------------------------------------------------------------------------------------------
相關API宣告: 
keybd_event

Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal Scan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要的控制元件:Timerinterval不為空)
--------------------------------------------------------------------------------------------------------------------------------------------------------
程式碼:
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal Scan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) 
Private Sub Timer1_Timer()
Call keybd_event(82, 0, 0, 0) '模擬按下"R"
End Sub
--------------------------------------------------------------------------------------------------------------------------------------------------------
其它模擬:
方法一:
   AppActivate sTitle
   SendKeys "5"
方法二:
   AppActivate sTitle
   SendKeys vbKey5
方法三:
   SendMessage Hwnd, WM_KEYDOWN, vbKey5, 0&
   SendMessage Hwnd, WM_KEYUP, vbKey5, 0&
方法四:
   AppActivate sTitle
   keybd_event 53, 0, 0, 0
   keybd_event 53, 0, KEYEVENTF_KEYUP, 0
方法五:
   PostMessage lHwnd, WM_KEYDOWN, vbKey5, 0&
   PostMessage lHwnd, WM_KEYUP, vbKey5, 0&
--------------------------------------------------------------------------------------------------------------------------------------------------------

VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
新增快捷鍵
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要VB API函式:
GetAsyncKeyState                             ←判斷函式呼叫時指定虛擬鍵的狀態 
--------------------------------------------------------------------------------------------------------------------------------------------------------
相關API宣告: 
GetAsyncKeyState 

Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Long) As Integer
Private Function MyHotKey(vKeyCode) As Boolean
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要的控制元件:Timerinterval不為空)
--------------------------------------------------------------------------------------------------------------------------------------------------------
程式碼:
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Long) As Integer
Private Function MyHotKey(vKeyCode) As Boolean
MyHotKey = (GetAsyncKeyState(vKeyCode) < 0)
End Function
'然後在迴圈中或TimerTimer事件中檢測:
Private Sub Timer1_Timer()
If MyHotKey(vbKeyA) And vbKeyControl Then   'ctrl+A
End  '關閉
End If
'其中vbkeyA是鍵盤〃A〃的常數,其他鍵可按F1查得。
End Sub
--------------------------------------------------------------------------------------------------------------------------------------------------------
其它方法:
比如按下"ctrl+A"就退出!
'可以設定FormKeyPreview屬性為True,然後在Form_KeyDown事件中新增程式碼: 
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)      
If KeyCode = Asc("A") And Shift = vbCtrlMask Then  unload me '如果ctrl+A鍵被按下就退出
End Sub 
--------------------------------------------------------------------------------------------------------------------------------------------------------


VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
前邊談了模擬鍵盤,下面說說模擬滑鼠。
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要VB API函式:
mouse_event                             ←模擬一次滑鼠事件
--------------------------------------------------------------------------------------------------------------------------------------------------------
相關API宣告: 
mouse_event

Private Declare Sub mouse_event Lib "user32"  ( ByVal dwFlags As Long, ByVal dx As Long,  ByVal dy As Long,  ByVal cButtons As Long, ByVal dwExtraInfo As Long  )
--------------------------------------------------------------------------------------------------------------------------------------------------------
定義變數:
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_MOVE = &H1
Const MOUSEEVENTF_ABSOLUTE = &H8000
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10
--------------------------------------------------------------------------------------------------------------------------------------------------------
MOUSEEVENTF_LEFTDOWN'滑鼠左鍵按下
MOUSEEVENTF_LEFTUP'滑鼠鬆開
MOUSEEVENTF_RIGHTDOWN '滑鼠右鍵按下
MOUSEEVENTF_RIGHTUP'滑鼠右鍵鬆開
--------------------------------------------------------------------------------------------------------------------------------------------------------
程式碼:
Private Declare Sub mouse_event Lib "user32"  ( ByVal dwFlags As Long, ByVal dx As Long,  ByVal dy As Long,  ByVal cButtons As Long, ByVal dwExtraInfo As Long  )
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_MOVE = &H1
Const MOUSEEVENTF_ABSOLUTE = &H8000
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10
'這裡是 滑鼠左鍵按下 和鬆開兩個事件的組合即一次單擊
mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
'模擬滑鼠右鍵單擊事件
mouse_event MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
'兩次連續的滑鼠左鍵單擊事件 構成一次滑鼠雙擊事件
mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
--------------------------------------------------------------------------------------------------------------------------------------------------------



VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
應用實戰
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要VB API函式:
FindWindow 
GetWindowThreadProcessId 
OpenProcess
ReadProcessMemory
CloseHandle
--------------------------------------------------------------------------------------------------------------------------------------------------------
相關API宣告:
FindWindow

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

GetWindowThreadProcessId 

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) 
As Long

OpenProcess

Private Declare Function OpenProcess Lib  "kernel32" (ByVal  dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal  dwProcessId As Long) As Long

ReadProcessMemory

Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

CloseHandle

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

GetCurrentProcess

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
--------------------------------------------------------------------------------------------------------------------------------------------------------
需要的控制元件:LabelTimerinterval不為空)、Text
--------------------------------------------------------------------------------------------------------------------------------------------------------
定義函式:
Dim SetHp As Integer        ' 定義設定的體力值
Dim SetMp As Integer         ' 定義設定的魔法值
Dim NowHp As Long           ' 定義目前的體力值
Dim NowMp As Long           ' 定義目前的魔法值
Dim MaxHp As Long           ' 定義角色的最高體力值
Dim MaxMp As Long          ' 定義角色的最高魔法值
Dim DiZhi As Long              '定義記憶體地址函式
Dim hwnd As Long              ' 儲存 FindWindow 函式返回的控制代碼
--------------------------------------------------------------------------------------------------------------------------------------------------------
程式碼:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) 
As Long
Private Declare Function OpenProcess Lib  "kernel32" (ByVal  dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal  dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Dim SetHp As Integer        ' 定義設定的體力值
Dim SetMp As Integer         ' 定義設定的魔法值
Dim NowHp As Long           ' 定義目前的體力值
Dim NowMp As Long           ' 定義目前的魔法值
Dim MaxHp As Long           ' 定義角色的最高體力值
Dim MaxMp As Long          ' 定義角色的最高魔法值
Dim DiZhi As Long              '定義記憶體地址函式

Private Function ncnr(lpADDress As Long) As Integer
   ' 宣告一些需要的變數
   Dim hwnd As Long        ' 儲存 FindWindow 函式返回的控制代碼
   Dim pid As Long         ' 儲存程序識別符號( Process Id )
   Dim pHandle As Long     ' 儲存程序控制代碼
   hwnd = FindWindow(vbNullString, "封神榜·網路版")
   ' 取得程序識別符號
   GetWindowThreadProcessId hwnd, pid
   ' 使用程序識別符號取得程序控制代碼
   pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
   ' 在記憶體地址中讀取資料
   ReadProcessMemory pHandle, lpADDress, ByVal VarPtr(ncnr), 4, 0&
   ' 關閉程序控制代碼
   CloseHandle hProcess
End Function
Const STANDARD_RIGHTS_REQUIRED = &HF0000
Const SYNCHRONIZE = &H100000
Const SPECIFIC_RIGHTS_ALL = &HFFFF
Const STANDARD_RIGHTS_ALL = &H1F0000
Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
Const PROCESS_VM_OPERATION = &H8&
Const PROCESS_VM_READ = &H10&
Const PROCESS_VM_WRITE = &H20&


Private Sub Form_Load()
 ' 體力:07F68F3 這裡替換你所搜尋到的地址 魔法:07F6860 同前
   DiZhi = &H07F68F3
   Timer1.Enabled = True
   Timer2.Enabled = False
   Timer3.Enabled = False
End Sub

Private Sub Timer1_Timer()
   Dim hwnd As Long
   hwnd = FindWindow(vbNullString, "封神榜·網路版")
   
   If hwnd = 0 Then
       Label12.Caption = "遊戲未載入"
       Timer1.Enabled = True
       Timer2.Enabled = False
       Timer3.Enabled = False
       Exit Sub
   End If

   Label12.Caption = "遊戲已載入"
   SetHp = Text1.Text          ' 獲取設定的體力值
   SetMp = Text2.Text          ' 獲取設定的魔法值
   NowHp = ncnr(DiZhi)         ' 獲取當前的體力值
   NowMp = ncnr(DiZhi + 12)    ' 獲取當前的魔法值
   MaxHp = ncnr(DiZhi + 4)     ' 獲取角色的最高體力值
   MaxMp = ncnr(DiZhi + 16)    ' 獲取角色的最高魔法值
   Label3.Caption = Str(NowHp) + "/" + Str(MaxHp)      ' 顯示角色體力值狀態
   Label4.Caption = Str(NowMp) + "/" + Str(MaxMp)      ' 顯示角色魔法值狀態

   If Check1.Value Then
       Timer2.Enabled = True
   Else
       Timer2.Enabled = False
   End If
   If Check2.Value Then
       Timer3.Enabled = True
   Else
       Timer3.Enabled = False
   End If
End Sub

Private Sub Timer2_Timer()
   ' 體力值小於設定值按下數字鍵1
   If (NowHp) < SetHp Then
       SendKeys "1"
   End If
End Sub

Private Sub Timer3_Timer()
   ' 魔法值小於設定值按下數字鍵2
   If (NowMp) < SetMp Then
       SendKeys "2"
   End If
End Sub
--------------------------------------------------------------------------------------------------------------------------------------------------------
軟體截圖:

--------------------------------------------------------------------------------------------------------------------------------------------------------


VB 從零開始編外掛(
--------------------------------------------------------------------------------------------------------------------------------------------------------
鉤子:喜歡外掛的人都知道,很多外掛都是在遊戲當中才能撥出。這個就用到了鉤子
N多人說:哎,VB做鉤子想都別想!去學C語言吧!只要大家遇到這種人,就別理會他。
可以說他是個垃圾。在實現鉤子方面VB可能沒有VC快,但是也不像那種人說的想都別想
C語言,我最近幾天看了看。{ } ;這些太多了。腦袋也大了!可能那些學C語言的人是接觸電腦
程式設計的時候就學的它吧!但是呢,我接觸電腦學的就是VB。沒辦法我愛它!