【问题标题】:Having issues getting the module base address C++在获取模块基地址 C++ 时遇到问题
【发布时间】:2014-04-06 14:02:59
【问题描述】:

我正在尝试编写一个程序,将值 500 存储到计算器应用程序上的 MR(内存恢复)按钮的计算器内存地址中。 我知道这个整数的地址是 "calc.exe"+00073320 + 0 + C

如果我使用像作弊引擎这样的程序,我可以获取我正在运行的calculator.exe 实例的当前地址,并以这种方式写入它。但是,由于这不是静态地址,我需要一种方法来获取模块基地址。

我尝试使用这个 GetModuleBase 函数(参见下面的代码)来获取 calc.exe 的基地址,但我的问题是我无法获取基地址。该函数总是返回 0 而不是正确的地址。

我调试了它,发现在 GetModuleBase 函数中,它甚至没有在 while 循环中循环一次,因为 bModule 从 Module32First 函数返回 0。

    #include <tchar.h>
    #include <windows.h> 
    #include <TlHelp32.h> 
    #include <iostream> 
    #include <Psapi.h>
    #include <wchar.h>
    #pragma comment( lib, "psapi" )
    using namespace std;

    DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
    {
       MODULEENTRY32 lpModuleEntry = {0};
       HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
       if(!hSnapShot)
          return NULL;
       lpModuleEntry.dwSize = sizeof(lpModuleEntry);
       BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
       while(bModule)
       {
          if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
          {
             CloseHandle( hSnapShot );
             return (DWORD)lpModuleEntry.modBaseAddr;
          }
          bModule = Module32Next( hSnapShot, &lpModuleEntry );
       }
       CloseHandle( hSnapShot );
       return NULL;
    }

    int main() {

      HWND hWnd = FindWindow(0, "Calculator");
      DWORD BaseAddr;
      if(hWnd == 0){

        MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);

      } else {

        DWORD proccess_ID;

        GetWindowThreadProcessId(hWnd, &proccess_ID);

        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);

        if(!hProcess){

          MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);

        } else {

          int newdata = 500;
          BaseAddr = GetModuleBase("calc.exe",proccess_ID);
          //GetModuleBase is always returning 0, so I am not getting the correct base address
          DWORD newdatasize = sizeof(newdata);

          if(WriteProcessMemory(hProcess, (LPVOID)0x002413FC, &newdata, newdatasize, NULL)){

            cout << "Memory successfully written." << endl;

          } else {

           cout << "Memory failed to write." << endl;

          }

          CloseHandle(hProcess);

        }

      }

      return 0;

    } 

总结:我无法使用我的 GetModuleBase 函数获取正确的基地址,我需要找出我做错了什么,以便我可以为“calc.exe”进程获取正确的基地址。

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    你应该像这样阅读模块:

    #include <windows.h>
    #include <TlHelp32.h>
    #include <iostream>
    
    //You don't have to use this function if you don't want to..
    int strcompare(const char* One, const char* Two, bool CaseSensitive)
    {
        #if defined _WIN32 || defined _WIN64
        return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
        #else
        return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
        #endif
    }
    
    //You read module information like this..
    MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
    {
        void* hSnap = nullptr;
        MODULEENTRY32 Mod32 = {0};
    
        if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
            return Mod32;
    
        Mod32.dwSize = sizeof(MODULEENTRY32);
        while (Module32Next(hSnap, &Mod32))
        {
            if (!strcompare(ModuleName, Mod32.szModule, false))
            {
                CloseHandle(hSnap);
                return Mod32;
            }
        }
    
        CloseHandle(hSnap);
        return {0};
    }
    
    int main()
    {
        //Change the process ID below..
        BYTE* BaseAddr = GetModuleInfo(5172, "calc.exe").modBaseAddr;
        std::cout<<"BASE ADDRESS: "<<(void*)BaseAddr<<"\n";            
    
        return 0;
    }
    

    编辑:经过进一步调查,我发现 Visual Studio 正在为 x32 平台编译,但 calc.exe 是 x64 进程..

    要让 Visual Studio 为 x64 编译,您需要执行以下操作:

    然后单击并从以下下拉菜单中选择“新建”:

    接下来在以下下拉菜单中选择 x64:

    保存设置并重建项目,它应该可以工作..

    【讨论】:

    • 感谢您的尝试,但该方法仍然为我返回 0 作为基地址。
    • 你试过以管理员身份运行吗?你确定进程ID是正确的吗?我刚刚修复了一个错误.. 在 main.. 中投射到 (void) 而不是 (void*) .. 这些有帮助吗?我尝试了代码,它可以在我的系统上运行。它打印:BASE ADDRESS: 0x7ff6da0f0000
    • 谢谢,但我已经认识到 (void*) 更改,并根据需要进行了更改。我也尝试以管理员身份运行(我以前没有想到过)。我刚刚检查了进程 ID,当您从十进制转换为十六进制时,它返回 17748 = 4554,在作弊引擎中它显示为 4554-calc.exe 。编辑:您是否还必须更改 GetModuleInfo 函数的结尾?它给了我一个错误,它说返回 {0}
    • 我不需要更改上面的任何内容。你可以让它返回Mod32。它为您返回 0 很奇怪。尝试在 !strcompare 行之前执行 std::cout&lt;&lt;Mod32.szModule&lt;&lt;"\n" 以查看找到的内容。
    • 你不知道我对此有多感激。过去3天我一直在寻找。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多