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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
| #include <ntddk.h>
typedef struct _PE_HEADER { UCHAR Signature[4]; USHORT Machine; USHORT NumberOfSections; ULONG TimeDateStamp; ULONG PointerToSymbolTable; ULONG NumberOfSymbols; USHORT SizeOfOptionalHeader; USHORT Characteristics; } PE_HEADER, * PPE_HEADER;
typedef struct _PE_OPTIONAL_HEADER { USHORT Magic; UCHAR MajorLinkerVersion; UCHAR MinorLinkerVersion; ULONG SizeOfCode; ULONG SizeOfInitializedData; ULONG SizeOfUninitializedData; ULONG AddressOfEntryPoint; ULONG BaseOfCode; ULONG BaseOfData; ULONG ImageBase; ULONG SectionAlignment; ULONG FileAlignment; USHORT MajorOperatingSystemVersion; USHORT MinorOperatingSystemVersion; USHORT MajorImageVersion; USHORT MinorImageVersion; USHORT MajorSubsystemVersion; USHORT MinorSubsystemVersion; ULONG Win32VersionValue; ULONG SizeOfImage; ULONG SizeOfHeaders; ULONG CheckSum; USHORT Subsystem; USHORT DllCharacteristics; ULONG SizeOfStackReserve; ULONG SizeOfStackCommit; ULONG SizeOfHeapReserve; ULONG SizeOfHeapCommit; ULONG LoaderFlags; ULONG NumberOfRvaAndSizes; } PE_OPTIONAL_HEADER, * PPE_OPTIONAL_HEADER;
typedef struct _PE_SECTION_HEADER { UCHAR Name[8]; union { ULONG PhysicalAddress; ULONG VirtualSize; }; ULONG VirtualAddress; ULONG SizeOfRawData; ULONG PointerToRawData; ULONG PointerToRelocations; ULONG PointerToLinenumbers; USHORT NumberOfRelocations; USHORT NumberOfLinenumbers; ULONG Characteristics; } PE_SECTION_HEADER, * PPE_SECTION_HEADER;
PVOID GetDriverEntryPoint(PVOID BaseAddress) { PPE_HEADER peHeader = (PPE_HEADER)BaseAddress;
if (peHeader->Signature[0] != 'P' || peHeader->Signature[1] != 'E' || peHeader->Signature[2] != '\0' || peHeader->Signature[3] != '\0') { DbgPrint("Invalid PE file signature\n"); return NULL; }
PPE_OPTIONAL_HEADER optionalHeader = (PPE_OPTIONAL_HEADER)((ULONG_PTR)BaseAddress + sizeof(PE_HEADER));
if (optionalHeader->Magic != 0x20b) { DbgPrint("Invalid PE file magic\n"); return NULL; }
ULONG entryPointRVA = optionalHeader->AddressOfEntryPoint;
PVOID entryPoint = (PVOID)((ULONG_PTR)BaseAddress + entryPointRVA);
return entryPoint; }
#define DRIVER_PATH L"\\??\\C:\\path\\to\\unsigned_driver.sys"
typedef struct _DRIVER_FILE_DATA { PVOID BaseAddress; SIZE_T FileSize; } DRIVER_FILE_DATA, * PDRIVER_FILE_DATA;
NTSTATUS ReadDriverFile(PUNICODE_STRING FilePath, PDRIVER_FILE_DATA DriverFileData) { HANDLE fileHandle = NULL; OBJECT_ATTRIBUTES objAttr; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status;
InitializeObjectAttributes(&objAttr, FilePath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwOpenFile(&fileHandle, GENERIC_READ, &objAttr, &ioStatusBlock, FILE_SHARE_READ, 0); if (!NT_SUCCESS(status)) { DbgPrint("Failed to open driver file\n"); return status; }
status = ZwQueryInformationFile(fileHandle, &ioStatusBlock, &DriverFileData->FileSize, sizeof(DriverFileData->FileSize), FileStandardInformation); if (!NT_SUCCESS(status)) { DbgPrint("Failed to query file size\n"); ZwClose(fileHandle); return status; }
DriverFileData->BaseAddress = ExAllocatePoolWithTag(NonPagedPool, DriverFileData->FileSize, 'drvr'); if (DriverFileData->BaseAddress == NULL) { DbgPrint("Memory allocation failed\n"); ZwClose(fileHandle); return STATUS_INSUFFICIENT_RESOURCES; }
status = ZwReadFile(fileHandle, NULL, NULL, NULL, &ioStatusBlock, DriverFileData->BaseAddress, DriverFileData->FileSize, NULL, NULL); if (!NT_SUCCESS(status)) { DbgPrint("Failed to read driver file into memory\n"); ExFreePoolWithTag(DriverFileData->BaseAddress, 'drvr'); ZwClose(fileHandle); return status; }
ZwClose(fileHandle); return STATUS_SUCCESS; }
NTSYSAPI NTSTATUS NTAPI ZwWaitForSingleObject( IN HANDLE ObjectHandle, IN BOOLEAN WaitAll, IN PLARGE_INTEGER Timeout );
NTSTATUS ExecuteDriver(PVOID DriverBaseAddress) { PVOID entryPoint = GetDriverEntryPoint(DriverBaseAddress);
HANDLE threadHandle; NTSTATUS status = PsCreateSystemThread(&threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, (PKSTART_ROUTINE)entryPoint, NULL); if (!NT_SUCCESS(status)) { DbgPrint("Failed to create thread\n"); return status; }
ZwWaitForSingleObject(threadHandle, FALSE, NULL); ZwClose(threadHandle); return STATUS_SUCCESS; }
NTSTATUS LoadAndExecuteDriver() { UNICODE_STRING filePath = RTL_CONSTANT_STRING(DRIVER_PATH); DRIVER_FILE_DATA driverFileData = { 0 };
NTSTATUS status = ReadDriverFile(&filePath, &driverFileData); if (!NT_SUCCESS(status)) { DbgPrint("Failed to read the driver file\n"); return status; }
status = ExecuteDriver(driverFileData.BaseAddress); if (!NT_SUCCESS(status)) { DbgPrint("Failed to execute driver\n"); ExFreePoolWithTag(driverFileData.BaseAddress, 'drvr'); return status; }
ExFreePoolWithTag(driverFileData.BaseAddress, 'drvr'); return STATUS_SUCCESS; }
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DbgPrint("Driver Loaded Successfully\n");
NTSTATUS status = LoadAndExecuteDriver(); if (!NT_SUCCESS(status)) { DbgPrint("Failed to load and execute the driver\n"); }
return STATUS_SUCCESS; }
|