zoukankan      html  css  js  c++  java
  • 自制 war3 map hack

    http://blog.csdn.net/aj3423/article/details/6670529

    0. 工具

      OD(ollydbg), CE (cheat engine),war3 1.24, win7

    1. 目标功能

      去除战争迷雾,只是走过的地方永久可见。

    3. 猜测

      如果你来写 war3,你是否会用一个 bool 变量比如 hasFog, 界面每次重画时候都判断该变量,是 true 就加迷雾,false 就去迷雾。至于你会不会这样写,我反正会这样写。

    4. 用 CE 找当前游戏 hasFog 内存地址

      用 OD 加载 war3.exe(加参数-window),建一单机游戏,此时是有迷雾的(hasFog == true)。

      操作:用CE打开war3.exe,搜索内存为1的值(true==1),列出无数个地址。然后输入全图指令 iseedeadpeople,此时 hasFog == false,到CE中,在上次搜索结果里继续搜索0的值。

      重复上述操作步骤,直到剩下少数几个地址

      范围被缩小到了7个地址,一个个试。先双击第一个,CE下方会出现该地址,双击value那一列,修改为0,war3迷雾还在,说明不是这个地址。

      重复上述步骤, 直到 这个地址

      0A8D009C 就是 hasFog,到此 CE 的工作结束

      写段代码直接改这个地址为 0 就ok了?no

      上面找到的 hasFog 地址,在每次建游戏时候都会变(从CE中也可以看出,静态地址是绿色,黑色的是动态地址)

    5. OD 分析

      如何动态找这个 hasFog 地址?war3 是怎么找的我们也怎么找,如果在 hasFog 处加写断点,然后打全屏指令,war3 就会找到该地址,并且写入值。

      ok,换到 OD,在 0A8D009C 处加内存写入断点,然后到 war3 输入 iseedeadpeople, 断在 6F408906

    (ctrl+A 分析该函数可以看到整个函数范围)

    分析: esi 可能是指向这样一个struct

    [cpp] view plaincopy

    1. struct MapInfo { 
    2. BYTE unknown[0x14]; 
    3. bool hasFog; 
    4.   .... 

    看这个esi是怎么来的,往上几行可以看到

    注释1:war3是vc编译的,vc处理类成员函数时候就是把 this 指针放到 ecx 中,然后 call 函数,比如

    [cpp] view plaincopy

    1. class A { 
    2. void hello() {} 
    3. }; 
    4. A a; 
    5. a.hello(); // 这句的汇编代码为

    [cpp] view plaincopy

    1. mov ecx, a 
    2. call hello 

    猜测: 全局变量 [6FACD44C] 里放的是 GAME 指针,包含各种游戏信息,
    GAME + 0x34 处,放的是 MapInfo 指针,里面放的map信息,包括 hasFog, 大致是

    [cpp] view plaincopy

    1. struct GAME { 
    2. BYTE unknown[0x34]; 
    3.   MapInfo* map_info; 
    4.   ... 

    在 od 中,按工具条的 M 按钮,查看内存镜像

    因为 dll 每次加载到内存的位置可能不同,所以 dll 的内存地址采用 基址+偏移 组成,基址可能会变,但偏移不变。
    对于全局变量 6FACD44C,是由基址 6F000000 + ACD44C组成,
    整个过程就是
    1. 找 game.dll 基址
    2. 用 基址+ACD44C 找全局变量 GAME 指针
    3. 从GAME 的 0x34 偏移处找到 MapInfo
    4. 修改 MapInfo 0x14 偏移处的 hasFog
    以下是代码:

    [cpp] view plaincopy

    1. // main.cpp
    2. #include <windows.h>
    3. #include <iostream>
    4. using namespace std; 
    5. #define W3_CLASS "Warcraft III"
    6. #include "mem_manip.h"
    7. typedef struct process_info_ { 
    8. HWND    hwnd; 
    9. DWORD   pid; 
    10. HANDLE  hProcess; 
    11. } process_info; 
    12. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { 
    13.     process_info ps; 
    14.     ps.hwnd = ::FindWindow(W3_CLASS, NULL); 
    15. if(!ps.hwnd) { 
    16. throw("no war3 found"); 
    17.     } 
    18.     ::GetWindowThreadProcessId(ps.hwnd, &ps.pid); 
    19.     EnableDebugPrivilege(); 
    20.     ps.hProcess = ::OpenProcess(0x1FFFFF, FALSE, ps.pid); //0x1FFFFF from dll_injector
    21. if (ps.hProcess == NULL) { 
    22. throw("OpenProcess error"); 
    23.     } 
    24. DWORD GAME_DLL_BASE = GetBaseAddress(ps.pid, "game.dll"); 
    25.     cout << "base of game.dll: " << hex << GAME_DLL_BASE << dec << endl; 
    26. DWORD GAME = GAME_DLL_BASE + 0x00ACD44C; 
    27. DWORD addr; 
    28.     cout << "try to read: " << hex << GAME << dec << endl; 
    29.     ReadProcessBYTES(ps.hProcess, GAME, &addr, 4); 
    30.     cout << "1. addr = " << hex << addr << dec << endl; 
    31.     addr += 0x34; 
    32.     ReadProcessBYTES(ps.hProcess, addr, &addr, 4); 
    33.     cout << "2. addr = " << hex << addr << dec << endl; 
    34.     addr += 0x14; 
    35. DWORD zero = 0; 
    36.     WriteProcessBYTES(ps.hProcess, addr, &zero, 4); 
    37.     cout << "done!" << endl; 
    38. return 0; 

    [cpp] view plaincopy

    1. // mem_manip.h
    2. #include <windows.h>
    3. #include <stdio.h>
    4. #include <tlhelp32.h>
    5. void  EnableDebugPrivilege() { 
    6. HANDLE hToken; 
    7.   LUID seDebugNameValue; 
    8.   TOKEN_PRIVILEGES tkp; 
    9. if ( !OpenProcessToken( GetCurrentProcess(), 
    10.       TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return; 
    11. if ( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &seDebugNameValue) ) 
    12.      { CloseHandle( hToken ); return; } 
    13.   tkp.PrivilegeCount = 1; 
    14.   tkp.Privileges[0].Luid = seDebugNameValue; 
    15.   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    16. if ( !AdjustTokenPrivileges( hToken, false, &tkp, sizeof(tkp), NULL, NULL)) 
    17.      { CloseHandle( hToken ); return; } 
    18. void WriteProcessBYTES(HANDLE hProcess, DWORD lpAddress, void* buf, int len) { 
    19. DWORD oldprot,dummy = 0; 
    20.     VirtualProtectEx(hProcess, (void*) lpAddress, len, PAGE_READWRITE, &oldprot); 
    21.     WriteProcessMemory(hProcess, (void*) lpAddress, buf, len, 0); 
    22.     ::FlushInstructionCache(hProcess, (void*)lpAddress, len); 
    23.     VirtualProtectEx(hProcess, (void*) lpAddress, len, oldprot, &dummy); 
    24. void ReadProcessBYTES(HANDLE hProcess, DWORD lpAddress, void* buf, int len) { 
    25. DWORD oldprot, dummy = 0; 
    26.     VirtualProtectEx(hProcess, (void*) lpAddress, len, PAGE_READWRITE, &oldprot); 
    27.     ReadProcessMemory(hProcess, (void*) lpAddress, buf, len, 0); 
    28.     VirtualProtectEx(hProcess, (void*) lpAddress, len, oldprot, &dummy); 
    29. DWORD GetBaseAddress(DWORD pid, const char* ModuleName) { 
    30. // Typedefs for toolhelp32
    31. typedef BOOL (WINAPI *fnModule32First)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); 
    32. typedef BOOL (WINAPI *fnModule32Next)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); 
    33. typedef HANDLE (WINAPI *fnCreateToolhelp32Snapshot)(DWORD dwFlags, DWORD th32ProcessID); 
    34. // Find out if the toolhelp API exists in kernel32
    35. HMODULE k32=GetModuleHandle("kernel32.dll"); 
    36. if (!k32) { 
    37. throw("Unable to get handle of KERNEL32.DLL."); 
    38.     } 
    39.     fnModule32First Module32First = (fnModule32First)GetProcAddress(k32, "Module32First"); 
    40.     fnModule32Next Module32Next = (fnModule32Next)GetProcAddress(k32, "Module32Next"); 
    41.     fnCreateToolhelp32Snapshot CreateToolhelp32Snapshot=(fnCreateToolhelp32Snapshot)GetProcAddress(k32,"CreateToolhelp32Snapshot"); 
    42. // Verify that the ToolHelp32 API is available
    43. if (!(Module32First) || !(Module32Next) || !(CreateToolhelp32Snapshot)) { 
    44. throw("Your operating system does not support the TOOLHELP32 API.\nCheck back for updates that use PSAPI instead."); 
    45.     } else { 
    46. // toolhelp code
    47. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); 
    48. if ((int)hSnapshot == -1) { 
    49. throw("Can't create toolhelp32 snapshot of game."); 
    50.         } 
    51.         MODULEENTRY32 lpme; 
    52.         lpme.dwSize=sizeof(MODULEENTRY32); 
    53. // Get first module, this is needed for win9x/ME
    54. if (!Module32First(hSnapshot, &lpme)) { 
    55.             CloseHandle(hSnapshot); 
    56. throw("Can't get first module of game."); 
    57.         }; 
    58. // Loop through all other modules
    59. while (TRUE) { 
    60. if (!stricmp(lpme.szModule, ModuleName)) { 
    61.                 CloseHandle(hSnapshot); 
    62. return (DWORD)lpme.modBaseAddr; 
    63.             } 
    64. if (!Module32Next(hSnapshot, &lpme)) { 
    65.                 CloseHandle(hSnapshot); 
    66. return 0; 
    67.             }; 
    68.         } 
    69. return 0; 
    70.     } 

    [javascript] view plaincopy

    1. <pre name="code" class="cpp"><pre name="code" class="javascript"><pre name="code" class="php"></pre> 
    2. <pre></pre> 
    3. <pre></pre> 
    4. <pre></pre> 
    5. <pre></pre> 
    6. <pre></pre> 
    7. <pre></pre> 
    8. <pre></pre> 
    9. </pre></pre> 
  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/adodo1/p/4327409.html
Copyright © 2011-2022 走看看