在获取模块基地址C ++时遇到问题

时间:2014-04-06 14:02:59

标签: c++ winapi

我正在尝试制作一个程序,将值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”进程的正确基址。

1 个答案:

答案 0 :(得分:4)

你应该阅读这样的模块:

#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编译,您需要执行以下操作:

enter image description here

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

enter image description here

接下来在下面的下拉菜单中,选择x64:

enter image description here

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