aboutsummaryrefslogtreecommitdiff
path: root/examples/dpp-example.c
blob: 2b9f26f599b4f4346112149483e2c5cb48873d34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <ntddk.h>

#include <except.h>

DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;

extern NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle,
                                             _In_ _Out_ PVOID * BaseAddress,
                                             _In_ _Out_ PULONG NumberOfBytesToProtect,
                                             _In_ ULONG NewAccessProtection,
                                             _Out_ PULONG OldAccessProtection);
extern NTSTATUS NTAPI ZwQuerySystemInformation(_In_ int SystemInformationClass,
                                               _Inout_ PVOID SystemInformation,
                                               _In_ ULONG SystemInformationLength,
                                               _Out_opt_ PULONG ReturnLength);
extern NTSTATUS NTAPI WrapperZwQuerySystemInformation(_In_ int SystemInformationClass,
                                                      _Inout_ PVOID SystemInformation,
                                                      _In_ ULONG SystemInformationLength,
                                                      _Out_opt_ PULONG ReturnLength);
extern NTSTATUS NTAPI WrapperZwCreateFile(_Out_ PHANDLE FileHandle,
                                          _In_ ACCESS_MASK DesiredAccess,
                                          _In_ POBJECT_ATTRIBUTES ObjectAttributes,
                                          _Out_ PIO_STATUS_BLOCK StatusBlock,
                                          _In_ PLARGE_INTEGER AllocationSize,
                                          _In_ ULONG FileAttributes,
                                          _In_ ULONG ShareAccess,
                                          _In_ ULONG CreateDisposition,
                                          _In_ ULONG CreateOptions,
                                          _In_ PVOID EaBuffer,
                                          _In_ ULONG EaLength);
extern NTSTATUS NTAPI WrapperZwClose(_In_ HANDLE Handle);
extern NTSTATUS NTAPI WrapperZwWriteFile(_In_ HANDLE FileHandle,
                                         _In_ HANDLE Event,
                                         _In_ PIO_APC_ROUTINE ApcRoutine,
                                         _In_ PVOID ApcContext,
                                         _Out_ PIO_STATUS_BLOCK StatusBlock,
                                         _In_ PVOID Buffer,
                                         _In_ ULONG Length,
                                         _In_ PLARGE_INTEGER ByteOffset,
                                         _In_ PULONG Key);

int example_exception_handler(_In_ EXCEPTION_POINTERS * lpEP)
{
    (void)lpEP;
    DbgPrint("Exception handler called!\n");
    return EXCEPTION_EXECUTE_HANDLER;
}

static void another_seh_test()
{
    DbgPrint("Another SEH test..\n");
    __dpptry(example_exception_handler, anotherseh)
    {
        *(int *)0 = 0;
    }
    __dppexcept(anotherseh)
    {
        DbgPrint("Success!\n");
    }
    __dpptryend(anotherseh);
}

static void zw_test()
{
    NTSTATUS ret;
    ULONG memoryNeeded = 0;

    ret = ZwQuerySystemInformation(0x5, NULL, 0, &memoryNeeded);
    if (ret != STATUS_INFO_LENGTH_MISMATCH || !memoryNeeded)
    {
        DbgPrint("ZwQuerySystemInformation failed with 0x%lX (memory needed: %lu)\n", ret, memoryNeeded);
    }

    memoryNeeded = 0;
    ret = WrapperZwQuerySystemInformation(0x5, NULL, 0, &memoryNeeded);
    if (ret != STATUS_INFO_LENGTH_MISMATCH || !memoryNeeded)
    {
        DbgPrint("ZwQuerySystemInformation failed 0x%lX (memory needed: %lu)\n", ret, memoryNeeded);
    }
}

static NTSTATUS WriteToFile()
{
    UNICODE_STRING fileName = RTL_CONSTANT_STRING(L"\\??\\C:\\dpp-example-text.log");
    OBJECT_ATTRIBUTES objAttr;
    IO_STATUS_BLOCK ioStatusBlock;
    HANDLE fileHandle;
    NTSTATUS status;

    InitializeObjectAttributes(&objAttr, &fileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);

    status = WrapperZwCreateFile(&fileHandle,
                                 GENERIC_WRITE,
                                 &objAttr,
                                 &ioStatusBlock,
                                 NULL,
                                 FILE_ATTRIBUTE_NORMAL,
                                 0,
                                 FILE_OVERWRITE_IF,
                                 FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    CHAR data[] = "Test data from the kernel driver\n";
    status = WrapperZwWriteFile(fileHandle, NULL, NULL, NULL, &ioStatusBlock, data, sizeof(data) - 1, NULL, NULL);

    WrapperZwClose(fileHandle);
    return status;
}

NTSTATUS DriverEntry(struct _DRIVER_OBJECT * DriverObject, PUNICODE_STRING RegistryPath)
{
    (void)DriverObject;
    (void)RegistryPath;

    DbgPrint("%s\n", "Hello ring0!");

    DbgPrint("Testing SEH..\n");
    __dpptry(example_exception_handler, testseh)
    {
        *(int *)0 = 0;
        DbgPrint("You should never see this text!\n");
    }
    __dppexcept(testseh)
    {
        DbgPrint("Success! SEH seems to work.\n");
    }
    __dpptryend(testseh);

    another_seh_test();
    zw_test();

    DbgPrint("%s\n", "Disable/Enable Interrupts!");
    _disable();
    _enable();
    DbgPrint("%s\n", "Done with Disable/Enable Interrupts!");

    DbgPrint("%s\n", "WriteToFile");
    WriteToFile();

    return STATUS_SUCCESS;
}

VOID DriverUnload(struct _DRIVER_OBJECT * DriverObject)
{
    (void)DriverObject;

    DbgPrint("%s\n", "Bye ring0!");
}