驅動程式 - Windows Driver Model (WDM) - 如何在User Mode開啟"\Device\"下的驅動程式(非Symbolic Link)



參考資訊:
https://www.exploit-db.com/exploits/37052/
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
https://googleprojectzero.blogspot.tw/2016/02/the-definitive-guide-on-win32-to-nt.html

main.c

#include <windows.h>
#include <winternl.h>
#include <stdio.h>

#pragma comment(lib, "ntdll.lib")

void WINAPI RtlInitUnicodeString(PUNICODE_STRING target, LPCWSTR source)
{
    if ((target->Buffer = (LPWSTR)source))
    {
        target->Length = wcslen(source) * sizeof(WCHAR);
        target->MaximumLength = target->Length + sizeof(WCHAR);
    }
    else
    {
        target->Length = target->MaximumLength = 0;
    }
}

int __cdecl main(int argc, CHAR *argv[])
{
    typedef NTSTATUS(__stdcall * NT_OPEN_FILE)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions);
    NT_OPEN_FILE NtOpenFileStruct;

    PVOID Info;
    HMODULE hModule = LoadLibrary("ntdll.dll");
    NtOpenFileStruct = (NT_OPEN_FILE)GetProcAddress(hModule, "NtOpenFile");

    if (NtOpenFileStruct == NULL)
    {
        return -1;
    }

    HANDLE hCF = CreateFile("\\Device\\CNG", MAXIMUM_ALLOWED, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

    printf("CreateFile(\"\\Device\\CNG\"): (handle:0x%X, err:0x%x)\n", hCF, GetLastError());
    if (hCF != (HANDLE)-1)
    {
        CloseHandle(hCF);
    }

    UNICODE_STRING filename;
    RtlInitUnicodeString(&filename, L"\\Device\\CNG");

    OBJECT_ATTRIBUTES obja;
    obja.Attributes = 0x40;
    obja.ObjectName = &filename;
    obja.Length = 0x18;
    obja.RootDirectory = NULL;
    obja.SecurityDescriptor = NULL;
    obja.SecurityQualityOfService = NULL;

    IO_STATUS_BLOCK iostatusblock;
    HANDLE hCNG = NULL;
    NTSTATUS stat = NtOpenFileStruct(&hCNG, 0x100001, &obja, &iostatusblock, 7, 0x20);

    printf("NtOpenFileStruct(\"\\Device\\CNG\"): (status:0x%x)\n", stat);
    if (stat == 0)
    {
        CloseHandle(hCNG);
    }
    return 0;
}