
Una pequeña biblioteca x64 para cargar dlls en memoria.
Una pequeña librería x64 para cargar dll's en memoria.
Los flags se pueden combinar
LIBRARYEX_NONE: Mapea el módulo desde disco a memoria y ejecuta el entrypoint.
LIBRARYEX_BYPASS_LOAD_CALLBACK: Mapea el módulo desde disco a memoria privada (sin respaldo), lo que omite los image load callbacks (PsSetLoadImageNotifyRoutine)
LIBRARYEX_NO_ENTRY: No ejecuta el entrypoint del módulo.
LIBRARYEX_BUFFER: Mapea el módulo desde memoria en lugar de desde disco.
LdrLibraryFunción fácil de usar para cargar una librería en memoria. El primer parámetro, según los flags especificados, puede ser un nombre de módulo en wide string para cargar o una dirección de memoria donde se encuentra el 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
);
Este ejemplo muestra cómo cargar un módulo desde disco (desde la ruta 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 );
Este ejemplo muestra cómo cargar un módulo desde un buffer de 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 );
También es posible cargar módulos basados en su api set (solo soporte para 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 permite enganchar (hook) ciertas funciones para modificar el comportamiento de cómo debería mapearse una librería en 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;
}
Este código está escrito y optimizado para x86_64-mingw y muy probablemente no funcionará ni compilará bajo Visual Studio.
Un enorme agradecimiento a los siguientes recursos y proyectos:
Este proyecto no debería usarse en un entorno u operación del mundo real. Principalmente lo escribí para entender y aprender más sobre cómo funciona el cargador de Windows. Lo escribí como una librería porque quería usarlo para otro tipo de proyectos públicos y privados. Logré mi objetivo. Nos vemos.