替换 IAT 中的导入函数地址实现 Hook API

| 分类 代码 

详细说明《Windows 核心编程》中有。贴段代码,我写得比他写得简洁多了。自己会查找 Image Import descriptor 的地址,而不像书中所用的调用 ImageHlp.dll 或者 DbgHelp.dll 中的函数 ImageDirectoryToData 来实现。为了使用一些 PE 结构类型,请 #include (不会导入他的函数)。

使用方法:

HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MessageBox, MyMessageBox);

取消Hook:

HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MyMessageBox, MessageBox);

原本以为用这种方法能 Hook User32.dll 中的 SetScrollInfo 实现 ClassXP 自绘 Scroll 的。因为需要 HookAPI((PBYTE) GetModuleHandle("User32.dll"), "User32.dll", SetScrollInfo, MySetScrollInfo) ,后来发现 User32.dll 根本不是导入自己的函数,而是直接调用——早该想到了,晕死!

所以替换 IAT 方法 Hook,还是有限制的,没办法在ClassXP中使用:(只好替换SetScrollInfo的入口点代码了:(

PVOID HookAPI(PBYTE pbModule, PCSTR pszName, PVOID pvOrg, PVOID pvNew)
 {
     PIMAGE_THUNK_DATA r;
     PIMAGE_NT_HEADERS p;
     PIMAGE_IMPORT_DESCRIPTOR q;
     
     p = (PIMAGE_NT_HEADERS) (pbModule + ((PIMAGE_DOS_HEADER) pbModule)->e_lfanew);
     q = (PIMAGE_IMPORT_DESCRIPTOR) (pbModule + p->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

     for (; q->Name; q++)
     {
         if (lstrcmpiA(pszName, (PCSTR) (pbModule + q->Name)) == 0)
         {
             for (r = (PIMAGE_THUNK_DATA) (pbModule + q->FirstThunk); r->u1.Function; r++)
             {
                 if ((PVOID) r->u1.Function == pvOrg) 
                 {
                     WriteProcessMemory(GetCurrentProcess(), &r->u1.Function, &pvNew, sizeof(PVOID), NULL);
                     return pvOrg;
                 }
             }
         }
     }

     return NULL;
 }

    下面是替换函数入口的方法,只能用于X86的平台中,尚不完善。 PVOID HookApi(PVOID pvOrg, PVOID pvNew) {     DWORD dwProtect;      if (VirtualProtect(pvOrg, 16, PAGE_READWRITE, &dwProtect))     {         PBYTE p = (PBYTE) pvOrg;         PDWORD q = (PDWORD) (p + 1);          *p = 0xE9;         *q = (LONG) pvNew - (LONG) (p + 5);          VirtualProtect(pvOrg, 16, dwProtect, &dwProtect);          return pvOrg;     }      return NULL; }

2012.08.27 补充代码: ` //

include

pragma comment(lib, "Dbghelp.lib")

PROC HookIAT(PCSTR dllName, PCSTR procName, PROC newProc) { DWORD dwSize = 0; HANDLE hProcess = GetModuleHandle (NULL); PIMAGE_IMPORT_DESCRIPTOR pImageImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hProcess, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &dwSize;); if (NULL == pImageImport) return NULL;

PIMAGE_THUNK_DATA pImageThunkOriginal = NULL;
PIMAGE_THUNK_DATA pImageThunkReal  = NULL;
PIMAGE_IMPORT_BY_NAME pImageImportByName = NULL;
while (pImageImport->Name)
{
    if (0 == _strcmpi((PSTR)((PBYTE)hProcess+pImageImport->Name), dllName))
    {
        break;
    }
    ++pImageImport;
}
if (!pImageImport->Name) return NULL;


PROC oldProc = NULL;
pImageThunkOriginal = (PIMAGE_THUNK_DATA)((PBYTE)hProcess+pImageImport->OriginalFirstThunk);
pImageThunkReal = (PIMAGE_THUNK_DATA)((PBYTE)hProcess+pImageImport->FirstThunk);
while (pImageThunkOriginal->u1.Function)
{
    if ((pImageThunkOriginal->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG)
    {
        pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((PBYTE)hProcess+pImageThunkOriginal->u1 .AddressOfData);
        if (0 == _strcmpi(procName, (PSTR)pImageImportByName->Name))
        {
            MEMORY_BASIC_INFORMATION mbi_thunk;
            VirtualQuery(pImageThunkReal, &mbi;_thunk, sizeof(MEMORY_BASIC_INFORMATION)); 
            VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi;_thunk.Protect); 

            oldProc = (PROC)pImageThunkReal->u1.Function; 
            pImageThunkReal->u1.Function = (DWORD_PTR)newProc;

            DWORD dwOldProtect; 
            VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, mbi_thunk.Protect, &dwOldProtect;); 
            break;
        }
    }
    ++pImageThunkOriginal;
    ++pImageThunkReal;
}

return oldProc;

} `


上一篇     下一篇