超强回归—菜鸟进阶,c++魔兽争霸全图外挂制作全教程

更新时间:2023-10-13 13:07:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

半年前浅尝制作外挂,初试成功,很是兴奋。发表一贴《菜鸟教程-全图外挂制作全程教学》。地址:http://www.breeze356.com/thread-2485-1-1.html。

貌似点击量很高。但看贴后的留言,有很多人说难?也有人骂我,说我自己都不会的,是抄袭别人的文章,我还轮不到你个瘪三来指三道四。下面不说这个瘪三了,进入正题。

难在何处?我想:

第一,你不会编程。对于这类人,你们应该去学习,至少掌握一门编程语言。如C++,VB,Delphi等。

第二,你没有弄懂外挂制作原理和思路。首先说原理,思路下面再详细说。其实这个在《菜鸟教程-全图外挂制作全程教学》中有提到。外挂原理一般包括:模拟式,内存式,封包式和指今修改式。比如:大部分改建就是模拟键盘(模拟式)。全图外挂为内存式或指令修改式。

第三,你没有仔细看《菜鸟教程-全图外挂制作全程教学》,对于这类人,我要严重的批判和表示强烈的鄙视。

好了,我们继续正题。如果你已经掌握一门编程语言了,想做外挂,你必须清楚实现整个功能的思路,这个在《菜鸟教程-全图外挂制作全程教学》中也是有的。我们做的全图外挂为内存式,又分DLL注入和程序两种形式,我这里讲的是软件形式,DLL注入的看BR以前的源码。

首先,我们要提升外挂本身程序权限,使其能够有权限修改war3游戏的内存。这个c++可以使用如下代码

1. void EnableDebugPriv()//提升程序自身权限 2. {

3. HANDLE hToken;

4. LUID sedebugnameValue; 5. TOKEN_PRIVILEGES tkp; 6.

if

(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return; 7.

if

(!LookupPrivilegeValue(NULL,

SE_DEBUG_NAME,&sedebugnameValue)) 8. {

9. CloseHandle(hToken); 10. return; 11. }

12. tkp.PrivilegeCount = 1;

13. tkp.Privileges[0].Luid = sedebugnameValue;

14. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 15. if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) CloseHandle(hToken); 16. }

其次,有了权限以后,我们要找到war3.exe进程ID。并打开进程以供编辑修改内存,到达作弊目的。而这个也是重点了。他妈的,都别猴急,哥我打字也很辛苦,先喝杯茶??

啊,下面开始讲重点了,请大家做好笔记,别过后说老子没讲。尼玛,论坛是有记录的,别想坑爹。

获得进程ID:下面这个函数方法就是返回进程的,直接写进程名称,如:GetPIDForProcess(“war3.exe”),还可以用FindWindow的方法,反正能找到进程ID就可以了。

1. //HWND hwar3=::FindWindow(NULL,TEXT(\2. //DWORD PID, TID;

3. //TID = ::GetWindowThreadProcessId (hwar3, &PID); 4. DWORD GetPIDForProcess(char* process)//获取进程ID 5. {

6. BOOL working; 7. PROCESSENTRY32 lppe= {0}; 8. DWORD targetPid=0; 9.

HANDLE

hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS ,0); 10. if (hSnapshot) 11. {

12. lppe.dwSize=sizeof(lppe);

13. working=Process32First(hSnapshot,&lppe);

14. while (working) 15. {

16. if(strcmp((const char *)lppe.szExeFile,process)==0) 17. {

18. targetPid=lppe.th32ProcessID; 19. break;

20. }working=Process32Next(hSnapshot,&lppe);

21. } 22. }

23. CloseHandle( hSnapshot ); 24. return targetPid; 25. }

注意:有的名称为War3.exe或war3.exe,需要区分大小写。c++有不区分大小写比较的方法,自己去找??我操,这点专研精神都没有,怎么不去死,还学编程做外挂?自己先挂吧。其实我后面有个教你们查看自己的进程和game.dll到底是大写还是小些的方法。

进程ID已经找到,现在是不是直接打开修改内存作弊呢?不,还早呢。我们修改内存也不能乱来,你得先找到Game.dll判断游戏版本,对应修改,要不会把魔兽搞火了,突然跳出来,那你就崩溃了,后悔都来不及。有木有,有木有?开图导致游戏崩溃的老实交代一下。

下面的方法获取game.dll的基址和路径。GetDLLBase(“game.dll”,PID)直接返回的就是game.dll的基址,这个后面是需要用到的。定义一个全局变量TCHAR LastDLLPath[260],LastDLLPath返回的就是game.dll路径,。 1. DWORD GetDLLBase(char* DllName, DWORD tPid) 2. {

3. HANDLE snapMod; 4. MODULEENTRY32 me32; 5. if (tPid == 0) return 0;

6. snapMod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, tPid);

7. me32.dwSize = sizeof(MODULEENTRY32); 8. if (Module32First(snapMod, &me32)) 9. { 10. do 11. {

12. if (strcmp(DllName,(const char *)me32.szModule) == 0) 13. {

14. strcpy(LastDLLPath ,me32.szExePath);//game.dll路径

15. CloseHandle(snapMod);

16. return (DWORD) me32.modBaseAddr; 17. }

18. }while(Module32Next(snapMod,&me32)); 19. } 20. else 21. {

22. Powers=true; 23. }

24. CloseHandle(snapMod); 25. return 0; 26. }

这里也需要注意的是game.dll的大小写或者名称,如有的平台为game124.dll。然后用下面两个方法获得版本。定义全局变量WC3VER g_War3Ver,enum WC3VER{_UN,_120E,_124B,_124E,_125B,_126B}。 1. void GetWar3Ver() 2. {

3. TCHAR FileVer[64];

4. ODV(TEXT(\

5. GetFileVer(LastDLLPath,FileVer,64); 6. ODV(TEXT(\

7. if(lstrcmpi(FileVer,TEXT(\8. {

9. g_War3Ver=_120E; 10. }

11. else if(lstrcmpi(FileVer,TEXT(\12. {

13. g_War3Ver=_124B; 14. }

15. else if(lstrcmpi(FileVer,TEXT(\16. {

17. g_War3Ver=_124E; 18. }

19. else if(lstrcmpi(FileVer,TEXT(\20. {

21. g_War3Ver=_125B; 22. }

23. else if(lstrcmpi(FileVer,TEXT(\24. {

25. g_War3Ver=_126B; 26. } 27. else 28. {

29. g_War3Ver=_UN; 30. } 31. }

32. DWORD GetFileVer(__in LPTSTR FileName, __out LPTSTR lpVersion, __in DWORD nSize) 33. {

34. TCHAR SubBlock[64]; 35. DWORD InfoSize;

36. InfoSize =

GetFileVersionInfoSize(FileName,NULL); if(InfoSize==0) return 0;

37. TCHAR *InfoBuf = new TCHAR[InfoSize];

38. GetFileVersionInfo(FileName,0,InfoSize,InfoBuf); 39. unsigned int cbTranslate = 0; 40. struct LANGANDCODEPAGE 41. {

42. WORD wLanguage; 43. WORD wCodePage; 44. }

45. *lpTranslate; 46.

VerQueryValue(InfoBuf,

TEXT(\

47. (LPVOID*)&lpTranslate,&cbTranslate);

48. // Read the file description for each language and code page.

49. wsprintf( SubBlock,

50. TEXT(\,

51. lpTranslate[0].wLanguage, 52. lpTranslate[0].wCodePage); 53. void *lpBuffer=NULL; 54. unsigned int dwBytes=0;

55. VerQueryValue(InfoBuf, SubBlock, &lpBuffer, &dwBytes); 56. lstrcpyn(lpVersion,(LPTSTR)lpBuffer,nSize); 57. delete[] InfoBuf; 58. return dwBytes; 59. }

获得版本后我们就可以打开进程了。

1. HANDLE hopen=OpenProcess( PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,FALSE,PID);

2. //打开war进程以供编辑 再用switch语句判断。如 1. switch(g_War3Ver) 2. {

3. case _120E:

4. //修改内存代码自己去找吧//大地图去除迷雾 5. PATCH(0x406B53,\6. PATCH(0x2A0930,\7. //野外显血

8. PATCH(0x166E5E,\9. PATCH(0x16FE0A,\10. //视野外点选

11. PATCH(0x1BD5A7,\12. PATCH(0x1BD5BB,\13. //小地图显示单位

14. PATCH(0x1491A8, \15. break;

16. case _124B: 17. //小地图显示单位

18. PATCH(0x361EAB,\x00\\x00\\xEB\\x07\19. break;

20. case _124E:

21. //至于作弊代码你们是直接写,还是写成一个方法调用,随你们自己。 22. break;

23. case _UN: 24. default: 25. break;

26. }

这里还有个特别重要的:PATCH,这是定义的一个宏,不懂的百度。

#define PATCH(i,w) WriteProcessMemory(hopen,(LPVOID)(g_dwGameAddr+i),w,sizeof(w)-1,0);

hopen就是先打开war进程以供编辑时返回的句柄的,g_dwGameAddr就是GetDLLBase(char* DllName, DWORD tPid)返回的基址。

回想:在《菜鸟教程-全图外挂制作全程教学》里面,有人在那“教训”我,我只想说:“你装B装的可以了,爷我法眼一开就知道你是个瘪三”。

记得有人问过为什么这个宏在这里使用WriteProcessMemory,和BR的不同,什么意思?是因为这个是在自己的程序里面,如果DLL注入的话就要用 #define PATCH(i,w) memcpy((LPVOID)(g_dwGameAddr+i),w,sizeof(w)-1)。

这个教程难免还有疏漏的地方,如有留言,看到必回。谢谢大家支持!

补充一下,在前面,两处说道大小写不一致的问题,这里教你们一个方法,怎么知道具体的名称.

首先,我们打开魔兽,找到War3.exe进程,直接就可以看出他的大小写是什么。然后可以根据上面的DWORD GetDLLBase(char* DllName, DWORD tPid)和DWORD GetPIDForProcess(char* process)获得War3.exe进程加载的所有模块,如果单机启动,是加载本地的game.dll。如果在平台上启动游戏,你会发现加载的是平台自带的game.dll。

如建一个控制台程序,源码如下: 1. #include \2. #include 3. #include 4. #include 5. TCHAR LastDLLPath[260];

6. DWORD GetDLLBase(char* DllName, DWORD tPid) 7. {

8. HANDLE snapMod; 9. MODULEENTRY32 me32; 10. if (tPid == 0) return 0;

11. snapMod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, tPid);

12. me32.dwSize = sizeof(MODULEENTRY32); 13. if (Module32First(snapMod, &me32)) 14. { 15. 16. do 17. {

18. /*if (strcmp(DllName,(const char *)me32.szModule) == 0) 19. { */

20. printf( \\21. 22. /*}*/ 23. }

24. while(Module32Next(snapMod,&me32)); 25. }

26. CloseHandle(snapMod); 27. return 0; 28. }

29. DWORD GetPIDForProcess(char* process) 30. {

31. BOOL working; 32. PROCESSENTRY32 lppe= {0}; 33. DWORD targetPid=0; 34.

HANDLE

hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS ,0); 35. if (hSnapshot){

36. lppe.dwSize=sizeof(lppe);

37. working=Process32First(hSnapshot,&lppe); 38. while (working){

39. if(strcmp((const char *)lppe.szExeFile,process)==0) 40. {

41. targetPid=lppe.th32ProcessID; 42. break;

43. }working=Process32Next(hSnapshot,&lppe);

44. } 45. }

46. CloseHandle( hSnapshot ); 47. return targetPid; 48. } 49. 50.

51. int main(int argc, char* argv[]) 52. {

53. HANDLE hToken; 54. LUID sedebugnameValue; 55. TOKEN_PRIVILEGES tkp; 56.

OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 57.

LookupPrivilegeValue(NULL,

SE_DEBUG_NAME,&sedebugnameValue); 58. tkp.PrivilegeCount = 1;

59. tkp.Privileges[0].Luid = sedebugnameValue;

60. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 61. AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL);

62. CloseHandle(hToken); 63.

64. //HWND hwar3=::FindWindow(NULL,TEXT(\65. //DWORD PID,TD;

66. //TD = GetWindowThreadProcessId (hwar3, &PID); 67. //和下面一样的效果。

68. DWORD PID=GetPIDForProcess(\69. GetDLLBase(\70. getchar(); 71. return 0; 72. }

54. LUID sedebugnameValue; 55. TOKEN_PRIVILEGES tkp; 56.

OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); 57.

LookupPrivilegeValue(NULL,

SE_DEBUG_NAME,&sedebugnameValue); 58. tkp.PrivilegeCount = 1;

59. tkp.Privileges[0].Luid = sedebugnameValue;

60. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 61. AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL);

62. CloseHandle(hToken); 63.

64. //HWND hwar3=::FindWindow(NULL,TEXT(\III\

65. //DWORD PID,TD;

66. //TD = GetWindowThreadProcessId (hwar3, &PID); 67. //和下面一样的效果。 68. DWORD PID=GetPIDForProcess(\69. GetDLLBase(\70. getchar(); 71. return 0; 72. }

本文来源:https://www.bwwdw.com/article/mv4f.html

Top