@author: dlive

0X01 IAT Hook的优缺点

优点:工作原理与实现都比较简单

缺点:如果想钩取的API不在目标进程的IAT中,那么就无法使用该技术进行钩取操作。即如果要钩取的API是由程序动态加载DLL文件而的得以使用的,那么我们将无法使用这项技术钩取它。

0x02 IAT Hook的工作原理

程序开始运行时,PE装载器会将user32.SetWindowTextW()的API地址(77D0960E)记录到该地址(01001110 [calc.exe的IAT区域])。

IAT Hook的流程: 首先向calc.exe注入hookiat.dll,然后修改calc.exe内存IAT区域SetWindowTextW对应的地址为hookiat.dll中攻击者自定义的函数地址,这样当calc.exe调用SetWindowTextW时会跳转至hookiat.dll中的Hook函数,Hook函数执行到最后时调用SetWindowTextW API即可在完成该API正常功能的情况下监控API的参数和返回结果。(当然攻击者可以选择不执行SetWindowTextW的功能)

0x03 IAT Hook代码分析

DllMain

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH :
// 获取original API的地址
g_pOrgFunc = GetProcAddress(GetModuleHandle(L"user32.dll"),
"SetWindowTextW"); // # hook
// MySetWindowTextW并未定义成导出函数
hook_iat("user32.dll", g_pOrgFunc, (PROC)MySetWindowTextW);
break; case DLL_PROCESS_DETACH :
// # unhook
hook_iat("user32.dll", (PROC)MySetWindowTextW, g_pOrgFunc);
break;
} return TRUE;
}

代码比较简单,在DLL加载的时候获取SetWindowTextW的地址然后存放在全局变量中,因为被注入进程已经加载了user32.dll,所以直接GetModuleHandle获取其句柄即可(但最好先判断dll是否加载,若没有加载使用LoadLibrary加载DLL)

MySetWindowTextW

BOOL WINAPI MySetWindowTextW(HWND hWnd, LPWSTR lpString)
{
wchar_t* pNum = L"零一二三四五六七八九";
wchar_t temp[2] = {0,};
int i = 0, nLen = 0, nIndex = 0; nLen = wcslen(lpString);
for(i = 0; i < nLen; i++)
{
// 阿拉伯数字转换为中文
if( L'0' <= lpString[i] && lpString[i] <= L'9' )
{
temp[0] = lpString[i];
nIndex = _wtoi(temp);
lpString[i] = pNum[nIndex];
}
} // 调用user32!SetWindowTextW(),参数为修改后的字符串缓冲区
return ((PFSETWINDOWTEXTW)g_pOrgFunc)(hWnd, lpString);
}

hook_iat

// hook_iat
// 修改IAT中的数据
// 将IAT中 pfnOrg 修改为 pfnNew
BOOL hook_iat(LPCSTR szDllName, PROC pfnOrg, PROC pfnNew)
{
HMODULE hMod;
LPCSTR szLibName;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PIMAGE_THUNK_DATA pThunk;
DWORD dwOldProtect, dwRVA;
PBYTE pAddr; // hMod, pAddr = ImageBase of calc.exe
// = VA to MZ signature (IMAGE_DOS_HEADER)
hMod = GetModuleHandle(NULL);
pAddr = (PBYTE)hMod; // pAddr = VA to PE signature (IMAGE_NT_HEADERS)
pAddr += *((DWORD*)&pAddr[0x3C]); // dwRVA = RVA to IMAGE_IMPORT_DESCRIPTOR Table
dwRVA = *((DWORD*)&pAddr[0x80]); // pImportDesc = VA to IMAGE_IMPORT_DESCRIPTOR Table
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hMod+dwRVA); // IMAGE_IMPORT_DESCRIPTOR[] 以空的IMAGE_IMPORT_DESCRIPTOR为结尾
for( ; pImportDesc->Name; pImportDesc++ )
{
// szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name
szLibName = (LPCSTR)((DWORD)hMod + pImportDesc->Name);
if( !_stricmp(szLibName, szDllName) )
{
// pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk
// = VA to IAT(Import Address Table)
pThunk = (PIMAGE_THUNK_DATA)((DWORD)hMod +
pImportDesc->FirstThunk); // pThunk->u1.Function = VA to API
// IAT Thunk 数组以空IAT Thunk为结尾
for( ; pThunk->u1.Function; pThunk++ )
{
if( pThunk->u1.Function == (DWORD)pfnOrg )
{
// 修改内存属性为 E R W
VirtualProtect((LPVOID)&pThunk->u1.Function,
4,
PAGE_EXECUTE_READWRITE,
&dwOldProtect); // 修改IAT值为新的函数地址
pThunk->u1.Function = (DWORD)pfnNew; // 恢复内存属性为只读
VirtualProtect((LPVOID)&pThunk->u1.Function,
4,
dwOldProtect,
&dwOldProtect); return TRUE;
}
}
}
} return FALSE;
}

IAT Hook的步骤如下:

calc.exe的ImageBase的地址 -> Image_Nt_Headers地址 -> Image_Import_Descriptor结构体组成的数组的起始地址(其中存储着DLL名称,IAT数组的起始地址)-> 通过DLL名称找到user32.dll对应的Image_Import_Descriptor -> 找到对应的IAT数组起始地址 -> 遍历IAT找到SetWindowTextW对应的条目,修改其值为MySetWindowTextW

IAT Hook的更多相关文章

  1. EAT/IAT Hook

    标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...

  2. ring3下的IAT HOOK

    标 题: [原创]ring3下的IAT HOOK作 者: hostzhen时 间: 2013-03-28,11:30:53链 接: http://bbs.pediy.com/showthread.ph ...

  3. IAT Hook 原理分析与代码编写

    Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...

  4. C++浅析——虚表和虚表Hook

    为了探究虚表的今生前世,先来一段测试代码 虚函数类: class CTest { public: int m_nData; virtual void PrintData() { printf(&quo ...

  5. hook研究结果备忘

    hook研究结果: 最近一周时间仔细研究了一下hook,也许不能称之为研究吧.顶多是让别人的思想拿过来抄袭一遍而已,写点结果也算对得起自己的这几天的苦心了. 1,首先从同事旁边听到了hook,然后看的 ...

  6. hook技术分类

    1.HOOK SERVICE TABLE:HOOK SSDT 这种方法对于拦截 NATIVE API 来说用的比较多. SSDT hook,一句话——Windows把需要调用的内核API地址全都存在了 ...

  7. XP下的进程静音技术(遍历进程,遍历输入模块,遍历输入函数,找到函数并HOOK) good

    很多浏览器有这种功能,实现原理都是一样.发声源基本都来自Flash,比如Flash游戏啦,视频播放器啦等等 而Flash的发声都是通过winmm.dll::waveOutWrite函数来完成,所以,我 ...

  8. 64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 )

    64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 ) [PS: 如果在64位系统下,出现调用测试demo,返回false的情况下,请修改Hook Dll的代码] glhH ...

  9. 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展

    [Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...

随机推荐

  1. Codeforces Round #458C DP

    C. Travelling Salesman and Special Numbers time limit per test 1 second memory limit per test 256 me ...

  2. [BZOJ2243][SDOI2011]染色(树链剖分)

    [传送门] 树链剖分就行了,注意线段树上颜色的合并 Code #include <cstdio> #include <algorithm> #define N 100010 # ...

  3. 陌生又熟悉的数据库之ID增加

    当我们设计一张表时,通常为了保证记录的唯一性,会为表增加一个ID字段,生成记录时ID自动加一

  4. 关于原生JS获取class,ID等属性的一些封装

    一.传统上获取是通过document.getElementById获取元素的ID属性,通过总结与学习总结一下获取元素class以及id属性的一些封装; 1.创建构造函数,这里面不需要多解释什么:(主要 ...

  5. Android面试收集录15 Android Bitmap压缩策略

    一.为什么Bitmap需要高效加载? 现在的高清大图,动辄就要好几M,而Android对单个应用所施加的内存限制,只有小几十M,如16M,这导致加载Bitmap的时候很容易出现内存溢出.如下异常信息, ...

  6. jQuery的Ajax初识

    1. 什么是Ajax? Ajax是“Asynchronous Javascript And XML(异步Javascript和XML)”的缩写, 是指一种创建交互式网页应用的网站开发技术. Ajax不 ...

  7. Java-JNA使用心得2

    自5月初第一次尝试使用Java封装调用C的dll之后,已经先后经历了3次小项目了. 上月末是最近的一次项目实际,任务来的急时间又少,还好在加班加点后还是完成了任务,并把第二次没有实现的功能给实现了(C ...

  8. 剑指Offer - 九度1510 - 替换空格

    剑指Offer - 九度1510 - 替换空格2013-11-29 20:53 题目描述: 请实现一个函数,将一个字符串中的空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之 ...

  9. python中subprocess.Popen执行命令并持续获取返回值

    先举一个Android查询连接设备的命令来看看Python中subprocess.Popen怎么样的写法.用到的命令为 adb devices. import subprocess order='ad ...

  10. HTML DOM简易学习笔记

    文字版:https://github.com/songzhenhua/github/blob/master/HTML DOM简易学习笔记.txt 学习地址:http://www.w3school.co ...