
Uma pequena biblioteca x64 para carregar DLLs na memória.
Uma pequena biblioteca x64 para carregar DLLs na memória.
As flags podem ser combinadas
LIBRARYEX_NONE: Mapeia o módulo do disco para a memória e executa o entrypoint.
LIBRARYEX_BYPASS_LOAD_CALLBACK: Mapeia o módulo do disco para memória privada (sem backing), o que ignora callbacks de carregamento de imagem (PsSetLoadImageNotifyRoutine)
LIBRARYEX_NO_ENTRY: Não executa o entrypoint do módulo.
LIBRARYEX_BUFFER: Mapeia o módulo a partir da memória em vez do disco.
LdrLibraryFunção fácil de usar para carregar uma biblioteca na memória. O primeiro parâmetro, dependendo das flags especificadas, pode ser um nome de módulo em string wide para carregar ou um endereço de memória onde o PE está localizado.
/*!
* @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 exemplo mostra como carregar um módulo do disco (a partir do caminho 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 exemplo mostra como carregar um módulo a partir de um buffer de memória:
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 );
Também é possível carregar módulos com base no seu api set (suporte apenas 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 interceptar determinadas funções para modificar o comportamento de como uma biblioteca deve ser mapeada na memória.
//
// 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 foi escrito e otimizado para x86_64-mingw e provavelmente não funcionará e/ou compilará no Visual Studio.
Um enorme crédito vai para os seguintes recursos e projetos:
este projeto não deve ser usado em um ambiente ou operação do mundo real. Escrevi isto principalmente para entender e aprender mais sobre como o loader do Windows funciona. Escrevi como uma biblioteca porque queria usar isso para outros tipos de projetos públicos e privados. Alcancei meu objetivo. Até mais.