user3503712
user3503712

Reputation: 51

Having issues getting the module base address C++

I am trying to make a program to store the value 500 into the calculator's memory address for the MR (Memory Restore) button on the calculator application. I know that the address for this integer is "calc.exe"+00073320 + 0 + C

If I use a program like cheat engine, I can get the current address for the instance of the calculator.exe i'm running, and write to it just fine that way. However, since this is not a static address, I need a way to get the module base address.

I tried using this GetModuleBase function (see code below) to get the Base Address of the calc.exe, but my issue is that I cannot get the base address. The function always returns 0 instead of the correct address.

I debugged it and found that in the GetModuleBase function, it is not even cycling once through the while loop because bModule is returning 0 from the Module32First function.

    #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;

    } 

Summary: I cannot get the correct base address using my GetModuleBase function, and I need to figure out what I am doing wrong so that I can get the correct base address for the "calc.exe" process.

Upvotes: 2

Views: 8272

Answers (1)

Brandon
Brandon

Reputation: 23485

You should read the modules like this:

#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;
}

EDIT: After further investigation, I found that Visual Studio was compiling for an x32 platform but calc.exe is an x64 process..

To get Visual Studio to compile for x64 you need to do the following:

enter image description here

Then click and select "NEW" from the following drop-down menu:

enter image description here

Next in the following drop down, select x64:

enter image description here

Save the settings and rebuild the project and it should work..

Upvotes: 4

Related Questions