diff --git a/EtwHook/DriverMain.cpp b/EtwHook/DriverMain.cpp new file mode 100644 index 0000000..a382b4e --- /dev/null +++ b/EtwHook/DriverMain.cpp @@ -0,0 +1,101 @@ +#include "hook.hpp" + +typedef NTSTATUS(NTAPI* PNtCreateFile)( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer, + IN ULONG EaLength); +PNtCreateFile g_NtCreateFile = 0; + +NTSTATUS NTAPI MyNtCreateFile( + PHANDLE FileHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PIO_STATUS_BLOCK IoStatusBlock, + PLARGE_INTEGER AllocationSize, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PVOID EaBuffer, + ULONG EaLength) +{ + if (ObjectAttributes && + ObjectAttributes->ObjectName && + ObjectAttributes->ObjectName->Buffer) + { + wchar_t* name = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, ObjectAttributes->ObjectName->Length + sizeof(wchar_t),'xiq2'); + if (name) + { + RtlZeroMemory(name, ObjectAttributes->ObjectName->Length + sizeof(wchar_t)); + RtlCopyMemory(name, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length); + KdPrintEx((0, 0, "[%s] name:%wZ \n", __FUNCTION__, ObjectAttributes->ObjectName)); + + if (wcsstr(name, L"tips.txt")) + { + ExFreePool(name); + return STATUS_ACCESS_DENIED; + } + + ExFreePool(name); + } + } + + return NtCreateFile( + FileHandle, + DesiredAccess, + ObjectAttributes, + IoStatusBlock, + AllocationSize, + FileAttributes, + ShareAccess, + CreateDisposition, + CreateOptions, + EaBuffer, + EaLength); +} + +void __fastcall call_back(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction) +{ + UNREFERENCED_PARAMETER(SystemCallIndex); + + if (*SystemCallFunction == NtCreateFile) + { + *SystemCallFunction = MyNtCreateFile; + } +} + +VOID DriverUnload(PDRIVER_OBJECT driver) +{ + UNREFERENCED_PARAMETER(driver); + + KdPrintEx((0, 0, "[%s] \n", __FUNCTION__)); + + IfhRelease2(); +} + +EXTERN_C +NTSTATUS +DriverEntry( + PDRIVER_OBJECT driver, + PUNICODE_STRING registe) +{ + + UNREFERENCED_PARAMETER(registe); + + KdPrintEx((0, 0, "[%s] \n", __FUNCTION__)); + + driver->DriverUnload = DriverUnload; + + // ʼҹ + IfhInitialize2(call_back); + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/EtwHook/EtwHook.vcxproj b/EtwHook/EtwHook.vcxproj new file mode 100644 index 0000000..d4e5f68 --- /dev/null +++ b/EtwHook/EtwHook.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {1508383A-6C98-4451-8B0E-894DE0F9511B} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + Win32 + EtwHook + 10.0.19041.0 + EtwHookLib + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + false + + + Windows10 + false + WindowsKernelModeDriver10.0 + StaticLibrary + WDM + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + false + Disabled + + + + + false + + + + + + + + + + true + + + + + + + + + + + + + + false + + + + + + \ No newline at end of file diff --git a/EtwHook/EtwHook.vcxproj.filters b/EtwHook/EtwHook.vcxproj.filters new file mode 100644 index 0000000..10a11ac --- /dev/null +++ b/EtwHook/EtwHook.vcxproj.filters @@ -0,0 +1,59 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + {edae21d4-7ff9-4804-9dec-4d72e3413c77} + + + + + Hde + + + Source Files + + + Source Files + + + + + Hde + + + Hde + + + Hde + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/EtwHook/hde/hde64.cpp b/EtwHook/hde/hde64.cpp new file mode 100644 index 0000000..250a3f9 --- /dev/null +++ b/EtwHook/hde/hde64.cpp @@ -0,0 +1,350 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#include "../headers.hpp" + +#if defined(_M_X64) || defined(__x86_64__) +#pragma warning(push, 0) +#pragma warning(disable: 4701 4706 26451) + +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm(const void* code, hde64s* hs) +{ + uint8_t x, c, * p = (uint8_t*)code, cflags, opcode, pref = 0; + uint8_t* ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. + memset(hs, 0, sizeof(hde64s)); + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } +pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } + else if (c >= 0xa0 && c <= 0xa3) { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t*)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde64_table + DELTA_FPU_MODRM + t * 8; + t = ht[m_reg] << m_rm; + } + else { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } + else { + uint8_t* table_end, op = opcode; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } + else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } + else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t* table_end; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } + else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } + else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } + else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } + else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t*)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t*)p; + } + p += disp_size; + } + else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t*)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t*)p; + p += 8; + } + else if (!(pref & PRE_66)) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t*)p; + p += 4; + } + else + goto imm16_ok; + } + + if (cflags & C_IMM16) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t*)p; + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t*)p; + p += 4; + } + else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + +disasm_done: + + if ((hs->len = (uint8_t)(p - (uint8_t*)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#pragma warning(pop) +#endif // defined(_M_X64) || defined(__x86_64__) \ No newline at end of file diff --git a/EtwHook/hde/hde64.h b/EtwHook/hde/hde64.h new file mode 100644 index 0000000..ecbf4df --- /dev/null +++ b/EtwHook/hde/hde64.h @@ -0,0 +1,112 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde64_disasm(const void *code, hde64s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/EtwHook/hde/pstdint.h b/EtwHook/hde/pstdint.h new file mode 100644 index 0000000..82d7c7d --- /dev/null +++ b/EtwHook/hde/pstdint.h @@ -0,0 +1,37 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +// Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/EtwHook/hde/table64.h b/EtwHook/hde/table64.h new file mode 100644 index 0000000..01d4541 --- /dev/null +++ b/EtwHook/hde/table64.h @@ -0,0 +1,74 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; diff --git a/EtwHook/headers.hpp b/EtwHook/headers.hpp new file mode 100644 index 0000000..65828fc --- /dev/null +++ b/EtwHook/headers.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/EtwHook/hook.asm b/EtwHook/hook.asm new file mode 100644 index 0000000..eff9672 --- /dev/null +++ b/EtwHook/hook.asm @@ -0,0 +1,13 @@ +extern halCounterQueryRoutine:DQ +extern keQueryPerformanceCounterHook:DQ +.code +checkLogger PROC + push rcx + mov rcx,rsp + lea rax,keQueryPerformanceCounterHook + call rax + pop rax + mov rax,halCounterQueryRoutine + jmp rax +checkLogger ENDP +end diff --git a/EtwHook/hook.cpp b/EtwHook/hook.cpp new file mode 100644 index 0000000..cc98e76 --- /dev/null +++ b/EtwHook/hook.cpp @@ -0,0 +1,647 @@ +#include "utils.hpp" +#include "hook.h" +#pragma warning(disable : 4201) + +// ================================== +// 结构定义 +// ================================== + +#ifdef __cplusplus +extern "C" +#endif +/* 微软官方文档定义 +* https://docs.microsoft.com/en-us/windows/win32/etw/wnode-header*/ +typedef struct _WNODE_HEADER +{ + ULONG BufferSize; + ULONG ProviderId; + union { + ULONG64 HistoricalContext; + struct { + ULONG Version; + ULONG Linkage; + }; + }; + union { + HANDLE KernelHandle; + LARGE_INTEGER TimeStamp; + }; + GUID Guid; + ULONG ClientContext; + ULONG Flags; +} WNODE_HEADER, * PWNODE_HEADER; + +/* 微软文档定义 +* https://docs.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-event_trace_properties*/ +typedef struct _EVENT_TRACE_PROPERTIES +{ + WNODE_HEADER Wnode; + ULONG BufferSize; + ULONG MinimumBuffers; + ULONG MaximumBuffers; + ULONG MaximumFileSize; + ULONG LogFileMode; + ULONG FlushTimer; + ULONG EnableFlags; + union { + LONG AgeLimit; + LONG FlushThreshold; + } DUMMYUNIONNAME; + ULONG NumberOfBuffers; + ULONG FreeBuffers; + ULONG EventsLost; + ULONG BuffersWritten; + ULONG LogBuffersLost; + ULONG RealTimeBuffersLost; + HANDLE LoggerThreadId; + ULONG LogFileNameOffset; + ULONG LoggerNameOffset; +} EVENT_TRACE_PROPERTIES, * PEVENT_TRACE_PROPERTIES; + +typedef struct _CKCL_TRACE_PROPERIES : EVENT_TRACE_PROPERTIES +{ + ULONG64 Unknown[3]; + UNICODE_STRING ProviderName; +} CKCL_TRACE_PROPERTIES, * PCKCL_TRACE_PROPERTIES; + +typedef enum _trace_type +{ + start_trace = 1, + stop_trace = 2, + query_trace = 3, + syscall_trace = 4, + flush_trace = 5 +}trace_type; + + +// ================================== +// 全局变量 +// ================================== + + + +//#endif // MYFUNCTION_H + +//extern void checkLogger(void); // 汇编导出函数声明 + +GUID g_ckcl_session_guid = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; +INFINITYHOOKCALLBACK g_fptr = nullptr; // syscall 回调函数 +unsigned long g_build_number = 0; // 系统版本号 +void* g_EtwpDebuggerData = nullptr; +void* g_CkclWmiLoggerContext = nullptr; +void* g_syscall_table = nullptr; // ssdt 基地址 +void** g_EtwpDebuggerDataSilo = nullptr; +void** g_GetCpuClock = nullptr; +unsigned long long h_original_GetCpuClock = 0; // 原始的 GetCpuClock 值 +unsigned long long g_HvlpReferenceTscPage = 0; +unsigned long long g_HvlGetQpcBias = 0; // 18363 以上版本,要 hook 的位置 +typedef __int64 (*fptr_HvlGetQpcBias)(); +fptr_HvlGetQpcBias g_original_HvlGetQpcBias = nullptr; // 18363 以上版本,要 hook 的位置的原始值 + +// ================================== +// 函数实现 +// ================================== + +// 注册 etw +NTSTATUS modify_trace_settings(trace_type type) +{ + const unsigned long tag = 'VMON'; + + // 申请内存 + CKCL_TRACE_PROPERTIES* property = (CKCL_TRACE_PROPERTIES*)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, tag); + if (!property) + { + KdPrintEx((0, 0, "[%s] allocate ckcl trace propertice struct fail \n", __FUNCTION__)); + return STATUS_MEMORY_NOT_ALLOCATED; + } + wchar_t* provider_name = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, 256 * sizeof(wchar_t), tag); + if (!provider_name) + { + KdPrintEx((0, 0, "[%s] allocate provider name fail \n", __FUNCTION__)); + ExFreePoolWithTag(property, tag); + return STATUS_MEMORY_NOT_ALLOCATED; + } + + // 初始化内存 + RtlZeroMemory(property, PAGE_SIZE); + RtlZeroMemory(provider_name, 256 * sizeof(wchar_t)); + + // 名称赋值 + RtlCopyMemory(provider_name, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger")); + RtlInitUnicodeString(&property->ProviderName, (const wchar_t*)provider_name); + + // 结构体填充 + property->Wnode.BufferSize = PAGE_SIZE; + property->Wnode.Flags = 0x00020000; + property->Wnode.Guid = g_ckcl_session_guid; + property->Wnode.ClientContext = 3; + property->BufferSize = sizeof(unsigned long); + property->MinimumBuffers = 2; + property->MaximumBuffers = 2; + property->LogFileMode = 0x00000400; + + // 注册 etw + unsigned long length = 0; + if (type == trace_type::syscall_trace) + { + property->EnableFlags = 0x00000080; + } + NTSTATUS status = NtTraceControl(type, property, PAGE_SIZE, property, PAGE_SIZE, &length); + + // 释放内存空间 + ExFreePoolWithTag(provider_name, tag); + ExFreePoolWithTag(property, tag); + + return status; +} + +// 原作者堆栈回溯函数(这里只用它处理 1909 以前的版本) +unsigned long long self_get_cpu_clock() +{ + // 放过内核模式的调用 + if (ExGetPreviousMode() == KernelMode) + { + // 调用原函数 + return __rdtsc(); + } + + // 拿到当前线程 + PKTHREAD current_thread = (PKTHREAD)__readgsqword(0x188); + + // 不同版本不同偏移 + unsigned int call_index = 0; + if (g_build_number <= 7601) + { + call_index = *(unsigned int*)((unsigned long long)current_thread + 0x1f8); + } + else + { + call_index = *(unsigned int*)((unsigned long long)current_thread + 0x80); + } + + // 拿到当前栈底和栈顶 + void** stack_max = (void**)__readgsqword(0x1a8); + void** stack_frame = (void**)_AddressOfReturnAddress(); + + // 开始查找当前栈中的ssdt调用 + for (void** stack_current = stack_max; stack_current > stack_frame; --stack_current) + { + /* 栈中ssdt调用特征,分别是 + * mov [rsp+48h+var_20], 501802h + * mov r9d, 0F33h + */ + + // 第一个特征值检查 + unsigned long* l_value = (unsigned long*)stack_current; + if (*l_value != 0x501802) + { + continue; + } + + // 这里为什么减?配合寻找第二个特征值啊 + --stack_current; + + // 第二个特征值检查 + unsigned short* s_value = (unsigned short*)stack_current; + if (*s_value != 0xF33) + { + continue; + } + + // 特征值匹配成功,再倒过来查找 + for (; stack_current < stack_max; ++stack_current) + { + // 不在 ssdt 表内的 pass + unsigned long long* ull_value = (unsigned long long*)stack_current; + if (!(PAGE_ALIGN(*ull_value) >= g_syscall_table && PAGE_ALIGN(*ull_value) < (void*)((unsigned long long)g_syscall_table + (PAGE_SIZE * 2)))) + { + continue; + } + + // 拿到系统调用函数的地址 + void** system_call_function = &stack_current[9]; + + // 替换为我们的函数 + if (g_fptr) + { + g_fptr(call_index, system_call_function); + } + + break; + } + + break; + } + + // 调用原函数 + return __rdtsc(); +} + +#if 0 +// 原作者 hook 函数(已经用不到了) +EXTERN_C __int64 self_hvl_get_qpc_bias() +{ + // 我们的过滤函数 + self_get_cpu_clock(); + + // 这里是真正HvlGetQpcBias做的事情 + return *((unsigned long long*)(*((unsigned long long*)g_HvlpReferenceTscPage)) + 3); +} +#endif + + + +BOOLEAN start() +{ + + if (!g_fptr) + { + return false; + } + + // 注册 etw + if (!NT_SUCCESS(modify_trace_settings(syscall_trace))) + { + if (!NT_SUCCESS(modify_trace_settings(start_trace))) + { + KdPrintEx((0, 0, "[%s] start ckcl fail \n", __FUNCTION__)); + return false; + } + if (!NT_SUCCESS(modify_trace_settings(syscall_trace))) + { + KdPrintEx((0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__)); + return false; + } + } + + /* 这里我们区分一下系统版本 + * 从Win7到Win10 1909,g_GetCpuClock是一个函数,往后的版本是一个数值了 + * 大于3 抛异常 + * 等于3 用rdtsc + * 等于2 用off_140C00A30 + * 等于1 用KeQueryPerformanceCounter + * 等于0 用RtlGetSystemTimePrecise + * 参考网址: + * https://www.freebuf.com/articles/system/278857.html + * https://www.anquanke.com/post/id/206288 + */ + if (g_build_number <= 18363) + { + // 直接修改函数指针 + KdPrintEx((0, 0, "[%s] verion <= 18363 ,direct modify GetCpuClock:0x%p \n",__FUNCTION__, g_GetCpuClock)); + + *g_GetCpuClock = self_get_cpu_clock; + + KdPrintEx((0, 0, "[%s] after modify 0x%p\n", __FUNCTION__, *g_GetCpuClock)); + } + else + { + // 保存 GetCpuClock 原始值 + h_original_GetCpuClock = (unsigned long long)(*g_GetCpuClock); + KdPrintEx((0, 0, "[%s] verion > 18363 , GetCpuClock index:%lld \n", __FUNCTION__, h_original_GetCpuClock)); + + // 原作者将 GetCpuClock 设置为 2,但这样做在物理机上无效 + *g_GetCpuClock = (void*)1; + KdPrintEx((0, 0, "[%s] modify GetCpuClock:%p \n", __FUNCTION__, *g_GetCpuClock)); + +#if 0 + // 等于 2 时的挂钩逻辑 + g_original_HvlGetQpcBias = (fptr_HvlGetQpcBias)(*((unsigned long long*)g_HvlGetQpcBias)); + *((unsigned long long*)g_HvlGetQpcBias) = (unsigned long long)self_hvl_get_qpc_bias; + KdPrintEx((0, 0, "[%s] HvlGetQpcBias modify success:%p \n", __FUNCTION__, self_hvl_get_qpc_bias)); +#else + + + // 等于 1 时的挂钩逻辑 + *((unsigned long long*)g_HvlGetQpcBias) = (unsigned long long)checkLogger; + + KdPrintEx((0, 0, "[%s] HvlGetQpcBias modify success:%p \n", __FUNCTION__, checkLogger)); +#endif + } + + return true; +} + +bool stop() +{ + // 反注册 etw + bool result = NT_SUCCESS(modify_trace_settings(stop_trace)) && NT_SUCCESS(modify_trace_settings(start_trace)); + + if (g_build_number > 18363) + { +#if 0 + // 等于 2 时的恢复挂钩 + * ((unsigned long long*)g_HvlGetQpcBias) = (unsigned long long)g_original_HvlGetQpcBias; +#else + // 等于 1 时的恢复挂钩 + * ((unsigned long long*)g_HvlGetQpcBias) = (unsigned long long)halCounterQueryRoutine; +#endif + // 恢复 GetCpuClock + *g_GetCpuClock = (void*)h_original_GetCpuClock; + } + + return result; +} + +BOOLEAN IfhInitialize2(INFINITYHOOKCALLBACK fptr) +{ + //__debugbreak(); + + if (!fptr) + { + return false; + } + + // 保存 callback 函数地址 + g_fptr = fptr; + KdPrintEx((0, 0, "[%s] callback:0x%p \n", __FUNCTION__, g_fptr)); + + // 获取系统版本号 + g_build_number = k_utils::get_system_build_number(); + if (!g_build_number) + { + return false; + } + KdPrintEx((0, 0, "[%s] system version number:%ld \n", __FUNCTION__, g_build_number)); + + // 获取 ntoskrnl 基址 + unsigned long long ntoskrnl = k_utils::get_module_address("ntoskrnl.exe", nullptr); + if (!ntoskrnl) + { + return false; + } + KdPrintEx((0, 0, "[%s] ntoskrnl base address:0x%llX \n", __FUNCTION__, ntoskrnl)); + + // 定位 EtwpDebuggerData + unsigned long long EtwpDebuggerData = k_utils::find_pattern_image(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".text"); + if (!EtwpDebuggerData) + { + EtwpDebuggerData = k_utils::find_pattern_image(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".data"); + } + if (!EtwpDebuggerData) + { + EtwpDebuggerData = k_utils::find_pattern_image(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".rdata"); + } + if (!EtwpDebuggerData) + { + return false; + } + KdPrintEx((0, 0, "[%s] EtwpDebuggerData:0x%llX \n", __FUNCTION__, EtwpDebuggerData)); + g_EtwpDebuggerData = (void*)EtwpDebuggerData; + + // 定位 EtwpDebuggerDataSilo + g_EtwpDebuggerDataSilo = *(void***)((unsigned long long)g_EtwpDebuggerData + 0x10); + if (!g_EtwpDebuggerDataSilo) + { + return false; + } + KdPrintEx((0, 0, "[%s] EtwpDebuggerDataSilo:0x%p \n", __FUNCTION__, g_EtwpDebuggerDataSilo)); + + // 定位 CkclWmiLoggerContext + g_CkclWmiLoggerContext = g_EtwpDebuggerDataSilo[0x2]; + if (!g_CkclWmiLoggerContext) + { + return false; + } + KdPrintEx((0, 0, "[%s] CkclWmiLoggerContext:0x%p \n", __FUNCTION__, g_CkclWmiLoggerContext)); + + // 定位 GetCpuClock(Win7、Win11 都是偏移 0x18, 其它的是 0x28) + if (g_build_number <= 7601 || g_build_number == 22000) + { + g_GetCpuClock = (void**)((unsigned long long)g_CkclWmiLoggerContext + 0x18); + } + else + { + g_GetCpuClock = (void**)((unsigned long long)g_CkclWmiLoggerContext + 0x28); + } + if (!MmIsAddressValid(g_GetCpuClock)) + { + return false; + } + KdPrintEx((0, 0, "[%s] original GetCpuClock:0x%p \n", __FUNCTION__, *g_GetCpuClock)); + + // 定位 ssdt + g_syscall_table = PAGE_ALIGN(k_utils::get_syscall_entry(ntoskrnl)); + if (!g_syscall_table) + { + return false; + } + KdPrintEx((0, 0, "[%s] ssdt:0x%p \n", __FUNCTION__, g_syscall_table)); + + // 大于 18363 版本要做额外的工作 + if (g_build_number > 18363) + { +#if 0 + // 等于 2 时 + + /* 定位 + * nt!HvlGetReferenceTimeUsingTscPage+0x3e: + 488b059b1b9700 mov rax,qword ptr [nt!HvlpReferenceTscPage] + 488b4008 mov rax,qword ptr [rax+8] + 488b0d901b9700 mov rcx,qword ptr [nt!HvlpReferenceTscPage] + 48f7e2 mul rax,rdx + */ + unsigned long long address2 = k_utils::find_pattern_image(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\x40\x00\x48\x8b\x0d\x00\x00\x00\x00\x48\xf7\xe2", + "xxx????xxx?xxx????xxx"); + if (!address2) + { + return false; + } + + // 计算 HvlpReferenceTscPage 地址 + g_HvlpReferenceTscPage = reinterpret_cast(reinterpret_cast(address2) + 7 + *reinterpret_cast(reinterpret_cast(address2) + 3)); + if (!g_HvlpReferenceTscPage) + { + return false; + } + KdPrintEx((0, 0, "[%s] hvlp reference tsc page is 0x%llX \n", __FUNCTION__, g_HvlpReferenceTscPage)); + + /* 定位 HvlGetQpcBias(HalpEnlightenment+0x178) + * 参考:https://www.freebuf.com/articles/system/278857.html + * nt!HalpTimerQueryHostPerformanceCounter+0x22: + 488b05ef8f7900 mov rax,qword ptr [nt!HalpEnlightenment+0x178] + 4885c0 test rax,rax + 7428 je nt!HalpTimerQueryHostPerformanceCounter+0x56 + 48833d928e790000 cmp qword ptr [nt!HalpEnlightenment+0x28],0 + 741e je nt!HalpTimerQueryHostPerformanceCounter+0x56 + e803d5f4ff call nt!guard_dispatch_icall <<< 调用 rax 中的函数,HalpEnlightenment+0x178 + */ + address2 = k_utils::find_pattern_image(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x48\x83\x3d\x00\x00\x00\x00\x00\x74", + "xxx????xxxx?xxx?????x"); + if (!address2) + { + address2 = k_utils::find_pattern_image(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x48\x03\xd8\x48\x89\x1f", + "xxx????x????xxxxxx"); + } + if (!address2) + { + return false; + } + + // 保存 hook 地址 + g_HvlGetQpcBias = reinterpret_cast(reinterpret_cast(address) + 7 + *reinterpret_cast(reinterpret_cast(address) + 3)); + +#else + // 等于 1 时 + + /* 定位特征 + nt!KeQueryPerformanceCounter: + fffff801`68485190 48895c2420 mov qword ptr [rsp+20h],rbx + fffff801`68485195 56 push rsi + fffff801`68485196 4883ec20 sub rsp,20h + fffff801`6848519a 48897c2430 mov qword ptr [rsp+30h],rdi + fffff801`6848519f 488bf1 mov rsi,rcx + fffff801`684851a2 488b3d276c9c00 mov rdi,qword ptr [nt!HalpPerformanceCounter (fffff801`68e4bdd0)] <<< 获取这条指令的地址 + fffff801`684851a9 4c89742440 mov qword ptr [rsp+40h],r14 + fffff801`684851ae 83bfe400000005 cmp dword ptr [rdi+0E4h],5 + fffff801`684851b5 0f8581000000 jne nt!KeQueryPerformanceCounter+0xac (fffff801`6848523c) + fffff801`684851bb 48833d1d6d9c0000 cmp qword ptr [nt!HalpTimerReferencePage (fffff801`68e4bee0)],0 + fffff801`684851c3 48c744243880969800 mov qword ptr [rsp+38h],989680h + fffff801`684851cc 0f842e181900 je nt!KeQueryPerformanceCounter+0x191870 (fffff801`68616a00) + fffff801`684851d2 f787e000000000000100 test dword ptr [rdi+0E0h],10000h + fffff801`684851dc 0f8536191900 jne nt!KeQueryPerformanceCounter+0x191988 (fffff801`68616b18) + fffff801`684851e2 488b4f48 mov rcx,qword ptr [rdi+48h] + fffff801`684851e6 488b4770 mov rax,qword ptr [rdi+70h] + fffff801`684851ea e8d1ca1700 call nt!guard_dispatch_icall (fffff801`68601cc0) <<< 这个 call 调用的是 rax 指向的函数 + fffff801`684851ef 488bc8 mov rcx,rax + fffff801`684851f2 49b8b803000080f7ffff mov r8,0FFFFF780000003B8h + fffff801`684851fc 488b05dd6c9c00 mov rax,qword ptr [nt!HalpTimerReferencePage (fffff801`68e4bee0)] + fffff801`68485203 488b4008 mov rax,qword ptr [rax+8] + fffff801`68485207 4d8b00 mov r8,qword ptr [r8] + fffff801`6848520a 48f7e1 mul rax,rcx + fffff801`6848520d 498d0410 lea rax,[r8+rdx] + fffff801`68485211 488b0db06b9c00 mov rcx,qword ptr [nt!HalpOriginalPerformanceCounter (fffff801`68e4bdc8)] + fffff801`68485218 4c8b742440 mov r14,qword ptr [rsp+40h] + fffff801`6848521d 483bf9 cmp rdi,rcx + fffff801`68485220 488b7c2430 mov rdi,qword ptr [rsp+30h] + fffff801`68485225 0f85db000000 jne nt!KeQueryPerformanceCounter+0x176 (fffff801`68485306) + fffff801`6848522b 4885f6 test rsi,rsi + fffff801`6848522e 7545 jne nt!KeQueryPerformanceCounter+0xe5 (fffff801`68485275) + fffff801`68485230 488b5c2448 mov rbx,qword ptr [rsp+48h] + fffff801`68485235 4883c420 add rsp,20h + fffff801`68485239 5e pop rsi + fffff801`6848523a c3 ret + fffff801`6848523b cc int 3 + */ + + unsigned long long address1 = k_utils::find_pattern_image(ntoskrnl, + "\x48\x8b\x3d\x00\x00\x00\x00\x4c\x89\x74\x24\x40\x83\xbf\xe4\x00\x00\x00\x05", + "xxx????xxxxxxxxxxxx"); + if (!address1) + { + address1 = k_utils::find_pattern_image(ntoskrnl, + "\x48\x8b\x3d\x00\x00\x00\x00\x4c\x8b\xf1\xbd\x80\x96\x98\x00\x83\xbf\xe4\x00\x00\x00\x05", + "xxx????xxxxxxxxxxxxxxx"); + } + if (!address1) + { + return false; + } + + // [HalpPerformanceCounter]+0x70 这个地址里存放了要替换的函数指针 + g_HvlGetQpcBias = reinterpret_cast(reinterpret_cast(address1) + 7 + *reinterpret_cast(reinterpret_cast(address1) + 3)); + if (!g_HvlGetQpcBias) + { + return false; + } + + // 保存 hook 地址 + g_HvlGetQpcBias = *(ULONG64*)g_HvlGetQpcBias + 0x70; + KdPrintEx((0, 0, "[%s] HvlGetQpcBias:0x%llX \n", __FUNCTION__, g_HvlGetQpcBias)); + + // 保存 hook 之前的函数 + halCounterQueryRoutine = *(ULONG64*)g_HvlGetQpcBias; +#endif + + } + + start(); + + return true; +} + +BOOLEAN IfhRelease2() +{ + return stop(); +} + +VOID keQueryPerformanceCounterHook(ULONG_PTR* pStack) +{ + // pStack 参数用不到 + UNREFERENCED_PARAMETER(pStack); + + // 内核层的调用不处理 + if (ExGetPreviousMode() == KernelMode) + { + return; + } + + // 拿到当前线程 KTHREAD + PKTHREAD current_thread = KeGetCurrentThread(); + + // 不同版本不同偏移 KTHREAD->SystemCallNumber + UINT call_index = 0; + if (g_build_number <= 7601) + { + call_index = *(unsigned int*)((unsigned long long)current_thread + 0x1f8); + } + else + { + call_index = *(unsigned int*)((unsigned long long)current_thread + 0x80); + } + + // 拿到当前栈顶(KPCR->Prcb.RspBase,其中 gs:[0] = KPCR) + void** stack = (void**)__readgsqword(0x1a8); + + // 搜索全部堆栈会导致卡死,这里搜前 0x100 范围 + for (void** stack_current = stack; stack_current > stack - 0x100; --stack_current) + { + /* 栈中ssdt调用特征,分别是 + * mov [rsp+48h+var_20], 501802h + * mov r9d, 0F33h + */ + // 第一个特征值检查 + unsigned long* l_value = (unsigned long*)stack_current; + if (*l_value != 0x501802) + { + continue; + } + + // 第二个特征值检查 + --stack_current; + unsigned short* s_value = (unsigned short*)stack_current; + if (*s_value != 0xF33) + { + continue; + } + + // 特征值匹配成功,再倒过来查找 + for (; stack_current < stack; ++stack_current) + { + // 检查是否在 ssdt 表内 + ULONG_PTR* ull_value = (ULONG_PTR*)stack_current; + if (!(PAGE_ALIGN(*ull_value) >= g_syscall_table && PAGE_ALIGN(*ull_value) < (void*)((unsigned long long)g_syscall_table + (PAGE_SIZE * 2)))) + { + continue; + } + + // 获取系统调用函数地址 + PVOID* system_call_function = &stack_current[9]; + + // 调用回调函数 + if (g_fptr) + { + g_fptr(call_index, system_call_function); + } + + break; + } + + break; + } + + return; +} diff --git a/EtwHook/hook.h b/EtwHook/hook.h new file mode 100644 index 0000000..1a09534 --- /dev/null +++ b/EtwHook/hook.h @@ -0,0 +1,28 @@ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void(__fastcall* INFINITYHOOKCALLBACK)(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction); + +BOOLEAN start(); + +BOOLEAN IfhInitialize2(INFINITYHOOKCALLBACK fptr); + +BOOLEAN IfhRelease2(); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void checkLogger(); + ULONG_PTR halCounterQueryRoutine; // 1 ʱhook ֮ǰĺ + void keQueryPerformanceCounterHook(ULONG_PTR* pStack); // 1 ʱhook ݵջ + +#ifdef __cplusplus + } +#endif diff --git a/EtwHook/imports.hpp b/EtwHook/imports.hpp new file mode 100644 index 0000000..56facd8 --- /dev/null +++ b/EtwHook/imports.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "headers.hpp" + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct _SYSTEM_MODULE + { + ULONG_PTR Reserved[2]; + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; + } SYSTEM_MODULE, * PSYSTEM_MODULE; + + typedef struct _SYSTEM_MODULE_INFORMATION + { + ULONG_PTR ulModuleCount; + SYSTEM_MODULE Modules[1]; + } SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION; + + NTSTATUS ZwQuerySystemInformation( + DWORD32 systemInformationClass, + PVOID systemInformation, + ULONG systemInformationLength, + PULONG returnLength); + + NTSTATUS + NTAPI + NtTraceControl( + _In_ ULONG FunctionCode, + _In_reads_bytes_opt_(InBufferLen) PVOID InBuffer, + _In_ ULONG InBufferLen, + _Out_writes_bytes_opt_(OutBufferLen) PVOID OutBuffer, + _In_ ULONG OutBufferLen, + _Out_ PULONG ReturnLength); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/EtwHook/utils.hpp b/EtwHook/utils.hpp new file mode 100644 index 0000000..2f8cced --- /dev/null +++ b/EtwHook/utils.hpp @@ -0,0 +1,169 @@ +#pragma once +#include "imports.hpp" +#include "hde/hde64.h" + +namespace k_utils +{ + // ȡϵͳ汾 + unsigned long get_system_build_number() + { + unsigned long number = 0; + RTL_OSVERSIONINFOEXW info{ 0 }; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&info))) number = info.dwBuildNumber; + return number; + } + + // ȡָģַ + unsigned long long get_module_address(const char* name, unsigned long* size) + { + unsigned long long result = 0; + + unsigned long length = 0; + ZwQuerySystemInformation(11, &length, 0, &length); + if (!length) return result; + + const unsigned long tag = 'VMON'; + PSYSTEM_MODULE_INFORMATION system_modules = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, length, tag); + if (!system_modules) return result; + + NTSTATUS status = ZwQuerySystemInformation(11, system_modules, length, 0); + if (NT_SUCCESS(status)) + { + for (unsigned long long i = 0; i < system_modules->ulModuleCount; i++) + { + PSYSTEM_MODULE mod = &system_modules->Modules[i]; + if (strstr(mod->ImageName, name)) + { + result = (unsigned long long)mod->Base; + if (size) *size = (unsigned long)mod->Size; + break; + } + } + } + + ExFreePoolWithTag(system_modules, tag); + return result; + } + + // ģʽƥ + bool pattern_check(const char* data, const char* pattern, const char* mask) + { + size_t len = strlen(mask); + + for (size_t i = 0; i < len; i++) + { + if (data[i] == pattern[i] || mask[i] == '?') + continue; + else + return false; + } + + return true; + } + + // ģʽ + unsigned long long find_pattern(unsigned long long addr, unsigned long size, const char* pattern, const char* mask) + { + size -= (unsigned long)strlen(mask); + + for (unsigned long i = 0; i < size; i++) + { + if (pattern_check((const char*)addr + i, pattern, mask)) + return addr + i; + } + + return 0; + } + + // ӳģʽ + unsigned long long find_pattern_image(unsigned long long addr, const char* pattern, const char* mask, const char* name = ".text") + { + PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)addr; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return 0; + + PIMAGE_NT_HEADERS64 nt = (PIMAGE_NT_HEADERS64)(addr + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) return 0; + + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(nt); + for (unsigned short i = 0; i < nt->FileHeader.NumberOfSections; i++) + { + PIMAGE_SECTION_HEADER p = §ion[i]; + + if (strstr((const char*)p->Name, name)) + { + unsigned long long result = find_pattern(addr + p->VirtualAddress, p->Misc.VirtualSize, pattern, mask); + if (result) return result; + } + } + + return 0; + } + + // ȡӳַ + unsigned long long get_image_address(unsigned long long addr, const char* name, unsigned long* size) + { + PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)addr; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return 0; + + PIMAGE_NT_HEADERS64 nt = (PIMAGE_NT_HEADERS64)(addr + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) return 0; + + PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(nt); + for (unsigned short i = 0; i < nt->FileHeader.NumberOfSections; i++) + { + PIMAGE_SECTION_HEADER p = §ion[i]; + + if (strstr((const char*)p->Name, name)) + { + if (size) *size = p->SizeOfRawData; + return (unsigned long long)p + p->VirtualAddress; + } + } + + return 0; + } + + // ȡSSDTַ + void* get_syscall_entry(unsigned long long ntoskrnl) + { + if (!ntoskrnl) return nullptr; + + /* + 2018ںҳ벹 https://bbs.pediy.com/thread-223805.htm + ûвĻKiSystemCall64 + */ +#define IA32_LSTAR_MSR 0xC0000082 + void* syscall_entry = (void*)__readmsr(IA32_LSTAR_MSR); + + // ûв,ֱӷKiSystemCall64 + unsigned long section_size = 0; + unsigned long long KVASCODE = get_image_address(ntoskrnl, "KVASCODE", §ion_size); + if (!KVASCODE) return syscall_entry; + + // KiSystemCall64,Ҳֱӷ + if (!(syscall_entry >= (void*)KVASCODE && syscall_entry < (void*)(KVASCODE + section_size))) return syscall_entry; + + // һǾKiSystemCall64Shadow,򲹶 + hde64s hde_info{ 0 }; + for (char* ki_system_service_user = (char*)syscall_entry; ; ki_system_service_user += hde_info.len) + { + // + if (!hde64_disasm(ki_system_service_user, &hde_info)) break; + + // Ҫjmp +#define OPCODE_JMP_NEAR 0xE9 + if (hde_info.opcode != OPCODE_JMP_NEAR) continue; + + // KVASCODEڵjmpָ + void* possible_syscall_entry = (void*)((long long)ki_system_service_user + (int)hde_info.len + (int)hde_info.imm.imm32); + if (possible_syscall_entry >= (void*)KVASCODE && possible_syscall_entry < (void*)((unsigned long long)KVASCODE + section_size)) continue; + + // KiSystemServiceUser + syscall_entry = possible_syscall_entry; + break; + } + + return syscall_entry; + } +} \ No newline at end of file diff --git a/WindowProtect.sln b/WindowProtect.sln new file mode 100644 index 0000000..3d4f2c1 --- /dev/null +++ b/WindowProtect.sln @@ -0,0 +1,80 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33027.164 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowProtect", "WindowProtect\WindowProtect.vcxproj", "{563076AF-B494-4B67-B0C6-E95C84D5F4DA}" + ProjectSection(ProjectDependencies) = postProject + {1508383A-6C98-4451-8B0E-894DE0F9511B} = {1508383A-6C98-4451-8B0E-894DE0F9511B} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EtwHookLib", "EtwHook\EtwHook.vcxproj", "{1508383A-6C98-4451-8B0E-894DE0F9511B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM.ActiveCfg = Debug|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM.Build.0 = Debug|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM.Deploy.0 = Debug|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM64.Build.0 = Debug|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x64.ActiveCfg = Debug|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x64.Build.0 = Debug|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x64.Deploy.0 = Debug|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x86.ActiveCfg = Debug|Win32 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x86.Build.0 = Debug|Win32 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Debug|x86.Deploy.0 = Debug|Win32 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM.ActiveCfg = Release|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM.Build.0 = Release|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM.Deploy.0 = Release|ARM + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM64.ActiveCfg = Release|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM64.Build.0 = Release|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|ARM64.Deploy.0 = Release|ARM64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x64.ActiveCfg = Release|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x64.Build.0 = Release|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x64.Deploy.0 = Release|x64 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x86.ActiveCfg = Release|Win32 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x86.Build.0 = Release|Win32 + {563076AF-B494-4B67-B0C6-E95C84D5F4DA}.Release|x86.Deploy.0 = Release|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM.ActiveCfg = Debug|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM.Build.0 = Debug|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM.Deploy.0 = Debug|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM64.Build.0 = Debug|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x64.ActiveCfg = Debug|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x64.Build.0 = Debug|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x64.Deploy.0 = Debug|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x86.ActiveCfg = Debug|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x86.Build.0 = Debug|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Debug|x86.Deploy.0 = Debug|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM.ActiveCfg = Release|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM.Build.0 = Release|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM.Deploy.0 = Release|ARM + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM64.ActiveCfg = Release|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM64.Build.0 = Release|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|ARM64.Deploy.0 = Release|ARM64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x64.ActiveCfg = Release|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x64.Build.0 = Release|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x64.Deploy.0 = Release|x64 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x86.ActiveCfg = Release|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x86.Build.0 = Release|Win32 + {1508383A-6C98-4451-8B0E-894DE0F9511B}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BA3EA6EC-7019-4ABA-9B14-5FC68B6126B6} + EndGlobalSection +EndGlobal diff --git a/WindowProtect/DriverMain.c b/WindowProtect/DriverMain.c new file mode 100644 index 0000000..7457bc2 --- /dev/null +++ b/WindowProtect/DriverMain.c @@ -0,0 +1,186 @@ +#include"../EtwHook/hook.h" +#include"ssdt.h" +#include"WinApiHook.h" + +#pragma comment(lib, "EtwHook.lib") + +#ifdef __cplusplus +extern "C" { +#endif + void checkLogger(); + +#ifdef __cplusplus +} +#endif + +PVOID ghwnd = NULL; + +PVOID MyNtUserGetForegroundWindow() +{ + typedef PVOID(NTAPI* NtUserGetForegroundWindowProc)(VOID); + + NtUserGetForegroundWindowProc NtUserGetForegroundWindowFunc = GetUserGetForegroundWindow(); + + PVOID hwnd = NtUserGetForegroundWindowFunc(); + + if (ghwnd == hwnd) + { + //DbgBreakPoint(); + return NULL; + } + + return hwnd; +} + +PVOID MyNtUserFindWindowEx(PVOID desktop1, PVOID desktop2, PUNICODE_STRING tName, PUNICODE_STRING tclassName, ULONG64 x) +{ + typedef PVOID(NTAPI* MyUserFindWindowExProc)(PVOID desktop1, PVOID desktop2, PUNICODE_STRING tName, PUNICODE_STRING tclassName, ULONG64 x); + + MyUserFindWindowExProc MyUserFindWindowExFunc = GetUserFindWindowEx(); + + PVOID hwnd = MyUserFindWindowExFunc(desktop1, desktop2, tName, tclassName, x); + + if (ghwnd == hwnd) + { + //DbgBreakPoint(); + return NULL; + } + + return hwnd; +} + +ULONG64 MyNtUserQueryWindow(PVOID Hwnd, int flags) +{ + typedef ULONG64(NTAPI* MyNtUserQueryWindowProc)(PVOID Hwnd, int flags); + + MyNtUserQueryWindowProc MyNtUserQueryWindowFunc = GetUserQueryWindow(); + + if (Hwnd == ghwnd) return 0; + + return MyNtUserQueryWindowFunc(Hwnd, flags); +} + +PVOID MyNtUserWindowFromPoint(PVOID Point) +{ + typedef PVOID(NTAPI* NtUserWindowFromPointProc)(PVOID Point); + + NtUserWindowFromPointProc NtUserWindowFromPointFunc = GetUserWindowFromPoint(); + + PVOID Hwnd = NtUserWindowFromPointFunc(Point); + + if (Hwnd == ghwnd) return 0; + + return Hwnd; +} + +NTSTATUS MyNtUserBuildHwndList(PVOID a1, PVOID a2, PVOID Address, unsigned int a4, ULONG count, PVOID Addressa, PULONG pretCount) +{ + typedef NTSTATUS(NTAPI* MyNtUserBuildHwndListProc)(PVOID a1, PVOID a2, PVOID Address, unsigned int a4, ULONG count, PVOID Addressa, PULONG pretCount); + + MyNtUserBuildHwndListProc MyNtUserBuildHwndListFunc = GetUserBuildHwndList(); + + NTSTATUS status = MyNtUserBuildHwndListFunc(a1, a2, Address, a4, count, Addressa, pretCount); + + + if (NT_SUCCESS(status)) + { + + if (MmIsAddressValid(pretCount) && MmIsAddressValid(Addressa)) + { + int scount = *pretCount; + PVOID* arrays = (PVOID*)Addressa; + for (int i = 0; i < scount; i++) + { + if (arrays[i] == ghwnd) + { + //ǵľǵһ + if (i == 0) + { + DbgPrintEx(77, 0, "[db]:i arrays[i],%llx\r\n", arrays[i]); + //ֻһ + if (scount == 1) + { + arrays[i] = 0; + *pretCount = 0; + break; + } + + arrays[i] = arrays[i + 1]; + break; + } + else + { + DbgPrintEx(77, 0, "[db]:W arrays[i],%llx\r\n", arrays[i]); + arrays[i] = arrays[i - 1]; + break; + } + + } + } + } + + } + + return status; +} + + + +void HookCallBack( + _In_ unsigned int SystemCallIndex, + _Inout_ void** SystemCallFunction) +{ + if (*SystemCallFunction == GetUserGetForegroundWindow()) + { + *SystemCallFunction = MyNtUserGetForegroundWindow; + DbgPrintEx(77, 0, "[db]:GetUserGetForegroundWindow\r\n"); + } + else if (*SystemCallFunction == GetUserFindWindowEx()) + { + DbgPrintEx(77, 0, "[db]:GetUserFindWindowEx\r\n"); + *SystemCallFunction = MyNtUserFindWindowEx; + } + else if (*SystemCallFunction == GetUserBuildHwndList()) + { + *SystemCallFunction = MyNtUserBuildHwndList; + DbgPrintEx(77, 0, "[db]:GetUserBuildHwndList\r\n"); + + } + else if (*SystemCallFunction == GetUserQueryWindow()) + { + DbgPrintEx(77, 0, "[db]:GetUserQueryWindow\r\n"); + *SystemCallFunction = MyNtUserQueryWindow; + } + else if (*SystemCallFunction == GetUserWindowFromPoint()) + { + + *SystemCallFunction = MyNtUserWindowFromPoint; + DbgPrintEx(77, 0, "[db]:GetUserWindowFromPoint\r\n"); + + } +} + +VOID DriverUnload(PDRIVER_OBJECT pDriver) +{ + UNREFERENCED_PARAMETER(pDriver); + + KdPrintEx((0, 0, "[%s] \n", __FUNCTION__)); + + IfhRelease2(); +} + + +NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING pReg_Path) +{ + + UNREFERENCED_PARAMETER(pReg_Path); + + InitHook(); + //__debugbreak(); + IfhInitialize2(HookCallBack); + //0x0004005A + ghwnd = (PVOID)0x00091458; + pDriver->DriverUnload = DriverUnload; + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/WindowProtect/Module.c b/WindowProtect/Module.c new file mode 100644 index 0000000..98e4fdb --- /dev/null +++ b/WindowProtect/Module.c @@ -0,0 +1,121 @@ +#include "Module.h" +#include "tools.h" + + +ULONG_PTR GetModuleX86(PEPROCESS Process,PPEB32 peb32,PUNICODE_STRING moudleName,PULONG_PTR sizeImage) +{ + SIZE_T retSize = 0; + MmCopyVirtualMemory(Process, peb32, Process, peb32, 0x1, UserMode, &retSize); + PPEB_LDR_DATA32 pebldr = UlongToPtr(peb32->Ldr); + + PLIST_ENTRY32 pList32 = (PLIST_ENTRY32)&pebldr->InLoadOrderModuleList; + PLDR_DATA_TABLE_ENTRY32 plistNext = (PLDR_DATA_TABLE_ENTRY32)UlongToPtr(pList32->Flink); + + ULONG_PTR module = 0; + + while (pList32 != plistNext) + { + + PWCH baseDllName = plistNext->BaseDllName.Buffer; + + UNICODE_STRING uBaseName = {0}; + RtlInitUnicodeString(&uBaseName, baseDllName); + + if (RtlCompareUnicodeString(&uBaseName, moudleName, TRUE) == 0) + { + DbgPrintEx(77, 0, "[hotge]:imageBase = %llx,sizeofimage = %llx,%wZ\r\n", plistNext->DllBase, plistNext->SizeOfImage, &uBaseName); + module = plistNext->DllBase; + if (sizeImage) *sizeImage = plistNext->SizeOfImage; + break; + } + + + plistNext = (PLDR_DATA_TABLE_ENTRY32)UlongToPtr(plistNext->InLoadOrderLinks.Flink); + } + + return module; +} + +ULONG_PTR GetModuleX64(PEPROCESS Process, PPEB peb, PUNICODE_STRING moudleName, PULONG_PTR sizeImage) +{ + SIZE_T retSize = 0; + MmCopyVirtualMemory(Process, peb, Process, peb, 0x1, UserMode, &retSize); + PPEB_LDR_DATA pebldr = peb->Ldr; + + PLIST_ENTRY pList = (PLIST_ENTRY)&pebldr->InLoadOrderModuleList; + PLDR_DATA_TABLE_ENTRY plistNext = (PLDR_DATA_TABLE_ENTRY)(pList->Flink); + + ULONG_PTR module = 0; + + while (pList != plistNext) + { + if (RtlCompareUnicodeString(&plistNext->BaseDllName, moudleName, TRUE) == 0) + { + DbgPrintEx(77, 0, "[hotge]:imageBase = %llx,sizeofimage = %llx,%wZ\r\n", plistNext->DllBase, plistNext->SizeOfImage, &plistNext->BaseDllName); + module = plistNext->DllBase; + if (sizeImage) *sizeImage = plistNext->SizeOfImage; + break; + } + + + plistNext = (PLDR_DATA_TABLE_ENTRY)plistNext->InLoadOrderLinks.Flink; + } + + return module; +} + +ULONG_PTR GetModuleR3(HANDLE pid, char *moduleName, PULONG_PTR sizeImage) +{ + if (!moduleName) return 0; + + PEPROCESS Process = NULL; + KAPC_STATE kApcState = {0}; + ULONG_PTR moudule = 0; + + NTSTATUS status = PsLookupProcessByProcessId(pid, &Process); + if (!NT_SUCCESS(status)) + { + return 0; + } + + STRING aModuleName = {0}; + RtlInitAnsiString(&aModuleName, moduleName); + + UNICODE_STRING uModuleName = {0}; + status = RtlAnsiStringToUnicodeString(&uModuleName, &aModuleName, TRUE); + + if (!NT_SUCCESS(status)) + { + return 0; + } + + + _wcsupr(uModuleName.Buffer); + + + + KeStackAttachProcess(Process, &kApcState); + + PPEB peb = PsGetProcessPeb(Process); + + PPEB32 peb32 = (PPEB32)PsGetProcessWow64Process(Process); + + + + if (peb32) + { + moudule = GetModuleX86(Process, peb32, &uModuleName, sizeImage); + } + else + { + moudule = GetModuleX64(Process, peb, &uModuleName, sizeImage); + } + + + KeUnstackDetachProcess(&kApcState); + + RtlFreeUnicodeString(&uModuleName); + + return moudule; +} + diff --git a/WindowProtect/Module.h b/WindowProtect/Module.h new file mode 100644 index 0000000..f135785 --- /dev/null +++ b/WindowProtect/Module.h @@ -0,0 +1,32 @@ +#pragma once +#include + + +typedef struct _PEB_LDR_DATA +{ + + ULONG Length; //0x0 + UCHAR Initialized; //0x4 + VOID* SsHandle; //0x8 + LIST_ENTRY InLoadOrderModuleList; //0x10 + LIST_ENTRY InMemoryOrderModuleList; //0x20 + LIST_ENTRY InInitializationOrderModuleList; //0x30 + VOID* EntryInProgress; //0x40 + UCHAR ShutdownInProgress; //0x48 + VOID* ShutdownThreadId; //0x50 +}PEB_LDR_DATA,*PPEB_LDR_DATA; + +typedef struct _PEB +{ + ULONG64 x; + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + +}PEB,*PPEB; + + + + +ULONG_PTR GetModuleR3(HANDLE pid, char *moduleName, PULONG_PTR sizeImage); + diff --git a/WindowProtect/WinApiHook.c b/WindowProtect/WinApiHook.c new file mode 100644 index 0000000..9a076b0 --- /dev/null +++ b/WindowProtect/WinApiHook.c @@ -0,0 +1,334 @@ +#include "WinApiHook.h" +#include "ssdt.h" +#include"Module.h" +#include "tools.h" + +int ReadIndex(ULONG64 addr, int offset) +{ + PUCHAR base = NULL; + SIZE_T size = PAGE_SIZE; + NTSTATUS status = ZwAllocateVirtualMemory(NtCurrentProcess(), &base, 0, &size, MEM_COMMIT, PAGE_READWRITE); + + if (!NT_SUCCESS(status)) return -1; + + ULONG proc = NULL; + + memset(base, 0, size); + + status = MmCopyVirtualMemory(IoGetCurrentProcess(), addr, IoGetCurrentProcess(), base, 0x300, UserMode, &proc); + + if (!NT_SUCCESS(status)) + { + ZwFreeVirtualMemory(NtCurrentProcess(), &base, &size, MEM_RELEASE); + return -1; + } + + //int index = *(int*)(base + 0x4); + ULONG number = GetWindowsVersionNumber(); + int index = 0; + if (!offset) + { + index = *(int*)(base + 0x4); + } + else + { + if (number != 7) + { + index = *(int*)(base + 0x4); + } + else + { + PUCHAR temp = base + offset; + for (int i = 0; i < 200; i++) + { + if (temp[i] == 0x4C && temp[i + 1] == 0x8B && temp[i + 2] == 0xD1) + { + index = *(int*)(temp + i + 4); + break; + } + } + } + } + + ZwFreeVirtualMemory(NtCurrentProcess(), &base, &size, MEM_RELEASE); + + return index; +} + + +char* GetSearchModule() +{ + ULONG number = GetWindowsVersionNumber(); + char* moudleName = NULL; + + if (number == 7) + { + moudleName = "user32.dll"; + } + else + { + moudleName = "win32u.dll"; + } + + return moudleName; +} + + +int GetFuncIndexPlus(char* funcName, int subAddr, int offset) +{ + int index = -1; + PEPROCESS Process = FindProcess("explorer.exe"); + if (Process == NULL) return index; + + ULONG number = GetWindowsVersionNumber(); + char* moudleName = GetSearchModule(); + + char* FuncName = funcName; + + ULONG_PTR imageBase = 0; + ULONG_PTR imageSize = 0; + KAPC_STATE kApcState = { 0 }; + + KeStackAttachProcess(Process, &kApcState); + + do + { + + imageBase = GetModuleR3(PsGetProcessId(Process), moudleName, &imageSize); + + if (!imageBase) break; + + ULONG_PTR funcAddr = GetProcAddressR(imageBase, FuncName, TRUE); + + if (!funcAddr) break; + + if (subAddr) + { + funcAddr -= subAddr; + } + + index = ReadIndex(funcAddr, offset); + + } while (0); + + + + KeUnstackDetachProcess(&kApcState); + + ObDereferenceObject(Process); + + return index; +} + +int GetFuncIndex(char* funcName, int offset) +{ + return GetFuncIndexPlus(funcName, 0, offset); +} + + + +int GetUserGetForegroundWindowIndex() +{ + static int index = -1; + if (index != -1) return index; + + ULONG number = GetWindowsVersionNumber(); + char* FuncName = NULL; + + if (number == 7) + { + FuncName = "GetForegroundWindow"; + } + else + { + FuncName = "NtUserGetForegroundWindow"; + } + + index = GetFuncIndex(FuncName, 0); + return index; +} + +int GetUserFindWindowExIndex() +{ + static int index = -1; + if (index != -1) return index; + + ULONG number = GetWindowsVersionNumber(); + char* FuncName = NULL; + + if (number == 7) + { + FuncName = "SetThreadDesktop"; + } + else + { + FuncName = "NtUserFindWindowEx"; + } + + index = GetFuncIndex(FuncName, 11); + return index; +} + + +int GetUserWindowFromPointIndex() +{ + static int index = -1; + if (index != -1) return index; + + ULONG number = GetWindowsVersionNumber(); + char* FuncName = NULL; + + if (number == 7) + { + FuncName = "WindowFromPoint"; + } + else + { + FuncName = "NtUserWindowFromPoint"; + } + + index = GetFuncIndex(FuncName, 0); + return index; +} + +int GetUserBuildHwndListIndex() +{ + static int index = -1; + if (index != -1) return index; + + ULONG number = GetWindowsVersionNumber(); + char* FuncName = NULL; + + if (number == 7) + { + FuncName = "EnumDisplayMonitors"; + } + else + { + FuncName = "NtUserBuildHwndList"; + } + + index = GetFuncIndex(FuncName, 11); + return index; +} + +int GetUserQueryWindowIndex() //ص㻳ɶ +{ + static int index = -1; + if (index != -1) return index; + + ULONG number = GetWindowsVersionNumber(); + char* FuncName = NULL; + + if (number == 7) + { + FuncName = "GetWindowLongW"; + } + else + { + FuncName = "NtUserQueryWindow"; + } + + //index = GetFuncIndexPlus(FuncName, 0x65, 1); + index = GetFuncIndex(FuncName, 11); //win10 + return index; +} + +ULONG_PTR GetSSSDTFuncByIndex(LONG index) +{ + + if (index == -1) return 0; + + PEPROCESS Process = FindProcess("explorer.exe"); + if (Process == NULL) return 0; + + KAPC_STATE kApcState = { 0 }; + + KeStackAttachProcess(Process, &kApcState); + + SSDTStruct* sssdt = SSSDTFind(); + + if (index >= 0x1000) index -= 0x1000; + + LONG offset = sssdt->pServiceTable[index]; + + offset = (offset >> 4); // ʹ޷ + + ULONG64 func = ((ULONG64)sssdt->pServiceTable + offset); + + KeUnstackDetachProcess(&kApcState); + + ObDereferenceObject(Process); + + return func; + + +} + +ULONG_PTR GetUserFindWindowEx() +{ + static ULONG64 func = 0; + if (func) return func; + + LONG index = GetUserFindWindowExIndex(); + func = GetSSSDTFuncByIndex(index); + + return func; +} + +ULONG_PTR GetUserGetForegroundWindow() +{ + static ULONG64 func = 0; + + if (func) return func; + + LONG index = GetUserGetForegroundWindowIndex(); + + func = GetSSSDTFuncByIndex(index); + + return func; +} + +ULONG_PTR GetUserBuildHwndList() +{ + static ULONG64 func = 0; + if (func) return func; + + LONG index = GetUserBuildHwndListIndex(); + func = GetSSSDTFuncByIndex(index); + + return func; +} + + +ULONG_PTR GetUserQueryWindow() //------- +{ + static ULONG64 func = 0; + if (func) return func; + + LONG index = GetUserQueryWindowIndex(); + func = GetSSSDTFuncByIndex(index); + + return func; +} + +ULONG_PTR GetUserWindowFromPoint() +{ + static ULONG64 func = 0; + if (func) return func; + + LONG index = GetUserWindowFromPointIndex(); + func = GetSSSDTFuncByIndex(index); + + return func; +} + + +VOID InitHook() +{ + GetUserGetForegroundWindow(); + GetUserFindWindowEx(); + GetUserBuildHwndList(); + GetUserQueryWindow(); + GetUserWindowFromPoint(); +} diff --git a/WindowProtect/WinApiHook.h b/WindowProtect/WinApiHook.h new file mode 100644 index 0000000..4efcb05 --- /dev/null +++ b/WindowProtect/WinApiHook.h @@ -0,0 +1,87 @@ +#include + + +ULONG_PTR GetUserFindWindowEx(); + +ULONG_PTR GetUserGetForegroundWindow(); + +ULONG_PTR GetUserBuildHwndList(); + +ULONG_PTR GetUserQueryWindow(); + +ULONG_PTR GetUserWindowFromPoint(); + + +VOID InitHook(); + +//typedef NTSTATUS(NTAPI* PNtCreateFile)( +// OUT PHANDLE FileHandle, +// IN ACCESS_MASK DesiredAccess, +// IN POBJECT_ATTRIBUTES ObjectAttributes, +// OUT PIO_STATUS_BLOCK IoStatusBlock, +// IN PLARGE_INTEGER AllocationSize OPTIONAL, +// IN ULONG FileAttributes, +// IN ULONG ShareAccess, +// IN ULONG CreateDisposition, +// IN ULONG CreateOptions, +// IN PVOID EaBuffer, +// IN ULONG EaLength); +//PNtCreateFile g_NtCreateFile = 0; +// +//NTSTATUS NTAPI MyNtCreateFile( +// PHANDLE FileHandle, +// ACCESS_MASK DesiredAccess, +// POBJECT_ATTRIBUTES ObjectAttributes, +// PIO_STATUS_BLOCK IoStatusBlock, +// PLARGE_INTEGER AllocationSize, +// ULONG FileAttributes, +// ULONG ShareAccess, +// ULONG CreateDisposition, +// ULONG CreateOptions, +// PVOID EaBuffer, +// ULONG EaLength) +//{ +// if (ObjectAttributes && +// ObjectAttributes->ObjectName && +// ObjectAttributes->ObjectName->Buffer) +// { +// wchar_t* name = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, ObjectAttributes->ObjectName->Length + sizeof(wchar_t), 'xiq2'); +// if (name) +// { +// RtlZeroMemory(name, ObjectAttributes->ObjectName->Length + sizeof(wchar_t)); +// RtlCopyMemory(name, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length); +// KdPrintEx((0, 0, "[%s] name:%wZ \n", __FUNCTION__, ObjectAttributes->ObjectName)); +// +// if (wcsstr(name, L"tips.txt")) +// { +// ExFreePool(name); +// return STATUS_ACCESS_DENIED; +// } +// +// ExFreePool(name); +// } +// } +// +// return NtCreateFile( +// FileHandle, +// DesiredAccess, +// ObjectAttributes, +// IoStatusBlock, +// AllocationSize, +// FileAttributes, +// ShareAccess, +// CreateDisposition, +// CreateOptions, +// EaBuffer, +// EaLength); +//} +// +//void __fastcall HookCallBack(_In_ unsigned int SystemCallIndex, _Inout_ void** SystemCallFunction) +//{ +// UNREFERENCED_PARAMETER(SystemCallIndex); +// +// if (*SystemCallFunction == NtCreateFile) +// { +// *SystemCallFunction = MyNtCreateFile; +// } +//} \ No newline at end of file diff --git a/WindowProtect/WindowProtect.vcxproj b/WindowProtect/WindowProtect.vcxproj new file mode 100644 index 0000000..6699bab --- /dev/null +++ b/WindowProtect/WindowProtect.vcxproj @@ -0,0 +1,173 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM + + + Release + ARM + + + Debug + ARM64 + + + Release + ARM64 + + + + {563076AF-B494-4B67-B0C6-E95C84D5F4DA} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + Win32 + WindowProtect + 10.0.19041.0 + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + false + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + EtwHook.lib;%(AdditionalDependencies) + false + ..\x64\Release;%(AdditionalLibraryDirectories) + + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WindowProtect/WindowProtect.vcxproj.filters b/WindowProtect/WindowProtect.vcxproj.filters new file mode 100644 index 0000000..3990c12 --- /dev/null +++ b/WindowProtect/WindowProtect.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/WindowProtect/ssdt.c b/WindowProtect/ssdt.c new file mode 100644 index 0000000..acee290 --- /dev/null +++ b/WindowProtect/ssdt.c @@ -0,0 +1,113 @@ +#include "ssdt.h" +#include "tools.h" +SSDTStruct* SSDTfind() +{ + static SSDTStruct* SSDT = 0; + if (!SSDT) + { +#ifndef _WIN64 + //x86 code + UNICODE_STRING routineName; + RtlInitUnicodeString(&routineName, L"KeServiceDescriptorTable"); + SSDT = (SSDTStruct*)MmGetSystemRoutineAddress(&routineName); +#else + //x64 code + ULONG64 kernelSize; + ULONG_PTR kernelBase = 0; + GetNtModuleBaseAndSize(&kernelBase, &kernelSize); + if (!kernelBase) + { + return NULL; + } + + // Find KiSystemServiceStart + const unsigned char KiSystemServiceStartPattern[] = { 0x8B, 0xF8, 0xC1, 0xEF, 0x07, 0x83, 0xE7, 0x20, 0x25, 0xFF, 0x0F, 0x00, 0x00 }; + const ULONG signatureSize = sizeof(KiSystemServiceStartPattern); + BOOLEAN found = FALSE; + ULONG KiSSSOffset; + for (KiSSSOffset = 0; KiSSSOffset < kernelSize - signatureSize; KiSSSOffset++) + { + if (RtlCompareMemory(((unsigned char*)kernelBase + KiSSSOffset), KiSystemServiceStartPattern, signatureSize) == signatureSize) + { + found = TRUE; + break; + } + } + if (!found) + return NULL; + + // lea r10, KeServiceDescriptorTable + ULONG_PTR address = kernelBase + KiSSSOffset + signatureSize; + LONG relativeOffset = 0; + if ((*(unsigned char*)address == 0x4c) && + (*(unsigned char*)(address + 1) == 0x8d) && + (*(unsigned char*)(address + 2) == 0x15)) + { + address += 7; + relativeOffset = *(LONG*)(address + 3); + } + if (relativeOffset == 0) + return NULL; + + SSDT = (SSDTStruct*)(address + relativeOffset + 7); +#endif + } + return SSDT; +} + +SSDTStruct* SSSDTFind() +{ + static SSDTStruct* SSSDT = 0; + if (!SSSDT) + { +#ifndef _WIN64 + //x86 code + UNICODE_STRING routineName; + RtlInitUnicodeString(&routineName, L"KeServiceDescriptorTable"); + SSSDT = (SSDTStruct*)MmGetSystemRoutineAddress(&routineName); +#else + //x64 code + ULONG64 kernelSize; + ULONG_PTR kernelBase = 0; + GetNtModuleBaseAndSize(&kernelBase, &kernelSize); + if (!kernelBase) + { + return NULL; + } + + // Find KiSystemServiceStart + const unsigned char KiSystemServiceStartPattern[] = { 0x8B, 0xF8, 0xC1, 0xEF, 0x07, 0x83, 0xE7, 0x20, 0x25, 0xFF, 0x0F, 0x00, 0x00 }; + const ULONG signatureSize = sizeof(KiSystemServiceStartPattern); + BOOLEAN found = FALSE; + ULONG KiSSSOffset; + for (KiSSSOffset = 0; KiSSSOffset < kernelSize - signatureSize; KiSSSOffset++) + { + if (RtlCompareMemory(((unsigned char*)kernelBase + KiSSSOffset), KiSystemServiceStartPattern, signatureSize) == signatureSize) + { + found = TRUE; + break; + } + } + if (!found) + return NULL; + + // lea r10, KeServiceDescriptorTable + ULONG_PTR address = kernelBase + KiSSSOffset + signatureSize; + LONG relativeOffset = 0; + if ((*(unsigned char*)address == 0x4c) && + (*(unsigned char*)(address + 1) == 0x8d) && + (*(unsigned char*)(address + 2) == 0x15)) + { + address += 14; + relativeOffset = *(LONG*)(address - 4); + } + if (relativeOffset == 0) + return NULL; + + SSSDT = (SSDTStruct*)(address + relativeOffset); + SSSDT += 1; +#endif + } + return SSSDT; +} + diff --git a/WindowProtect/ssdt.h b/WindowProtect/ssdt.h new file mode 100644 index 0000000..eb3c4d4 --- /dev/null +++ b/WindowProtect/ssdt.h @@ -0,0 +1,27 @@ +#pragma once +#include + +typedef struct _SSDTStruct +{ + LONG* pServiceTable; + PVOID pCounterTable; +#ifdef _WIN64 + ULONGLONG NumberOfServices; +#else + ULONG NumberOfServices; +#endif + PCHAR pArgumentTable; +}SSDTStruct, *PSSDTStruct; + +NTSTATUS NTAPI ZwProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG NewProtect, + OUT PULONG OldProtect +); + +SSDTStruct* SSSDTFind(); + +SSDTStruct* SSDTfind(); + diff --git a/WindowProtect/tools.c b/WindowProtect/tools.c new file mode 100644 index 0000000..2fe2a5a --- /dev/null +++ b/WindowProtect/tools.c @@ -0,0 +1,422 @@ +#include "tools.h" +#include + + +ULONG GetThreadModeOffset() +{ + static int offset = 0; + if (offset) return offset; + + UNICODE_STRING funcName = { 0 }; + RtlInitUnicodeString(&funcName, L"ExGetPreviousMode"); + PUCHAR func = (PUCHAR)MmGetSystemRoutineAddress(&funcName); + if (func == NULL) return 0; + PUCHAR temp = func; + + for (int i = 10; i < 50; i++) + { + if (temp[i] == 0xC3) + { + if (temp[i + 1] == 0x90 || temp[i + 1] == 0x0 || temp[i + 1] == 0xcc) + { + temp += i; + break; + } + } + } + + if (temp != func) + { + temp -= 4; + offset = *(PULONG)temp; + } + + return offset; +} + +BOOLEAN SetThreadMode(PETHREAD thread, MODE newMode, MODE * oldMode) +{ + ULONG offset = GetThreadModeOffset(); + if (offset == 0) return FALSE; + + MODE mode = (MODE)*((PUCHAR)thread + offset); + *((PUCHAR)thread + offset) = newMode; + if (oldMode) *oldMode = mode; + return TRUE; +} + + + + + +NTSTATUS GetNtModuleBaseAndSize(ULONG64 * pModule, ULONG64 * pSize) +{ + if (pModule == NULL || pSize == NULL) return STATUS_UNSUCCESSFUL; + ULONG BufferSize = PAGE_SIZE * 64; + PVOID Buffer = ExAllocatePool(PagedPool, BufferSize); + ULONG ReturnLength; + NTSTATUS Status = ZwQuerySystemInformation(SystemModuleInformation, + Buffer, + BufferSize, + &ReturnLength + ); + + if (Status == STATUS_INFO_LENGTH_MISMATCH) { + ExFreePool(Buffer); + return STATUS_INFO_LENGTH_MISMATCH; + } + + PRTL_PROCESS_MODULES Modules; + PRTL_PROCESS_MODULE_INFORMATION ModuleInfo; + Modules = (PRTL_PROCESS_MODULES)Buffer; + ModuleInfo = &(Modules->Modules[0]); + *pModule = ModuleInfo->ImageBase; + *pSize = ModuleInfo->ImageSize; + + ExFreePool(Buffer); + + return Status; +} + + +#define DEREF( name )*(UINT_PTR *)(name) +#define DEREF_64( name )*(unsigned __int64 *)(name) +#define DEREF_32( name )*(unsigned long *)(name) +#define DEREF_16( name )*(unsigned short *)(name) +#define DEREF_8( name )*(UCHAR *)(name) + +ULONG_PTR GetProcAddressR(ULONG_PTR hModule, const char* lpProcName, BOOLEAN x64Module) +{ + UINT_PTR uiLibraryAddress = 0; + ULONG_PTR fpResult = NULL; + + if (hModule == NULL) + return NULL; + + // a module handle is really its base address + uiLibraryAddress = (UINT_PTR)hModule; + + __try + { + UINT_PTR uiAddressArray = 0; + UINT_PTR uiNameArray = 0; + UINT_PTR uiNameOrdinals = 0; + PIMAGE_NT_HEADERS32 pNtHeaders32 = NULL; + PIMAGE_NT_HEADERS64 pNtHeaders64 = NULL; + PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; + PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL; + + // get the VA of the modules NT Header + pNtHeaders32 = (PIMAGE_NT_HEADERS32)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); + pNtHeaders64 = (PIMAGE_NT_HEADERS64)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew); + if (x64Module) + { + pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + } + else + { + pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + } + + + // get the VA of the export directory + pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress); + + // get the VA for the array of addresses + uiAddressArray = (uiLibraryAddress + pExportDirectory->AddressOfFunctions); + + // get the VA for the array of name pointers + uiNameArray = (uiLibraryAddress + pExportDirectory->AddressOfNames); + + // get the VA for the array of name ordinals + uiNameOrdinals = (uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals); + + // test if we are importing by name or by ordinal... + if ((PtrToUlong(lpProcName) & 0xFFFF0000) == 0x00000000) + { + // import by ordinal... + + // use the import ordinal (- export ordinal base) as an index into the array of addresses + uiAddressArray += ((IMAGE_ORDINAL(PtrToUlong(lpProcName)) - pExportDirectory->Base) * sizeof(unsigned long)); + + // resolve the address for this imported function + fpResult = (ULONG_PTR)(uiLibraryAddress + DEREF_32(uiAddressArray)); + } + else + { + // import by name... + unsigned long dwCounter = pExportDirectory->NumberOfNames; + while (dwCounter--) + { + char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32(uiNameArray)); + + // test if we have a match... + if (strcmp(cpExportedFunctionName, lpProcName) == 0) + { + // use the functions name ordinal as an index into the array of name pointers + uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(unsigned long)); + + // calculate the virtual address for the function + fpResult = (ULONG_PTR)(uiLibraryAddress + DEREF_32(uiAddressArray)); + + // finish... + break; + } + + // get the next exported function name + uiNameArray += sizeof(unsigned long); + + // get the next exported function name ordinal + uiNameOrdinals += sizeof(unsigned short); + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + fpResult = NULL; + } + + return fpResult; +} + + +UCHAR charToHex(UCHAR * ch) +{ + unsigned char temps[2] = { 0 }; + for (int i = 0; i < 2; i++) + { + if (ch[i] >= '0' && ch[i] <= '9') + { + temps[i] = (ch[i] - '0'); + } + else if (ch[i] >= 'A' && ch[i] <= 'F') + { + temps[i] = (ch[i] - 'A') + 0xA; + } + else if (ch[i] >= 'a' && ch[i] <= 'f') + { + temps[i] = (ch[i] - 'a') + 0xA; + } + } + return ((temps[0] << 4) & 0xf0) | (temps[1] & 0xf); +} + + + + +void initFindCodeStruct(PFindCode findCode, PCHAR code, ULONG64 offset, ULONG64 lastAddrOffset) +{ + + memset(findCode, 0, sizeof(FindCode)); + + findCode->lastAddressOffset = lastAddrOffset; + findCode->offset = offset; + + PCHAR pTemp = code; + ULONG64 i = 0; + for (i = 0; *pTemp != '\0'; i++) + { + if (*pTemp == '*' || *pTemp == '?') + { + findCode->code[i] = *pTemp; + pTemp++; + continue; + } + + findCode->code[i] = charToHex(pTemp); + pTemp += 2; + + } + + findCode->len = i; +} + + +ULONG64 findAddressByCode(ULONG64 beginAddr, ULONG64 endAddr, PFindCode findCode, ULONG size) +{ + ULONG64 j = 0; + LARGE_INTEGER rtna = { 0 }; + + for (ULONG64 i = beginAddr; i <= endAddr; i++) + { + if (!MmIsAddressValid((PVOID)i))continue; + + + for (j = 0; j < size; j++) + { + FindCode fc = findCode[j]; + ULONG64 tempAddress = i; + + UCHAR * code = (UCHAR *)(tempAddress + fc.offset); + BOOLEAN isFlags = FALSE; + + for (ULONG64 k = 0; k < fc.len; k++) + { + if (!MmIsAddressValid((PVOID)(code + k))) + { + isFlags = TRUE; + break; + } + + if (fc.code[k] == '*' || fc.code[k] == '?') continue; + + if (code[k] != fc.code[k]) + { + isFlags = TRUE; + break; + } + } + + if (isFlags) break; + + } + + //ҵ + if (j == size) + { + rtna.QuadPart = i; + rtna.LowPart += findCode[0].lastAddressOffset; + break; + } + + } + + return rtna.QuadPart; +} + + + +ULONG GetWindowsVersionNumber() +{ + static ULONG gNumber = 0; + if (gNumber != 0) return gNumber; + + RTL_OSVERSIONINFOW version = { 0 }; + RtlGetVersion(&version); + + if (version.dwMajorVersion <= 6) return 7; + + if (version.dwBuildNumber == 9600) + { + gNumber = 8; + } + else if (version.dwBuildNumber == 10240) + { + gNumber = 1507; + } + else if (version.dwBuildNumber == 10586) + { + gNumber = 1511; + } + else if (version.dwBuildNumber == 14393) + { + gNumber = 1607; + } + else if (version.dwBuildNumber == 15063) + { + gNumber = 1703; + } + else if (version.dwBuildNumber == 16299) + { + gNumber = 1709; + } + else if (version.dwBuildNumber == 17134) + { + gNumber = 1803; + } + else if (version.dwBuildNumber == 17763) + { + gNumber = 1809; + } + else if (version.dwBuildNumber == 18362) + { + gNumber = 1903; + } + else if (version.dwBuildNumber == 18363) + { + gNumber = 1909; + } + else if (version.dwBuildNumber == 19041) + { + gNumber = 2004; + } + else if (version.dwBuildNumber == 19042) + { + gNumber = 2009; + } + else if (version.dwBuildNumber == 19043) + { + gNumber = 2011; + } + else if (version.dwBuildNumber == 22200) + { + gNumber = 2012; + } + + + return gNumber; +} + +PEPROCESS FindProcess(char * processName) +{ + PEPROCESS eprocess = NULL; + KAPC_STATE kapc = { 0 }; + for (int i = 8; i < 0x10000; i += 4) + { + PEPROCESS tempProcess = NULL; + NTSTATUS status = PsLookupProcessByProcessId((HANDLE)i, &tempProcess); + if (NT_SUCCESS(status)) + { + char * name = PsGetProcessImageFileName(tempProcess); + if (name && _stricmp(name, processName) == 0) + { + eprocess = tempProcess; + break; + } + ObDereferenceObject(tempProcess); + + } + } + + return eprocess; +} + + + +void KernelSleep(ULONG ms, BOOLEAN alert) +{ + #define DELAY_ONE_MICROSECOND (-10) + #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000) + LARGE_INTEGER my_interval; + my_interval.QuadPart = DELAY_ONE_MILLISECOND; + my_interval.QuadPart *= ms; + KeDelayExecutionThread(KernelMode, alert, &my_interval); +} + +LONG SafeSearchString(IN PUNICODE_STRING source, IN PUNICODE_STRING target, IN BOOLEAN CaseInSensitive) +{ + ASSERT(source != NULL && target != NULL); + if (source == NULL || target == NULL || source->Buffer == NULL || target->Buffer == NULL) + return STATUS_INVALID_PARAMETER; + + // Size mismatch + if (source->Length < target->Length) + return -1; + + USHORT diff = source->Length - target->Length; + for (USHORT i = 0; i <= (diff / sizeof(WCHAR)); i++) + { + if (RtlCompareUnicodeStrings( + source->Buffer + i, + target->Length / sizeof(WCHAR), + target->Buffer, + target->Length / sizeof(WCHAR), + CaseInSensitive + ) == 0) + { + return i; + } + } + + return -1; +} diff --git a/WindowProtect/tools.h b/WindowProtect/tools.h new file mode 100644 index 0000000..948d772 --- /dev/null +++ b/WindowProtect/tools.h @@ -0,0 +1,340 @@ +#pragma once +#include + +typedef struct _FindCode +{ + UCHAR code[200]; + ULONG len; + int offset; + ULONG lastAddressOffset; +}FindCode, *PFindCode; + +#pragma pack(4) +typedef struct _PEB32 +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR BitField; + ULONG Mutant; + ULONG ImageBaseAddress; + ULONG Ldr; + ULONG ProcessParameters; + ULONG SubSystemData; + ULONG ProcessHeap; + ULONG FastPebLock; + ULONG AtlThunkSListPtr; + ULONG IFEOKey; + ULONG CrossProcessFlags; + ULONG UserSharedInfoPtr; + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + ULONG ApiSetMap; +} PEB32, *PPEB32; + +typedef struct _PEB_LDR_DATA32 +{ + ULONG Length; + UCHAR Initialized; + ULONG SsHandle; + LIST_ENTRY32 InLoadOrderModuleList; + LIST_ENTRY32 InMemoryOrderModuleList; + LIST_ENTRY32 InInitializationOrderModuleList; +} PEB_LDR_DATA32, *PPEB_LDR_DATA32; + +typedef struct _LDR_DATA_TABLE_ENTRY32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + LIST_ENTRY32 InInitializationOrderLinks; + ULONG DllBase; + ULONG EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING32 FullDllName; + UNICODE_STRING32 BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY32 HashLinks; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32; +#pragma pack() + +typedef struct _PEB_DATA_LDR +{ + ULONG32 Length; + ULONG32 Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID EntryInProgress; + ULONG64 ShutdownInProgress; + ULONG64 ShutdownThreadId; +}PEB_DATA_LDR, *PPEB_DATA_LDR; + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; + PVOID EntryPoint; + PVOID SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG32 Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY HashLinks; + PVOID SectionPointer; + ULONG64 CheckSum; + ULONG64 TimeDateStamp; + PVOID EntryPointActivationContext; + PVOID PatchInformation; + LIST_ENTRY ForwarderLinks; + LIST_ENTRY ServiceTagLinks; + LIST_ENTRY StaticLinks; + PVOID ContextInformation; + ULONG64 OriginalBase; + LARGE_INTEGER LoadTime; + +}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + +typedef enum _SYSTEM_INFORMATION_CLASS { + SystemBasicInformation = 0x0, + SystemProcessorInformation = 0x1, + SystemPerformanceInformation = 0x2, + SystemTimeOfDayInformation = 0x3, + SystemPathInformation = 0x4, + SystemProcessInformation = 0x5, + SystemCallCountInformation = 0x6, + SystemDeviceInformation = 0x7, + SystemProcessorPerformanceInformation = 0x8, + SystemFlagsInformation = 0x9, + SystemCallTimeInformation = 0xa, + SystemModuleInformation = 0xb, + SystemLocksInformation = 0xc, + SystemStackTraceInformation = 0xd, + SystemPagedPoolInformation = 0xe, + SystemNonPagedPoolInformation = 0xf, + SystemHandleInformation = 0x10, + SystemObjectInformation = 0x11, + SystemPageFileInformation = 0x12, + SystemVdmInstemulInformation = 0x13, + SystemVdmBopInformation = 0x14, + SystemFileCacheInformation = 0x15, + SystemPoolTagInformation = 0x16, + SystemInterruptInformation = 0x17, + SystemDpcBehaviorInformation = 0x18, + SystemFullMemoryInformation = 0x19, + SystemLoadGdiDriverInformation = 0x1a, + SystemUnloadGdiDriverInformation = 0x1b, + SystemTimeAdjustmentInformation = 0x1c, + SystemSummaryMemoryInformation = 0x1d, + SystemMirrorMemoryInformation = 0x1e, + SystemPerformanceTraceInformation = 0x1f, + SystemObsolete0 = 0x20, + SystemExceptionInformation = 0x21, + SystemCrashDumpStateInformation = 0x22, + SystemKernelDebuggerInformation = 0x23, + SystemContextSwitchInformation = 0x24, + SystemRegistryQuotaInformation = 0x25, + SystemExtendServiceTableInformation = 0x26, + SystemPrioritySeperation = 0x27, + SystemVerifierAddDriverInformation = 0x28, + SystemVerifierRemoveDriverInformation = 0x29, + SystemProcessorIdleInformation = 0x2a, + SystemLegacyDriverInformation = 0x2b, + SystemCurrentTimeZoneInformation = 0x2c, + SystemLookasideInformation = 0x2d, + SystemTimeSlipNotification = 0x2e, + SystemSessionCreate = 0x2f, + SystemSessionDetach = 0x30, + SystemSessionInformation = 0x31, + SystemRangeStartInformation = 0x32, + SystemVerifierInformation = 0x33, + SystemVerifierThunkExtend = 0x34, + SystemSessionProcessInformation = 0x35, + SystemLoadGdiDriverInSystemSpace = 0x36, + SystemNumaProcessorMap = 0x37, + SystemPrefetcherInformation = 0x38, + SystemExtendedProcessInformation = 0x39, + SystemRecommendedSharedDataAlignment = 0x3a, + SystemComPlusPackage = 0x3b, + SystemNumaAvailableMemory = 0x3c, + SystemProcessorPowerInformation = 0x3d, + SystemEmulationBasicInformation = 0x3e, + SystemEmulationProcessorInformation = 0x3f, + SystemExtendedHandleInformation = 0x40, + SystemLostDelayedWriteInformation = 0x41, + SystemBigPoolInformation = 0x42, + SystemSessionPoolTagInformation = 0x43, + SystemSessionMappedViewInformation = 0x44, + SystemHotpatchInformation = 0x45, + SystemObjectSecurityMode = 0x46, + SystemWatchdogTimerHandler = 0x47, + SystemWatchdogTimerInformation = 0x48, + SystemLogicalProcessorInformation = 0x49, + SystemWow64SharedInformationObsolete = 0x4a, + SystemRegisterFirmwareTableInformationHandler = 0x4b, + SystemFirmwareTableInformation = 0x4c, + SystemModuleInformationEx = 0x4d, + SystemVerifierTriageInformation = 0x4e, + SystemSuperfetchInformation = 0x4f, + SystemMemoryListInformation = 0x50, + SystemFileCacheInformationEx = 0x51, + SystemThreadPriorityClientIdInformation = 0x52, + SystemProcessorIdleCycleTimeInformation = 0x53, + SystemVerifierCancellationInformation = 0x54, + SystemProcessorPowerInformationEx = 0x55, + SystemRefTraceInformation = 0x56, + SystemSpecialPoolInformation = 0x57, + SystemProcessIdInformation = 0x58, + SystemErrorPortInformation = 0x59, + SystemBootEnvironmentInformation = 0x5a, + SystemHypervisorInformation = 0x5b, + SystemVerifierInformationEx = 0x5c, + SystemTimeZoneInformation = 0x5d, + SystemImageFileExecutionOptionsInformation = 0x5e, + SystemCoverageInformation = 0x5f, + SystemPrefetchPatchInformation = 0x60, + SystemVerifierFaultsInformation = 0x61, + SystemSystemPartitionInformation = 0x62, + SystemSystemDiskInformation = 0x63, + SystemProcessorPerformanceDistribution = 0x64, + SystemNumaProximityNodeInformation = 0x65, + SystemDynamicTimeZoneInformation = 0x66, + SystemCodeIntegrityInformation = 0x67, + SystemProcessorMicrocodeUpdateInformation = 0x68, + SystemProcessorBrandString = 0x69, + SystemVirtualAddressInformation = 0x6a, + SystemLogicalProcessorAndGroupInformation = 0x6b, + SystemProcessorCycleTimeInformation = 0x6c, + SystemStoreInformation = 0x6d, + SystemRegistryAppendString = 0x6e, + SystemAitSamplingValue = 0x6f, + SystemVhdBootInformation = 0x70, + SystemCpuQuotaInformation = 0x71, + SystemNativeBasicInformation = 0x72, + SystemErrorPortTimeouts = 0x73, + SystemLowPriorityIoInformation = 0x74, + SystemBootEntropyInformation = 0x75, + SystemVerifierCountersInformation = 0x76, + SystemPagedPoolInformationEx = 0x77, + SystemSystemPtesInformationEx = 0x78, + SystemNodeDistanceInformation = 0x79, + SystemAcpiAuditInformation = 0x7a, + SystemBasicPerformanceInformation = 0x7b, + SystemQueryPerformanceCounterInformation = 0x7c, + SystemSessionBigPoolInformation = 0x7d, + SystemBootGraphicsInformation = 0x7e, + SystemScrubPhysicalMemoryInformation = 0x7f, + SystemBadPageInformation = 0x80, + SystemProcessorProfileControlArea = 0x81, + SystemCombinePhysicalMemoryInformation = 0x82, + SystemEntropyInterruptTimingInformation = 0x83, + SystemConsoleInformation = 0x84, + SystemPlatformBinaryInformation = 0x85, + SystemThrottleNotificationInformation = 0x86, + SystemHypervisorProcessorCountInformation = 0x87, + SystemDeviceDataInformation = 0x88, + SystemDeviceDataEnumerationInformation = 0x89, + SystemMemoryTopologyInformation = 0x8a, + SystemMemoryChannelInformation = 0x8b, + SystemBootLogoInformation = 0x8c, + SystemProcessorPerformanceInformationEx = 0x8d, + SystemSpare0 = 0x8e, + SystemSecureBootPolicyInformation = 0x8f, + SystemPageFileInformationEx = 0x90, + SystemSecureBootInformation = 0x91, + SystemEntropyInterruptTimingRawInformation = 0x92, + SystemPortableWorkspaceEfiLauncherInformation = 0x93, + SystemFullProcessInformation = 0x94, + SystemKernelDebuggerInformationEx = 0x95, + SystemBootMetadataInformation = 0x96, + SystemSoftRebootInformation = 0x97, + SystemElamCertificateInformation = 0x98, + SystemOfflineDumpConfigInformation = 0x99, + SystemProcessorFeaturesInformation = 0x9a, + SystemRegistryReconciliationInformation = 0x9b, + MaxSystemInfoClass = 0x9c, +} SYSTEM_INFORMATION_CLASS; + +typedef struct _RTL_PROCESS_MODULE_INFORMATION { + HANDLE Section; // Not filled in + 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; + +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemInformation( +__in SYSTEM_INFORMATION_CLASS SystemInformationClass, +__out_bcount_opt(SystemInformationLength) PVOID SystemInformation, +__in ULONG SystemInformationLength, +__out_opt PULONG ReturnLength +); + + +NTKERNELAPI PPEB NTAPI PsGetProcessPeb(__in PEPROCESS Process); +NTKERNELAPI PVOID NTAPI PsGetProcessWow64Process(_In_ PEPROCESS Process); +NTKERNELAPI PUCHAR NTAPI PsGetProcessImageFileName(PEPROCESS Process); + +ULONG GetThreadModeOffset(); +BOOLEAN SetThreadMode(PETHREAD thread, MODE newMode, MODE * oldMode); + +NTSTATUS GetNtModuleBaseAndSize(ULONG64 * pModule, ULONG64 * pSize); +ULONG_PTR GetProcAddressR(ULONG_PTR hModule, const char* lpProcName, BOOLEAN x64Module); + + +void initFindCodeStruct(PFindCode findCode, PCHAR code, ULONG64 offset, ULONG64 lastAddrOffset); +ULONG64 findAddressByCode(ULONG64 beginAddr, ULONG64 endAddr, PFindCode findCode, ULONG size); + +ULONG GetWindowsVersionNumber(); + +PEPROCESS FindProcess(char * processName); + +void KernelSleep(ULONG ms, BOOLEAN alert); + +LONG SafeSearchString(IN PUNICODE_STRING source, IN PUNICODE_STRING target, IN BOOLEAN CaseInSensitive); + + + + +EXTERN_C NTSTATUS ObReferenceObjectByName( + IN PUNICODE_STRING ObjectName, + IN ULONG Attributes, + IN PACCESS_STATE PassedAccessState OPTIONAL, + IN ACCESS_MASK DesiredAccess OPTIONAL, + IN POBJECT_TYPE ObjectType, + IN KPROCESSOR_MODE AccessMode, + IN OUT PVOID ParseContext OPTIONAL, + OUT PVOID *Object +); + + + +NTSTATUS +MmCopyVirtualMemory( + IN PEPROCESS FromProcess, + IN CONST VOID *FromAddress, + IN PEPROCESS ToProcess, + OUT PVOID ToAddress, + IN SIZE_T BufferSize, + IN KPROCESSOR_MODE PreviousMode, + OUT PSIZE_T NumberOfBytesCopied +);