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> 
  • 相关阅读:
    HttpClient POST/GET方法
    Selenium+Java(十一)Selenium窗口切换
    Selenium+Java(十)Selenium常用方法
    Selenium+Java(九)Selenium键盘与鼠标事件
    Selenium+Java(八)Selenium下拉框处理
    Selenium+Java(七)Selenium对话框的处理
    Selenium+Java(六)Selenium 强制等待、显式等待、隐实等待
    [java]对象创建的过程
    [正则表达式] 表达式使用记录
    【Mysql】主从复制
  • 原文地址:https://www.cnblogs.com/adodo1/p/4328132.html
Copyright © 2011-2022 走看看