-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathCreateDriver.h
More file actions
169 lines (141 loc) · 5.21 KB
/
CreateDriver.h
File metadata and controls
169 lines (141 loc) · 5.21 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
***************************************************
* Author: Th3Spl *
* Lang: C++ | Usable in C as well *
* Date: 27/12/2023 *
* Purpose: IoCreateDriver Implementation *
***************************************************
*/
#pragma once
//
// Inclusions
//
#include <ntifs.h>
#include <ntstrsafe.h>
#include <windef.h>
#include "definitions.h"
//
// Dummy function used as default function for the IRP_MJ functions
//
NTSTATUS NTAPI IopInvalidDeviceRequest( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
//
// Custom IoCreateDriver in order to bypass PsLoadedModule and EtwTiLogDriverObjectLoad
// it makes easier tohe usage of IOCTL if you're using KdMapper
//
NTSTATUS __fastcall IoCreateDriver( _In_ NTSTATUS(__fastcall* EntryPoint)(_In_ PDRIVER_OBJECT, _In_ PUNICODE_STRING))
{
//
// Variables
//
HANDLE drv_handle;
USHORT name_length;
WCHAR name_buffer[100];
PDRIVER_OBJECT drv_obj;
OBJECT_ATTRIBUTES obj_attribs;
UNICODE_STRING local_drv_name;
UNICODE_STRING service_key_name;
NTSTATUS status = STATUS_SUCCESS;
ULONG obj_size = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
//
// We meed to create a UNICODE_STRING which contains the (randomic) name of the driver (we're not interested in that)
//
name_length = (USHORT)swprintf(name_buffer, L"\\Driver\\%08u", (ULONG)KeQueryUnbiasedInterruptTime());
local_drv_name.Length = name_length * sizeof(WCHAR);
local_drv_name.MaximumLength = local_drv_name.Length + sizeof(UNICODE_NULL);
local_drv_name.Buffer = name_buffer;
//
// Initializing the object attributes [PERMANENT, CASE_SENSITIVE, KERNEL_HANLE]
//
InitializeObjectAttributes(&obj_attribs, &local_drv_name, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
//
// Creating the driver object itself [ObCreateObject exported by ntoskrnl.exe]
//
status = ObCreateObject(KernelMode, IoDriverObjectType, &obj_attribs, KernelMode, NULL, obj_size, 0, 0, (PVOID*)&drv_obj);
if (!NT_SUCCESS(status))
return status;
//
// Setting up the driver object
//
RtlZeroMemory(drv_obj, obj_size); // Cleaning up
drv_obj->Type = IO_TYPE_DRIVER; // Specifying the driver type
drv_obj->Size = sizeof(DRIVER_OBJECT); // Setting its size
drv_obj->Flags = DRVO_BUILTIN_DRIVER; // Setting it as a BUILTIN_DRIVER
drv_obj->DriverExtension = (PDRIVER_EXTENSION)(drv_obj + 1); // Setting up the driver extension
drv_obj->DriverExtension->DriverObject = drv_obj; // Assigning the driver
drv_obj->DriverInit = EntryPoint; // Setting the driver entry point
//
// We need to set the IRPP_MJ functions to IopInvalidDeviceRequest
//
for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
drv_obj->MajorFunction[i] = IopInvalidDeviceRequest;
}
//
// Setting up the service key for the driver
//
service_key_name.MaximumLength = local_drv_name.Length + sizeof(UNICODE_NULL);
service_key_name.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, local_drv_name.MaximumLength, (ULONG)KeQueryUnbiasedInterruptTime());
if (!service_key_name.Buffer)
{
ObMakeTemporaryObject(drv_obj);
ObfDereferenceObject(drv_obj);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&service_key_name, &local_drv_name);
service_key_name.Buffer[service_key_name.Length / sizeof(WCHAR)] = UNICODE_NULL;
drv_obj->DriverExtension->ServiceKeyName = service_key_name;
//
// Saving the driver name within the driver object
//
drv_obj->DriverName.MaximumLength = local_drv_name.Length;
drv_obj->DriverName.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, drv_obj->DriverName.MaximumLength, (ULONG)KeQueryUnbiasedInterruptTime());
if (!drv_obj->DriverName.Buffer)
{
ObMakeTemporaryObject(drv_obj);
ObfDereferenceObject(drv_obj);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&drv_obj->DriverName, &local_drv_name);
//
// Creating the kernel object (DRIVER_OBJECT) so we can get its handle
//
status = ObInsertObject(drv_obj, NULL, FILE_READ_DATA, 0, NULL, &drv_handle);
ZwClose(drv_handle);
if (!NT_SUCCESS(status))
{
ObMakeTemporaryObject(drv_obj);
ObfDereferenceObject(drv_obj);
return status;
}
/* fixup --> Credits: https://github.com/danydollaro */
ClearFlag( drv_obj->Flags, DO_DEVICE_INITIALIZING );
//
// Actually starting the driver's entry point (passing the driver object)
//
status = EntryPoint(drv_obj, NULL);
if (!NT_SUCCESS(status))
{
ObMakeTemporaryObject(drv_obj);
ObDereferenceObject(drv_obj);
return status;
}
//
// Since having the IRP_MJ functions set to null it's illegal
// we gotta set them to IopInvalidDeviceRequest
//
for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
if (!drv_obj->MajorFunction[i])
{
drv_obj->MajorFunction[i] = IopInvalidDeviceRequest;
}
}
return status; // If everything went correctly this will return the driver's result
}