IAT Hook
@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的更多相关文章
- EAT/IAT Hook
标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...
- ring3下的IAT HOOK
标 题: [原创]ring3下的IAT HOOK作 者: hostzhen时 间: 2013-03-28,11:30:53链 接: http://bbs.pediy.com/showthread.ph ...
- IAT Hook 原理分析与代码编写
Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...
- C++浅析——虚表和虚表Hook
为了探究虚表的今生前世,先来一段测试代码 虚函数类: class CTest { public: int m_nData; virtual void PrintData() { printf(&quo ...
- hook研究结果备忘
hook研究结果: 最近一周时间仔细研究了一下hook,也许不能称之为研究吧.顶多是让别人的思想拿过来抄袭一遍而已,写点结果也算对得起自己的这几天的苦心了. 1,首先从同事旁边听到了hook,然后看的 ...
- hook技术分类
1.HOOK SERVICE TABLE:HOOK SSDT 这种方法对于拦截 NATIVE API 来说用的比较多. SSDT hook,一句话——Windows把需要调用的内核API地址全都存在了 ...
- XP下的进程静音技术(遍历进程,遍历输入模块,遍历输入函数,找到函数并HOOK) good
很多浏览器有这种功能,实现原理都是一样.发声源基本都来自Flash,比如Flash游戏啦,视频播放器啦等等 而Flash的发声都是通过winmm.dll::waveOutWrite函数来完成,所以,我 ...
- 64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 )
64位下Hook NtOpenProcess的实现进程保护 + 源码 (升级篇 ) [PS: 如果在64位系统下,出现调用测试demo,返回false的情况下,请修改Hook Dll的代码] glhH ...
- 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展
[Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...
随机推荐
- 財務会計関連(FI&CO)
[財務会計伝票]FB01: 登録FB02: 伝票変更FB09: 明細変更FB03: 照会FB04: 変更履歴照会FB08: 反対仕訳FB05: 消込転記FB50: G/L勘定伝票一般転記FB1S: 勘 ...
- git回滚到指定commit
一次性commit好多文件,push上去之后,发现工程不可用,只能回滚,上网搜索回滚办法,下边这个是自己亲试的,特别好使: 操作步骤: 1.git checkout the_branch 2.git ...
- 2,Python常用库之二:Pandas
Pandas是用于数据操纵和分析,建立在Numpy之上的.Pandas为Python带来了两种新的数据结构:Pandas Series和Pandas DataFrame,借助这两种数据结构,我们能够轻 ...
- 编译ffmpeg
1.下载ffmpeg-0.9.2.tar.gz http://ffmpeg.org/releases/ 下载需要的版本 2.编译linux (centos5.5) 64位版本 ./configure ...
- php中utf-8转unicode
public function utf8_unicode($str) { $unicode = array(); $values = array(); $lookingFor = 1; for ($i ...
- SQL Server 分组取 Top 笔记(row_number + over 实现)
先看SQL语句(注意:这是在SQL Server 2005+ [包括2005] 的版本才支持的哦,o(∩_∩)o 哈哈~) SELECT col1,col2,col3 FROM table1 AS a ...
- cannot bind to 127.0.0.1:5037 报错
使用appium连接真机时,提示这个错误,找了很久,发现是端口被占用 打开cmd,netstat -nao查看当前的TCP连接,找到使用127.0.0.1:5037的代码,然后到任务管理器查看详细进程 ...
- 常用模块(random)
import randomimport string# dt = random.randint(1,2) # 从1-2间取随机数,包括1.2# dt = random.randrange(1,3) # ...
- 九 DIP 依赖倒置原则
首先看定义: 1.高层模块不依赖于低层模块,两者都应该依赖于抽象层 2.抽象不能依赖于细节,细节必须依赖于抽象 首先,模块是个抽象的概念,可以大到一个系统中的子系统作为一个模块,也可以是某个子系统中的 ...
- 重复造轮子系列--字符串处理(C语言)
这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...