GetModuleHandle without WinAPI, from PEB

March 3, 2013 by Johan — 1 Comment

This is an implementation of GetModuleHandle to get the module handle directly from PEB in memory rather than calling the Windows API-function GetModuleHandle, the purpose is to get the handle for a module in the current process without WinAPI. So, how to GetModuleHandle without WinAPI:

HMODULE GetModuleHandlePEB( wchar* szModule )
{
  _LDR_MODULE* pModule = NULL;
  
  _asm
  {
    MOV EAX, FS:[ 0x18 ];    // TEB (Thread Environment Block)
    MOV EAX, [ EAX + 0x30 ]; // PEB (Process Environment Block)
    MOV EAX, [ EAX + 0x0C ]; // pModule
    MOV EAX, [ EAX + 0x0C ]; // pModule->InLoadOrderModuleList.Flink
    MOV pModule, EAX;
  }
  
  while( pModule->BaseAddress )
  {
    if( _wcsicmp( pModule->BaseDllName.Buffer, szModule ) == 0 )
    {
      return (HMODULE)pModule->BaseAddress;
    }

    pModule = (ModuleInfoNode*)pModule->InLoadOrderModuleList.Flink; // grab the next module in the list
  }
  
  return NULL;
}

Explanation of the inline ASM (Assembly) used:

First we read the pointer to the TEB:
MOV EAX, FS:[ 0x18 ];

Then at TEB+0x30 is PEB pointer so we read that:
MOV EAX, [ EAX + 0x30 ];

PEB+0xC is the pointer to the module list (a linked list), we read that:
MOV EAX, [ EAX + 0x0C ];

And finally we grab the pointer to the first module in the load order list:
MOV EAX, [ EAX + 0x0C ];

Store the module pointer in our variable pModule
MOV pModule, EAX;

After this we do normal linked list-iteration, comparing the module name.

Iterate until we get an invalid entry (end of list):
while( pModule->BaseAddress )

Check if the current module’s base name matches the one we are looking for ..
if( _wcsicmp( pModule->BaseDllName.Buffer, szModule ) == 0 )

.. if it does, we return its’ base address
return (HMODULE)pModule->BaseAddress;

.. if not, get the pointer to the next module in the linked list
pModule = (ModuleInfoNode*)pModule->InLoadOrderModuleList.Flink;

undocumented-nt-internals-peb-teb
This uses some undocumented NT structures, you can find documentation for them here: http://undocumented.ntinternals.net/

The ones that are not documented there can be found in MSDN, for example LIST_ENTRY and UNICODE_STRING

You can get my complete ntheader.h file which contains the undocumented NT internals header that I use.

Incoming search terms:

  • getmodulehandle memory address
  • c GetModuleHandle without winapi
  • peb read asm

Johan

Posts Twitter Facebook

Blogging out of many years of experience with gamehacking, programming and reverse-engineering. Currently freelancing in webprogramming.

One response to GetModuleHandle without WinAPI, from PEB

  1. You can also check my own GetModuleHandle implementation on my blog. http://blog.szulak.net/programming/creating-own-getmodulehandle-function
    Comments are very welcome :)

Leave a Reply