How to Get the Starting/Base Address of a Process in C++

How to get the base address of a process in C++ Internally?

Use GetModuleHandler. Pass in NULL, like this:

GetModuleHandler(NULL);

It will return the handle for the current running module (the .exe), which is actually its base address.

In case you want to know the base address of a different (loaded) module, like a DLL, then just pass its name.

Get base address of process

If you want to get the virtual address within the other process's address space, you can do that like so:

  1. Open the process using OpenProcess -- if successful, the value returned is a handle to the process, which is just an opaque token used by the kernel to identify a kernel object. Its exact integer value (0x5c in your case) has no meaning to userspace programs, other than to distinguish it from other handles and invalid handles.
  2. Call GetProcessImageFileName to get the name of the main executable module of the process.
  3. Use EnumProcessModules to enumerate the list of all modules in the target process.
  4. For each module, call GetModuleFileNameEx to get the filename, and compare it with the executable's filename.
  5. When you've found the executable's module, call GetModuleInformation to get the raw entry point of the executable.

This will give you the virtual address, but there's not a whole lot you can do with it since it's not mapped into your current process's address space.

Finding the base address after creating suspended process

You never set context.ContextFlags, you must set it to CONTEXT_INTEGER before calling GetThreadContext().

Here's a sample code:

#if defined(_WIN64)
WOW64_CONTEXT context;
memset(&context, 0, sizeof(WOW64_CONTEXT));
context.ContextFlags = CONTEXT_INTEGER;
Wow64GetThreadContext(pi.hThread, &context);
#else
CONTEXT context;
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_INTEGER;
GetThreadContext(pi.hThread, &context);
#endif

Taken from hasherezade's excellent runpe implementation

How can I get a process entry point address

When you execute a process with CREATE_SUSPENDED, it starts out in ntdll initialization code. This is of little use for finding the .exe's entry point; you must examine the exe file's headers directly for this:

#include <Windows.h>
#include <WinNT.h>

DWORD FindEntryPointAddress(_TCHAR *exeFile)
{
BY_HANDLE_FILE_INFORMATION bhfi;
HANDLE hMapping;
char *lpBase;
HANDLE hFile = CreateFile(exeFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
fail("Opening exe file", GetLastError());

if (!GetFileInformationByHandle(hFile, &bhfi))
fail("GetFileInformationByHandle", GetLastError());

hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, bhfi.nFileSizeHigh, bhfi.nFileSizeLow, NULL);
if (!hMapping)
fail("CreateFileMapping", GetLastError());
lpBase = (char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, bhfi.nFileSizeLow);
if (!lpBase)
fail("MapViewOfFile", GetLastError());

PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpBase;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
fail("bad dos header signature", 0);

PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS32)(lpBase + dosHeader->e_lfanew);
if (ntHeader->Signature != IMAGE_NT_SIGNATURE)
fail("bad nt header signature", 0);

DWORD pEntryPoint = ntHeader->OptionalHeader.ImageBase + ntHeader->OptionalHeader.AddressOfEntryPoint;

UnmapViewOfFile((LPCVOID)lpBase);
CloseHandle(hMapping);
CloseHandle(hFile);

return pEntryPoint;
}

Note that this address is of the first code that executes after DLL initialization completes. It may not be (and usually isn't) equal to the address of main or WinMain; it's usually some C library startup code statically linked into the EXE.

Also note that this will fail if the EXE is relocatable and ASLR is enabled, as the EXE may be loaded at a different base address. You'll have to find where the EXE base address is and use that instead of ntHeader->OptionalHeader.ImageBase in this case.



Related Topics



Leave a reply



Submit