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
+);