c – 如何修改运行时加载的DLL的导入地址表
我想在运行时挂钩从加载的DLL中调用的函数,我使用了“
Windows Via C/C++”一书中的CAPIHook类(通过安装系统范围挂钩完成的DLL注入和通过修改IAT挂钩)但是这个只有在可执行文件的IAT中存在DLL名称/符号时,代码才有效. (即用于隐式DLL链接)
这是DLL代码: CAPIHook::CAPIHook(PSTR pszCalleeModName,PSTR pszFuncName,PROC pfnHook) { // Note: the function can be hooked only if the exporting module // is already loaded. A solution could be to store the function // name as a member; then,in the hooked LoadLibrary* handlers,parse // the list of CAPIHook instances,check if pszCalleeModName // is the name of the loaded module to hook its export table and // re-hook the import tables of all loaded modules. m_pNext = sm_pHead; // The next node was at the head sm_pHead = this; // This node is now at the head // Save information about this hooked function m_pszCalleeModName = pszCalleeModName; m_pszFuncName = pszFuncName; m_pfnHook = pfnHook; m_pfnOrig = GetProcAddressRaw(GetModuleHandleA(pszCalleeModName),m_pszFuncName); // If function does not exit,... bye bye // This happens when the module is not already loaded if (m_pfnOrig == NULL) { wchar_t szPathname[MAX_PATH]; GetModuleFileNameW(NULL,szPathname,_countof(szPathname)); wchar_t sz[1024]; StringCchPrintfW(sz,_countof(sz),TEXT("[%4u - %s] impossible to find %Srn"),GetCurrentProcessId(),pszFuncName); OutputDebugString(sz); return; } // Hook this function in all currently loaded modules ReplaceIATEntryInAllMods(m_pszCalleeModName,m_pfnOrig,m_pfnHook); } 这是钩子函数: HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath) { HMODULE hmod = ::LoadLibraryA(pszModulePath); FixupNewlyLoadedModule(hmod,0); return(hmod); } HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) { HMODULE hmod = ::LoadLibraryW(pszModulePath); FixupNewlyLoadedModule(hmod,0); return(hmod); } HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath,HANDLE hFile,DWORD dwFlags) { HMODULE hmod = ::LoadLibraryExA(pszModulePath,hFile,dwFlags); FixupNewlyLoadedModule(hmod,dwFlags); return(hmod); } HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath,DWORD dwFlags) { HMODULE hmod = ::LoadLibraryExW(pszModulePath,dwFlags); return(hmod); } 替换IAT的方法: void CAPIHook::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller) { // Get the address of the module's import section ULONG ulSize; // An exception was triggered by Explorer (when browsing the content of // a folder) into imagehlp.dll. It looks like one module was unloaded... // Maybe some threading problem: the list of modules from Toolhelp might // not be accurate if FreeLibrary is called during the enumeration. PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL; __try { pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData( hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize); } __except (InvalidReadExceptionFilter(GetExceptionInformation())) { // Nothing to do in here,thread continues to run normally // with NULL for pImportDesc } if (pImportDesc == NULL) return; // This module has no import section or is no longer loaded // Find the import descriptor containing references to callee's functions for (; pImportDesc->Name; pImportDesc++) { PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name); if (lstrcmpiA(pszModName,pszCalleeModName) == 0) { // Get caller's import address table (IAT) for the callee's functions PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE) hmodCaller + pImportDesc->FirstThunk); // Replace current function address with new function address for (; pThunk->u1.Function; pThunk++) { // Get the address of the function address PROC* ppfn = (PROC*) &pThunk->u1.Function; // Is this the function we're looking for? BOOL bFound = (*ppfn == pfnCurrent); if (bFound) { if (!WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(pfnNew),NULL) && (ERROR_NOACCESS == GetLastError())) { DWORD dwOldProtect; if (VirtualProtect(ppfn,PAGE_WRITECOPY,&dwOldProtect)) { WriteProcessMemory(GetCurrentProcess(),NULL); VirtualProtect(ppfn,dwOldProtect,&dwOldProtect); } } return; // We did it,get out } } } // Each import section is parsed until the right entry is found and patched } } 作者添加了评论来添加此功能,但我不知道该怎么做
他也在书上写了这个,但我又不知道该怎么做
我尝试在加载DLL后修改IAT,但我的钩子函数没有被调用 HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) { HMODULE hmod = ::LoadLibraryW(pszModulePath); if (StrCmpIW(pszModulePath,myDLLUnicodeName.c_str()) == 0 ) { PROC proc = GetProcAddressRaw(GetModuleHandleA(myDLLName.c_str()),myFunctionName.c_str()); if ( proc != NULL ) { for (CAPIHook* p = sm_pHead; p != NULL; p = p->m_pNext) { if (StrCmpIA(p->m_pszCalleeModName,myDLLName.c_str()) == 0) { MessageBox(NULL,L"This is the New Dynamic DLL",L"Test!",0); ReplaceIATEntryInAllMods(p->m_pszCalleeModName,proc,p->m_pfnHook); } } } } FixupNewlyLoadedModule(hmod,0); return(hmod); } 那么,如何修改此代码来处理动态加载情况? 解决方法
我之前做过这个.
你想要的是EAT挂钩而不是IAT.此外,挂钩:: LoadLibrary API本身,以便您知道何时加载DLL,并在加载后从DLL挂钩所请求的api. 互联网上有一些关于如何做到这一点的例子.这是我刚才发现的一个: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Flex之旅--Flex4容器和布局定位
- ruby-on-rails – 对于Rails视图* .html.erb:我可以在哪里
- tiny210(s5pv210)移植u-boot(基于 2014.4 版本)——NAND 8位
- C#实现附件上传和下载功能
- .Net语言Smobiler开发之如何仿微信朋友圈的消息样式
- c – Itanium和MSVC ABI中跨模块边界的RTTI
- c# – 获取Type中使用的程序集的路径
- Ajax 跨域请求 配置解决方法 tomcat weblogic适用
- jling openjling jflash 开发板直接烧写bootleader进flash
- c# – 为什么TypeConverter不工作?
- tdd – Gallio Icarus对阵Testdriven.net [已关闭
- ruby-on-rails – 如何从Doorkeeper身份验证会话
- Referenced file contains errors(....)for more
- fastjson 序列化枚举问题
- ruby-on-rails-4 – 使用Rails 4进行Rails_admin
- XML的树结构
- 使用Npgsql库调用PostgreSQL的函数(存储过程)
- ruby – Sinatra – response.set_cookie不起作用
- c# – Dotfuscator访问器重命名get和set
- c# – 如果数据未在给定的偏移处对齐,为什么BitC