mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-03 10:14:44 +08:00
add hook of ssl_ex version (#164)
Co-authored-by: Ivoripuion <Ivoropuion@github.com>
This commit is contained in:
@@ -16,6 +16,13 @@ struct {
|
||||
__uint(value_size, sizeof(__u32));
|
||||
} perf_SSL_events SEC(".maps");
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 10240);
|
||||
__type(key, __u32);
|
||||
__type(value, size_t*);
|
||||
} readbytes_ptrs SEC(".maps");
|
||||
|
||||
#define BASE_EVENT_SIZE ((size_t)(&((struct probe_SSL_data_t *)0)->buf))
|
||||
#define EVENT_SIZE(X) (BASE_EVENT_SIZE + ((size_t)(X)))
|
||||
#define MAX_ENTRIES 10240
|
||||
@@ -153,6 +160,142 @@ int BPF_URETPROBE(probe_SSL_write_exit) {
|
||||
return (SSL_exit(ctx, 1));
|
||||
}
|
||||
|
||||
SEC("uprobe/SSL_write_ex")
|
||||
int BPF_UPROBE(probe_SSL_write_ex_enter, void *ssl, void *buf, size_t num, size_t *readbytes) {
|
||||
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();
|
||||
|
||||
if (!trace_allowed(uid, pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_map_update_elem(&bufs, &tid, &buf, BPF_ANY);
|
||||
bpf_map_update_elem(&start_ns, &tid, &ts, BPF_ANY);
|
||||
|
||||
bpf_map_update_elem(&readbytes_ptrs, &tid, &readbytes, BPF_ANY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("uprobe/SSL_read_ex")
|
||||
int BPF_UPROBE(probe_SSL_read_ex_enter, void *ssl, void *buf, size_t num, size_t *readbytes) {
|
||||
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();
|
||||
|
||||
if (!trace_allowed(uid, pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_map_update_elem(&bufs, &tid, &buf, BPF_ANY);
|
||||
bpf_map_update_elem(&start_ns, &tid, &ts, BPF_ANY);
|
||||
|
||||
bpf_map_update_elem(&readbytes_ptrs, &tid, &readbytes, BPF_ANY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ex_SSL_exit(struct pt_regs *ctx, int rw, int len) {
|
||||
int ret = 0;
|
||||
u32 zero = 0;
|
||||
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();
|
||||
|
||||
if (!trace_allowed(uid, pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* store arg info for later lookup */
|
||||
u64 *bufp = bpf_map_lookup_elem(&bufs, &tid);
|
||||
if (bufp == 0)
|
||||
return 0;
|
||||
|
||||
u64 *tsp = bpf_map_lookup_elem(&start_ns, &tid);
|
||||
if (!tsp)
|
||||
return 0;
|
||||
u64 delta_ns = ts - *tsp;
|
||||
|
||||
if (len <= 0) // no data
|
||||
return 0;
|
||||
|
||||
struct probe_SSL_data_t *data = bpf_map_lookup_elem(&ssl_data, &zero);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
data->timestamp_ns = ts;
|
||||
data->delta_ns = delta_ns;
|
||||
data->pid = pid;
|
||||
data->tid = tid;
|
||||
data->uid = uid;
|
||||
data->len = (u32)len;
|
||||
data->buf_filled = 0;
|
||||
data->rw = rw;
|
||||
data->is_handshake = false;
|
||||
u32 buf_copy_size = min((size_t)MAX_BUF_SIZE, (size_t)len);
|
||||
|
||||
bpf_get_current_comm(&data->comm, sizeof(data->comm));
|
||||
|
||||
if (bufp != 0)
|
||||
ret = bpf_probe_read_user(&data->buf, buf_copy_size, (char *)*bufp);
|
||||
|
||||
bpf_map_delete_elem(&bufs, &tid);
|
||||
bpf_map_delete_elem(&start_ns, &tid);
|
||||
|
||||
if (!ret)
|
||||
data->buf_filled = 1;
|
||||
else
|
||||
buf_copy_size = 0;
|
||||
|
||||
bpf_perf_event_output(ctx, &perf_SSL_events, BPF_F_CURRENT_CPU, data,
|
||||
EVENT_SIZE(buf_copy_size));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("uretprobe/SSL_write_ex")
|
||||
int BPF_URETPROBE(probe_SSL_write_ex_exit)
|
||||
{
|
||||
u32 tid = (u32)bpf_get_current_pid_tgid();
|
||||
size_t **readbytes_ptr = bpf_map_lookup_elem(&readbytes_ptrs, &tid);
|
||||
if (!readbytes_ptr)
|
||||
return 0;
|
||||
|
||||
size_t written = 0;
|
||||
bpf_probe_read_user(&written, sizeof(written), *readbytes_ptr);
|
||||
bpf_map_delete_elem(&readbytes_ptrs, &tid);
|
||||
|
||||
int ret = PT_REGS_RC(ctx);
|
||||
int len = (ret == 1) ? written : 0;
|
||||
|
||||
return ex_SSL_exit(ctx, 1, len);
|
||||
}
|
||||
|
||||
SEC("uretprobe/SSL_read_ex")
|
||||
int BPF_URETPROBE(probe_SSL_read_ex_exit)
|
||||
{
|
||||
u32 tid = (u32)bpf_get_current_pid_tgid();
|
||||
size_t **readbytes_ptr = bpf_map_lookup_elem(&readbytes_ptrs, &tid);
|
||||
if (!readbytes_ptr)
|
||||
return 0;
|
||||
|
||||
size_t written = 0;
|
||||
bpf_probe_read_user(&written, sizeof(written), *readbytes_ptr);
|
||||
bpf_map_delete_elem(&readbytes_ptrs, &tid);
|
||||
|
||||
int ret = PT_REGS_RC(ctx);
|
||||
int len = (ret == 1) ? written : 0;
|
||||
|
||||
return ex_SSL_exit(ctx, 1, len);
|
||||
}
|
||||
|
||||
SEC("uprobe/do_handshake")
|
||||
int BPF_UPROBE(probe_SSL_do_handshake_enter, void *ssl) {
|
||||
u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
@@ -217,4 +360,4 @@ int BPF_URETPROBE(probe_SSL_do_handshake_exit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char LICENSE[] SEC("license") = "GPL";
|
||||
char LICENSE[] SEC("license") = "GPL";
|
||||
@@ -8,9 +8,7 @@
|
||||
#include <bpf/libbpf.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
@@ -92,8 +90,8 @@ struct env {
|
||||
.uid = INVALID_UID,
|
||||
.pid = INVALID_PID,
|
||||
.openssl = true,
|
||||
.gnutls = true,
|
||||
.nss = true,
|
||||
.gnutls = false,
|
||||
.nss = false,
|
||||
.comm = NULL,
|
||||
};
|
||||
|
||||
@@ -197,6 +195,11 @@ int attach_openssl(struct sslsniff_bpf *skel, const char *lib) {
|
||||
ATTACH_UPROBE_CHECKED(skel, lib, SSL_read, probe_SSL_rw_enter);
|
||||
ATTACH_URETPROBE_CHECKED(skel, lib, SSL_read, probe_SSL_read_exit);
|
||||
|
||||
ATTACH_UPROBE_CHECKED(skel, lib, SSL_write_ex, probe_SSL_write_ex_enter);
|
||||
ATTACH_URETPROBE_CHECKED(skel, lib, SSL_write_ex, probe_SSL_write_ex_exit);
|
||||
ATTACH_UPROBE_CHECKED(skel, lib, SSL_read_ex, probe_SSL_read_ex_enter);
|
||||
ATTACH_URETPROBE_CHECKED(skel, lib, SSL_read_ex, probe_SSL_read_ex_exit);
|
||||
|
||||
if (env.latency && env.handshake) {
|
||||
ATTACH_UPROBE_CHECKED(skel, lib, SSL_do_handshake,
|
||||
probe_SSL_do_handshake_enter);
|
||||
|
||||
Reference in New Issue
Block a user