标 题: 【原创】ring3下的IAT HOOK
作 者: hostzhen
时 间:
2013-03-28,11:30:53
链 接:
http://bbs.pediy.com/showthread.php?t=166993

IAT hooking
当应用程序使用另一个动态库的函数时,PE装载器会找到每个IAMGE_IMPORT_BY_NAME结构所指向的输入函数的地址,然后把这些地址存储在一个叫做IAT的表。当函数CALL一个输入函数的时候,会先在IAT找到对应的函数地址,紧接着再进入该函数空间。熟悉PE结构的朋友应该清楚,IAT是一个IMAGE_THUNK_DATAj结构的数组。只要程序装载进内存中,就只与IAT查询信息,所以可见IAT表是一个非常重要的位置。
如果在IAT表中把某个函数的地址修改为钩子函数的地址,当调用到函数的时候,就会执行到该钩子函数中去。示例代码如下:
钩子函数,这里只是简单的弹出个窗口:

代码:
int
WINAPI
MyMessageBoxW(
/* __in_opt HWND hWnd,
__in_opt LPCWSTR lpText,
__in_opt LPCWSTR lpCaption,
__in UINT uType*/)
{
//todo yourself
return MessageBox(NULL, "hello world", "caption", MB_OK);
}

ROOKIT函数,获取目标函数的地址,然后调用IAT HOOK函数ImportAddressTableHook,修改IAT表的值。

代码:
BOOL Rookits
(
IN HMODULE hModule,
IN LPCTSTR pImageName,
IN LPCTSTR pTargetFuncName
)
{
LPDWORD pTargetFuncAddr = NULL;
HMODULE hLib = LoadLibrary(pImageName);
if (NULL != hLib)
{
pTargetFuncAddr = (LPDWORD)GetProcAddress(hLib, pTargetFuncName);
return ImportAddressTableHook(hModule, pImageName, pTargetFuncAddr, MyMessageBoxW);
} return FALSE;
}

修改IAT表的函数,通过所在模块的基地址hModule找到输入表的数据目录项,获取IAT的首指针,查询目标函数地址所在的位置,然后修改为钩子函数的地址。

代码:
BOOL ImportAddressTableHook
(
IN HMODULE hModule,
IN LPCTSTR pImageName,
IN LPCVOID pTargetFuncAddr,
IN LPCVOID pReplaceFuncAddr
)
{
IMAGE_DOS_HEADER* pImageDosHearder = (IMAGE_DOS_HEADER*)hModule;
IMAGE_OPTIONAL_HEADER* pImageOptionalHeader = (IMAGE_OPTIONAL_HEADER*)((DWORD)hModule+pImageDosHearder->e_lfanew+);
IMAGE_IMPORT_DESCRIPTOR* pImageImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*)
((DWORD)hModule+
pImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
IMAGE_THUNK_DATA* pImageThunkData = NULL;
string TargetLibraryName;
DWORD Value = , OldProtect = , NewProtect = ;
LPDWORD FunctionAddress = NULL;
MEMORY_BASIC_INFORMATION InforMation; while(pImageImportDescriptor->Characteristics != )
{
TargetLibraryName=(LPCTSTR)((DWORD)hModule+pImageImportDescriptor->Name);
if(TargetLibraryName.compare(pImageName) == )
{
pImageThunkData = (IMAGE_THUNK_DATA*)((DWORD)hModule + pImageImportDescriptor->FirstThunk);
break;
}
pImageImportDescriptor++;
}
if (pImageThunkData == NULL)
{
return FALSE;
}
while(pImageThunkData->u1.Function)
{
//循环查找目标函数地址所在的位置
FunctionAddress = (LPDWORD)&(pImageThunkData->u1.Function);
if(*FunctionAddress == (DWORD)pTargetFuncAddr)
{
//找到目标函数的地址,然后修改为钩子函数的地址
VirtualProtect(FunctionAddress, sizeof(DWORD), PAGE_READWRITE, &OldProtect);
if(!WriteProcessMemory((HANDLE)-, FunctionAddress, &pReplaceFuncAddr, , NULL))
{
return FALSE;
}
VirtualProtect(FunctionAddress, sizeof(DWORD), OldProtect, NewProtect );
return TRUE;
}
pImageThunkData++;
}
return FALSE;
}

也许你会注意到,如果使用了延迟装入数据,那么示例代码是无效的,因为程序会使用___delayLoadHelper2来加载,具体代码可在delayhlp.cpp查看,里面直接GetProcAddress获取该函数地址,对于这种情况只能再HOOK多一个函数,即GetProcAddress。
___delayLoadHelper2代码片段:

代码:
// Go for the procedure now.
//
dli.hmodCur = hmod;
if (__pfnDliNotifyHook2) {
pfnRet = (*__pfnDliNotifyHook2)(dliNotePreGetProcAddress, &dli);
}
if (pfnRet == ) {
if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
// bound imports exist...check the timestamp from the target image
//
PIMAGE_NT_HEADERS pinh(PinhFromImageBase(hmod)); if (pinh->Signature == IMAGE_NT_SIGNATURE &&
TimeStampOfImage(pinh) == idd.dwTimeStamp &&
FLoadedAtPreferredAddress(pinh, hmod)) { // Everything is good to go, if we have a decent address
// in the bound IAT!
//
pfnRet = FARPROC(UINT_PTR(idd.pBoundIAT[iIAT].u1.Function));
if (pfnRet != ) {
goto SetEntryHookBypass;
}
}
} pfnRet = ::GetProcAddress(hmod, dli.dlp.szProcName);
}

ring3下的IAT HOOK的更多相关文章

  1. IAT Hook

    @author: dlive 0X01 IAT Hook的优缺点 优点:工作原理与实现都比较简单 缺点:如果想钩取的API不在目标进程的IAT中,那么就无法使用该技术进行钩取操作.即如果要钩取的API ...

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

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

  3. EAT/IAT Hook

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

  4. Ring3下干净的强行删除文件

    在某公司实习完,再次回到寝室.还是在学校好. 实习期间的给我的任务就是为项目添加一个强行删除的模块. 背景是硬盘上存储空间不够时,需要删掉老的文件,如果这时后,老的文件被打开了,没有关掉,就无法删除. ...

  5. x64下进程保护HOOK

    目录 x64(32)下的进程保护回调. 一丶进程保护线程保护 1.简介以及原理 1.2 代码 1.3注意的问题 二丶丶回调函数写法 2.1 遇到的问题. 2.2 回调代码 x64(32)下的进程保护回 ...

  6. X86 下的SSDT HOOK

    目录 SSDTHOOK 1.SSDTHOOK 原理. 1.x32下的SSDT HOOK 2.SSDT HOOK代码 3.结果 4.总结 SSDTHOOK 1.SSDTHOOK 原理. x32下,直接获 ...

  7. ART模式下基于Xposed Hook开发脱壳工具

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78092365 Dalvik模式下的Android加固技术已经很成熟了,Dalvik ...

  8. 基于dalvik模式下的Xposed Hook开发的某加固脱壳工具

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77966109 这段时间好好的学习了一下Android加固相关的知识和流程也大致把A ...

  9. Ring3下Hook NtQueryDirectoryFile隐藏文件

    NTSTATUS WINAPI Hook_NtQueryDirectoryFile(IN HANDLE FileHandle,IN HANDLE Event OPTIONAL,IN PIO_APC_R ...

随机推荐

  1. css3实现切片动画

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta http- ...

  2. bat语法集【转】

    源文链接:http://www.cnblogs.com/jiangzhichao/archive/2012/02/15/2353004.html 1 echo 和 @@                 ...

  3. WordPaster-UEditor1.x整合教程

    版权所有 2009-2017 荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webplug/wordpa ...

  4. 2.3.1关键字volatile与死循环

    关键字volatile的主要作用是使变量在多个线程间可见. 测试如下 package com.cky.test; /** * Created by edison on 2017/12/9. */ pu ...

  5. 1.8.2suspend与resume方法的缺点-独占

    这两个方法使用不当,容易造成公共的同步对象的独占,使得其他线程无法访问公共的同步对象 测试 package com.cky.bean; /** * Created by edison on 2017/ ...

  6. mac终端的命令都失效的解决方法

    step1. 在terminal里面输入: export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin&qu ...

  7. hdu 4704 Sum 【费马小定理】

    题目 题意:将N拆分成1-n个数,问有多少种组成方法. 例如:N=4,将N拆分成1个数,结果就是4:将N拆分成2个数,结果就是3(即:1+3,2+2,3+1)--1+3和3+1这个算两个,则这个就是组 ...

  8. hdu 5087 次长升序串的长度

    http://acm.hdu.edu.cn/showproblem.php?pid=5087 求数列次长升序串的长度 还是dp求最长升序串的长度,再开一个数组记录对于dp值的串的个数 最后看一下最长字 ...

  9. hdu 5056 所有字母数都<=k的子串数目

    <a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=5056" style="font ...

  10. hdu 1.3.4 shǎ崽 OrOrOrOrz

    简单的排序,注意输出即可 #include <iostream> #include <algorithm> using namespace std; int main() { ...