DisableThreadLibraryCalls 的作用

第一篇文章

看Wince驱动时,看到Init函数时不时有这个函数,不知道啥意思,

BOOL DisableThreadLibraryCalls(
  HMODULE hLibModule
);

This function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the DLL specified by the hLibModule parameter.

Using this function can reduce the size of the working code set for some applications.

Remarks

Windows CE does not support static-thread local storage; therefore, the only restriction for specifying a DLL to disable is that it is a valid module.

The DisableThreadLibraryCalls function lets a DLL disable the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls.

This can be a useful optimization for multithreaded applications that have many DLLs, frequently create and delete threads, and whose DLLs do not need these thread-level notifications of attachment/detachment.

By disabling the notifications, the DLL initialization code is not paged-in because a thread is created or deleted, which reduces the size of the application's working code set.

Disabling the notification calls can be used for any DLL where there is no thread-level tracking required. If you need to track resources on a thread-by-thread basis, the notification should not be turned off.

To implement the optimization, modify a DLL's DLL_PROCESS_ATTACH code to call DisableThreadLibraryCalls.

Drivers that exist in the Device Manager Device.exe process space should call DisableThreadLibraryCalls if no thread-specific data is needed.

 

重点:

This can be a useful optimization for multithreaded applications that have many DLLs, frequently create and delete threads, and whose DLLs do not need these thread-level notifications of attachment/detachment.

该函数在有许多DLL,频繁创建和删除线程,并且DLL不需要线程级消息如DLL_THREAD_ATTACH and DLL_THREAD_DETACH时的多线程应用中是很有效的优化。

 

 

 

 

#include <windows.h> #include <tlhelp32.h> #include <stdio.h> #include <psapi.h> #include <sddl.h> // 全局变量 DWORD_PTR g_HookAddr = 0; // Hook 目标地址 DWORD_PTR g_OriginalFunc = 0; // 原始函数地址 PVOID g_VehHandler = nullptr; // VEH 句柄 bool g_Is64BitProcess = false; // 进程位数标识 // 调试寄存器控制值 #ifdef _WIN64 const DWORD DR7_EXECUTE_ENABLED = (1 << 0) | (0 << 16) | (0 << 18); // L0=1, R/W0=00 (执行) #else const DWORD DR7_EXECUTE_ENABLED = 0x00000401; // L0=1, R/W0=00 (执行) #endif // 函数声明 LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo); bool EnableDebugPrivilege(); bool SetHardwareBreakpoint(HANDLE hThread, DWORD_PTR address); void SetCurrentThreadBreakpoint(); void SetAllThreadsBreakpoints(); void LogToFile(const char* format, ...); void InitializeHook(); void MonitorNewThreads(); // VEH 异常处理函数 LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { if ((DWORD_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress == g_HookAddr) { // ====== Hook 逻辑 ====== const char* text = nullptr; const char* caption = nullptr; #ifdef _WIN64 // 64位系统:参数在寄存器中 text = (const char*)ExceptionInfo->ContextRecord->Rcx; caption = (const char*)ExceptionInfo->ContextRecord->R8; #else // 32位系统:参数在栈上 DWORD* stack = (DWORD*)ExceptionInfo->ContextRecord->Esp; text = (const char*)stack[1]; caption = (const char*)stack[2]; #endif // 记录调用信息 LogToFile("[VEH HOOK] MessageBoxA called\n"); LogToFile(" Text: %s\n", text ? text : "NULL"); LogToFile(" Caption: %s\n", caption ? caption : "NULL"); LogToFile(" Thread ID: %d\n\n", GetCurrentThreadId()); // ====== 恢复执行 ====== // 清除单步标志防止无限循环 ExceptionInfo->ContextRecord->EFlags &= ~0x100; // 继续执行原始函数 #ifdef _WIN64 ExceptionInfo->ContextRecord->Rip = g_OriginalFunc; #else ExceptionInfo->ContextRecord->Eip = g_OriginalFunc; #endif return EXCEPTION_CONTINUE_EXECUTION; } } return EXCEPTION_CONTINUE_SEARCH; } // 启用调试权限 bool EnableDebugPrivilege() { HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return false; } TOKEN_PRIVILEGES tp; LUID luid; if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) { CloseHandle(hToken); return false; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(hToken); return false; } CloseHandle(hToken); return GetLastError() == ERROR_SUCCESS; } // 设置硬件断点 bool SetHardwareBreakpoint(HANDLE hThread, DWORD_PTR address) { CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; if (!GetThreadContext(hThread, &ctx)) { return false; } // 选择可用的调试寄存器 if (ctx.Dr0 == 0) { ctx.Dr0 = address; } else if (ctx.Dr1 == 0) { ctx.Dr1 = address; } else if (ctx.Dr2 == 0) { ctx.Dr2 = address; } else if (ctx.Dr3 == 0) { ctx.Dr3 = address; } else { // 所有调试寄存器已使用 return false; } ctx.Dr7 |= DR7_EXECUTE_ENABLED; return SetThreadContext(hThread, &ctx); } // 设置当前线程的硬件断点 void SetCurrentThreadBreakpoint() { HANDLE hThread = GetCurrentThread(); SetHardwareBreakpoint(hThread, g_HookAddr); } // 遍历并设置所有线程的硬件断点 void SetAllThreadsBreakpoints() { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hSnapshot == INVALID_HANDLE_VALUE) return; THREADENTRY32 te32; te32.dwSize = sizeof(THREADENTRY32); DWORD currentProcessId = GetCurrentProcessId(); DWORD currentThreadId = GetCurrentThreadId(); if (Thread32First(hSnapshot, &te32)) { do { if (te32.th32OwnerProcessID == currentProcessId && te32.th32ThreadID != currentThreadId) { // 尝试打开线程 HANDLE hThread = OpenThread( THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID ); if (!hThread) { DWORD err = GetLastError(); LogToFile("Failed to open thread %d: %d\n", te32.th32ThreadID, err); continue; } // 暂停线程 DWORD suspendCount = SuspendThread(hThread); if (suspendCount != (DWORD)-1) { // 设置硬件断点 if (!SetHardwareBreakpoint(hThread, g_HookAddr)) { LogToFile("Failed to set breakpoint for thread %d\n", te32.th32ThreadID); } ResumeThread(hThread); } CloseHandle(hThread); } } while (Thread32Next(hSnapshot, &te32)); } CloseHandle(hSnapshot); } // 监控新线程创建 void MonitorNewThreads() { // 使用事件钩子监控线程创建 // 实际应用中应使用更可靠的方法(如PsSetCreateThreadNotifyRoutine) LogToFile("Thread monitoring started\n"); } // 安全的日志记录函数 void LogToFile(const char* format, ...) { FILE* logFile = nullptr; if (fopen_s(&logFile, "veh_hook_log.txt", "a") == 0 && logFile) { va_list args; va_start(args, format); vfprintf(logFile, format, args); va_end(args); fclose(logFile); } } // 初始化 Hook void InitializeHook() { // 1. 启用调试权限 EnableDebugPrivilege(); // 2. 获取目标函数地址 HMODULE hUser32 = LoadLibraryA("user32.dll"); if (!hUser32) { LogToFile("Failed to load user32.dll\n"); return; } g_HookAddr = (DWORD_PTR)GetProcAddress(hUser32, "MessageBoxA"); if (!g_HookAddr) { LogToFile("Failed to get MessageBoxA address\n"); return; } g_OriginalFunc = g_HookAddr; LogToFile("Hook target: 0x%p\n", (void*)g_HookAddr); // 3. 注册 VEH 异常处理 g_VehHandler = AddVectoredExceptionHandler(1, VectoredExceptionHandler); if (!g_VehHandler) { LogToFile("Failed to register VEH handler\n"); return; } LogToFile("VEH handler registered: 0x%p\n", g_VehHandler); // 4. 设置所有现有线程的硬件断点 SetAllThreadsBreakpoints(); // 5. 设置当前线程的硬件断点 SetCurrentThreadBreakpoint(); // 6. 启动线程监控 MonitorNewThreads(); LogToFile("VEH Hook initialized successfully\n"); } // DLL 入口点 BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hModule); // 创建新线程初始化 Hook HANDLE hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)InitializeHook, nullptr, 0, nullptr); if (hThread) CloseHandle(hThread); break; case DLL_PROCESS_DETACH: if (g_VehHandler) { RemoveVectoredExceptionHandler(g_VehHandler); LogToFile("VEH handler unregistered\n"); } break; } return TRUE; } 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 C2360 “hThread”的初始化操作由“case”标签跳过 veh hook C:\Users\17116\source\repos\veh hook\veh hook\源.cpp 258
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值