
Una piccola libreria x64 per caricare DLL in memoria.
Una piccola libreria x64 per caricare dll in memoria.
I flag possono essere combinati
LIBRARYEX_NONE: Mappa il modulo dal disco in memoria ed esegue l'entrypoint.
LIBRARYEX_BYPASS_LOAD_CALLBACK: Mappa il modulo dal disco in memoria privata (non supportata da file), bypassando i callback di caricamento delle immagini (PsSetLoadImageNotifyRoutine)
LIBRARYEX_NO_ENTRY: Non esegue l'entrypoint del modulo.
LIBRARYEX_BUFFER: Mappa il modulo dalla memoria invece che dal disco.
LdrLibraryFunzione facile da usare per caricare una libreria in memoria. Il primo parametro, in base ai flag specificati, può essere un nome di modulo come stringa wide da caricare oppure un indirizzo di memoria in cui si trova il file PE.
/*!
* @brief
* load library into memory
*
* @param Buffer
* buffer context to load library
* either a wide string or a buffer pointer
* the to PE file to map (LIBRARYEX_BUFFER)
*
* @param Library
* loaded library pointer
*
* @param Flags
* flags
*
* @return
* status of function
*/
NTSTATUS LdrLibrary(
_In_ PVOID Buffer,
_Out_ PVOID* Library,
_In_ ULONG Flags
);
Questo esempio mostra come caricare un modulo dal disco (dal percorso System32):
PVOID Module = { 0 };
ULONG Flags = { 0 };
//
// mapping flags to be used by the library
//
Flags = LIBRARYEX_NONE;
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( L"advapi32.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", Module );
Questo esempio mostra come caricare un modulo da un buffer in memoria:
PVOID Module = { 0 };
ULONG Flags = { 0 };
//
// mapping flags to be used by the library
//
Flags = LIBRARYEX_NONE |
LIBRARYEX_BUFFER;
//
// read file on disk into memory
//
if ( ! ( Image = ReadFileBuffer( L"C:\\Windows\\System32\\advapi32.dll", NULL ) ) ) {
puts( "[-] ReadFileBuffer Failed" );
return;
}
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( Image, &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", Module );
È anche possibile caricare moduli in base al loro api set (supporto solo win10+):
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( L"api-ms-win-base-util-l1-1-0.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", );
LdrLibraryExLdrLibraryEx consente di agganciare (hook) determinate funzioni per modificare il comportamento con cui una libreria viene mappata in memoria.
//
// mapping flags to be used by the library
// and insert the loaded module into Peb
//
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
LIBRARYEX_NO_ENTRY;
//
// init LibraryEx context
//
if ( ! NT_SUCCESS( Status = LdrLibraryCtx( &Ctx, Flags ) ) ) {
printf( "[-] LdrLibraryCtx Failed: %d\n", Status );
goto END;
}
//
// hook function
//
Ctx.LdrLoadDll = C_PTR( HookLdrLoadDll );
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibraryEx( &Ctx, L"cryptsp.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
Questo codice è scritto e ottimizzato per x86_64-mingw e molto probabilmente non funzionerà né compilerà con Visual Studio.
Un enorme ringraziamento va alle seguenti risorse e progetti:
Questo progetto non dovrebbe essere usato in ambienti reali o in operazioni reali. L'ho scritto principalmente per capire e imparare di più su come funziona il loader di Windows. L'ho scritto come libreria perché volevo usarlo per altri tipi di progetti pubblici e privati. Ho raggiunto il mio obiettivo. Ci si vede!