linux hook各种方式

我目前已知的方式

1 )内核态:找到和替换系统调用表- syscall table  (如/proc/kallsyms,符号 kallsyms)

限制:

1只能替换/proc/kallsyms中有的,且自定义内核可能会修改这个符号。从而必须对每个系统内核进行详细适配。

2需要根据内核头重新编译

2 )内核态:通过找系统调用表和call的汇编和机器码替换函数内部调用地址,如patch_kernel

限制:

1非常规手段,且非常不稳定。

2需要根据内核头重新编译

3) 内核态:通过 ftrace hook有ftrace 插桩的函数比如各个导出过的函数,是内核提供的方式,所以比较稳定。

限制:

1只有内核源码插桩的受支持。

2需要根据内核头重新编译

4)内核态:通过ebpf 或者他的延申 bpftrace 等特殊脚本支持。

限制:

1只有内核源码插桩的受支持。

2性能可能不及上述。

5)应用态:通过内核态上述方式hook 系统调用表函数(ring 0级别):sys_open,sys_read  等,重定向 glibc ldconfig 的缓存配置(/etc/ld.so.preload)加载指定动态库。

限制:

1 比较依赖ld.so的实现。

2 需要内核态协助。

6)应用态:直接修改ld.so.preload文件加载。

限制:

1 比较依赖ld.so的实现。

2 容易和别的软件冲突。

3基本不具备安全性。

6)应用态:直接修改preload 的环境变量

限制:

1 比较依赖ld.so的实现。

2 容易和别的软件冲突。

3基本不具备安全性。

 

内核态共通限制:如果有返回值参数的修改后,会造成后续内核态函数使用这些值的时候,会有地址检查的问题。(已知多硬件架构的解决方法)