This guide covers loading and unloading modules (DLLs on Windows, shared objects on Linux) into processes using libmem. Module injection is useful for loading custom code into games and applications.
Module Structure
The lm_module_t structure contains information about a loaded module:
typedef struct lm_module_t {
lm_address_t base; // Module base address
lm_address_t end; // Module end address
lm_size_t size; // Module size
lm_char_t path [LM_PATH_MAX]; // Full path to module
lm_char_t name [LM_PATH_MAX]; // Module name
} lm_module_t ;
Loading Modules into Current Process
Use LM_LoadModule to load a module into the current process.
Prepare the module path
Specify the full path to the module you want to load: #ifdef _WIN32
lm_string_t module_path = "C: \\ mods \\ myhack.dll" ;
#else
lm_string_t module_path = "/home/user/mods/myhack.so" ;
#endif
Load the module
Use LM_LoadModule to inject the module: lm_module_t loaded_mod;
if ( LM_LoadModule (module_path, & loaded_mod )) {
printf ( "Module loaded successfully! \n " );
printf ( "Name: %s \n " , loaded_mod . name );
printf ( "Base: %p \n " , ( void * ) loaded_mod . base );
printf ( "Size: 0x %zX bytes \n " , loaded_mod . size );
} else {
printf ( "Failed to load module \n " );
}
The module parameter is optional. Pass LM_NULLPTR if you don’t need the module information.
Loading Without Storing Module Info
if ( LM_LoadModule ( "myhack.dll" , LM_NULLPTR)) {
printf ( "Module loaded \n " );
}
Loading Modules into Remote Process
Use LM_LoadModuleEx to inject a module into another process.
Find the target process
Obtain a reference to the target process: lm_process_t process;
if ( ! LM_FindProcess ( "game.exe" , & process )) {
printf ( "Process not found \n " );
return ;
}
printf ( "Target process: %s (PID: %d ) \n " , process.name, process.pid);
Inject the module
Use LM_LoadModuleEx to load the module into the remote process: lm_string_t dll_path = "C: \\\\ mods \\\\ cheat.dll" ; // Use full path
lm_module_t injected_mod;
if ( LM_LoadModuleEx ( & process , dll_path, & injected_mod )) {
printf ( "Module injected successfully! \n " );
printf ( "Name: %s \n " , injected_mod . name );
printf ( "Base address: %p \n " , ( void * ) injected_mod . base );
printf ( "Size: 0x %zX bytes \n " , injected_mod . size );
} else {
printf ( "Failed to inject module \n " );
}
On Windows, you may need administrator privileges to inject into other processes. On Linux, you typically need to run as root or have appropriate permissions.
Finding Loaded Modules
Before injecting, you might want to check if a module is already loaded.
Finding Module in Current Process
lm_module_t mod;
if ( LM_FindModule ( "game.dll" , & mod )) {
printf ( "Module already loaded at: %p \n " , ( void * ) mod . base );
} else {
printf ( "Module not loaded, injecting... \n " );
LM_LoadModule ( "C: \\\\ path \\\\ to \\\\ game.dll" , & mod);
}
Finding Module in Remote Process
lm_process_t process;
LM_FindProcess ( "game.exe" , & process );
lm_module_t mod;
if ( LM_FindModuleEx ( & process , "cheat.dll" , & mod )) {
printf ( "Cheat already injected \n " );
} else {
printf ( "Injecting cheat... \n " );
LM_LoadModuleEx ( & process, "C: \\\\ cheats \\\\ cheat.dll" , & mod);
}
Enumerating All Modules
Use LM_EnumModules or LM_EnumModulesEx to list all loaded modules:
lm_bool_t module_callback ( lm_module_t * module , lm_void_t * arg )
{
printf ( "Module: %s \n " , module -> name );
printf ( " Path: %s \n " , module -> path );
printf ( " Base: %p \n " , ( void * ) module -> base );
printf ( " Size: 0x %zX \n\n " , module -> size );
return LM_TRUE;
}
// Enumerate modules in current process
LM_EnumModules (module_callback, LM_NULLPTR);
// Enumerate modules in remote process
lm_process_t process;
LM_FindProcess ( "game.exe" , & process );
LM_EnumModulesEx ( & process , module_callback, LM_NULLPTR);
Unloading Modules
Use LM_UnloadModule to unload a module from the current process.
Find the module to unload
Get the module information: lm_module_t mod;
if ( ! LM_FindModule ( "myhack.dll" , & mod )) {
printf ( "Module not found \n " );
return ;
}
Unload the module
Use LM_UnloadModule to remove it: if ( LM_UnloadModule ( & mod )) {
printf ( "Module unloaded successfully \n " );
} else {
printf ( "Failed to unload module \n " );
}
Unloading from Remote Process
Use LM_UnloadModuleEx to unload from a remote process:
lm_process_t process;
LM_FindProcess ( "game.exe" , & process );
lm_module_t mod;
if ( LM_FindModuleEx ( & process , "cheat.dll" , & mod )) {
if ( LM_UnloadModuleEx ( & process, & mod)) {
printf ( "Cheat unloaded from game \n " );
}
}
Complete Example: DLL Injector
Here’s a complete example that injects and unloads a DLL:
#include <libmem/libmem.h>
#include <stdio.h>
#include <stdlib.h>
void print_module_info ( const lm_module_t * mod )
{
printf ( " Name: %s \n " , mod -> name );
printf ( " Path: %s \n " , mod -> path );
printf ( " Base: %p \n " , ( void * ) mod -> base );
printf ( " End: %p \n " , ( void * ) mod -> end );
printf ( " Size: 0x %zX bytes ( %.2f MB) \n " ,
mod -> size , mod -> size / 1024.0 / 1024.0 );
}
int main ( int argc , char * argv [] )
{
if (argc < 3 ) {
printf ( "Usage: %s <process_name> <dll_path> \n " , argv [ 0 ]);
printf ( "Example: %s game.exe C: \\\\ mods \\\\ hack.dll \n " , argv [ 0 ]);
return 1 ;
}
lm_string_t process_name = argv [ 1 ];
lm_string_t dll_path = argv [ 2 ];
printf ( "LibMem DLL Injector \n " );
printf ( "=================== \n\n " );
// Find target process
printf ( "[*] Finding process: %s \n " , process_name);
lm_process_t process;
if ( ! LM_FindProcess (process_name, & process)) {
printf ( "[!] Process not found \n " );
return 1 ;
}
printf ( "[+] Found process: \n " );
printf ( " Name: %s \n " , process . name );
printf ( " PID: %d \n " , process . pid );
printf ( " Path: %s \n " , process . path );
printf ( " Bits: %zu \n\n " , process . bits );
// Check if already injected
printf ( "[*] Checking if module is already loaded... \n " );
lm_module_t existing_mod;
// Extract just the filename from the path
lm_string_t dll_name = strrchr (dll_path, ' \\ ' );
if ( ! dll_name) dll_name = strrchr (dll_path, '/' );
if (dll_name) dll_name ++ ; else dll_name = dll_path;
if ( LM_FindModuleEx ( & process, dll_name, & existing_mod)) {
printf ( "[!] Module already loaded: \n " );
print_module_info ( & existing_mod);
printf ( " \n [*] Unload module? (y/n): " );
char choice = getchar ();
if (choice == 'y' || choice == 'Y' ) {
if ( LM_UnloadModuleEx ( & process, & existing_mod)) {
printf ( "[+] Module unloaded successfully \n " );
} else {
printf ( "[!] Failed to unload module \n " );
return 1 ;
}
} else {
printf ( "[*] Exiting... \n " );
return 0 ;
}
}
// Inject the DLL
printf ( " \n [*] Injecting: %s \n " , dll_path);
lm_module_t injected_mod;
if ( ! LM_LoadModuleEx ( & process, dll_path, & injected_mod)) {
printf ( "[!] Injection failed \n " );
return 1 ;
}
printf ( "[+] Injection successful! \n\n " );
print_module_info ( & injected_mod);
// Wait for user input to unload
printf ( " \n Press Enter to unload the module... \n " );
while ( getchar () != ' \n ' ); // Clear input buffer
getchar ();
printf ( "[*] Unloading module... \n " );
if ( LM_UnloadModuleEx ( & process, & injected_mod)) {
printf ( "[+] Module unloaded successfully \n " );
} else {
printf ( "[!] Failed to unload module \n " );
}
return 0 ;
}
Important Notes
Full Paths Always use absolute paths when loading modules to avoid path resolution issues.
Architecture Match Ensure the module architecture (32/64-bit) matches the target process.
Permissions You may need elevated privileges to inject into other processes.
Clean Unload Always unload injected modules cleanly to prevent crashes.
Common Use Cases
Mod loading : Inject custom game modifications
Cheat injection : Load cheat DLLs into games (educational purposes)
Plugin systems : Dynamically load plugins into applications
Code injection : Inject custom functionality into running processes
Debugging : Load debugging/profiling tools into target processes
Be aware of anti-cheat systems when injecting modules into games. Module injection can be detected and may result in bans.