Skip to content

Instantly share code, notes, and snippets.

@sandip4n
Last active October 1, 2019 09:09
Show Gist options
  • Save sandip4n/1e10f261b3b562233c629bfe758c3c63 to your computer and use it in GitHub Desktop.
Save sandip4n/1e10f261b3b562233c629bfe758c3c63 to your computer and use it in GitHub Desktop.
bpf: read nested struct members
#!/usr/bin/python
from __future__ import print_function
from bcc import BPF
from bcc.utils import printb
from time import sleep
# load BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
struct string {
size_t len;
char *buf;
};
BPF_ARRAY(data, struct string, 1);
int trace_entry__do_work(struct pt_regs *ctx)
{
struct string str, *ptr = NULL;
int ret, zero = 0;
ptr = data.lookup(&zero);
if (!ptr)
return 0;
/* Read the struct string and put it in the data map */
ret = bpf_probe_read(&str, sizeof(str), (void *) PT_REGS_PARM1(ctx) + sizeof(unsigned long));
bpf_trace_printk("bpf_probe_read() returned %d\\n", ret);
(*ptr) = str;
return 0;
};
int trace_exit__do_work(struct pt_regs *ctx)
{
struct string *ptr = NULL;
int ret, zero = 0;
char buf[80];
/* Read the struct string back from the data map */
ptr = data.lookup(&zero);
if (!ptr)
return 0;
/* This should work now */
ret = bpf_probe_read_str(buf, sizeof(buf), (void *) ptr->buf);
bpf_trace_printk("bpf_probe_read() returned %d\\n", ret);
bpf_trace_printk("buf = %s, len = %u\\n", buf, ptr->len);
return 0;
};
""")
b.attach_uprobe(name="./xyz", sym="do_work", fn_name="trace_entry__do_work")
b.attach_uretprobe(name="./xyz", sym="do_work", fn_name="trace_exit__do_work")
# sleep until Ctrl-C
try:
sleep(99999999)
except KeyboardInterrupt:
pass
/*
* Compile with:
* gcc -o xyz -Wall -g -O0 xyz.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
struct string {
size_t len;
char *buf;
};
struct load {
unsigned long val;
struct string str;
};
void do_work(struct load *l)
{
if (!l || !l->str.len || !l->str.buf)
return;
printf("address of l = %016lx\n", (unsigned long) l);
printf("address of l->str = %016lx\n", (unsigned long) &(l->str));
printf("address of l->str.buf = %016lx\n", (unsigned long) (l->str).buf);
printf("val = %lu, len = %lu, buf = %s",
l->val, l->str.len, l->str.buf);
}
int main(int argc, char **argv)
{
struct load l = {
1000, { 12, "Hello world!" }
};
do_work(&l);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment