好在 , IT行业从来不缺造轮子的人 , 已经有不少优秀的开源项目将Inline HOOK封装成库 , 比如:Detours 。
除了直接修改函数的机器指令 , 还有一类HOOK , 它们修改的是某些重要的函数指针 , 从而达到劫持执行的目的 。
形形色色的函数指针 , 就衍生出各式各样的HOOK技术 。
IAT HOOK
一个程序的所有代码一般不会全部都编译到一个模块中 , 分拆到不同的模块既有利于合作开发 , 也有利于代码管理 , 降低耦合 。
动态链接库就提供了这样的能力 , 将不同的模块编译成一个个的动态库文件 , 在使用时引入调用 。
在Windows平台上 , 动态链接库一般以DLL文件的形式存在 , 主程序模块一般是EXE文件形式存在 。 无论是EXE还是DLL , 都是属于PE文件 。
一个模块引用了哪些模块的哪些函数 , 是被记录在PE文件的导入表IAT中 。 这个表格位于PE文件的头部 , 里面记录了模块的名字 , 函数的名字 。
在模块加载时 , 模块加载器将解析对应函数的实际地址 , 填入到导入表中 。
通过修改导入表IAT中函数的地址 , 这种HOOK叫IAT HOOK 。
SEH HOOK
SEH是Windows操作系统上结构化异常处理的缩写 , 在代码中通过try/except来捕获异常时 , 操作系统将会在线程的栈空间里安置一个异常处理器(其实就是一个数据结构) , 里面定义了发生异常时该去执行哪里的代码处理异常 。
异常处理可以多级嵌套 , 那多个异常处理就构成了一个链表 , 存在于栈空间之上 。

文章插图
当发生异常时 , 操作系统系统就从最近的异常处理器进行寻求处理 , 如果能处理则罢了 , 不能处理就继续寻求更上一级的异常处理器 , 直到找到能处理的异常处理器 。 如果都没法处理 , 那对不起 , 只好弹出那个经典的报错对话框 , 进程崩溃 。

文章插图
SEH HOOK针对的目标就是修改这些异常处理器中记录的函数指针 , 当异常发生时就能获得执行 , 从而劫持到执行流!因为这些异常处理器都位于线程的栈空间 , 修改起来并非难事 。
C++ virtable HOOK
C++是一门面向对象的编程语言 , 支持面向对象的三大特性:封装性、继承性、多态性 。
其中的多态性 , 各个C++编译器基本上都是通过一种叫虚函数表的机制来实现 。
下面通过一个实际的例子来感受一下虚函数表在C++多态性上发挥的作用 。
#include
using namespace std;
class Animal {
public:
virtual void breathe() {
cout << "Animal breathe" << endl;
}
virtual void eat() {
cout << "Animal eat" << endl;
}
};
class Fish : public Animal {
public:
virtual void breathe() {
cout << "Fish breathe" << endl;
}
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
