导出表钩子------EAT HOOK(转)
来源:互联网 发布:对对子软件在线 编辑:程序博客网 时间:2024/05/02 06:11
标 题: 【原创】导出表钩子------EAT HOOK
作 者: Sysnap
时 间: 2008-04-05,17:13:48
链 接: http://bbs.pediy.com/showthread.php?t=62574
看了combojiang大侠的rootkit专题,发现少了一个导出表钩子,既EAT;HOOK,刚好前几天自己搞了个IAT HOOK,然后就把其中的代码稍做修改,于是有这篇文章,
偶学的东西不久,很多东西还不知道,请多指教,呵呵
导出表钩子比导入表钩子感觉好用多,先说下原理吧,函数导入的函数的地址是再运行时候才确定的,比如我们的一个驱动程序导入了PsGetCurrentProcessId这个ntkrnlpa.exe
导出的函数,那在我们驱动程序加载运行的时候,装载程序会确定ntkrnlpa.exe在内存的基地址,接着遍历它的导出表,在AddressOfNames指向的"函数名字表"中找到
PsGetCurrentProcessId的位置,也就是如果在AddressOfNames[i]中找到PsGetCurrentProcessId,那就用i在AddressOfNameOrdinals中索引,假使得到是X,那么
AddressOfFunctions[index]的值就是PsGetCurrentProcessId的RVA了,最后就可以知道PsGetCurrentProcessId在内存的值是MM=ntkrnlpa.exe在内存的基地址
+PsGetCurrentProcessId的RVA,然后转载程序就把这个值写到我们驱动程序的IAT中,好了知道这些后,EAT HOOK就是修改PsGetCurrentProcessId的RVA,使得
PsGetCurrentProcessId的RVA(修改后的)+ntkrnlpa.exe在内存的基地址=我们自己函数的值,这样装载程序会把我们的函数的地址写入那些调用PsGetCurrentProcessId
的驱动程序的IAT,那么当那些驱动程序调用PsGetCurrentProcessId时,实际上是执行了我们自己的函数...呵呵.是不是比IAT HOOK更好用呢
EAT HOOK可以用来监控系统函数的调用情况,比如我们EAT HOOK了
PsGetCurrentProcessId,那谁调用该函数我们就知道了,你也可以HOOK KeInitializeApc等热门函数,其实知道了EAT HOOK原理后,我们
可以修改函数名字表,比如把PsGetCurrentProcessId改成其它名字,这样装载程序遍历"函
数名字表"就找不到匹对的名字,那驱动程序就宣告装载失败,详细代码请看
<<利用导出表来禁止一些驱动程序的加载>>http://bbs.pediy.com/showthread.php?t=62531
那怎么防止EAT HOOK,一个方法是自己定位函数在内存地址,请看下面的代码,用于枚举
ntkrnlpa.exe导出函数在内存的地址
运行后:
未命名.jpg下载此附件需要消耗2Kx,下载中会自动扣除。
--------------------
--------------
-----------------
---------------------
好了,讲了这么多时候进去正题,怎样EAT HOOK,这里我们以HOOK ntkrnlpa.exe导出的
PsGetCurrentProcessId
首先我们是定位ntkrnlpa.exe被加载在内存中的什么地方,那就写一个函数吧,
自己添加点测试代码编译下,没什么问题,这样我们就完成了第一个问题
接着是写自己的函数了,就是替换PsGetCurrentProcessId的函数,这里我们很简单的输
出点内容就可以了
好了,那就开始写安装钩子程序吧,因为在卸在钩子时需要用到一些变量,这里我们就把安
装和卸载写成一个函数就可以了,注意IN unsigned int test,传入1表示安装钩子,否则表
示卸载,IN PCSTR funName这里我们传入PsGetCurrentProcessId,好了请看代码
好了,基本框架就差不多了,接着就是一些结构的声明,我们把它放在hookiat.h这个头文件
里,因为很长就不帖了,可以在附件里看,上面的代码很多地方不是很好,需要自己修改,不
保证在你机器不蓝,呵呵,学习靠思考,在代码里我修改了一处地方
作 者: Sysnap
时 间: 2008-04-05,17:13:48
链 接: http://bbs.pediy.com/showthread.php?t=62574
看了combojiang大侠的rootkit专题,发现少了一个导出表钩子,既EAT;HOOK,刚好前几天自己搞了个IAT HOOK,然后就把其中的代码稍做修改,于是有这篇文章,
偶学的东西不久,很多东西还不知道,请多指教,呵呵
导出表钩子比导入表钩子感觉好用多,先说下原理吧,函数导入的函数的地址是再运行时候才确定的,比如我们的一个驱动程序导入了PsGetCurrentProcessId这个ntkrnlpa.exe
导出的函数,那在我们驱动程序加载运行的时候,装载程序会确定ntkrnlpa.exe在内存的基地址,接着遍历它的导出表,在AddressOfNames指向的"函数名字表"中找到
PsGetCurrentProcessId的位置,也就是如果在AddressOfNames[i]中找到PsGetCurrentProcessId,那就用i在AddressOfNameOrdinals中索引,假使得到是X,那么
AddressOfFunctions[index]的值就是PsGetCurrentProcessId的RVA了,最后就可以知道PsGetCurrentProcessId在内存的值是MM=ntkrnlpa.exe在内存的基地址
+PsGetCurrentProcessId的RVA,然后转载程序就把这个值写到我们驱动程序的IAT中,好了知道这些后,EAT HOOK就是修改PsGetCurrentProcessId的RVA,使得
PsGetCurrentProcessId的RVA(修改后的)+ntkrnlpa.exe在内存的基地址=我们自己函数的值,这样装载程序会把我们的函数的地址写入那些调用PsGetCurrentProcessId
的驱动程序的IAT,那么当那些驱动程序调用PsGetCurrentProcessId时,实际上是执行了我们自己的函数...呵呵.是不是比IAT HOOK更好用呢
EAT HOOK可以用来监控系统函数的调用情况,比如我们EAT HOOK了
PsGetCurrentProcessId,那谁调用该函数我们就知道了,你也可以HOOK KeInitializeApc等热门函数,其实知道了EAT HOOK原理后,我们
可以修改函数名字表,比如把PsGetCurrentProcessId改成其它名字,这样装载程序遍历"函
数名字表"就找不到匹对的名字,那驱动程序就宣告装载失败,详细代码请看
<<利用导出表来禁止一些驱动程序的加载>>http://bbs.pediy.com/showthread.php?t=62531
那怎么防止EAT HOOK,一个方法是自己定位函数在内存地址,请看下面的代码,用于枚举
ntkrnlpa.exe导出函数在内存的地址
{ HANDLE hMod; PVOID BaseAddress = NULL; IMAGE_DOS_HEADER * dosheader; IMAGE_OPTIONAL_HEADER * opthdr; PIMAGE_EXPORT_DIRECTORY exports; USHORT index=0 ; ULONG addr, i; PVOID FuncNameRVA; PUCHAR pFuncName = NULL; PULONG pAddressOfFunctions,pAddressOfNames,pAddressOfNameOrdinals; BaseAddress= GetDriverBaseAdress("ntkrnlpa.exe"); DbgPrint("Map BaseAddress is:%x\n",BaseAddress); hMod = BaseAddress; dosheader = (IMAGE_DOS_HEADER *)hMod; opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24); exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions); pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames); pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals); for (i = 0; i < exports->NumberOfNames; i++) { index=pAddressOfNameOrdinals[i]; addr=pAddressOfFunctions[index]; pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]); addr = pAddressOfFunctions[index]; DbgPrint("the function: %s is at: 0x%x\n",pFuncName,addr+(BYTE*)hMod); }
运行后:
未命名.jpg下载此附件需要消耗2Kx,下载中会自动扣除。
--------------------
--------------
-----------------
---------------------
好了,讲了这么多时候进去正题,怎样EAT HOOK,这里我们以HOOK ntkrnlpa.exe导出的
PsGetCurrentProcessId
首先我们是定位ntkrnlpa.exe被加载在内存中的什么地方,那就写一个函数吧,
PVOID GetModlueBaseAdress(char* ModlueName){ ULONG size,index; PULONG buf;NTSTATUS status; PSYSTEM_MODULE_INFORMATION module; PVOID driverAddress=0; ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size))) { DbgPrint("failed alloc memory failed \n"); return 0; }status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0); if(!NT_SUCCESS( status )) {DbgPrint("failed query\n"); return 0; }module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1); for (index = 0; index < *buf; index++) if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0) {driverAddress = module[index].Base;DbgPrint("Module found at:%x\n",driverAddress); } ExFreePool(buf); return driverAddress;}
自己添加点测试代码编译下,没什么问题,这样我们就完成了第一个问题
接着是写自己的函数了,就是替换PsGetCurrentProcessId的函数,这里我们很简单的输
出点内容就可以了
ULONG g_OriginalPsGetCurrentProcessId;typedef HANDLE (*PSGETCURRENTPROCESSID)(); HANDLEMyPsGetCurrentProcessId() { HANDLE handle; DbgPrint("HOOK_PsGetCurrentProcessId called!\n");handle =((PSGETCURRENTPROCESSID)(g_OriginalPsGetCurrentProcessId))();return handle; }
好了,那就开始写安装钩子程序吧,因为在卸在钩子时需要用到一些变量,这里我们就把安
装和卸载写成一个函数就可以了,注意IN unsigned int test,传入1表示安装钩子,否则表
示卸载,IN PCSTR funName这里我们传入PsGetCurrentProcessId,好了请看代码
VOID StartHook_And_Unhook(IN PCSTR funName, IN unsigned int test) { HANDLE hMod; PUCHAR BaseAddress = NULL; IMAGE_DOS_HEADER * dosheader; IMAGE_OPTIONAL_HEADER * opthdr; PIMAGE_EXPORT_DIRECTORY exports; USHORT index=0 ; ULONG addr ,i; PUCHAR pFuncName = NULL; PULONG pAddressOfFunctions,pAddressOfNames; PUSHORT pAddressOfNameOrdinals; BaseAddress= GetModlueBaseAdress("ntkrnlpa.exe"); DbgPrint("Map BaseAddress is:%x\n",BaseAddress); hMod = BaseAddress; dosheader = (IMAGE_DOS_HEADER *)hMod; opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24); exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions); pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames); pAddressOfNameOrdinals=(USHORT*)((BYTE*)hMod+exports->AddressOfNameOrdinals); for (i = 0; i < exports->NumberOfNames; i++) { index=pAddressOfNameOrdinals[i]; pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]); if (_stricmp( (char*)pFuncName,funName) == 0){ addr=pAddressOfFunctions[index]; break;} } if(test==1) { _asm { CLI MOV EAX, CR0 AND EAX, NOT 10000H MOV CR0, EAX } DbgPrint("PsGetCurrentProcessId is:%x\n",(PUCHAR)hMod + pAddressOfFunctions[index]); pAddressOfFunctions[index] = ( PCHAR )MyPsGetCurrentProcessId - BaseAddress; DbgPrint("g_OriginalPsGetCurrentProcessId is:%x\n",g_OriginalPsGetCurrentProcessId); g_OriginalPsGetCurrentProcessId= (PUCHAR)hMod + pAddressOfFunctions[index] ;_asm { MOV EAX, CR0 OR EAX, 10000H MOV CR0, EAX STI } } else {_asm { CLI MOV EAX, CR0 AND EAX, NOT 10000H MOV CR0, EAX } pAddressOfFunctions[index] = ( PCHAR )g_OriginalPsGetCurrentProcessId - BaseAddress; _asm { MOV EAX, CR0 OR EAX, 10000H MOV CR0, EAX STI } } }
好了,基本框架就差不多了,接着就是一些结构的声明,我们把它放在hookiat.h这个头文件
里,因为很长就不帖了,可以在附件里看,上面的代码很多地方不是很好,需要自己修改,不
保证在你机器不蓝,呵呵,学习靠思考,在代码里我修改了一处地方
- 导出表钩子------EAT HOOK(转)
- 导出表钩子------EAT HOOK
- 【原创】导出表钩子------EAT HOOK
- hook_导出表eat
- C++ EAT / Hook
- [转]PHP hook钩子类
- IAT HOOK、EAT HOOK和Inline Hook
- 钩子(Hook)
- hook(钩子)
- 钩子HOOK
- 钩子(hook)
- 钩子HOOK
- 钩子HOOK
- 钩子(Hook)
- 钩子 (Hook) Hook解释
- Windows Hook钩子机制及键盘钩子实例(转)
- rootkit hook 之[八]------EAT HOOK
- Dll导出表Hook
- myeclipse学习笔记
- Java设计模式Proxy之动态代理
- 天冷了多加衣服哈!
- Android软件去广告教程
- 使用pgrouting2.0求最短路径
- 导出表钩子------EAT HOOK(转)
- JAVA的Split小技巧
- win7中右击“计算机”点“管理” 则出现“该文件没有与之关联的程序来执行操作。请安装一个程序,或者,如果已安装程序,请在‘默认程序’控制面板中创建关联。”
- Linux c字符串拷贝函数
- 关于java中bufferedreader的一些注意事项
- 互联网思维到底是什么?
- tcmalloc for arm
- UIScrollView代理方法的实现
- C指针