v0.1.1 testing backends (break a lot!)
- ptrace: parallel & v2 (daemon + seize) - bpf: not working - uprobe: not working
This commit is contained in:
parent
d43498b0bb
commit
50bd00b77b
14 changed files with 153726 additions and 143 deletions
5
bpf/make.sh
Executable file
5
bpf/make.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
INCDIR=/usr/include
|
||||
clang -O2 -g -target bpf \
|
||||
-D__TARGET_ARCH_arm64 \
|
||||
-I"$INCDIR" \
|
||||
-c sendrecv.bpf.c -o sendrecv.bpf.o
|
||||
150
bpf/sendrecv.bpf.c
Normal file
150
bpf/sendrecv.bpf.c
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
#include "vmlinux.h"
|
||||
#include <asm/types.h>
|
||||
|
||||
#include <linux/bpf_common.h>
|
||||
// #include <bpf/bpf.h>
|
||||
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
// Target: arm64 calling convention
|
||||
#ifndef __TARGET_ARCH_arm64
|
||||
# define __TARGET_ARCH_arm64
|
||||
#endif
|
||||
|
||||
#ifndef __PT_PARM1_REG
|
||||
struct user_pt_regs {
|
||||
__u64 regs[31];
|
||||
__u64 sp;
|
||||
__u64 pc;
|
||||
__u64 pstate;
|
||||
};
|
||||
#define __PT_PARM1_REG regs[0]
|
||||
#define __PT_PARM2_REG regs[1]
|
||||
#define __PT_PARM3_REG regs[2]
|
||||
#define __PT_PARM4_REG regs[3]
|
||||
#define __PT_PARM5_REG regs[4]
|
||||
#define __PT_PARM6_REG regs[5]
|
||||
#define __PT_RC_REG regs[0]
|
||||
#endif
|
||||
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
|
||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
||||
|
||||
#define MAX_PEEK 256
|
||||
|
||||
struct call_ctx {
|
||||
uint64_t buf;
|
||||
uint64_t len;
|
||||
uint32_t is_send; // 1=send/write, 0=recv/read
|
||||
};
|
||||
|
||||
struct event {
|
||||
uint32_t pid, tid;
|
||||
uint32_t is_send;
|
||||
uint32_t len;
|
||||
uint8_t data[MAX_PEEK];
|
||||
};
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__type(key, uint32_t); // tid
|
||||
__type(value, struct call_ctx);
|
||||
__uint(max_entries, 8192);
|
||||
} in_flight SEC(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||
__uint(max_entries, 1 << 22);
|
||||
} rb SEC(".maps");
|
||||
|
||||
// helpers
|
||||
static __always_inline void save_ctx(uint32_t tid, uint64_t buf, uint64_t len, uint32_t is_send) {
|
||||
struct call_ctx ctx = {.buf = buf, .len = len, .is_send = is_send};
|
||||
bpf_map_update_elem(&in_flight, &tid, &ctx, BPF_ANY);
|
||||
}
|
||||
|
||||
static __always_inline int emit_ret(uint32_t tid, int64_t ret, uint32_t is_send) {
|
||||
struct call_ctx *ctx = bpf_map_lookup_elem(&in_flight, &tid);
|
||||
if (!ctx) return 0;
|
||||
if (ret <= 0) { bpf_map_delete_elem(&in_flight, &tid); return 0; }
|
||||
|
||||
uint64_t want = ctx->len < (unsigned long)ret ? ctx->len : (unsigned long)ret;
|
||||
if (want > MAX_PEEK) want = MAX_PEEK;
|
||||
|
||||
struct event *e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
|
||||
if (!e) { bpf_map_delete_elem(&in_flight, &tid); return 0; }
|
||||
e->pid = bpf_get_current_pid_tgid() >> 32;
|
||||
e->tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
e->is_send = is_send;
|
||||
e->len = (uint32_t)want;
|
||||
|
||||
if (want > 0 && ctx->buf) {
|
||||
bpf_probe_read_user(e->data, want, (void*)ctx->buf);
|
||||
}
|
||||
|
||||
bpf_ringbuf_submit(e, 0);
|
||||
bpf_map_delete_elem(&in_flight, &tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---- send/write entry (x1 = buf, x2 = len)
|
||||
SEC("uprobe/libc_send")
|
||||
int BPF_KPROBE(up_send) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
uint64_t buf = PT_REGS_PARM2(ctx);
|
||||
uint64_t len = PT_REGS_PARM3(ctx);
|
||||
save_ctx(tid, buf, len, 1);
|
||||
return 0;
|
||||
}
|
||||
SEC("uretprobe/libc_send")
|
||||
int BPF_KRETPROBE(ur_send) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
return emit_ret(tid, PT_REGS_RC(ctx), 1);
|
||||
}
|
||||
|
||||
// write(int fd, const void *buf, size_t count)
|
||||
SEC("uprobe/libc_write")
|
||||
int BPF_KPROBE(up_write) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
uint64_t buf = PT_REGS_PARM2(ctx);
|
||||
uint64_t len = PT_REGS_PARM3(ctx);
|
||||
save_ctx(tid, buf, len, 1);
|
||||
return 0;
|
||||
}
|
||||
SEC("uretprobe/libc_write")
|
||||
int BPF_KRETPROBE(ur_write) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
return emit_ret(tid, PT_REGS_RC(ctx), 1);
|
||||
}
|
||||
|
||||
// ---- recv/read entry (x1 = buf, x2 = len)
|
||||
SEC("uprobe/libc_recv")
|
||||
int BPF_KPROBE(up_recv) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
uint64_t buf = PT_REGS_PARM2(ctx);
|
||||
uint64_t len = PT_REGS_PARM3(ctx);
|
||||
save_ctx(tid, buf, len, 0);
|
||||
return 0;
|
||||
}
|
||||
SEC("uretprobe/libc_recv")
|
||||
int BPF_KRETPROBE(ur_recv) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
return emit_ret(tid, PT_REGS_RC(ctx), 0);
|
||||
}
|
||||
|
||||
// read(int fd, void *buf, size_t count)
|
||||
SEC("uprobe/libc_read")
|
||||
int BPF_KPROBE(up_read) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
uint64_t buf = PT_REGS_PARM2(ctx);
|
||||
uint64_t len = PT_REGS_PARM3(ctx);
|
||||
save_ctx(tid, buf, len, 0);
|
||||
return 0;
|
||||
}
|
||||
SEC("uretprobe/libc_read")
|
||||
int BPF_KRETPROBE(ur_read) {
|
||||
uint32_t tid = (uint32_t)bpf_get_current_pid_tgid();
|
||||
return emit_ret(tid, PT_REGS_RC(ctx), 0);
|
||||
}
|
||||
150324
bpf/vmlinux.h
Normal file
150324
bpf/vmlinux.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue