parent
4e4912c9c3
commit
62bf24fb47
@ -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,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…
Reference in new issue