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

This uses some undocumented NT structures, you can find documentation for them here:

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 winapi
  • get windows peb api
  • getmodulehandle
  • getmodulehandle 0
  • InLoadOrderModuleList Flink
  • list_entry winapi
  • thread environment block 0x18
  • video pebapi
  • \ pmodule\


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.
    Comments are very welcome :)

Leave a Reply