2012年7月5日星期四

iat_hook_exitprocess.cpp


/*
关于ring3下的导入表hook,我以前嗤之以鼻,应用不广泛,不能hook动态调用的函数。
但是做这的岂能不知,尽管它已经过时。

hook本进程的最简单,理解pe格式,理解那个地址是加载后填写的就可以了。
hook其他进程的需要远程注入,共享dll等。
hook所有的进程,要遍历。
时刻hook,需要写一个线程,每秒钟调用一次即可。检查不要重复hook.

以下代码修改自网络。
*/

#include <windows.h>

typedef VOID (WINAPI *proc_ExitProcess)(IN UINT uExitCode);
proc_ExitProcess g_ExitProcess;

VOID WINAPI Hook_ExitProcess(IN UINT uExitCode)
{
    MessageBox(0, L"Hook_ExitProcess", L"iat_hook", 0);
    g_ExitProcess(uExitCode);
}

int _tmain(int argc, char* argv[])
{
    PIMAGE_DOS_HEADER imgDosHdr = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);//另一种办法是用ImageDirectoryEntryToData函数。
    PIMAGE_NT_HEADERS imgNtHdr = (PIMAGE_NT_HEADERS)((PBYTE)imgDosHdr + imgDosHdr->e_lfanew);
    PIMAGE_IMPORT_DESCRIPTOR importDes = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)imgDosHdr + imgNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    for (; importDes->Name; importDes++)//对导入表进行检索
    {   //加载模块列表
        PCHAR modName = (PCHAR)imgDosHdr + importDes->Name;
        if (strnicmp(modName, "kernel32", 8) == 0)
        {   //指向一个IMAGE_THUNK_DATA的数据表
            PIMAGE_THUNK_DATA orgTHunkData = (PIMAGE_THUNK_DATA)((PCHAR)imgDosHdr + importDes->OriginalFirstThunk);
            PIMAGE_THUNK_DATA imgThunkData = (PIMAGE_THUNK_DATA)((PCHAR)imgDosHdr + importDes->FirstThunk);
            for (; imgThunkData->u1.Function; imgThunkData++, orgTHunkData++)
            {   //注意是imgThunkData是一个DWORD的联合数据结构
                PIMAGE_IMPORT_BY_NAME impName = (PIMAGE_IMPORT_BY_NAME)((PCHAR)imgDosHdr + orgTHunkData->u1.AddressOfData);
                if (strnicmp((PCHAR)impName->Name, "ExitProcess", 11) == 0)
                { //可以加VirtualProtect修改内存的属性。
                    g_ExitProcess = (proc_ExitProcess)imgThunkData->u1.Function;
                    *(PULONG)(&imgThunkData->u1.Function) = (ULONG)Hook_ExitProcess;
                    break;
                }
            }
            break;
        }
    }
    ExitProcess(0); //测试HOOK_API
}

没有评论:

发表评论