一步一步教你寫DOTA外掛程式

2021-08-26 13:21:50 字數 3126 閱讀 8320

好久木有研究dota了,整理篇小菜文章。

首先,我們要提公升外掛程式本身程式許可權,使其能夠有許可權修改war3遊戲的記憶體。這個c++可以使用如下**

void enabledebugpriv()//提公升程式自身許可權 tkp.privilegecount = 1; tkp.privileges[0].luid = sedebugnamevalue; tkp.privileges[0].attributes = se_privilege_enabled; if (!adjusttokenprivileges(htoken, false, &tkp, sizeof tkp, null, null)) closehandle(htoken); }

其次,有了許可權以後,我們要找到war3.exe程序id。並開啟程序以供編輯修改記憶體,到達目的。

獲得程序id:下面這個函式方法就是返回程序的,直接寫程序名稱,如:getpidforprocess(「war3.exe」),還可以用findwindow的方法,反正能找到程序id就可以了。

注意:有的名稱為war3.exe或war3.exe,用toolhelp32方式需要比較程序名字,這時是會區分大小寫的。findwindow則不用,視窗標題都是固定的warcraft iii。

程序id已經找到,現在是不是直接開啟修改記憶體呢?不,還早呢。我們修改記憶體也不能亂來,你得先找到game.dll判斷遊戲版本,對應修改,要不會把魔獸搞火了,突然跳出來,那你就崩潰了,後悔都來不及。有木有,有木有?開圖導致遊戲崩潰的老實交代一下。

下面的方法獲取game.dll的基址和路徑。getdllbase(「game.dll」,pid)直接返回的就是game.dll的基址,這個後面是需要用到的。定義乙個全域性變數tcharlastdllpath[260],lastdllpath返回的就是game.dll路徑,。

dword getdllbase(char* dllname, dword tpid) }while(module32next(snapmod,&me32)); } else closehandle(snapmod); return 0; } 還有就是使用native apizwqueryvirtualmemory來獲取gamedll的基址,這個有些麻煩不過還算是稍微底層些

typedef enum _memory_information_class memory_information_class; typedef long (ntapi * pf_zwqueryvirtualmemory) ( in handle processhandle, in pvoid baseaddress, in memory_information_class memoryinformationclass, out pvoid memoryinformation, in ulong memoryinformationlength, out pulong returnlength optional ); typedef struct _unicode_string unicode_string, *punicode_string; dword getgamedlladdr(handle hwar3handle,wchar * modulename) } // 遞增基址,開始下一輪查詢! } startaddr += 0x10000; } while( startaddr < 0x80000000 ); return 0; };

這裡也需要注意的是game.dll的大小寫或者名稱,如有的平台為game124.dll。然後用下面兩個方法獲得版本。定義全域性變數wc3verg_war3ver,enum wc3ver。

void getwar3ver() else if(lstrcmpi(filever,text("1, 24, 1, 6374")) ==0) else if(lstrcmpi(filever,text("1, 24, 4, 6387")) ==0) else if(lstrcmpi(filever,text("1, 25, 1, 6397")) ==0) else if(lstrcmpi(filever,text("1, 26, 0, 6401")) ==0) else } dword getfilever(__in lptstr filename, __out lptstr lpversion, __in dword nsize) *lptranslate; verqueryvalue(infobuf, text("\\varfileinfo\\translation"), (lpvoid*)&lptranslate,&cbtranslate); // read the file description for each language and code page. wsprintf( subblock, text("\\stringfileinfo\\%04x%04x\\fileversion"), lptranslate[0].wlanguage, lptranslate[0].wcodepage); void *lpbuffer=null; unsigned int dwbytes=0; verqueryvalue(infobuf, subblock, &lpbuffer, &dwbytes); lstrcpyn(lpversion,(lptstr)lpbuffer,nsize); delete infobuf; return dwbytes; }

獲得版本後就可以openprocess然後根據對應的版本來修改記憶體以實現我們想要的東東了。

switch(g_war3ver)

patch,這是定義的乙個巨集,#definepatch(i,w)writeprocessmemory(hopen,(lpvoid)(g_dwgameaddr+i),w,sizeof(w)-1,0);實現向目標程序某個位址寫入資料。

這個巨集在這裡使用writeprocessmemory,如果你使用dll注入的話就要用

#define patch(i,w) memcpy((lpvoid)(g_dwgameaddr+i),w,sizeof(w)-1)。

最後補充一下根據上面的dword getdllbase(char* dllname, dword tpid)和dword getpidforprocess(char* process)可以獲得war3.exe程序載入的所有模組,如果單機啟動,是載入本地的game.dll。如果在平台上啟動遊戲,你會發現載入的是平台自帶的game.dll。可以修改下getdllbase函式列印下載入模組的路徑自己看下。

這時我通過本機跟11載入時的截圖

另外還要注意下使用tlhelp32庫的函式時最好程式使用ansi編碼。

一步一步教你寫pdf檔案

pdf作為一種跨平台的檔案格式,越來越受到使用者的歡迎。現在除了adobe官方提供的pdflib有很多第三方的庫可以實現pdf的檔案建立 修改 格式轉換。pdf文件採用的是二進位制和文字混排的方式。近期專案需要,對pdf檔案的結構做了一些研究。最終,領導決定採用第三方庫,沒能用得上。在此,跟大家分享...

一步一步教你配置vnc

配置 vnc遠端桌面連線 1.在命令列輸入 init 3 進入純字元介面 2.kill 掉所有與 x有關的程序 用命令ps aux grep x 然後kill 程序號1 程序號2 只要找到的程序都 kill 掉 如果不會使用 kill 命令,直接重啟電腦 3.首先檢查 vncserver 是否安裝使...

教你一步一步用OpenGL寫遊戲 前言

這是乙個系列的教程。在這套教程裡,我將會把之前用opengl qt做過的一款遊戲和大家分享,並且從頭到尾一步步分析整個遊戲的實現過程和架構設計。關於寫這些東西的目的,我想大概有三點吧 其一是想把自己寫過的這個遊戲重新梳理一遍,認真重構重構,真正理解其中用到的技術和演算法,更加深入地把握軟體專案開發技...