'How do I get the (physical) baseaddress of an .DLL used in a process?
I recently started a new c++ win32 console Project. It basically rewrites the value of a given Address in Memory.
The point is, I want it to use a pointer-map with offsets to recalculate the address it should use. Here is an image of the pointer map in Cheat Engine.
As I said, I managed it to rewrite the value (1147 in this case) manually if I just type the address, but I want it to be automatic! Hope you understand my problem
have a nice day.
Solution 1:[1]
To get the base address of a module(DLL or EXE) in memory you can enumerate the loaded modules using ToolHelp32Snapshot Windows API function. Microsoft provides documented source code to find the module. Basically you need 2 functions, one to grab the ProcessId and then one to get the base address.
bool GetPid(const wchar_t* targetProcess, DWORD* procID)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!wcscmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
*procID = pe.th32ProcessID;
return true;
}
} while (Process32Next(snap, &pe));
}
}
return false;
}
char* GetModuleBase(const wchar_t* ModuleName, DWORD procID)
{
MODULEENTRY32 ModuleEntry = { 0 };
HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procID);
if (!SnapShot) return NULL;
ModuleEntry.dwSize = sizeof(ModuleEntry);
if (!Module32First(SnapShot, &ModuleEntry)) return NULL;
do
{
if (!wcscmp(ModuleEntry.szModule, ModuleName))
{
CloseHandle(SnapShot);
return (char*)ModuleEntry.modBaseAddr;
}
} while (Module32Next(SnapShot, &ModuleEntry));
CloseHandle(SnapShot);
return NULL;
}
Then you do:
DWORD ProcId;
GetPid(L"ac_client.exe", &ProcId);
char* ExeBaseAddress = GetModuleBase(L"ac_client.exe", ProcId);
If you've injected into the process in an internal hack you can use GetModuleHandle because as of posting the handle returned is just the address of the module:
DWORD BaseAddress = (DWORD)GetModuleHandle(L"ac_client.exe");
To calculate the dynamic address pointed to by a multi-level pointer you can use this function, it basically de-references the pointer externally for you using ReadProcessMemory():
uintptr_t FindDmaAddy(int PointerLevel, HANDLE hProcHandle, uintptr_t Offsets[], uintptr_t BaseAddress)
{
uintptr_t pointer = BaseAddress;
uintptr_t pTemp;
uintptr_t pointerAddr;
for(int i = 0; i < PointerLevel; i++)
{
if(i == 0)
{
ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
}
pointerAddr = pTemp + Offsets[i];
ReadProcessMemory(hProcHandle, (LPCVOID)pointerAddr, &pTemp, sizeof(pTemp), NULL);
}
return pointerAddr;
}
Solution 2:[2]
This is a more complete example in C++20 (because of lambdas in unevaluated context):
#define NOMINMAX
#include <Windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <memory>
#include <limits>
using namespace std;
using XHANDLE = unique_ptr<void, decltype([]( void *h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( (HANDLE)h ); })>;
using XHMODULE = unique_ptr<void, decltype([]( void *h ) { h && FreeLibrary( (HMODULE)h ); })>;
[[noreturn]]
void throwSysErr( char const *errStr );
int main( int argc, char *argv[] )
{
try
{
if( argc < 3 )
return 0;
XHMODULE xhm( GetModuleHandleA( argv[1] ) );
if( !xhm.get() )
xhm.reset( LoadLibraryA( argv[1] ) );
static char const enumErr[] = "error enumerating modules";
XHANDLE xhSnapshot( CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, GetProcessId( GetCurrentProcess() ) ) );
if( xhSnapshot.get() == INVALID_HANDLE_VALUE )
throwSysErr( enumErr );;
MODULEENTRY32W me;
me.dwSize = sizeof me;
if( !Module32FirstW( xhSnapshot.get(), &me ) )
throwSysErr( enumErr );;
size_t moduleLength = strlen( argv[1] );
wstring moduleName;
moduleName.resize( strlen( argv[1] ), 0 );
for( size_t i = 0; i != moduleLength; ++i )
moduleName[i] = (unsigned char)argv[1][i];
for( ; ; )
{
if( _wcsicmp( me.szModule, moduleName.c_str() ) == 0 )
break;
me.dwSize = sizeof me;
if( !Module32NextW( xhSnapshot.get(), &me ) )
if( GetLastError() == ERROR_NO_MORE_FILES )
return 0;
else
throwSysErr( enumErr );;
}
cout << (void *)me.modBaseAddr << endl;
void *procAddr = GetProcAddress( (HMODULE)xhm.get(), argv[2] );
if( !procAddr )
throwSysErr( "GetProcAddress() failed" );
ptrdiff_t offset = (char *)procAddr - (char *)me.modBaseAddr;
// here the code fails because if a very large positive
// offset near the wrap-around (32 bit process)
if( offset < 0 || (size_t)offset >= me.modBaseSize )
return 0;
cout << "relative address " << hex << offset << endl;
return offset <= numeric_limits<int>::max() ? (int)offset : 0;
}
catch( exception const &exc )
{
cout << exc.what() << endl;
return 0;
}
}
[[noreturn]]
void throwSysErr( char const *errStr )
{
throw system_error( (int)GetLastError(), system_category(), errStr );
}
Solution 3:[3]
Edit your Podfile replacing platform :ios, '10.0' to platform :ios, '11.0', then run pod install --repo-update
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | GuidedHacking |
| Solution 2 | Bonita Montero |
| Solution 3 | Jonathan Ferreira |
