
Небольшая x64-библиотека для загрузки dll в память.
Небольшая x64 библиотека для загрузки DLL в память.
Флаги можно комбинировать.
LIBRARYEX_NONE: Сопоставляет модуль с диска в память и выполняет точку входа.
LIBRARYEX_BYPASS_LOAD_CALLBACK: Сопоставляет модуль с диска в приватную память (без резервного файла), что обходит image load callbacks (PsSetLoadImageNotifyRoutine).
LIBRARYEX_NO_ENTRY: Не выполнять точку входа модуля.
LIBRARYEX_BUFFER: Сопоставляет модуль из памяти, а не с диска.
LdrLibraryПростая в использовании функция для загрузки библиотеки в память. Первый параметр, в зависимости от указанных флагов, может быть либо широкой строкой с именем модуля для загрузки, либо адресом в памяти, где расположен 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
);
Этот пример показывает, как загрузить модуль с диска (из пути 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 );
Этот пример показывает, как загрузить модуль из буфера в памяти:
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 );
Также можно загружать модули на основе их api set (поддержка только Windows 10+):
//
// 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 позволяет перехватывать определённые функции, чтобы изменить поведение сопоставления библиотеки с памятью.
//
// 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;
}
Эта кодовая база написана и оптимизирована для x86_64-mingw и, скорее всего, не будет работать или компилироваться в Visual Studio.
Огромная благодарность следующим ресурсам и проектам:
Этот проект не следует использовать в реальной среде или операции. Я в основном написал его, чтобы понять и узнать больше о том, как работает загрузчик Windows. Я написал его в виде библиотеки, потому что хотел использовать его для других публичных и приватных проектов. Я достиг своей цели. Увидимся.