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基本不具备安全性。
内核态共通限制:如果有返回值参数的修改后,会造成后续内核态函数使用这些值的时候,会有地址检查的问题。(已知多硬件架构的解决方法)