1. 程式人生 > >遊戲外掛制作原理

遊戲外掛制作原理

成了 而是 要點 需要 找到 mem 資料 mark 了解

外掛現在大體上來講分為三種,分別是模擬按鍵,WPE封包和內存掛。比如模擬鍵盤的,鼠標的,這種就叫做按鍵模擬,也叫腳本精靈;還有修改數據包的,這種就叫做WPE封包外掛,這種外掛相對而言比較穩定,但是對於技術要求難度也比較高,因為修改WPE封包,你需要知道和了解加密解密算法等等一系列的知識;還有最後一種就是修改本地內存的,這種相對而言比較常見,市場上面比較常見的也是這種遊戲外掛,相對而言技術要求也不是太高,資料也比較齊全,比較大眾;但好像沒有修改服務器內存的哦,呵呵。其實修改服務器也是有辦法的,只是技術太高一般人沒有辦法入手而已。這裏就記一下本地修改內存的外掛制作原理。

   其實,制作內存掛也不是很難,步驟就這麽幾步。第一步,找遊戲數據內存地址,偏移地址;第二步,修改內存地址的值,達到外掛的目的;第三步,用編程語言寫出一個程序,使得外掛方便於攜帶傳輸,同時也方便於下次玩遊戲直接使用。其實第三步主要是方便使用,方便販賣等等,很多時候對於一個高手而言,根本不需要寫出來,記錄下內存地址,偏移地址以後,下次上遊戲直接工具裏面修改就是了。但是如果經常玩某個遊戲,可以寫出來,用不著每次玩遊戲都去修改。

外掛開發第一步——找遊戲內存地址
說道找遊戲內存地址,偏移地址,這可能是整個遊戲外掛開發中最難的一步,因為一個大型的網絡遊戲,可能一個技能或者血條的內存基址可能會偏移很多次,最後才得到一個內存地址也叫物理地址。那麽,這裏有個問題來了,我們為什麽要找技能或者血條的內存基址?不是直接修改物理地址就行了嗎?這樣是不行的,因為物理地址是會變動的;舉個例子,每次關閉遊戲重新啟動以後,遊戲進程是會變動的,同樣的,遊戲代碼在內存中的存放位置,因為遊戲結束以後,釋放掉了內存地址,這個內存地址可能會被其他程序所占用,所以是會變動的;當你關閉遊戲重新進入以後,遊戲的技能或者血條在內存中的物理地址就變了。但是,遊戲技能或者血條的內存基址是不會變動的,在內存中的物理地址不管怎麽變動,內存基址都不會變動。那麽內存基址和物理地址之間是一種什麽樣的關系呢?看下面這個公式:

物理地址 = 一級偏移地址 + 偏移地址
一級偏移地址 = 二級偏移地址 + 偏移地址
二級偏移地址 = 三級偏移地址 + 偏移地址
三級偏移地址 = 遊戲技能基址 + 偏移地址
如上公式,一個遊戲的物理地址是等於這個遊戲的基址加上偏移地址的,所以,想要每次重新進入遊戲都能夠找到準確的物理地址進行修改內存地址的值,達到外掛的目的的話,就必須找到這個物理地址當前對應的偏移地址和基址,只有這樣才能夠確保每次登陸遊戲都能夠修改物理地址的值。下面,就通過《植物大戰僵屍》這款經典的單機遊戲來演示一下找這款遊戲的內存基址的過程。
首先,介紹一款找遊戲內存基址的工具Cheat Engine簡稱CE,Cheat Engine是一款內存修改編輯工具 ,它允許修改遊戲或軟件內存數據,以得到一些其他功能。它包括16進制編輯,反匯編程序,內存查找工具。與同類修改工具相比,它具有強大的反匯編功能,且自身附帶了外掛制作工具,可以用它直接生成外掛。好了,這個工具的具體介紹有興趣的去百度,這裏也就是百度了一下,簡單的說了一下這個工具的作用,下面,打開植物大戰僵屍,打開CE,在CE中找到植物大戰僵屍,附加到CE中去,如圖所示:

技術分享圖片
技術分享圖片
遊戲附加到OD以後,看自己想修改哪兒的內容,就去找對應的內存基址,怎麽找呢?比如修改無限陽光吧;首先,看一下最開始的陽光是多少?比如這裏,開局陽光是50,就在CE中數值一項輸入50,掃描類型選擇精確數值在數值類型選擇4字節然後點擊首次搜索,這裏不懂為什麽這樣選擇的,自己百度科普一下基礎知識。如圖所示:
技術分享圖片
如上圖所示,出來了這麽多的地址,究竟哪一個是我們想要的物理地址呢?接下來就需要在遊戲中改動一下陽光的值,然後點擊再次搜索,結果就會出來了,如圖所示:
技術分享圖片
技術分享圖片
如上第二幅圖所示,我們想要的物理地址就出來了,把這個地址添加到地址列表中去,然後修改一下陽光的值,確認一下是不是想要的地址,不過這裏要註意,在修改的時候,我們需要點擊列表地址中我們拉下來的這一行的數值這一欄,其他是修改地址和字節類型用的,不要亂動,如圖所示:
技術分享圖片
如上圖所示,這就是我們想要的物理地址,這裏我們可以鎖定這個內存地址的值,一直是100或者200或者更多。只需要點擊前面激活這一欄選中就行了,從而達到鎖定陽光值的效果。但是當關閉遊戲,重新進入,這個地址就沒用了,又需要重新找。所以,這裏就需要找到真正的陽光值的基址和偏移地址,那麽,怎麽找呢?我們找到這個物理地址以後,就右鍵,選擇找出是什麽改寫了這個地址也就是快捷鍵F6這個名字每個版本的漢化效果都不一樣的,這裏就會彈出一個窗口,是空白,然後我們再到遊戲中改變陽光的值,看看這個空白窗口中出現的代碼,如圖所示:
技術分享圖片
技術分享圖片
技術分享圖片
如上圖三所示,分析這兩條代碼,看見最終都指向了一個指針數值17C88118,然後我們分析一下這兩條代碼什麽意思,相信稍微懂一點匯編語言的人都能夠看懂。首先分析一下mov [edi+00005560],esi這條指令,我們在詳細信息中看見,寄存器esi中的代碼是000026DE這個值換算成十進制剛好是9950,那麽這個9950是怎麽來的呢?其實就是剛剛我在做上一步的時候,說了要變動遊戲中的陽光值,所以我先直接把陽光值修改成了10000,然後種了一個石頭,剛好是50,所以陽光值發生了變化,這條指令mov [edi+00005560],esi就是把寄存器esi的9950的陽光值放入edi+00005560這個地址中去,這個地址是誰呢?其實這個地址就是剛剛找出來的物理地址,剛好滿足前面的公式:物理地址 = 陽光基址地址 + 偏移地址不信的朋友可以自己加一下算一算,用寄存器edi裏面的指針數值17C88118加上偏移地址00005560看看是不是等於陽光物理地址17C8D678。接下看看add [eax+00005560],ecx這條指令,add指令是相加的意思,前面的mov是賦值或者移動的意思,這條代碼的意思就是,把ecx寄存器中的值加入[eax+00005560]這個地址中的值當中去,再看看寄存器eax的地址是多少?剛好又是17C88118這個指針數值,那麽,我們就可以確定一個事情,那就是17C88118這個指針數值,肯定是上一級的地址的指針數值,那麽上一級要麽是基址,要麽還是一個不偏移地址,這個需要進一步來確認。怎麽確認呢?這裏不是出來了17C88118這個指針數值嘛,再次放到CE中搜索一波,看看這個值對應的地址是多少,看看出來的是一個動態地址還是靜態地址,這裏需要普及一個知識點,在CE中,黑色的地址表示動態地址,綠色的表示靜態地址,那好,丟到CE中搜索,這裏這個值是十六進制的,所以在搜索的時候,需要勾選搜索框前面的hex,也就是十六進制搜索的意思,這裏填好以後點擊新的掃描,首次掃描如圖所示:
技術分享圖片
這裏可以看見結果為56個地址,這麽多,我們怎麽來確認究竟是哪個呢?可以看見還有很多紅色的地址。其實,這裏的紅色的地址,是一直在改變的地址,我們不用管它,直接點擊再次掃描,把這些紅色的過濾掉,然後看看還剩下的地址有哪些,如圖所示:技術分享圖片
多次點擊再次掃描以後發現不管怎麽點擊都剩下來了52個結果,然後看了一下這些結果中並沒有綠色的靜態地址,並且其他地址開頭幾位都比較像,唯獨如圖所示兩個地址比較特殊,這兩個可能就是我們需要的地址了,後來我也去百度了一波,結果所說的是這種開頭比較像的是數組,也就是說,遇到這種,基本都不是我們需要的地址,直接放棄,把這兩個特殊的拉進下邊的地址列表,開始分析,雙擊地址這一欄,在出來的更改地址窗口中復制下這個地址,然後再勾選指針選項,在出來的內容框中填寫入剛剛復制的地址,在上面的內容框中寫入剛剛找到的00005560這個偏移地址,得到的結果剛好是陽光的物理地址,最後的陽光值也正好和當前的陽光值一樣,並且,這兩個地址都是一樣的,而且都是動態地址,如圖所示:技術分享圖片
技術分享圖片
如上圖所示,這兩個地址加上偏移地址都可以得到陽光物理地址,那麽哪個才是我們所需要的真正的一級偏移地址呢?這裏就需要我們對這兩個地址進行詳細的分析了,同樣的右鍵–找出是什麽訪問了這個地址,也就是快捷鍵的F5,這裏一定不要搞混淆了,前面是找出是什麽改寫了這個地址,不一樣的!我們進去以後也是和前面一樣出來一個窗口,但是這兩個窗口裏面的內容就不一樣了,第一個地址0264A400在F5找出是什麽訪問了這個地址以後的窗口中會出現內容,但是第二個地址0956BD3C在出現的窗口裏面是一片空白,所以,這兩個地址中,0264A400才是我們要找的真正的一級偏移地址,如圖所示:
技術分享圖片
技術分享圖片
如上第二幅圖所示,找到了真正的一級偏移地址0264A400後,訪問這個地址的窗口中看這些代碼指令,通過對比,發現這些代碼都指向同一個指針數值02649C98且都有偏移地址00000768,如圖所示:
技術分享圖片
如上圖所示,既然所有的代碼都指向了同一個指針數值02649C98那麽就繼續按照前面找一級偏移地址的辦法,丟到CE中,繼續新的十六進制搜索,搜索指針數值02649C98以後得到如下圖所示的結果:技術分享圖片
如上圖所示,一共搜索到923個地址,而且還有幾個綠色的靜態地址,這裏我們就可以嘗試一下了,看看這幾個綠色的靜態地址究竟是不是我們想要的陽光基址,同樣的原理,我們把幾個綠色的靜態地址拉到地址列表中,在地址這一欄雙擊,在出來的更改地址窗口中復制下這個地址,然後再勾選指針選項,在出來的內容框中填寫入剛剛復制的地址,在上面的內容框中寫入剛剛找到的00000768這個偏移地址,然後再點擊添加偏移在出來的內容框中輸入剛剛第一次找到的00005560這個偏移地址,得到的結果剛好是陽光物理地址和陽光當前的值,並且這幾個靜態地址的結果都是一樣的。這裏需要說明一下,為什麽這裏要填寫兩個偏移地址,因為剛剛第一次找到的是一級偏移地址,這次是二級偏移地址了,所以,這裏

陽光物理地址 = 一級偏移地址 + 偏移地址
一級偏移地址 = 陽光基址 + 偏移地址
陽光物理地址 = 陽光基址 + 第一次的偏移地址 + 第二次的偏移地址
如圖所示:
技術分享圖片
技術分享圖片
技術分享圖片
如上四幅圖所示,四個靜態地址最終結果都是一樣的,都可以用作陽光基址,那麽就隨便取一個就行。這樣,陽關的基址和偏移地址就找到了,陽光的基址和偏移地址如下:

陽光基址:006A9EC0
一級偏移:00000768
二級偏移:00005560

這裏可能有人會問,一級偏移地址不是我們第一次找出來的地址嗎?你這裏的一級偏移不應該是00005560嗎?對,也不對,我這裏所說的一級偏移不是一級偏移地址的偏移,而是基於陽光基址的一級偏移,可以理解為從陽關基址開始,第一次偏移是00000768第二次偏移才是00005560,這樣做主要是為了方便後面寫代碼。好了,這就是找遊戲基址的思路,同樣的道理,還可以找植物冷卻時間,不過找冷卻時間思路不太一樣,因為冷卻時間我們不知道具體的值,可以通過找未知的初始化值的方式來找,也可以通過字節的方式來找,具體詳見百度,我這裏只是把找遊戲內存基址的思路和過程中怎麽分析的給寫了出來,免得後人掉坑,比如我在找植物冷卻時間的時候,就掉了一個坑,我是通過字節的方式來找來找的,通過植物冷卻的時候為0,冷卻好了為1找到了物理地址以後,在找一級偏移地址的時候,忘記把搜索方式字節換為4字節型了,找了半天沒找到!其他思路是一樣的!

外掛開發第二步——修改遊戲內存地址的值
其實,這一步就比較簡單了,比如陽光的值,找到了以後,我們每次上遊戲,直接在CE的地址列表框中手動添加地址,把像上面我們驗證這幾個基址的時候一樣,把基址,偏移地址填寫好,然後在數值這一欄雙擊,修改數值成為我們想要的陽光值就可以了,冷卻就把數值改為1即可,這一步就不用過多的提及了!

外掛開發第三步——編寫遊戲外掛
其實編寫外掛只有會寫程序的人都知道該怎麽弄了,只要找出來想要的功能的內存基址,偏移等,直接在程序中寫上讀取和寫入內存地址就行了,比較簡單,我大概說一下就好了,就是在外掛軟件啟動以後,我就讀取植物大戰僵屍的遊戲進程ID,然後讀取陽光的物理地址,加以輸出顯示,然後在啟動窗口創建完畢的時候還加一個定時器,達到實時監控陽光值的目的,然後設置了幾個按鈕,分別是增加陽光、鎖定陽光、鎖定冷卻時間和減少陽光、取消鎖定陽光、取消鎖定冷卻時間。下面分別來說一下幾個按鈕怎麽實現功能的。

增加陽光
增加陽光就定義了一個全局變量,變量中獲取輸入框中的值,然後讓陽光物理地址裏面的值加上輸入的值,就達到了增加陽光的目的!

WriteMemory函數實現

減少陽光
減少陽光和增加陽關的寫法一模一樣,只不過把陽光物理地址裏面的值設置為了減去輸入的值而已,這樣就達到了減少陽關的目的!

WriteMemory函數實現

鎖定陽光
鎖定陽光我定義了一個定時器,設置周期為999毫秒,然後設置了陽光固定值1000。當按鈕鎖定陽光被單擊以後,就執行這個定時器的周期,也就是每隔999毫秒執行一次定時器下面的代碼,也就是執行在陽光物理地址中改陽光的值為1000,這樣就達到了鎖定陽光的目的!

SetTimer WriteMemory函數實現

取消鎖定陽光
取消鎖定陽光其實就是把鎖定陽光這個定時器的周期設置為0,當取消鎖定陽光的按鈕被單擊以後,就執行這個定時器周期事件,定時器下面的代碼也就不執行了,達到了取消陽光鎖定的目的!
後面的鎖定冷卻時間和取消鎖定冷卻時間的原理和上面鎖定陽光和取消鎖定陽光的原理一樣,就不再做詳細的解釋了,因為我這裏針對每個欄位的植物做了單獨的冷卻鎖定和取消鎖定,所以代碼比較長,其實在找植物冷卻時間的時候,可以配合OD,直接找到冷卻時間前面的循環幹掉,這樣所有的植物欄的冷卻時間都沒了!

KillTimer函數實現

總結
其實不管是單機遊戲也好,還是網絡遊戲也罷,原理都一樣,只不過,可能遊戲類型不同,所需要的東西也不一樣,比如射擊類遊戲,就需要D3D技術來做人物透視的定位等等,這個具體的方法,可以百度參考。但是萬變不離其中,都是找內存基址,找偏移地址。最後感興趣的朋友可以加群一起閑聊qq群947405150,一起交流技術群947405150。

遊戲外掛制作原理