无法通过uprobe获取bash内置函数echo的参数,求解决方案
挂载bash内置echo函数uprobe无输出的问题解决
问题描述
使用Python BCC库编写BPF函数,尝试为bash内置函数echo_builtin挂载uprobe,但运行后仅输出空的trace信息,无法获取echo的参数:
原代码:
from bcc import BPF prog = """ #include<linux/sched.h> int echo_catch(struct pt_regs *ctx){ char command[64]={}; bpf_probe_read_user_str(command, sizeof(command), (char *) PT_REGS_PARM1(ctx)); bpf_trace_printk("%s", command); return 0; } """ b = BPF(text=prog) b.attach_uprobe(name="/bin/bash", sym="echo_builtin", fn_name="echo_catch") b.trace_print()
运行输出:
b' bash [001] 51239.033139: bpf_trace_printk:'
错误原因及修复方案
1. 对bash内置函数参数结构理解错误
bash的内置函数echo_builtin并非直接接收字符串参数,其原型为int echo_builtin(list *words),传入的第一个参数是list结构体指针,而非直接的字符串地址。list结构体用于存储shell命令的参数列表,结构大致如下(需匹配目标bash版本的实际定义):
struct word_desc { char *word; // 存储实际参数字符串 int flags; }; struct list { struct list *next; // 下一个参数节点 struct word_desc *word; // 当前参数的描述结构体 };
2. 修改BPF代码解析参数结构
需要先读取list结构体,再逐层解析出实际的参数字符串:
from bcc import BPF prog = """ #include <linux/sched.h> // 匹配bash的word_desc和list结构体定义 struct word_desc { char *word; int flags; }; struct list { struct list *next; struct word_desc *word; }; int echo_catch(struct pt_regs *ctx) { // 获取传入的参数列表指针 struct list *words = (struct list *)PT_REGS_PARM1(ctx); if (!words) return 0; struct word_desc *wd; // 读取第一个参数的word_desc指针 if (bpf_probe_read_user(&wd, sizeof(wd), &words->word) != 0) return 0; if (!wd) return 0; char arg[64] = {}; // 读取参数字符串 bpf_probe_read_user_str(arg, sizeof(arg), wd->word); bpf_trace_printk("echo arg: %s\\n", arg); return 0; } """ b = BPF(text=prog) b.attach_uprobe(name="/bin/bash", sym="echo_builtin", fn_name="echo_catch") b.trace_print()
3. 额外注意事项
- 确认
echo_builtin符号存在:执行nm /bin/bash | grep echo_builtin,若未找到符号,可能是bash编译时未保留符号表,需使用带调试符号的bash版本,或通过偏移量挂载uprobe。 - 适配bash版本:不同bash版本的
list和word_desc结构体可能存在字段差异,需参考对应版本的bash源码调整结构体定义。 - 运行权限:需以root权限执行脚本,否则无法挂载uprobe。
内容的提问来源于stack exchange,提问作者WKali
相关产品推荐
相关产品推荐

