好久木有研究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就可以了。
//hwnd hwar3=::findwindow(null,text("warcraft iii"));
//dword pid, tid;
//tid = ::getwindowthreadprocessid (hwar3, &pid);
dword getpidforprocess(char* process)//獲取程序id
; dword targetpid=0;
if (hsnapshot)
working=process32next(hsnapshot,&lppe);
} }
closehandle( hsnapshot );
return targetpid;
} 注意:有的名稱為war3.exe或war3.exe,用toolhelp32方式需要比較程序名字,這時是會區分大小寫的。findwindow則不用,視窗標題都是固定的warcraft iii。
程序id已經找到,現在是不是直接開啟修改記憶體作弊呢?不,還早呢。我們修改記憶體也不能亂來,你得先找到game.dll判斷遊戲版本,對應修改,要不會把魔獸搞火了,突然跳出來,那你就崩潰了,後悔都來不及。有木有,有木有?開圖導致遊戲崩潰的老實交代一下。
下面的方法獲取game.dll的基址和路徑。getdllbase(「game.dll」,pid)直接返回的就是game.dll的基址,這個後面是需要用到的。定義乙個全域性變數tchar lastdllpath[260],lastdllpath返回的就是game.dll路徑,。
dword getdllbase(char* dllname, dword tpid)
}while(module32next(snapmod,&me32));
} else
closehandle(snapmod);
return 0;
} 還有就是使用native api zwqueryvirtualmemory來獲取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。然後用下面兩個方法獲得版本。定義全域性變數wc3ver g_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,這是定義的乙個巨集,#define patch(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編碼。
**:
一步一步教你寫DOTA外掛程式
好久木有研究dota了,整理篇小菜文章。首先,我們要提公升外掛程式本身程式許可權,使其能夠有許可權修改war3遊戲的記憶體。這個c 可以使用如下 void enabledebugpriv 提公升程式自身許可權 tkp.privilegecount 1 tkp.privileges 0 luid se...
手把手教你編寫Logstash外掛程式
使用過logstash的朋友都知道,它強大的外掛程式生態幾乎覆蓋了所有的開源框架。從基本的http tcp udp file,到強大的kafa redis ganglia,還有豐富的解析工具,比如date json grok kv等等,有了它再也不用擔心資料不好蒐集了!不過需求是無限的,如果這些框架...
7 2 編寫外掛程式 模型外掛程式
概述 helloworld外掛程式教程 外掛程式允許完全訪問模型及其基本元素 鏈結 節點 碰撞物件 的物理屬性。下面的外掛程式將對其父模型應用乙個線性速度。cd gazebo plugin tutorial geditmodel push.cc 外掛程式 include include includ...