Skip to content

ntoskrnl7/ldk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ldk

Load Dll into Kernel space

CMake GitHub GitHub release (latest SemVer) Windows 7+ Visual Studio 2017+ CMake 3.14+ Architecture

Overview

  • 이 프로젝트는 사용자 모드 Dll을 Kernel 영역에 로드하여 커널 드라이버에서 Dll의 코드를 직접 호출할 수 있도록 도와줍니다.
  • Kernel32.dll과 Ntdll.dll는 커널에서 절대 사용할 수 없기 때문에 해당 모듈의 기능이 일부 구현되어있습니다.

Requirements

  • Windows 7 이상
  • Visual Studio 2017

Test Environments

  • Windows 10
  • Visual Studio 2017

Contents

Caution

이 프로젝트는 매우 실험적인 기능입니다.

  1. TEB나 PEB에 접근하는 코드가 있는 모듈은 사용하지 마십시오
  2. Dll Load를 직접 사용하는것은 많은 시험을 거친 후 적용하시기 바랍니다.

Build

Visual Studio 프로젝트에 이 라이브러리를 적용할때 참고하시기 바랍니다.

CMake 프로젝트에 이 라이브러리를 적용하시려면 CMake 섹션을 참고하시기 바랍니다.

  1. 아래 명령을 수행하여 라이브러리를 빌드하시기 바랍니다.

    • 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
  2. 빌드가 완료되었다면 아래 내용을 참고하여 드라이버 프로젝트에 적용하시기 바랍니다.

    1. {이 저장소}/include를 '추가 포함 디렉토리 속성'에 추가.
    2. Ldk.lib를 '추가 종속성 속성'에 추가.
    3. {이 저장소}/lib/$(PlatformShortName)/$(Configuration)를 '추가 라이브러리 디렉토리 속성'에 추가

Test

  1. 아래 명령을 수행하여 라이브러리 및 테스트 코드를 빌드하시기 바랍니다.

    git clone https://github.com/ntoskrnl7/ldk
    cd ldk/test
    mkdir build && cd build
    cmake .. -DWDK_WINVER=0x0602
    cmake --build .
  2. build/Debug/LdkTest.sys를 설치 및 로드하시기 바랍니다.

  3. 정상적으로 로드 및 언로드가 되는지 확인하시기 바랍니다.

Usage

CMake를 사용하는것을 권장합니다.

CMake

CMake를 사용하신다면 아래와 같이 CMakeLists.txt를 만드시기 바랍니다.

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)

main.c

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(&param->cs);
    while (!param->ready) {
        SleepConditionVariableCS(&param->cv, &param->cs, INFINITE);
    }

    DbgPrint("%s - %d - processed (%d)\n", param->name, GetCurrentThreadId(), InterlockedIncrement(&param->processed));

    LeaveCriticalSection(&param->cs);

    DbgPrint("%s - %d - end\n", param->name, GetCurrentThreadId());

    WakeConditionVariable(&param->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(&param.cs);
    InitializeConditionVariable(&param.cv);
    HANDLE threads[5];
    for (int i = 0; i < 5; ++i) {
        threads[i] = CreateThread(NULL, 0, CondTestThreadProc, &param, 0, NULL);
    }

    EnterCriticalSection(&param.cs);
    param.ready = TRUE;
    LeaveCriticalSection(&param.cs);
    WakeAllConditionVariable(&param.cv);

    EnterCriticalSection(&param.cs);
    while (param.processed < 5) {
        SleepConditionVariableCS(&param.cv, &param.cs, INFINITE);
    }
    WakeAllConditionVariable(&param.cv);
    LeaveCriticalSection(&param.cs);

    WaitForMultipleObjects(5, threads, TRUE, INFINITE);
    DeleteCriticalSection(&param.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);
}

TODO

아직 Dll을 로드하여 사용하기에는 API가 조금밖에 구현되지 않아서 간단한 Dll 밖에는 사용할 수 없습니다.

  • 빠른 구현을 위해서 ReactOS 코드를 일부 사용하였으며, 추후 자체 구현해야합니다.
  • 문서화
  • 기타

About

Load Dll into Kernel space

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages