Load Dll into Kernel space
- 이 프로젝트는 사용자 모드 Dll을 Kernel 영역에 로드하여 커널 드라이버에서 Dll의 코드를 직접 호출할 수 있도록 도와줍니다.
- Kernel32.dll과 Ntdll.dll는 커널에서 절대 사용할 수 없기 때문에 해당 모듈의 기능이 일부 구현되어있습니다.
- Windows 7 이상
- Visual Studio 2017
- Windows 10
- Visual Studio 2017
이 프로젝트는 매우 실험적인 기능입니다.
- TEB나 PEB에 접근하는 코드가 있는 모듈은 사용하지 마십시오
- Dll Load를 직접 사용하는것은 많은 시험을 거친 후 적용하시기 바랍니다.
Visual Studio 프로젝트에 이 라이브러리를 적용할때 참고하시기 바랍니다.
CMake 프로젝트에 이 라이브러리를 적용하시려면 CMake 섹션을 참고하시기 바랍니다.
-
아래 명령을 수행하여 라이브러리를 빌드하시기 바랍니다.
-
Visual Studio 사용
- {이 저장소}/msvc/ldk.sln 혹은 {이 저장소}/msvc/ldk.vcxproj를 열어서 빌드를 하시기 바랍니다.
-
CMake 사용
git clone https://github.com/ntoskrnl7/ldk cd ldk mkdir build && cd build cmake .. -DWDK_WINVER=0x0602 cmake --build . --config Release
-
-
빌드가 완료되었다면 아래 내용을 참고하여 드라이버 프로젝트에 적용하시기 바랍니다.
- {이 저장소}/include를 '추가 포함 디렉토리 속성'에 추가.
- Ldk.lib를 '추가 종속성 속성'에 추가.
- {이 저장소}/lib/$(PlatformShortName)/$(Configuration)를 '추가 라이브러리 디렉토리 속성'에 추가
-
아래 명령을 수행하여 라이브러리 및 테스트 코드를 빌드하시기 바랍니다.
git clone https://github.com/ntoskrnl7/ldk cd ldk/test mkdir build && cd build cmake .. -DWDK_WINVER=0x0602 cmake --build .
-
build/Debug/LdkTest.sys를 설치 및 로드하시기 바랍니다.
-
정상적으로 로드 및 언로드가 되는지 확인하시기 바랍니다.
CMake를 사용하는것을 권장합니다.
CMake를 사용하신다면 아래와 같이 CMakeLists.txt를 만드시기 바랍니다.
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# create project
project(MyProject)
# add dependencies
include(cmake/CPM.cmake)
CPMAddPackage("gh:ntoskrnl7/ldk@0.7.5")
# add dependencies
CPMAddPackage("gh:ntoskrnl7/FindWDK#master")
# use FindWDK
CPMAddPackage("gh:ntoskrnl7/FindWDK#master")
list(APPEND CMAKE_MODULE_PATH "${FindWDK_SOURCE_DIR}/cmake")
find_package(WDK REQUIRED)
# add driver
wdk_add_driver(TestDrv CUSTOM_ENTRY_POINT "LdkDriverEntry" main.c)
# link dependencies
target_link_libraries(TestDrv Ldk)
Condition Variable을 사용하는 간단한 샘플 코드입니다.
-
아래와 같이 진입점을 LdkDriverEntry로 설정한다면 LdkInitialize와 LdkTerminate를 호출할 필요가 없습니다. (권장)
wdk_add_driver(TestDrv CUSTOM_ENTRY_POINT "LdkDriverEntry" main.c)
-
만약 아래와 같이 진입점을 설정하지 않았다면 드라이버가 시작될 때는 LdkInitialize 함수를 반드시 호출해야하며, 드라이버 언로드 전에는 LdkTerminate 함수를 반드시 호출해야합니다.
wdk_add_driver(TestDrv main.c)
아래는 LdkDriverEntry를 진입점으로 설정한 프로젝트의 예제 코드입니다.
#include <Ldk/Windows.h>
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
typedef struct _COND_TEST_THREAD_PARAM {
PCSTR name;
BOOL ready;
LONG processed;
CONDITION_VARIABLE cv;
CRITICAL_SECTION cs;
} COND_TEST_THREAD_PARAM, *PCOND_TEST_THREAD_PARAM;
DWORD
WINAPI
CondTestThreadProc (
LPVOID lpThreadParameter
)
{
PCOND_TEST_THREAD_PARAM param = (PCOND_TEST_THREAD_PARAM)lpThreadParameter;
PAGED_CODE();
DbgPrint("%s - %d - start\n", param->name, GetCurrentThreadId());
EnterCriticalSection(¶m->cs);
while (!param->ready) {
SleepConditionVariableCS(¶m->cv, ¶m->cs, INFINITE);
}
DbgPrint("%s - %d - processed (%d)\n", param->name, GetCurrentThreadId(), InterlockedIncrement(¶m->processed));
LeaveCriticalSection(¶m->cs);
DbgPrint("%s - %d - end\n", param->name, GetCurrentThreadId());
WakeConditionVariable(¶m->cv);
return 0;
}
NTSTATUS
DriverEntry (
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
COND_TEST_THREAD_PARAM param;
param.name = "Test";
param.ready = FALSE;
param.processed = 0;
InitializeCriticalSection(¶m.cs);
InitializeConditionVariable(¶m.cv);
HANDLE threads[5];
for (int i = 0; i < 5; ++i) {
threads[i] = CreateThread(NULL, 0, CondTestThreadProc, ¶m, 0, NULL);
}
EnterCriticalSection(¶m.cs);
param.ready = TRUE;
LeaveCriticalSection(¶m.cs);
WakeAllConditionVariable(¶m.cv);
EnterCriticalSection(¶m.cs);
while (param.processed < 5) {
SleepConditionVariableCS(¶m.cv, ¶m.cs, INFINITE);
}
WakeAllConditionVariable(¶m.cv);
LeaveCriticalSection(¶m.cs);
WaitForMultipleObjects(5, threads, TRUE, INFINITE);
DeleteCriticalSection(¶m.cs);
for (int i = 0; i < 5; ++i) {
if (threads[i]) {
CloseHandle(threads[i]);
}
}
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
VOID
DriverUnload (
_In_ PDRIVER_OBJECT driverObject
)
{
PAGED_CODE();
UNREFERENCED_PARAMETER(driverObject);
}
아직 Dll을 로드하여 사용하기에는 API가 조금밖에 구현되지 않아서 간단한 Dll 밖에는 사용할 수 없습니다.
- 빠른 구현을 위해서 ReactOS 코드를 일부 사용하였으며, 추후 자체 구현해야합니다.
- 문서화
- 기타