收藏 分享(赏)

Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc

上传人:hwpkd79526 文档编号:9345489 上传时间:2019-08-02 格式:DOC 页数:7 大小:38KB
下载 相关 举报
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc_第1页
第1页 / 共7页
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc_第2页
第2页 / 共7页
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc_第3页
第3页 / 共7页
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc_第4页
第4页 / 共7页
Windows_Hook_易核心编程(3)_API_Hook_续_拦截API.doc_第5页
第5页 / 共7页
点击查看更多>>
资源描述

1、上一期,我们讲了用 HOOK技术实现远程线程插入,相信大家还记忆犹新.这一期我们来谈谈 API HOOKAPI Hook技术应用广泛,常用于屏幕取词,网络防火墙,病毒木马,加壳软件,串口红外通讯,游戏外挂,internet 通信等领域 API HOOK的中文意思就是钩住 API,对 API进行预处理,先执行我们的函数,例如我们用 API Hook技术挂接 ExitWindowsEx API函数,使关机失效,挂接 ZwOpenProcess函数,隐藏进程等等总的来说,常用的挂钩 API方法有以下两种: 改写 IAT导入表法我们知道,Windows 下的可执行文档的文件格式是一种叫 PE(“por

2、table executable” ,可移植 的可执行文件)的文件格式,这种文件格式是由微软设计的,接下来这张图描述了 PE文件的结构:+-+ - offset 0| MS DOS标志(“MZ“) 和 DOS 块 |+-+ | PE 标志 (“PE“) |+-+| .text | - 模块代码| 程序代码 | |+-+| .data | - 已初始化的(全局静态)数据| 已初始化的数据 | |+-+| .idata | - 导入函数的信息和数据| 导入表 | | |+-+| .edata | - 导出函数的信息和数据| 导出表 | | |+-+| 调试符号 |+-+这里对我们比较重要的是.id

3、ata 部分的导入地址表(IAT)。这个部分包含了导入的相关信息和导入函数的地址。有一点很重要的是我们必须知道 PE文件是如何创建的。当在编程语言里间接调用任意 API(这意味着我们是用函数的名字来调用它,而不是用它的地址),编译器并不直接把调用连接到模块,而是用 jmp指令连接调用到 IAT,IAT 在系统把进程调入内存时时会由进程载入器填满。这就是我们可以在两个不同版本的 Windows里使用相同的二进制代码的原因,虽然模块可能会加载到不同的地址。进程载入器会在程序代码里调用所使用的 IAT里填入直接跳转的 jmp指令。所以我们能在 IAT里找到我们想要挂钩的指定函数,我们就能很容易改变那

4、里的 jmp指令并重定向代码到我们的地址。完成之后每次调用都会执行我们的代码了。我们通过使用 imagehlp.dll里的 ImageDirectoryEntryToData来很容易地找到 IAT。.DLL命令 ImageDirectoryEntryToData, 整数型, “imagehlp“, , , 返回IMAGE_IMPORT_DESCRIPTOR数组的首地址.参数 Base, 整数型, , 模块句柄.参数 MappedAsImage, 逻辑型, , 真.参数 DirectoryEntry, 整数型, , 恒量:IMAGE_DIRECTORY_ENTRY_IMPORT,1.参数 Siz

5、e, 整数型, 传址, IMAGE_IMPORT_DESCRIPTOR 数组的大小.数据类型 IMAGE_IMPORT_DESCRIPTOR, , 输入描述结构.成员 OriginalFirstThunk, 整数型, , , 它是一个 RVA(32 位) ,指向一个以 0结尾的、由 IMAGE_THUNK_DATA(换长数据)的 RVA构成的数组,其每个 IMAGE_THUNK_DATA(换长数据)元素都描述一个函数。此数组永不改变。.成员 TimeDateStamp, 整数型, , , 它是一个具有好几个目的的 32位的时间日期戳.成员 ForwarderChain, 整数型, , , 它是

6、输入函数列表中第一个中转的、32 位的索引。.成员 Name, 整数型, , , 它是一个 DLL文件的名称(0 结尾的 ASCII码字符串)的、32位的 RVA。.成员 FirstThunk, 整数型, , , 它也是一个 RVA(32 位) ,指向一个 0结尾的、由IMAGE_THUNK_DATA(换长数据)的 RVA构成的数组,其每个 IMAGE_THUNK_DATA(换长数据)元素都描述一个函数。此数组是输入地址表的一部分,并且可以改变。如果我们找到了就必须用 VirtualProtectEx函数来改变内存页面的保护属性,然后就可以通过WriteProcessMemory在内存中的这些

7、部分写入代码了。在改写了地址之后我们要把保护属性改回来。在调用 VirtualProtectEx之前我们还要先知道有关页面的信息,这通过 VirtualQueryEx来实现。这种方法的好处是比较稳定,但有漏 API的可能,因为并不是所有的 API调用都是通过IAT的,可能易程序就是这种情况,我当初也是想用这种方法,但是在易里面调试时总不能在 IAT里得到正确的程序调用的 API,常常是些无关的 API(可能是易的核心支持库在做怪),不得不放弃.本来计划中是没有这一章的,但自从我的 Windows Hook 易核心编程(3) API Hook 发表以来,得到了广大易友的支持,这种情况很令我感动,

8、于是再接再力,写出了这章,希望没有辜负广大易友对我的支持与信任,好,废话不多说了,我们言归正转.在开始之前,让我们先来回顾一下:什么叫 Hook API?所谓 Hook就是钩子的意思,而 API是指 Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是一般的应用程序都需要调用 API来完成某些功能,Hook API的意思就是在这些应用程序调用真正的系统 API前可以先被截获,从而进行一些处理再调用真正的API来完成功能。在讲 Hook API之前先来看一下如何 Hook消息,例如 Hook全局键盘消息,从而可以知道用户按了哪些键.这种 Hook消息的功能可以由以

9、下函数来完成,该函数将一新的 Hook加入到原来的 Hook链中,当某一消息到达后会依次经过它的 Hook链再交给应用程序,这个在我的 Windows Hook 易核心编程(1)和(2)里有具体的说明和应用,大家可以看一看.DLL命令 api_SetWindowsHookExA, 整数型, , “SetWindowsHookExA“.参数 idHook, 整数型, , Hook 类型,例如 WH_KEYBOARD,WH_MOUSE.参数 lpfn, 子程序指针, , 钩子回调函数,Hook 处理过程函数的地址,.参数 nMod, 整数型, , 包含 Hook处理过程函数的 dll句柄(若在本进

10、程可以为NULL).参数 dwThreadID, 整数型, , 要 Hook的线程 ID,若为 0,表示全局 Hook所有.DLL命令 api_UnhookWindowsHookEx, 逻辑型, , “UnhookWindowsHookEx“.参数 hhook, 整数型,要关闭钩子的句柄.这里需要提一下的就是如果是 Hook全局的而不是某个特定的进程则需要将 Hook过程编写为一个DLL,以便让任何程序都可以加载它来获取 Hook过程函数。而对于 Hook API微软并没有提供直接的接口函数,也许它并不想让我们这样做,不过有 2种方法可以完成该功能。第一种,修改可执行文件的 IAT表(即输入表

11、) ,因为在该表中记录了所有调用 API的函数地址,则只需将这些地址改为自己函数的地址即可,但是这样有一个局限,因为有的程序会加壳,这样会隐藏真实的 IAT表,从而使该方法失效。第二种方法是直接跳转,改变 API函数的头几个字节,使程序跳转到自己的函数,然后恢复 API开头的几个字节,在调用 API完成功能后再改回来又能继续 Hook了,但是这种方法也有一个问题就是同步的问题,当然这是可以克服的,并且该方法不受程序加壳的限制。上一章我们就是用的第二种方法,通过直接改写 API函数 ExitWindowsEx入口点为195(即汇编的返回命令 retn),达到关机失效的目地,其实这不算是真正的 A

12、PI HOOK,没有实现自定 API函数的功能.记得我说过,如果要实现自定 API函数,可以写入一个跳转指令,JMP OX00000(其中 OX00000为自定 API函数地址),最后还给大家留了一道题,就是参照论坛上的教程写出自定 API函数的功能,不知道大家完成的什么样了,呵呵.其实,要真正实现 API HOOK,用 JMP OX00000是不能达到我们的目地的,因为要转移参数,我们先要mov eax OX00000 ,然后再 jmp eax,在易里面用用字节集连起来表示就是: 184 到字节集 (到整数 (.子程序 安装全局钩子, 整数型, , 安装全局消息钩子.参数 DLLPath,

13、文本型,DLL 名.局部变量 hMod, 整数型.局部变量 lpProc, 子程序指针hMod api_LoadLibraryA (DLLPath)lpProc api_GetProcAddress (hMod, “GetMsgProc”)hook api_SetWindowsHookExA (#WH_GETMESSAGE, lpProc, hMod, 0)返回 (hook)=主程序通过 api_UnhookWindowsHookEx(hook)就可以关闭全局钩子.结合下面的子程序(上期的 HOOK_API)便可以还原 API.=.子程序 还原 API.局部变量 i, 整数型.局部变量 结果,

14、 逻辑型.局部变量 进程信息, 进程信息输出, , “0“.局部变量 进程句柄, 整数型.局部变量 修改内容, 整数型刷新进程信息 (进程信息) 这个在上期中讲过,我就不重复了.计次循环首 (取数组成员数 (进程信息), i)进程句柄 打开进程 (2035711, 0, 进程信息 i.进程标识).如果真 (API_BAK 0 )结果 修改 API首地址 (进程句柄, API, API_BAK).如果真结束关闭内核对象 (进程句柄).计次循环尾 ()=可以看出,我们创建的 Hook类型是 WH_CALLWNDPROC类型,该类型的 Hook在进程与系统一通信时就会被加载到进程空间,从而调用 dl

15、l的初始化函数完成真正的 Hook,而在SetWindowsHookEx函数中指定的 HookProc函数将不作任何处理,只是调用 CallNextHookEx将消息交给 Hook链中下一个环节处理,因为这里 SetWindowsHookEx的唯一作用就是让进程加载我们的 dll。整个框架就是这样了,具体的就不在细说了.附件里有完整的易源码,大家可以下载下来研究.以上就是一个最简单的 Hook API的例子,该种技术可以完成许多功能。例如网游外挂制作过程中截取发送的与收到的封包(API 函数 send)即可使用该方法,或者也可以在 Hook到 API后加入木马功能,反向连接指定的主机或者监听某一端口,还有许多加壳也是用该原理来隐藏 IAT表,填入自己的函数地址,等等.希望本文能够对一些朋友有所帮助,当然,一定有许多不足之处,希望看了文章的高手可以指出:以下程序在 Windows XP +sp2和易 4.02中测试通过,有什么 Bug,请通知我.)

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报