init commit

merge-requests/1/head
_xeroxz 3 years ago
parent 4e4912c9c3
commit 62bf24fb47

@ -0,0 +1,45 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30621.155
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NtWin32k", "NtWin32k\NtWin32k.vcxproj", "{CB140ADD-1805-4F91-9E5A-4844F98EAB52}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NtWin32u", "NtWin32u\NtWin32u.vcxproj", "{DF92FE26-A275-403C-B242-35C82B881DEF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x64.ActiveCfg = Debug|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x64.Build.0 = Debug|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x64.Deploy.0 = Debug|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x86.ActiveCfg = Debug|Win32
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x86.Build.0 = Debug|Win32
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Debug|x86.Deploy.0 = Debug|Win32
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x64.ActiveCfg = Release|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x64.Build.0 = Release|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x64.Deploy.0 = Release|x64
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x86.ActiveCfg = Release|Win32
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x86.Build.0 = Release|Win32
{CB140ADD-1805-4F91-9E5A-4844F98EAB52}.Release|x86.Deploy.0 = Release|Win32
{DF92FE26-A275-403C-B242-35C82B881DEF}.Debug|x64.ActiveCfg = Debug|x64
{DF92FE26-A275-403C-B242-35C82B881DEF}.Debug|x64.Build.0 = Debug|x64
{DF92FE26-A275-403C-B242-35C82B881DEF}.Debug|x86.ActiveCfg = Debug|Win32
{DF92FE26-A275-403C-B242-35C82B881DEF}.Debug|x86.Build.0 = Debug|Win32
{DF92FE26-A275-403C-B242-35C82B881DEF}.Release|x64.ActiveCfg = Release|x64
{DF92FE26-A275-403C-B242-35C82B881DEF}.Release|x64.Build.0 = Release|x64
{DF92FE26-A275-403C-B242-35C82B881DEF}.Release|x86.ActiveCfg = Release|Win32
{DF92FE26-A275-403C-B242-35C82B881DEF}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {115B9250-3D35-44AE-B94B-3F3BF017926A}
EndGlobalSection
EndGlobal

@ -0,0 +1,87 @@
;
; NtWin32k.inf
;
[Version]
Signature="$WINDOWS NT$"
Class=Sample ; TODO: edit Class
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=NtWin32k.cat
DriverVer= ; TODO: set DriverVer in stampinf property pages
PnpLockDown=1
[DestinationDirs]
DefaultDestDir = 12
NtWin32k_Device_CoInstaller_CopyFiles = 11
; ================= Class section =====================
[ClassInstall32]
Addreg=SampleClassReg
[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5
[SourceDisksNames]
1 = %DiskName%,,,""
[SourceDisksFiles]
NtWin32k.sys = 1,,
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames
;*****************************************
; Install Section
;*****************************************
[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$
[Standard.NT$ARCH$]
%NtWin32k.DeviceDesc%=NtWin32k_Device, Root\NtWin32k ; TODO: edit hw-id
[NtWin32k_Device.NT]
CopyFiles=Drivers_Dir
[Drivers_Dir]
NtWin32k.sys
;-------------- Service installation
[NtWin32k_Device.NT.Services]
AddService = NtWin32k,%SPSVCINST_ASSOCSERVICE%, NtWin32k_Service_Inst
; -------------- NtWin32k driver install sections
[NtWin32k_Service_Inst]
DisplayName = %NtWin32k.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\NtWin32k.sys
;
;--- NtWin32k_Device Coinstaller installation ------
;
[NtWin32k_Device.NT.CoInstallers]
AddReg=NtWin32k_Device_CoInstaller_AddReg
CopyFiles=NtWin32k_Device_CoInstaller_CopyFiles
[NtWin32k_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"
[NtWin32k_Device_CoInstaller_CopyFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll
[NtWin32k_Device.NT.Wdf]
KmdfService = NtWin32k, NtWin32k_wdfsect
[NtWin32k_wdfsect]
KmdfLibraryVersion = $KMDFVERSION$
[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ClassName="Samples" ; TODO: edit ClassName
DiskName = "NtWin32k Installation Disk"
NtWin32k.DeviceDesc = "NtWin32k Device"
NtWin32k.SVCDESC = "NtWin32k Service"

@ -0,0 +1,177 @@
<?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|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{CB140ADD-1805-4F91-9E5A-4844F98EAB52}</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>NtWin32k</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</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>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</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|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>false</TreatWarningAsError>
<BufferSecurityCheck>false</BufferSecurityCheck>
<ControlFlowGuard>false</ControlFlowGuard>
</ClCompile>
<Link>
<EntryPointSymbol>driver_entry</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Inf Include="NtWin32k.inf" />
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="driver_entry.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="kutils.hpp" />
<ClInclude Include="ntwin32k.hpp" />
</ItemGroup>
<ItemGroup>
<MASM Include="filter_handler.asm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

@ -0,0 +1,40 @@
<?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="Driver Files">
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
<Extensions>inf;inv;inx;mof;mc;</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Inf Include="NtWin32k.inf">
<Filter>Driver Files</Filter>
</Inf>
</ItemGroup>
<ItemGroup>
<ClInclude Include="kutils.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ntwin32k.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="driver_entry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="filter_handler.asm">
<Filter>Source Files</Filter>
</MASM>
</ItemGroup>
</Project>

@ -0,0 +1,39 @@
#include "ntwin32k.hpp"
#define SYSCALL_KEY 0xDEADBEEF
extern "C" auto hook_handler(unsigned syscall_num, psyscall_args_t args) -> bool
{
if (args->rcx == SYSCALL_KEY)
{
DBG_PRINT("syscall number -> 0x%x\n", syscall_num);
DBG_PRINT(" - rcx: 0x%p\n", args->rcx);
DBG_PRINT(" - rdx: 0x%p\n", args->rdx);
DBG_PRINT(" - r8: 0x%p\n", args->r8);
DBG_PRINT(" - r9: 0x%p\n", args->r9);
return true;
}
return false;
}
// unhook win32k filter on unload...
auto driver_unload(PDRIVER_OBJECT driver_object) -> void
{
nt::win32k::unhook_filter(original_function);
}
auto driver_entry(
PDRIVER_OBJECT driver_object,
PUNICODE_STRING registry_path
) -> NTSTATUS
{
RTL_OSVERSIONINFOW version;
RtlGetVersion(&version);
if (version.dwBuildNumber >= 19041) // if 2004 and above...
original_function = nt::win32k::hook_filter(&asm_hook_handler_2004);
else
original_function = nt::win32k::hook_filter(&asm_hook_handler);
driver_object->DriverUnload = &driver_unload;
return STATUS_SUCCESS;
}

@ -0,0 +1,32 @@
extern hook_handler : proc
.code
asm_hook_handler_2004 proc
lea rdx, [rsp+58h] ; rcx is the syscall number...
; rdx is a pointer to arguments...
call hook_handler
cmp rax, 1
je sysreturn
xor rax, rax ; always return false...
ret
sysreturn:
add rsp, 80h
mov rax, 00C0FFEEh ; return back to usermode with 0xC0FFEE as result...
ret
asm_hook_handler_2004 endp
; stack distance to arguments is different on older versions of windows...
asm_hook_handler proc
lea rdx, [rsp + 28h]
call hook_handler
cmp rax, 1
je sysreturn
xor rax, rax
ret
sysreturn:
add rsp, 50h
mov rax, 00C0FFEEh
ret
asm_hook_handler endp
end

@ -0,0 +1,728 @@
#pragma once
#include <ntifs.h>
#include <intrin.h>
using u64 = unsigned long long;
using u32 = unsigned long;
using u16 = unsigned short;
using u8 = unsigned char;
#define DBG_PRINT(...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[kutils]" __VA_ARGS__);
// Export Directory
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
// Import Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
// Resource Directory
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
// Exception Directory
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
// Security Directory
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
// Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
// Debug Directory
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
// Description String
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
// Machine Value (MIPS GP)
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
// TLS Directory
#define IMAGE_DIRECTORY_ENTRY_TLS 9
// Load Configuration Directory
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
USHORT e_magic; // Magic number
USHORT e_cblp; // Bytes on last page of file
USHORT e_cp; // Pages in file
USHORT e_crlc; // Relocations
USHORT e_cparhdr; // Size of header in paragraphs
USHORT e_minalloc; // Minimum extra paragraphs needed
USHORT e_maxalloc; // Maximum extra paragraphs needed
USHORT e_ss; // Initial (relative) SS value
USHORT e_sp; // Initial SP value
USHORT e_csum; // Checksum
USHORT e_ip; // Initial IP value
USHORT e_cs; // Initial (relative) CS value
USHORT e_lfarlc; // File address of relocation table
USHORT e_ovno; // Overlay number
USHORT e_res[4]; // Reserved words
USHORT e_oemid; // OEM identifier (for e_oeminfo)
USHORT e_oeminfo; // OEM information; e_oemid specific
USHORT e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
short Machine;
short NumberOfSections;
unsigned TimeDateStamp;
unsigned PointerToSymbolTable;
unsigned NumberOfSymbols;
short SizeOfOptionalHeader;
short Characteristics;
} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY {
unsigned VirtualAddress;
unsigned Size;
} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_OPTIONAL_HEADER64 {
short Magic;
unsigned char MajorLinkerVersion;
unsigned char MinorLinkerVersion;
unsigned SizeOfCode;
unsigned SizeOfInitializedData;
unsigned SizeOfUninitializedData;
unsigned AddressOfEntryPoint;
unsigned BaseOfCode;
ULONGLONG ImageBase;
unsigned SectionAlignment;
unsigned FileAlignment;
short MajorOperatingSystemVersion;
short MinorOperatingSystemVersion;
short MajorImageVersion;
short MinorImageVersion;
short MajorSubsystemVersion;
short MinorSubsystemVersion;
unsigned Win32VersionValue;
unsigned SizeOfImage;
unsigned SizeOfHeaders;
unsigned CheckSum;
short Subsystem;
short DllCharacteristics;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
ULONGLONG SizeOfHeapReserve;
ULONGLONG SizeOfHeapCommit;
unsigned LoaderFlags;
unsigned NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
} IMAGE_OPTIONAL_HEADER64, * PIMAGE_OPTIONAL_HEADER64;
typedef struct _IMAGE_NT_HEADERS64 {
unsigned Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, * PIMAGE_NT_HEADERS64;
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
unsigned long Characteristics; // 0 for terminating null import descriptor
unsigned long OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
unsigned long TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
unsigned long ForwarderChain; // -1 if no forwarders
unsigned long Name;
unsigned long FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED* PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_IMPORT_BY_NAME {
unsigned long Hint;
CHAR Name[1];
} IMAGE_IMPORT_BY_NAME, * PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_THUNK_DATA64 {
union {
ULONGLONG ForwarderString; // PBYTE
ULONGLONG Function; // PDWORD
ULONGLONG Ordinal;
ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA64, * PIMAGE_THUNK_DATA64;
typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation
} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
unsigned short LoadCount;
unsigned short TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PVOID EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB_LDR_DATA
{
ULONG Length;
UCHAR Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
unsigned char Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
unsigned char TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, * PPEB;
typedef struct _SYSTEM_THREAD
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitchCount;
ULONG State;
KWAIT_REASON WaitReason;
} SYSTEM_THREAD, * PSYSTEM_THREAD;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
ULONG PrivatePageCount;
VM_COUNTERS VirtualMemoryCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD Threads[0];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES
{
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
typedef struct _OBJECT_DIRECTORY_ENTRY
{
struct _OBJECT_DIRECTORY_ENTRY* ChainLink;
PVOID Object;
ULONG HashValue;
} OBJECT_DIRECTORY_ENTRY, * POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY
{
POBJECT_DIRECTORY_ENTRY HashBuckets[37];
EX_PUSH_LOCK Lock;
struct _DEVICE_MAP* DeviceMap;
ULONG SessionId;
PVOID NamespaceEntry;
ULONG Flags;
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
typedef struct _DEVICE_MAP
{
POBJECT_DIRECTORY DosDevicesDirectory;
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
ULONG ReferenceCount;
ULONG DriveMap;
UCHAR DriveType[32];
} DEVICE_MAP, * PDEVICE_MAP;
extern "C" NTSTATUS NtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
extern "C" PVOID RtlFindExportedRoutineByName(
_In_ PVOID ImageBase,
_In_ PCCH RoutineNam
);
extern "C" PVOID PsGetProcessSectionBaseAddress(
__in PEPROCESS Process
);
extern "C" PPEB PsGetProcessPeb(PEPROCESS Process);
namespace kutils
{
namespace driver
{
inline auto get_driver_base(const char* driver_name) -> void*
{
u32 alloc_size{};
NtQuerySystemInformation(
SystemModuleInformation,
NULL, alloc_size, &alloc_size);
auto module_info =
reinterpret_cast<PRTL_PROCESS_MODULES>(
ExAllocatePool(NonPagedPool, alloc_size));
NtQuerySystemInformation(
SystemModuleInformation,
module_info, alloc_size, &alloc_size);
for (auto idx = 0u; idx < module_info->NumberOfModules; ++idx)
{
auto module_name =
reinterpret_cast<const char*>(
module_info->Modules[idx].FullPathName +
module_info->Modules[idx].OffsetToFileName);
if (!strcmp(module_name, driver_name))
{
auto result = module_info->Modules[idx].ImageBase;
ExFreePool(module_info);
return result;
}
}
ExFreePool(module_info);
return nullptr;
}
inline auto get_driver_export(const char* driver_name, const char* routine_name) -> void*
{
const auto driver_base =
get_driver_base(driver_name);
if (!driver_base)
return nullptr;
return RtlFindExportedRoutineByName(
reinterpret_cast<void*>(driver_base), routine_name);
}
inline auto get_driver_object(const wchar_t* driver_name) -> PDRIVER_OBJECT
{
HANDLE handle{};
OBJECT_ATTRIBUTES attributes{};
UNICODE_STRING directory_name{};
PVOID directory{};
BOOLEAN success = FALSE;
RtlInitUnicodeString(&directory_name, L"\\Driver");
InitializeObjectAttributes(
&attributes,
&directory_name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
// open OBJECT_DIRECTORY for \\Driver
auto status = ZwOpenDirectoryObject(
&handle,
DIRECTORY_ALL_ACCESS,
&attributes
);
if (!NT_SUCCESS(status))
{
ZwClose(handle);
return NULL;
}
// Get OBJECT_DIRECTORY pointer from HANDLE
status = ObReferenceObjectByHandle(
handle,
DIRECTORY_ALL_ACCESS,
nullptr,
KernelMode,
&directory,
nullptr
);
if (!NT_SUCCESS(status))
{
ZwClose(handle);
return NULL;
}
const auto directory_object = POBJECT_DIRECTORY(directory);
ExAcquirePushLockExclusiveEx(&directory_object->Lock, 0);
for (auto entry : directory_object->HashBuckets)
{
if (!entry)
continue;
while (entry && entry->Object)
{
auto driver = PDRIVER_OBJECT(entry->Object);
if (!driver)
continue;
if (wcscmp(driver->DriverExtension->ServiceKeyName.Buffer, driver_name) == 0)
return driver;
entry = entry->ChainLink;
}
}
ExReleasePushLockExclusiveEx(&directory_object->Lock, 0);
ObDereferenceObject(directory);
ZwClose(handle);
return nullptr;
}
inline auto iat_hook(void* base_addr, const char* routine_name, void* func_addr) -> void*
{
const auto dos_headers =
reinterpret_cast<PIMAGE_DOS_HEADER>(base_addr);
const auto nt_headers =
reinterpret_cast<PIMAGE_NT_HEADERS64>(
reinterpret_cast<DWORD_PTR>(base_addr) + dos_headers->e_lfanew);
const auto import_dir =
nt_headers->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
auto import_des =
reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
import_dir.VirtualAddress + (DWORD_PTR)base_addr);
LPCSTR lib_name = NULL;
PVOID result = NULL;
PIMAGE_IMPORT_BY_NAME func_name = NULL;
while (import_des->Name != NULL)
{
lib_name = (LPCSTR)import_des->Name + (DWORD_PTR)base_addr;
if (driver::get_driver_base(lib_name))
{
PIMAGE_THUNK_DATA org_first_thunk = NULL, first_thunk = NULL;
org_first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)base_addr + import_des->OriginalFirstThunk);
first_thunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)base_addr + import_des->FirstThunk);
while (org_first_thunk->u1.AddressOfData != NULL)
{
func_name = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)base_addr + org_first_thunk->u1.AddressOfData);
if (strcmp(func_name->Name, routine_name) == 0)
{
// save old function pointer
result = reinterpret_cast<PVOID>(first_thunk->u1.Function);
//
// although disabling wp bit can cause crashes, im disabling it for nano seconds. only to write 8 bytes...
// in reality this is 1 mov instruction.
//
{
//
// disable write protection
//
_disable();
auto cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
}
// swap address
first_thunk->u1.Function = reinterpret_cast<ULONG64>(func_addr);
{
//
// enable write protection
//
auto cr0 = __readcr0();
cr0 |= 0x10000;
__writecr0(cr0);
_enable();
}
return result;
}
++org_first_thunk;
++first_thunk;
}
}
++import_des;
}
return nullptr;
}
}
namespace process
{
inline auto get_pid(const wchar_t* process_name) -> u32
{
u32 alloc_size{};
NtQuerySystemInformation(
SystemProcessInformation,
nullptr, alloc_size, &alloc_size);
auto process_info =
reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(
ExAllocatePool(NonPagedPool, alloc_size));
const auto orig_ptr = process_info;
NtQuerySystemInformation(
SystemProcessInformation,
process_info, alloc_size, &alloc_size);
while (true)
{
if (process_info->ImageName.Buffer)
{
if (!_wcsicmp(process_info->ImageName.Buffer, process_name))
{
auto result = process_info->ProcessId;
ExFreePool(orig_ptr);
return (u32)result;
}
}
if (!process_info->NextEntryOffset)
break;
process_info = reinterpret_cast<PSYSTEM_PROCESS_INFORMATION>(
reinterpret_cast<u64>(process_info) + process_info->NextEntryOffset);
}
ExFreePool(orig_ptr);
return NULL;
}
inline auto get_process_base(u32 pid) -> void*
{
PEPROCESS peproc;
NTSTATUS result;
if ((result = PsLookupProcessByProcessId((HANDLE)pid, &peproc)) == STATUS_SUCCESS)
{
auto base_address =
PsGetProcessSectionBaseAddress(peproc);
ObDereferenceObject(peproc);
return base_address;
}
return nullptr;
}
inline auto get_module_base(u32 pid, const wchar_t* module_name) -> void*
{
PEPROCESS peproc;
NTSTATUS result;
KAPC_STATE apc_state;
if ((result = PsLookupProcessByProcessId((HANDLE)pid, &peproc)) == STATUS_SUCCESS)
{
KeStackAttachProcess(peproc, &apc_state);
{
const auto ldr_data =
reinterpret_cast<PPEB_LDR_DATA>(
PsGetProcessPeb(peproc)->LoaderData);
auto current_entry =
ldr_data->InMemoryOrderModuleList.Flink;
while (current_entry != &ldr_data->InMemoryOrderModuleList)
{
const auto current_entry_data =
reinterpret_cast<PLDR_DATA_TABLE_ENTRY>(
reinterpret_cast<u64>(current_entry) - sizeof LIST_ENTRY);
const auto entry_module_name =
current_entry_data->BaseDllName.Buffer;
if (!_wcsicmp(entry_module_name, module_name))
{
ObDereferenceObject(peproc);
auto module_base = current_entry_data->DllBase;
KeUnstackDetachProcess(&apc_state);
return module_base;
}
current_entry = current_entry->Flink;
}
}
KeUnstackDetachProcess(&apc_state);
ObDereferenceObject(peproc);
}
return nullptr;
}
}
namespace pe
{
inline auto get_nt_header(void* module_base) -> PIMAGE_NT_HEADERS64
{
const auto dos_header =
reinterpret_cast<PIMAGE_DOS_HEADER>(module_base);
return reinterpret_cast<PIMAGE_NT_HEADERS64>(
reinterpret_cast<u64>(module_base) + dos_header->e_lfanew);
}
}
namespace signature
{
inline auto scan(void* base, u32 size, const char* pattern, const char* mask) -> void*
{
static const auto check_mask =
[&](const char* base, const char* pattern, const char* mask) -> bool
{
for (; *mask; ++base, ++pattern, ++mask)
if (*mask == 'x' && *base != *pattern)
return false;
return true;
};
size -= strlen(mask);
for (auto i = 0; i <= size; ++i)
{
void* addr = (void*)&(((char*)base)[i]);
if (check_mask((char*)addr, pattern, mask))
return addr;
}
return nullptr;
}
}
}

@ -0,0 +1,223 @@
#pragma once
#include "kutils.hpp"
#define WIN32K_SYSCALL_FILTER_MASK "xxxxxxxxxxxxxxxxxxxxxxx????xxx"
#define WIN32K_SYSCALL_FILTER_SIG "\x48\x89\x4C\x24\x20\x48\x89\x54\x24\x28\x4C\x89\x44\x24\x30\x4C\x89\x4C\x24\x38\x48\xC7\xC1\x00\x00\x00\x00\x48\xFF\x15"
static_assert(sizeof WIN32K_SYSCALL_FILTER_SIG == sizeof WIN32K_SYSCALL_FILTER_MASK, "signature and mask len invalid...");
typedef union _MISC_THREAD_VALUES
{
struct
{
ULONG ThreadFlagsSpare : 2; //0x78
ULONG AutoAlignment : 1; //0x78
ULONG DisableBoost : 1; //0x78
ULONG AlertedByThreadId : 1; //0x78
ULONG QuantumDonation : 1; //0x78
ULONG EnableStackSwap : 1; //0x78
ULONG GuiThread : 1; //0x78
ULONG DisableQuantum : 1; //0x78
ULONG ChargeOnlySchedulingGroup : 1; //0x78
ULONG DeferPreemption : 1; //0x78
ULONG QueueDeferPreemption : 1; //0x78
ULONG ForceDeferSchedule : 1; //0x78
ULONG SharedReadyQueueAffinity : 1; //0x78
ULONG FreezeCount : 1; //0x78
ULONG TerminationApcRequest : 1; //0x78
ULONG AutoBoostEntriesExhausted : 1; //0x78
ULONG KernelStackResident : 1; //0x78
ULONG TerminateRequestReason : 2; //0x78
ULONG ProcessStackCountDecremented : 1; //0x78
ULONG RestrictedGuiThread : 1; //0x78
ULONG VpBackingThread : 1; //0x78
ULONG ThreadFlagsSpare2 : 1; //0x78
ULONG EtwStackTraceApcInserted : 8; //0x78
};
volatile LONG ThreadFlags; //0x78
} MISC_THREAD_VALUES, * PMISC_THREAD_VALUES;
typedef struct _syscall_args_t
{
u64 rcx, rdx, r8, r9;
} syscall_args_t, *psyscall_args_t;
inline void* original_function = nullptr;
// handler is designed to get the arguments passed in registers...
extern "C" void asm_hook_handler_2004(unsigned syscall_number);
extern "C" void asm_hook_handler(unsigned syscall_number);
namespace nt
{
inline auto enable_filter(HANDLE tid) -> bool
{
PETHREAD thread;
if (PsLookupThreadByThreadId(tid, &thread) == STATUS_SUCCESS)
{
const auto thread_misc_values =
reinterpret_cast<PMISC_THREAD_VALUES>(
reinterpret_cast<unsigned char*>(thread) + 0x78);
// make the thread gui and restricted...
thread_misc_values->GuiThread = 1;
thread_misc_values->RestrictedGuiThread = 1;
return true;
}
return false;
}
inline auto enable_filter(PETHREAD thread) -> void
{
const auto thread_misc_values =
reinterpret_cast<PMISC_THREAD_VALUES>(
reinterpret_cast<unsigned char*>(thread) + 0x78);
// make the thread gui and restricted...
thread_misc_values->GuiThread = 1;
thread_misc_values->RestrictedGuiThread = 1;
}
namespace win32k
{
inline auto hook_filter(void* hook_func) -> void*
{
PEPROCESS peproc;
KAPC_STATE apc_state;
RTL_OSVERSIONINFOW version;
RtlGetVersion(&version);
const auto explorer_pid = kutils::process::get_pid(L"explorer.exe");
PsLookupProcessByProcessId((HANDLE)explorer_pid, &peproc);
// attach to an address space that contains win32k.sys
KeStackAttachProcess(peproc, &apc_state);
{
const auto win32k = kutils::driver::get_driver_base("win32k.sys");
if (version.dwBuildNumber >= 19041) // if 2004 and above...
{
/*
* .text:FFFFF97FFF0172E4 48 89 4C 24 20 mov [rsp+48h+var_28], rcx
* .text:FFFFF97FFF0172E9 48 89 54 24 28 mov [rsp+48h+var_20], rdx
* .text:FFFFF97FFF0172EE 4C 89 44 24 30 mov [rsp+48h+var_18], r8
* .text:FFFFF97FFF0172F3 4C 89 4C 24 38 mov [rsp+48h+var_10], r9
* .text:FFFFF97FFF0172F8 48 C7 C1 00 00 00 00 mov rcx, 0 ; _QWORD
* .text:FFFFF97FFF0172FF 48 FF 15 [B2 A4 03 00] call cs:__imp_IsWin32KSyscallFiltered <==== 30 bytes to this RVA...
*/
auto sig_result = reinterpret_cast<u64>(
kutils::signature::scan(win32k,
kutils::pe::get_nt_header(win32k)->OptionalHeader.SizeOfImage,
WIN32K_SYSCALL_FILTER_SIG, WIN32K_SYSCALL_FILTER_MASK));
const auto sig_rva = *reinterpret_cast<int*>(sig_result + 30); // + 30 from above...
sig_result = sig_result + sig_rva + 34; // 34 bytes to RIP...
if (sig_result)
{
/*
* .rdata:FFFFF97FFF0517B8 ; __int64 (__fastcall *IsWin32KSyscallFiltered)(_QWORD)
* .rdata:FFFFF97FFF0517B8 E4 05 01 FF 7F F9 FF FF __imp_IsWin32KSyscallFiltered dq offset IsWin32KSyscallFiltered <=== deference this....
*/
const auto win32k_filter_func =
reinterpret_cast<u64>(
*reinterpret_cast<void**>(sig_result));
/*
* .text:FFFFF97FFF0105E4 IsWin32KSyscallFiltered proc near
* .text:FFFFF97FFF0105E4 48 83 EC 28 sub rsp, 28h
* .text:FFFFF97FFF0105E8 48 8B 05 [A1 67 05 00] mov rax, cs:qword_FFFFF97FFF066D90 <======= + 7 bytes to this RVA....
* .text:FFFFF97FFF0105EF 48 85 C0 test rax, rax
* .text:FFFFF97FFF0105F2 74 06 jz short loc_FFFFF97FFF0105FA
* .text:FFFFF97FFF0105F4 FF 15 66 43 06 00 call cs:__guard_dispatch_icall_fptr
*/
const auto ptr_swap_rva = *reinterpret_cast<int*>(win32k_filter_func + 7); // + 7 from above^
const auto win32k_syscall_filter_ptr = reinterpret_cast<void**>(ptr_swap_rva + win32k_filter_func + 11); // + 7 because 11 bytes in is the next instruction after the mov rax, cs....
const auto result = *win32k_syscall_filter_ptr;
*win32k_syscall_filter_ptr = hook_func;
KeUnstackDetachProcess(&apc_state);
return result;
}
}
else // else 1909 and below (IAT hook)...
{
auto result = kutils::driver::iat_hook(
win32k, "IsWin32KSyscallFiltered", hook_func);
KeUnstackDetachProcess(&apc_state);
return result;
}
}
KeUnstackDetachProcess(&apc_state);
return nullptr;
}
inline auto unhook_filter(void* original_function) -> void
{
PEPROCESS peproc;
KAPC_STATE apc_state;
RTL_OSVERSIONINFOW version;
RtlGetVersion(&version);
const auto explorer_pid = kutils::process::get_pid(L"explorer.exe");
PsLookupProcessByProcessId((HANDLE)explorer_pid, &peproc);
// attach to an address space that contains win32k.sys
KeStackAttachProcess(peproc, &apc_state);
{
const auto win32k = kutils::driver::get_driver_base("win32k.sys");
if (version.dwBuildNumber >= 19041) // if 2004 and above...
{
/*
* .text:FFFFF97FFF0172E4 48 89 4C 24 20 mov [rsp+48h+var_28], rcx
* .text:FFFFF97FFF0172E9 48 89 54 24 28 mov [rsp+48h+var_20], rdx
* .text:FFFFF97FFF0172EE 4C 89 44 24 30 mov [rsp+48h+var_18], r8
* .text:FFFFF97FFF0172F3 4C 89 4C 24 38 mov [rsp+48h+var_10], r9
* .text:FFFFF97FFF0172F8 48 C7 C1 00 00 00 00 mov rcx, 0 ; _QWORD
* .text:FFFFF97FFF0172FF 48 FF 15 [B2 A4 03 00] call cs:__imp_IsWin32KSyscallFiltered <==== 30 bytes to this RVA...
*/
auto sig_result = reinterpret_cast<u64>(
kutils::signature::scan(win32k,
kutils::pe::get_nt_header(win32k)->OptionalHeader.SizeOfImage,
WIN32K_SYSCALL_FILTER_SIG, WIN32K_SYSCALL_FILTER_MASK));
const auto sig_rva = *reinterpret_cast<int*>(sig_result + 30); // + 30 from above...
sig_result = sig_result + sig_rva + 34; // 34 bytes to RIP...
if (sig_result)
{
/*
* .rdata:FFFFF97FFF0517B8 ; __int64 (__fastcall *IsWin32KSyscallFiltered)(_QWORD)
* .rdata:FFFFF97FFF0517B8 E4 05 01 FF 7F F9 FF FF __imp_IsWin32KSyscallFiltered dq offset IsWin32KSyscallFiltered <=== deference this....
*/
const auto win32k_filter_func =
reinterpret_cast<u64>(
*reinterpret_cast<void**>(sig_result));
/*
* .text:FFFFF97FFF0105E4 IsWin32KSyscallFiltered proc near
* .text:FFFFF97FFF0105E4 48 83 EC 28 sub rsp, 28h
* .text:FFFFF97FFF0105E8 48 8B 05 [A1 67 05 00] mov rax, cs:qword_FFFFF97FFF066D90 <======= + 7 bytes to this RVA....
* .text:FFFFF97FFF0105EF 48 85 C0 test rax, rax
* .text:FFFFF97FFF0105F2 74 06 jz short loc_FFFFF97FFF0105FA
* .text:FFFFF97FFF0105F4 FF 15 66 43 06 00 call cs:__guard_dispatch_icall_fptr
*/
const auto ptr_swap_rva = *reinterpret_cast<int*>(win32k_filter_func + 7); // + 7 from above^
const auto win32k_syscall_filter_ptr = reinterpret_cast<void**>(ptr_swap_rva + win32k_filter_func + 11); // + 7 because 11 bytes in is the next instruction after the mov rax, cs....
*win32k_syscall_filter_ptr = original_function;
}
}
else // else 1909 and below (IAT hook)...
{
// restore IAT...
kutils::driver::iat_hook(win32k,
"IsWin32KSyscallFiltered", original_function);
}
}
KeUnstackDetachProcess(&apc_state);
}
}
}

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<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>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{df92fe26-a275-403c-b242-35c82b881def}</ProjectGuid>
<RootNamespace>NtWin32u</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<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|Win32'">
<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)'=='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|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ntwin32u.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,23 @@
<?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;c++;cppm;ixx;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;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ntwin32u.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

@ -0,0 +1,10 @@
#include "ntwin32u.hpp"
int main()
{
while (true)
{
std::printf("syscall result -> 0x%p\n", nt::win32u::syscall());
std::getchar();
}
}

@ -0,0 +1,93 @@
#pragma once
#include <Windows.h>
#include <winternl.h>
#include <map>
#include <string>
#include <time.h>
#include <atomic>
#include <vector>
#include <iostream>
namespace nt
{
namespace win32u
{
using syscall_table_t = std::vector<std::pair<std::string, std::uintptr_t>>;
inline syscall_table_t syscall_table = ([&]()-> syscall_table_t
{
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY syscall_policy{};
syscall_policy.DisallowWin32kSystemCalls = true;
std::printf("disable win32ksyscall -> %d\n",
SetProcessMitigationPolicy(ProcessSystemCallDisablePolicy,
&syscall_policy, sizeof syscall_policy));
LoadLibraryA("user32.dll");
syscall_table_t result;
const auto win32u =
reinterpret_cast<PIMAGE_DOS_HEADER>(
LoadLibraryA("win32u.dll"));
const auto nt_header =
reinterpret_cast<PIMAGE_NT_HEADERS64>(
reinterpret_cast<std::uintptr_t>(win32u) + win32u->e_lfanew);
const auto export_rvas =
nt_header->OptionalHeader.DataDirectory[
IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
const auto exports =
reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
reinterpret_cast<std::uintptr_t>(win32u) + export_rvas);
const auto name_rva =
reinterpret_cast<std::uint32_t*>(
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfNames);
for (auto idx = 0u; idx < exports->NumberOfNames; ++idx)
{
const auto function_name =
reinterpret_cast<const char*>(
reinterpret_cast<std::uintptr_t>(win32u) + name_rva[idx]);
// add Nt functions...
if (!strncmp(function_name, "Nt", 2))
{
const auto func_rva =
reinterpret_cast<std::uint32_t*>(
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfFunctions);
const auto ordinal_rva =
reinterpret_cast<std::uint16_t*>(
reinterpret_cast<std::uintptr_t>(win32u) + exports->AddressOfNameOrdinals);
const auto function_addr =
reinterpret_cast<std::uintptr_t>(win32u) + func_rva[ordinal_rva[idx]];
result.push_back({ function_name, function_addr });
}
}
return result;
})();
inline auto syscall() -> std::uintptr_t
{
static const auto random = [&](int min, int max) -> int
{
if (static std::atomic<bool> first = false; !first.exchange(true))
srand(time(NULL));
return min + rand() % ((max + 1) - min);
};
const auto [function_name, function_addr] =
syscall_table[random(NULL, syscall_table.size())];
std::printf("%s -> 0x%p\n", function_name.c_str(), function_addr);
std::getchar();
return reinterpret_cast<std::uintptr_t(*)(std::uintptr_t)>(function_addr)(0xC0FFEE);
}
}
}
Loading…
Cancel
Save