mozillazg / gobpf-examples

MIT License
1 stars 0 forks source link

do_fchmodat的系统调用第三个参数 umode_t mode,umode_t 是unsigned short,为什么data.mode = (__u32) mode;这里的mode是32长度? #2

Open Starryu opened 2 months ago

Starryu commented 2 months ago
SEC("kprobe/do_fchmodat")
int kprobe__do_fchmodat(struct pt_regs *ctx) {
        struct data_t data = {0};

        char *filename = (char *)PT_REGS_PARM2(ctx);
        unsigned int mode = PT_REGS_PARM3(ctx);

        bpf_probe_read(&data.file_name, sizeof(data.file_name), filename);

        data.mode = (__u32) mode;

        ...
}
mozillazg commented 2 months ago

@Starryu

data.mode = (__u32) mode

这里是因为 struct data_t 中 mode 定义的类型是 __u32 ,为什么要定义为 __u32,为了内存对齐方便在 go 程序中使用 cgo 进行数据转换。这里定义为 __u32 不是强制的,你也可以定义为 __u16

Starryu commented 2 months ago

@mozillazg 你好,我确实尝试过定义成u16,这样用户态解析出来func (e Event) modStr() string { return strconv.FormatUint(uint64(e.Mod), 2) }输出的结果就是HostPpid: 1910599, Comm: chmod, Mod: 111101101, File: test,Mod变成了(111)(101)(101)这样三个二进制数,但是为什么用u32解出来,就会 Comm: chmod, Mod: 755, File: test,就会变成十进制,我百思不得其解。

mozillazg commented 2 months ago

 func (e Event) modStr() string { return strconv.FormatUint(uint64(e.Mod), 2) }

是这个导致的问题,FormatUint 函数中第二个参数为 2 时,表示以二进制格式输出,所以输出成二进制数是预期的。 你按 8 进制去格式化输出的结果就会是我们常见的 8 进制格式,比如 0755strconv.FormatUint(uint64(event.Mode), 8)

Starryu commented 2 months ago

好的,不熟悉go的api,我理解错了,我以为这个是变量的大小。谢谢您的解答