
dll을 메모리에 로드하기 위한 작은 x64 라이브러리.
DLL을 메모리에 로드하기 위한 작은 x64 라이브러리입니다.
플래그는 조합할 수 있습니다.
LIBRARYEX_NONE: 디스크에서 모듈을 메모리로 매핑하고 엔트리포인트를 실행합니다.
LIBRARYEX_BYPASS_LOAD_CALLBACK: 디스크에서 모듈을 프라이빗 메모리(백업되지 않음)로 매핑하여 이미지 로드 콜백(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 세트를 기반으로 모듈을 로드하는 것도 가능합니다(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 로더가 어떻게 작동하는지 이해하고 배우기 위해 이 프로젝트를 작성했습니다. 다른 공개 및 비공개 프로젝트에서 사용하고 싶어서 라이브러리 형태로 작성했습니다. 목표를 달성했습니다. 다음에 봐요.