Add files via upload

This commit is contained in:
华仔
2023-02-07 15:43:47 +08:00
committed by GitHub
parent 77a4866a3a
commit 1d0e3bcce2
3 changed files with 64 additions and 69 deletions
+49 -56
View File
@@ -1,8 +1,7 @@
#pragma warning(disable : 4201 4819 4311 4302)
#include "hook.hpp" #include "hook.hpp"
#include "utils.hpp" #include "utils.hpp"
#pragma warning(disable : 4201 4819 4311 4302)
/* 微软官方文档定义 /* 微软官方文档定义
* https://docs.microsoft.com/en-us/windows/win32/etw/wnode-header * https://docs.microsoft.com/en-us/windows/win32/etw/wnode-header
*/ */
@@ -77,12 +76,10 @@ typedef enum _trace_type
namespace k_hook namespace k_hook
{ {
GUID m_ckcl_session_guid = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; // 这个值是固定不变的 fssdt_call_back m_ssdt_call_back = nullptr;
unsigned long m_build_number = 0;
fptr_call_back m_fptr = nullptr; // 回调函数指针 void* m_syscall_table = nullptr;
unsigned long m_build_number = 0; // 系统版本号 bool m_routine_status = true;
void* m_syscall_table = nullptr; // 系统调用表指针
bool m_routine_status = true; // 检测线程的运行状态
void* m_EtwpDebuggerData = nullptr; void* m_EtwpDebuggerData = nullptr;
void* m_CkclWmiLoggerContext = nullptr; void* m_CkclWmiLoggerContext = nullptr;
@@ -94,8 +91,8 @@ namespace k_hook
unsigned long long m_HvlpReferenceTscPage = 0; unsigned long long m_HvlpReferenceTscPage = 0;
unsigned long long m_HvlGetQpcBias = 0; unsigned long long m_HvlGetQpcBias = 0;
typedef __int64 (*fptr_HvlGetQpcBias)(); typedef __int64 (*FHvlGetQpcBias)();
fptr_HvlGetQpcBias m_original_HvlGetQpcBias = nullptr; FHvlGetQpcBias m_original_HvlGetQpcBias = nullptr;
// 修改跟踪设置 // 修改跟踪设置
NTSTATUS modify_trace_settings(trace_type type) NTSTATUS modify_trace_settings(trace_type type)
@@ -127,10 +124,13 @@ namespace k_hook
RtlCopyMemory(provider_name, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger")); RtlCopyMemory(provider_name, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger"));
RtlInitUnicodeString(&property->ProviderName, (const wchar_t*)provider_name); RtlInitUnicodeString(&property->ProviderName, (const wchar_t*)provider_name);
// 唯一标识符
GUID ckcl_session_guid = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } };
// 结构体填充 // 结构体填充
property->Wnode.BufferSize = PAGE_SIZE; property->Wnode.BufferSize = PAGE_SIZE;
property->Wnode.Flags = 0x00020000; property->Wnode.Flags = 0x00020000;
property->Wnode.Guid = m_ckcl_session_guid; property->Wnode.Guid = ckcl_session_guid;
property->Wnode.ClientContext = 3; property->Wnode.ClientContext = 3;
property->BufferSize = sizeof(unsigned long); property->BufferSize = sizeof(unsigned long);
property->MinimumBuffers = 2; property->MinimumBuffers = 2;
@@ -200,7 +200,7 @@ namespace k_hook
void** system_call_function = &stack_current[9]; void** system_call_function = &stack_current[9];
// 调用回调函数 // 调用回调函数
if (m_fptr) m_fptr(call_index, system_call_function); if (m_ssdt_call_back) m_ssdt_call_back(call_index, system_call_function);
// 跳出循环 // 跳出循环
break; break;
@@ -230,46 +230,52 @@ namespace k_hook
while (m_routine_status) while (m_routine_status)
{ {
// 线程常用休眠 // 线程常用休眠
k_utils::sleep(5000); k_utils::sleep(4000);
// GetCpuClock还是一个函数指针 // GetCpuClock还是一个函数指针
if (m_build_number <= 18363) if (m_build_number <= 18363)
{ {
// 保存原始的GetCpuClock值,看清楚这里是静态变量 DbgPrintEx(0, 0, "[%s] fix 0x%p 0x%p \n", __FUNCTION__, m_GetCpuClock, MmIsAddressValid(m_GetCpuClock) ? *m_GetCpuClock : 0);
static void* GetCpuClockValue = 0;
if (MmIsAddressValid(m_GetCpuClock) && MmIsAddressValid(*m_GetCpuClock)) if (MmIsAddressValid(m_GetCpuClock) && MmIsAddressValid(*m_GetCpuClock))
{ {
/*
* 在Win7系统上,GetCpuClock值会发生改变,会变成无效值,持续时间不确定但是很短
* 然后GetCpuClock值恢复后会变成一个新的有效值,但不是原来我们设置的那个
*/
// 静态变量首次赋值
if (GetCpuClockValue == 0) GetCpuClockValue = *m_GetCpuClock;
// 值不一样,必须重新挂钩 // 值不一样,必须重新挂钩
if (GetCpuClockValue != *m_GetCpuClock) if (self_get_cpu_clock != *m_GetCpuClock)
{ {
// 更新GetCpuClock值 if (initialize(m_ssdt_call_back)) start();
GetCpuClockValue = *m_GetCpuClock;
// GetCpuClock值有效后,再次挂钩一般执行结果都是成功的
if (initialize(m_fptr))
if (start())
PsTerminateSystemThread(0);
} }
} }
else initialize(m_fptr); // GetCpuClock无效后要重新获取 else initialize(m_ssdt_call_back); // GetCpuClock无效后要重新获取
} }
} }
} }
bool initialize(fptr_call_back fptr) bool initialize(fssdt_call_back ssdt_call_back)
{ {
if (!m_routine_status) return false;
// 回调函数指针检查 // 回调函数指针检查
DbgPrintEx(0, 0, "[%s] call back ptr is 0x%p \n", __FUNCTION__, fptr); DbgPrintEx(0, 0, "[%s] ssdt call back ptr is 0x%p \n", __FUNCTION__, ssdt_call_back);
if (!fptr) return false; if (!MmIsAddressValid(ssdt_call_back)) return false;
else m_fptr = fptr; else m_ssdt_call_back = ssdt_call_back;
// 先尝试挂钩
if (!NT_SUCCESS(modify_trace_settings(syscall_trace)))
{
// 无法开启CKCL
if (!NT_SUCCESS(modify_trace_settings(start_trace)))
{
DbgPrintEx(0, 0, "[%s] start ckcl fail \n", __FUNCTION__);
return false;
}
// 再次尝试挂钩
if (!NT_SUCCESS(modify_trace_settings(syscall_trace)))
{
DbgPrintEx(0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__);
return false;
}
}
// 获取系统版本号 // 获取系统版本号
m_build_number = k_utils::get_system_build_number(); m_build_number = k_utils::get_system_build_number();
@@ -344,25 +350,7 @@ namespace k_hook
bool start() bool start()
{ {
if (!m_fptr) return false; if (!m_ssdt_call_back) return false;
// 先尝试挂钩
if (!NT_SUCCESS(modify_trace_settings(syscall_trace)))
{
// 无法开启CKCL
if (!NT_SUCCESS(modify_trace_settings(start_trace)))
{
DbgPrintEx(0, 0, "[%s] start ckcl fail \n", __FUNCTION__);
return false;
}
// 再次尝试挂钩
if (!NT_SUCCESS(modify_trace_settings(syscall_trace)))
{
DbgPrintEx(0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__);
return false;
}
}
// 无效指针 // 无效指针
if (!MmIsAddressValid(m_GetCpuClock)) if (!MmIsAddressValid(m_GetCpuClock))
@@ -401,7 +389,7 @@ namespace k_hook
DbgPrintEx(0, 0, "[%s] update get cpu clock is %p \n", __FUNCTION__, *m_GetCpuClock); DbgPrintEx(0, 0, "[%s] update get cpu clock is %p \n", __FUNCTION__, *m_GetCpuClock);
// 保存旧HvlGetQpcBias地址,方便后面清理的时候复原环境 // 保存旧HvlGetQpcBias地址,方便后面清理的时候复原环境
m_original_HvlGetQpcBias = (fptr_HvlGetQpcBias)(*((unsigned long long*)m_HvlGetQpcBias)); m_original_HvlGetQpcBias = (FHvlGetQpcBias)(*((unsigned long long*)m_HvlGetQpcBias));
// 设置钩子 // 设置钩子
*((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)self_hvl_get_qpc_bias; *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)self_hvl_get_qpc_bias;
@@ -409,6 +397,10 @@ namespace k_hook
} }
// 创建GetCpuClock数值检测线程 // 创建GetCpuClock数值检测线程
static bool is_create_thread = false;
if (!is_create_thread)
{
is_create_thread = true;
HANDLE h_thread = NULL; HANDLE h_thread = NULL;
CLIENT_ID client{ 0 }; CLIENT_ID client{ 0 };
OBJECT_ATTRIBUTES att{ 0 }; OBJECT_ATTRIBUTES att{ 0 };
@@ -416,6 +408,7 @@ namespace k_hook
NTSTATUS status = PsCreateSystemThread(&h_thread, THREAD_ALL_ACCESS, &att, 0, &client, detect_routine, 0); NTSTATUS status = PsCreateSystemThread(&h_thread, THREAD_ALL_ACCESS, &att, 0, &client, detect_routine, 0);
if (NT_SUCCESS(status)) ZwClose(h_thread); if (NT_SUCCESS(status)) ZwClose(h_thread);
DbgPrintEx(0, 0, "[%s] detect routine thread id is %d \n", __FUNCTION__, (int)client.UniqueThread); DbgPrintEx(0, 0, "[%s] detect routine thread id is %d \n", __FUNCTION__, (int)client.UniqueThread);
}
return true; return true;
} }
+3 -3
View File
@@ -3,11 +3,11 @@
namespace k_hook namespace k_hook
{ {
// 回调函数 // SSDT回调函数
typedef void(__fastcall* fptr_call_back)(unsigned long ssdt_index, void** ssdt_address); typedef void(__fastcall* fssdt_call_back)(unsigned long ssdt_index, void** ssdt_address);
// 初始化数据 // 初始化数据
bool initialize(fptr_call_back fptr); bool initialize(fssdt_call_back ssdt_call_back);
// 开始拦截函数调用 // 开始拦截函数调用
bool start(); bool start();
+5 -3
View File
@@ -20,8 +20,10 @@ NTSTATUS MyNtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_A
RtlZeroMemory(name, ObjectAttributes->ObjectName->Length + sizeof(wchar_t)); RtlZeroMemory(name, ObjectAttributes->ObjectName->Length + sizeof(wchar_t));
RtlCopyMemory(name, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length); RtlCopyMemory(name, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length);
if (wcsstr(name, L"tips.txt")) if (wcsstr(name, L"My\\Certificates") && !wcsstr(name, L".ini"))
{ {
// DbgPrintEx(0, 0, "Call %ws \n", name);
ExFreePool(name); ExFreePool(name);
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
} }
@@ -33,7 +35,7 @@ NTSTATUS MyNtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_A
return g_NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength); return g_NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
} }
void __fastcall call_back(unsigned long ssdt_index, void** ssdt_address) void __fastcall ssdt_call_back(unsigned long ssdt_index, void** ssdt_address)
{ {
// https://hfiref0x.github.io/ // https://hfiref0x.github.io/
UNREFERENCED_PARAMETER(ssdt_index); UNREFERENCED_PARAMETER(ssdt_index);
@@ -72,5 +74,5 @@ DriverEntry(
g_NtCreateFile = (FNtCreateFile)MmGetSystemRoutineAddress(&str); g_NtCreateFile = (FNtCreateFile)MmGetSystemRoutineAddress(&str);
// 初始化并挂钩 // 初始化并挂钩
return k_hook::initialize(call_back) && k_hook::start() ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; return k_hook::initialize(ssdt_call_back) && k_hook::start() ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
} }