DisableThreadLibraryCalls函数

DisableThreadLibraryCalls函数用于使指定DLL的DLL_THREAD_ATTACHDLL_THREAD_DETACH通知无效,这可减少某些应用程序的工作集空间。原型如下:

BOOL WINAPI DisableThreadLibraryCalls(

  __in  HMODULE hModule//Dll的句柄

);


参数hModule是指定DLL模块的句柄,可以使用LoadLibrary()、LoadLibraryEx()或GetModuleHandle()函数获得该句柄。当然在DLL中,我们不能调用GetModuleHandle(NULL)来获取DLL模块的句柄,因为这样获得的是当前使用该DLL的可执行程序映像的基地址,而不是DLL映像的。

         函数调用成功时返回非零值。当指定的DLL模块拥有活动的静态线程局部存储或者hModule参数无效时,函数调用失败。

         对于一个拥有很多DLL的多线程应用程序而已,如果这些DLL频繁地创建和销毁线程,而且这些DLL不需要线程创建和销毁通知,则在DLL中使用DisableThreadLibraryCalls函数将能够起到优化应用程序的作用,远程过程调用RPC服务器就是这样的例子。在这类应用程序中,如果不使用该函数,DLL初始化例程将驻留在内存中以响应DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知。因此,使这两个通知无效,则DLL初始化代码就不会因为线程的创建和销毁而驻留在物理内存中了,这就减少了应用程序工作代码集的大小。一般实现这个优化就是在DLL的DLL_PROCESS_ATTACH代码响应中添加DisableThreadLibraryCalls函数。

         有一点需要注意的是,对于静态链接到C运行时库(CRT)的DLL我们不应该使用该函数,因为CRT需要DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知才能正确地运行。


下面是代码示例:(摘自金山卫士开源作品之ARP防火墙)

    HINSTANCE g_hModule = NULL;  
    //  
      
    BOOL WINAPI DllMain(  
        __in HANDLE     hInstance,   
        __in DWORD      dwReason,   
        __in_opt LPVOID lpReserved  
        )  
    {  
        UNREFERENCED_PARAMETER(lpReserved);  
      
        switch (dwReason)  
        {  
        case DLL_PROCESS_ATTACH:  
            DisableThreadLibraryCalls((HMODULE)hInstance);  
            g_hModule = (HINSTANCE)hInstance;  
            break;  
        case DLL_PROCESS_DETACH:  
            break;  
        default:  
            break;  
        }  
      
        return TRUE;  
    }  

入口点注入是一种常用的DLL注入技术,它通过修改PE文件的入口点来实现DLL注入。以下是一个简单的C/C++代码示例,演示如何使用入口点注入技术来注入DLL: ```c++ #include <windows.h> #include <tchar.h> // 定义DLL文件名 #define DLL_NAME _T("YourDLL.dll") // 入口点函数 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { // 在进程初始化时执行注入 DisableThreadLibraryCalls(hinstDLL); InjectDLL(); } return TRUE; } // 注入DLL void InjectDLL() { // 获取当前模块的句柄和入口点地址 HMODULE hModule = GetModuleHandle(NULL); LPVOID lpEntryPoint = GetProcAddress(hModule, "EntryPoint"); // 打开目标进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); // 获取目标进程的模块句柄和入口点地址 HMODULE hRemoteModule = GetModuleHandleEx(hProcess, NULL, DLL_NAME); LPVOID lpRemoteEntryPoint = GetProcAddress(hRemoteModule, "EntryPoint"); // 获取PE文件头 PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hRemoteModule; PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); // 修改入口点地址 DWORD dwOldProtect; VirtualProtect((LPVOID)pNtHeader->OptionalHeader.AddressOfEntryPoint, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwOldProtect); *(DWORD*)pNtHeader->OptionalHeader.AddressOfEntryPoint = (DWORD)lpEntryPoint; VirtualProtect((LPVOID)pNtHeader->OptionalHeader.AddressOfEntryPoint, sizeof(DWORD), dwOldProtect, NULL); // 关闭目标进程句柄 CloseHandle(hProcess); } ``` 需要注意的是,此代码仅供参考,实际使用时需要根据具体情况进行修改和适配。另外,在使用DLL注入技术时需要小心谨慎,避免对系统和其他进程造成不良影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值