我有我正在嘗試做的這個 ebpf 程式。基本上,我正在捕獲recvfrom函式呼叫并嘗試將我的recvfrom緩沖區共享給我的用戶空間應用程式。這是代碼:
SEC("kprobe/__x64_sys_recvfrom")
int bpf_prog1(struct pt_regs *ctx,int fd, const char *buf, size_t count)
{
struct S {
int pid;
char cookie[90];
} data={1,""};
//data.pid =count;// bpf_get_current_pid_tgid();
//if(buf==NULL)
// memcpy(data.cookie,buf,20);
// data.cookie[0]=buf[0];
bpf_get_current_comm(&data.cookie, sizeof(data.cookie));
int i=0;
bpf_perf_event_output(ctx, &my_map, 1, &data, sizeof(data));
return 0;
}
因此,似乎我有簽名,bpf_prog function并且在其中,我有recvfrom函式的緩沖區,但是當我嘗試訪問它時,我根本無法訪問它,因為我的程式正在加載抱怨。
root@this:/home/ubuntu/Desktop/ebpf/Linux-exFilter-main/pkg/probe/bpf# ./trace
libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---
libbpf:
R1 type=ctx expected=fp
; int bpf_prog1(struct pt_regs *ctx,int fd, const char *buf, size_t count)
0: (bf) r6 = r1
1: (b7) r1 = 0
; } data={1,""};
2: (7b) *(u64 *)(r10 -8) = r1
last_idx 2 first_idx 0
regs=2 stack=0 before 1: (b7) r1 = 0
3: (7b) *(u64 *)(r10 -16) = r1
4: (7b) *(u64 *)(r10 -24) = r1
5: (7b) *(u64 *)(r10 -32) = r1
6: (7b) *(u64 *)(r10 -40) = r1
7: (7b) *(u64 *)(r10 -48) = r1
8: (7b) *(u64 *)(r10 -56) = r1
9: (7b) *(u64 *)(r10 -64) = r1
10: (7b) *(u64 *)(r10 -72) = r1
11: (b7) r1 = 1
12: (63) *(u32 *)(r10 -96) = r1
; memcpy(data.cookie,buf,20);
13: (71) r4 = *(u8 *)(r3 1)
R3 !read_ok
processed 14 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
libbpf: -- END LOG --
libbpf: failed to load program 'bpf_prog1'
libbpf: failed to load object './kprobe_send.o'
ERROR: loading BPF object file failed
并且有一個類似bpf_get_current_comm(&data.cookie, sizeof(data.cookie));和bpf_perf_event_output(ctx, &my_map, 1, &data, sizeof(data));使用這些函式的函式給我垃圾資料。所以我想知道如何讀取ebpf程式中的函式引數。有沒有什么傳統的做法
我知道 ebpf 有地圖,地圖用于在 ebpf 程式和用戶空間應用程式之間共享資訊。共享引數是一個基本的東西,但我不知道為什么我沒有在網上看到它
uj5u.com熱心網友回復:
在這種情況下,您可以recvfrom使用PT_REGS_PARM 宏讀取 的引數PT_REGS_PARM2(ctx)。這是來自tracex4示例的示例:
SEC("kprobe/kmem_cache_free")
int bpf_prog1(struct pt_regs *ctx)
{
long ptr = PT_REGS_PARM2(ctx);
bpf_map_delete_elem(&my_map, &ptr);
return 0;
}
在 的情況下recvfrom,第二個引數應該是指向緩沖區的指標:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
要從內核到用戶空間進行通信,您確實需要一張地圖。您會注意到您對 的呼叫bpf_perf_event_output也帶有一個指向地圖的指標:&my_map。
在bpf_perf_event_output輔助功能需要的地圖型別的BPF_MAP_TYPE_PERF_EVENT_ARRAY運作。但與大多數地圖型別不同,這種地圖型別的作業方式類似于從 eBPF 程式到用戶空間的單向資料流。
我相信你的代碼是基于內核中的trace_output_kern示例的。你會注意到他們在這里也定義了一個地圖:
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(u32));
__uint(max_entries, 2);
} my_map SEC(".maps");
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/386328.html
