欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    大家好,我是小杰。又是一個不尋常的周末,昨天我舍友終于做出了他的個人游戲,經過一個月的思考、畫圖和設計,完成了他的第一個作品。大概的功能都已經出來了ce進程沒有圖標,剩下的就是一些優化,新人物新特效之類的了,總的玩法應該不會有什么其他變化啦。——緊接著,今天的重頭戲要登場了,他的游戲的結束正是我工作的開始!我做出了我第一個真正意義上的游戲外掛,我周六的時候耗時一天,從利用CE找偏移地址、到找基地址,踩過了好多坑,最后使用C++調用操作系統API進行游戲的注入和內存修改。晚上的時候終于打包完成了預計的功能,!

    今天的文章想聽故事有故事,想要干貨有干貨,硬核知識還是夠硬核的,歡迎收藏、點贊加在看,一鍵三連。

    我以為技術無罪,失責當誅,今天從外掛的角度來看程序,也許會有不一樣的收獲,文章的重點不在于教你怎么做外掛,重點在學從中學到知識,所以話不多說,直接發車。

    前情提要

    首先來說一下我使用的工具,我使用的工具很簡單,一個耳熟能詳的Cheat 用來定位數據的內存位置, 2019使用MFC來開發界面,方便外掛的使用,其次谷歌瀏覽器(最好可以科學上網,別問我為什么,因為我今天遇到的問題我在百度就沒查到過,都是用英文在谷歌上搜到的,淚目)

    接下來看看Cheat 界面長什么樣子,具體就不展開介紹了(因為重點不是在于做外掛,而是學知識),非常強大的東西

    最初的計劃

    拿到舍友做的游戲以后,首先先來看看游戲是什么樣子的,我們的外掛想實現什么樣的功能,**實際可以實現什么樣的功能。**下面是游戲的截圖:

    簡單介紹一下游戲的玩法,從上面的圖就可以看出,這是一個雙人對戰游戲,首先它是一個單機游戲,那么所有的數據都是放在本地上的。所以我的機會不就來了!雙方可以得分,類似于羽毛球比賽的規則,上面雙方有進度條,進度條可以稱為怒氣,怒氣值滿了以后可以放技能,技能還是很炫的,不得不說我舍友的創意和水平還是有的,畢竟是第一次做游戲。

    玩了一會兒這個游戲之后,我覺得可以做成外掛的點有:

    記分板上面的分數應該是存在內存中的某個位置兩個小人可以左右移動,不可以上下移動,但是可以進行跳躍,因此坐標也是可以修改的點,最起碼是個一維坐標羽毛球每次重置會在上方停留幾秒,這期間是無法觸碰的,應該是有變量用來控制,極有可能是個布爾值怒氣是不斷上漲的,當漲到最高的時候可以釋放技能,可以做出無限放技能,鎖死上漲的進度條。

    實際上我最后并沒有實現無限技能這個功能,我的確找到了那個介于0到1之間 不斷上漲的值,但是我鎖定后并不會達到我要的效果,而是會出現畫面問題,進度條脫離原來的位置接著漲。

    可以看一下我最終實現的外掛效果圖:

    ce加載游戲進程無圖標_ce打開dnf沒圖標_ce進程沒有圖標

    界面上有的已經都實現了,最后的小球模式是根據計劃中的第三條是否可觸碰小球實現的

    外掛原理和細節從游戲的角度

    游戲的本質和一個應用程序沒有什么區別,只不過游戲的資源類型和種類更多一些罷了。游戲再打包發布后是由一個exe和一個甚至多個dll文件還有其他文件組成的。我們這里關心的是exe文件和dll文件,因為我們的函數、變量以及各種邏輯都是主要在這兩個里面。

    游戲運行的原理就是首先會給程序分配一個內存空間,并不是直接在內存中分配,而是一個虛擬的地址空間,正因為是虛擬的地址空間,所以才可以從程序的角度看我可以擁有超過硬件實際內存的大小(因為段表和頁表的存在,所以才得以實現,設計到操作系統原理這里就不展開了,以后也會詳細寫這塊兒內容的)。然而剛才說了exe和dll本質上它們其實是等價的,但是在內存中該怎么存放呢,目前來說都是把exe放到固定的位置。這里又不得不提靜態鏈接庫和動態鏈接庫。這兩種方式是不同的,所謂靜態鏈接會把庫和exe打包在一起,而動態鏈接則是在外部以dll文件形式存在(這里推薦我之前看過的《程序員的自我修養》這本書寫的很硬核,也很有深度,感興趣的可以去看看)。因此dll里面有相應函數的一些實現,在exe被加載后他們也會動態映射到程序空間的不同地址,比靜態鏈接靈活很多。那么問題就來了,dll每次都被加載到不同的地址空間。回到之前的話題,一個程序的所有東西就這樣都放在你的面前了,那么我們需要什么數據,直接就改什么數據不就好了嘛。

    從外掛制作的角度

    外掛的本質在于對數據的修改,我們利用CE這個強大的工具,可以方便的幫我們定位數據在什么地方,也可以直接修改,也可以直接鎖定讓這個數值不變。但是我們是要制作一個外掛,而不是每次都用CE去找。所以我們需要寫一個程序來幫我們做這件事,什么事情呢?就是幫我們找到數據的地址然后修改它,沒錯就是這么簡單。

    我們需要思考的問題:

    如何找到我們需要的地址,我們以修改分數這個為例來展開說一下(這篇文章的主要目的在于學習知識,而不是一個外掛教程,如果真的感興趣的話可以從公眾號后臺加我的聯系方式,和我深入探討,也可以加入我的技術群,一起交流)

    首先需要做的就是獲取進程,打開CE的進程列表,獲取到進程后,才可以讀寫游戲的內存

    緊接著,獲取到進程之后首先根據右邊積分板中的數值,我們在CE中進行搜索,找到數值為1的8字節的數

    注意這里用的是8字節,因為我們看它的內存地址就知道它是個64位的程序,這是個我反復踩的坑,之前一直用的4字節搜的。

    首次我們搜索到了68587個地址,這些地址里面都存的是1,那么到底哪個才是真正的地址呢,所以我們需要改變數值,讓游戲運行右邊得分,我們點再次搜索

    此時我們看到數量大大減少,計分板的本質是通過某個地址中的變量來改變數值顯示的,所以它一定會隨著得分的變化而同步變化,為什么會出現多個變量呢,因為可能游戲中本來就使用了多個變量(比如臨時變量,又或者是碰巧數一樣而已),總之我們要找的就是最同步變化的那個地址

    ce打開dnf沒圖標_ce加載游戲進程無圖標_ce進程沒有圖標

    經過多次重復這個過程,最終我們找到了那個唯一的地址,這個地址就是控制右邊記分板數值的變量,很簡單吧?

    這樣找出地址的確很簡單,但是我們現在是要寫外掛而不是找到這個地址,那么問題就來了。這個地址下次會不會變化呢,顯然答案是肯定的,要不我就不會花那么長的時間了。這個地址是在堆中或者在全局區的靜態變量,它的地址每次申請和分配都是不一樣的,怎么才能每次重新加載游戲,重啟游戲后都準確的找到這個地址呢,這就需要知道什么是基地址和偏移地址了。

    右擊這個地址選擇看看是什么寫入了這個地址,我們可以先看看下面這個圖,然后我再來細說一下,這個圖的理解很重要

    我們現在得到的這個是一個偏移地址,從圖中反匯編的匯編代碼中可以看到,mov [rdi+54],eax ,把eax寄存器中的數據寫入rdi寄存器中的地址再偏移54之后得到的地址。所以它不是一個固定的地址,每次rdi寄存器的地址是變化的但是這個54的偏移是不會變的。所以,根據rdi寄存器中的數值,我們再去CE中搜索,是哪個地址存放的是rdi里面的這個地址呢,也就是指針的指針

    我們最終要找的是基地址,基地址是一個有固定位置或者相對固定位置的地址,而且它與我們這個地址是有關系的,因為經過多次偏移可以最終得到我們現在存放記分板的變量的地址。聽起來有點繞是吧,那么我來畫個圖你就大概明白了。

    找基地址的辦法還是很多的,最簡單的辦法就是像剛才那樣一次一次的搜索,不斷地搜索指向當前這個地址,這種方法非常的繁瑣,而且會遇到找錯地情況。但是原理講起來很清楚所以我以這個為例。目前我知道地找基地址地辦法還有:**搜索指針映射法、人造指針法、特征碼搜索法。**我最終使用地就是搜索指針映射法,再說一遍這篇文章不是外掛制作教程!想研究可以聯系我私下討論。

    寫程序來修改 現在基地址已經找到了,那么接下來要做的事情就是寫代碼。用程序來幫我們做這個根據基地址找偏移地址并且修改地址中數值地這個過程。

    那么現在我們來理一下思路:

    首先我們應該獲取到窗口句柄,然后獲取到進程句柄,才能進行游戲地址空間地訪問基地址最終找到的是某個模塊的地址再偏移一個數值,所以還需要讀取并找到這個dll模塊到底被加載到了什么地址空間中拿到句柄以后我們需要根據之前找到地基地址,然后不斷地讀取地址,加上偏移量之后再次讀取變化后的地址,這種就類似于模擬指針的過程得到最后的內存我們就可以改變里面的數據了

    我來說說在這個過程中遇到的坑:

    系統位數限制

    ce進程沒有圖標_ce加載游戲進程無圖標_ce打開dnf沒圖標

    游戲是64位程序,我一開新建的是32位的程序,在調用操作系統函數的時候會發生獲取不到窗口句柄的情況,經過我不斷的網上查閱資料最終得到了兩種解決辦法。

    附加一些匯編代碼,突破這個限制,缺點就是非常的麻煩把我的程序改成64位程序,這樣函數一樣但是使用的是64位的dll庫,可以獲取的到,我果斷選擇了這一種基地址找不到

    我一開始采用的就是最原始的辦法,手動去找但是真的是特別麻煩,不僅需要自己去記錄每次的偏移量是多少,而且每次搜到的都是好幾個,我踩坑踩了好久最終我采用了第二種找基地址的辦法。能通過第一種辦法找到的還是原來的那種比如植物大戰僵尸這種老游戲,現代游戲引擎都比較復雜,我舍友這個游戲就是通過Unity引擎做的,因此采用那種真的太累了。當然現在的CE也很智能,難道這就是所謂的“道高一尺魔高一丈”? 哈哈,開個玩笑。

    界面太丑了

    我使用的是C++的MFC開發的,因為手頭只有這么個做界面的工具,界面真的超級丑!QT重裝電腦被我卸載了,沒辦法我就去網上找一些界面庫,但是找來找去用不了ce進程沒有圖標,那些界面庫大多都是32位的庫,不能放在我64位的程序中!最終沒有改成,還是使用這個丑界面將就用吧。

    那么接下來簡單的看看部分代碼吧:

    這個代碼是用來獲取目標程序的模塊位置,可以算的上是一個通用的了

    unsigned long long dwGetModuleBaseAddress(DWORD dwProcessID, TCHAR* lpszModuleName)
    {
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
     unsigned long long dwModuleBaseAddress = 0;
     if (hSnapshot != INVALID_HANDLE_VALUE)
     {
      MODULEENTRY32 ModuleEntry32 = { 0 };
      ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
    

    ce加載游戲進程無圖標_ce打開dnf沒圖標_ce進程沒有圖標

    if (Module32First(hSnapshot, &ModuleEntry32)) { do { if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) { dwModuleBaseAddress = (unsigned long long)ModuleEntry32.hModule; break; } } while (Module32Next(hSnapshot, &ModuleEntry32)); } CloseHandle(hSnapshot); } return dwModuleBaseAddress; }

    ce進程沒有圖標_ce打開dnf沒圖標_ce加載游戲進程無圖標

    下面這個是用來根據窗口的名字獲取程序句柄的代碼

     hwnd = ::FindWindow(0, L"XXXXXXXXXXXXX");
     if (hwnd)
     {
      GetWindowThreadProcessId(hwnd, &pid);
      phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
      if (!phandle) {
       AfxMessageBox(_T("未獲取到進程句柄!"));
      }
     }
    

    故事結尾

    好了,到這兒差不多結束了,很抱歉的我代碼不能開源。首先總不能“游戲未發,外掛先行”吧?其次本文僅供學習并不是外掛教學,有興趣可以私下聯系我。目前這個游戲是單機版,不知道他之后會不會改成網絡游戲,改成網絡游戲之后數據就放在服務器上了,比如記分板,和人物坐標,我們的外掛也會有好多限制,但是可以對網絡封包進行截取和修改,也算多了一個新的思路。希望我們共同學習、共同進步!

    最后期待這個游戲的可以再等一等,技能特效和新人物還是很棒的,游戲還未發行,我就不劇透了,原創不易,到現在已經寫了四個小時了,歡迎關注,我會寫出更多高質量文章!

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有