-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Kernel4.19 failed to read data using bpf_probe_read_user
`from bcc import BPF
BPF_CODE = """
#include <linux/ptrace.h>
struct probe_open_data_t {
u64 timestamp_ns;
u32 pid;
u32 tid;
u32 uid;
char pathname[256];
int flags;
};
BPF_PERCPU_ARRAY(open_data, struct probe_open_data_t, 1);
BPF_PERF_OUTPUT(perf_open);
// int open(const char* pathname, int flags, ...)
int probe_hook_open_enter(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = (u32)pid_tgid;
u32 uid = bpf_get_current_uid_gid();
u64 ts = bpf_ktime_get_ns();
PID_FILTER
TID_FILTER
UID_FILTER
char *pathname = (char *)PT_REGS_PARM1(ctx);
int flags = PT_REGS_PARM2(ctx);
u32 zero = 0;
struct probe_open_data_t *data = open_data.lookup(&zero);
if (!data)
return 0;
data->timestamp_ns = ts;
data->pid = pid;
data->tid = tid;
data->uid = uid;
data->flags = flags;
int ret = bpf_probe_read_user(data->pathname, sizeof(data->pathname), pathname);
perf_open.perf_submit(ctx, data, sizeof(struct probe_open_data_t));
return 0;
}
"""
class BPFHooker:
def __init__(self, library: str, uid: int, pid: int = -1, tid: int = -1) -> None:
self.uid = uid
self.pid = pid
self.tid = tid
self.library = library
self.bpf_module = None # type: BPF
def hook(self):
text = BPF_CODE
if self.pid > 0:
text = text.replace('PID_FILTER', f'if (pid != {self.pid}) {{ return 0; }}')
else:
text = text.replace('PID_FILTER', '')
if self.tid > 0:
text = text.replace('TID_FILTER', f'if (tid != {self.tid}) {{ return 0; }}')
else:
text = text.replace('TID_FILTER', '')
if self.uid > 0:
text = text.replace('UID_FILTER', f'if (uid != {self.uid}) {{ return 0; }}')
else:
text = text.replace('UID_FILTER', '')
self.bpf_module = BPF(text=text)
self.bpf_module.attach_uprobe(
name=self.library,
sym='open',
fn_name='probe_hook_open_enter',
pid=self.pid,
)
print('attach end')
def print_event(self, ctx, data, size):
event = self.bpf_module['perf_open'].event(data)
# print(f'[print_event] event => {event}')
# print(
# f'[open] {event.uid} {event.pid} {event.tid} '
# f'pathname: {event.pathname.decode("utf-8")} flags: {hex(event.flags)}'
# )
print(f'[open] {event.pathname.decode("utf-8")}')
def show(self):
self.bpf_module["perf_open"].open_perf_buffer(self.print_event)
while 1:
try:
self.bpf_module.perf_buffer_poll()
except KeyboardInterrupt:
exit()
def main():
uid = 0
library = "/apex/com.android.runtime/lib64/bionic/libc.so"
bpf_hooker = BPFHooker(library, uid)
bpf_hooker.hook()
bpf_hooker.show()
if name == 'main':
main()`
Output information as follows:
root@localhost:~/project/hookopen# python open.py
attach end
[open]
[open]
[open]
[open]
[open]
[open]
[open]
[open]
[open]