我阅读了这篇文章并学习了如何使用ftrace来挂钩Linux内核函数。
int fh_install_hook(struct ftrace_hook *hook)
{
err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
if (err) {
pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
return err;
}
err = register_ftrace_function(&hook->ops);
if (err) {
pr_debug("register_ftrace_function() failed: %d\n", err);
/* Don’t forget to turn off ftrace in case of an error. */
ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
return err;
}
return 0;
}
在一台机器上,多个程序可以使用这种方法来挂钩相同的linux内核函数吗?我测试钩子 sys_execve 但如果其他程序已经钩子 sys_execve,我会得到 register_ftrace_function 返回 -16。
返回代码-16通常对应于EBUSY,因此尝试处理竞争条件和冲突。 这是一种可能的解决方案
#include <linux/ftrace.h>
#include <linux/semaphore.h>
struct ftrace_hook {
// ... Define necessary fields for the hook
};
static DEFINE_MUTEX(hook_mutex); // Mutex for synchronization
int fh_install_hook(struct ftrace_hook *hook) {
int err;
mutex_lock(&hook_mutex); // Acquire mutex to synchronize
err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
if (err) {
pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
goto unlock;
}
err = register_ftrace_function(&hook->ops);
if (err) {
pr_debug("register_ftrace_function() failed: %d\n", err);
ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
goto unlock;
}
unlock:
mutex_unlock(&hook_mutex); // Release mutex
return err;
}
void fh_remove_hook(struct ftrace_hook *hook) {
// ... Similar to fh_install_hook, but unregister_ftrace_function
}
static int replacement_function(void) {
// ... Custom tracing logic
return 0;
}
int init_module(void) {
struct ftrace_hook my_hook = {
// ... Initialize the hook structure with appropriate values
.ops = {
.func = replacement_function,
.flags = FTRACE_OPS_FL_SAVE_REGS,
}
};
return fh_install_hook(&my_hook);
}
void cleanup_module(void) {
struct ftrace_hook my_hook = {
// ... Initialize the hook structure with appropriate values
.ops = {
.func = replacement_function,
.flags = FTRACE_OPS_FL_SAVE_REGS,
}
};
fh_remove_hook(&my_hook);
}