forked from saaph/eBPF_processor
-
Notifications
You must be signed in to change notification settings - Fork 5
/
annotate_ebpf_helpers.py
executable file
·34 lines (28 loc) · 13.7 KB
/
annotate_ebpf_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# IDA Python script to annotate all eBPF call instructions
# which call eBPF helpers with the helper function's name
# Developed against Python3 and IDA 7.6
# started with the instruction enumeration example from the IDA Book
from idaapi import *
import idautils
import idc
# created using our generate_helper_lookup.sh script.
# will need to periodically update this as new helpers are added.
helper_id_to_signature = {1: 'void *bpf_map_lookup_elem(void *map, const void *key)', 2: 'long bpf_map_update_elem(void *map, const void *key, const void *value, __u64 flags)', 3: 'long bpf_map_delete_elem(void *map, const void *key)', 4: 'long bpf_probe_read(void *dst, __u32 size, const void *unsafe_ptr)', 5: '__u64 bpf_ktime_get_ns(void)', 6: 'long bpf_trace_printk(const char *fmt, __u32 fmt_size, ...)', 7: '__u32 bpf_get_prandom_u32(void)', 8: '__u32 bpf_get_smp_processor_id(void)', 9: 'long bpf_skb_store_bytes(struct __sk_buff *skb, __u32 offset, const void *from, __u32 len, __u64 flags)', 10: 'long bpf_l3_csum_replace(struct __sk_buff *skb, __u32 offset, __u64 from, __u64 to, __u64 size)', 11: 'long bpf_l4_csum_replace(struct __sk_buff *skb, __u32 offset, __u64 from, __u64 to, __u64 flags)', 12: 'long bpf_tail_call(void *ctx, void *prog_array_map, __u32 index)', 13: 'long bpf_clone_redirect(struct __sk_buff *skb, __u32 ifindex, __u64 flags)', 14: '__u64 bpf_get_current_pid_tgid(void)', 15: '__u64 bpf_get_current_uid_gid(void)', 16: 'long bpf_get_current_comm(void *buf, __u32 size_of_buf)', 17: '__u32 bpf_get_cgroup_classid(struct __sk_buff *skb)', 18: 'long bpf_skb_vlan_push(struct __sk_buff *skb, __be16 vlan_proto, __u16 vlan_tci)', 19: 'long bpf_skb_vlan_pop(struct __sk_buff *skb)', 20: 'long bpf_skb_get_tunnel_key(struct __sk_buff *skb, struct bpf_tunnel_key *key, __u32 size, __u64 flags)', 21: 'long bpf_skb_set_tunnel_key(struct __sk_buff *skb, struct bpf_tunnel_key *key, __u32 size, __u64 flags)', 22: '__u64 bpf_perf_event_read(void *map, __u64 flags)', 23: 'long bpf_redirect(__u32 ifindex, __u64 flags)', 24: '__u32 bpf_get_route_realm(struct __sk_buff *skb)', 25: 'long bpf_perf_event_output(void *ctx, void *map, __u64 flags, void *data, __u64 size)', 26: 'long bpf_skb_load_bytes(const void *skb, __u32 offset, void *to, __u32 len)', 27: 'long bpf_get_stackid(void *ctx, void *map, __u64 flags)', 28: '__s64 bpf_csum_diff(__be32 *from, __u32 from_size, __be32 *to, __u32 to_size, __wsum seed)', 29: 'long bpf_skb_get_tunnel_opt(struct __sk_buff *skb, void *opt, __u32 size)', 30: 'long bpf_skb_set_tunnel_opt(struct __sk_buff *skb, void *opt, __u32 size)', 31: 'long bpf_skb_change_proto(struct __sk_buff *skb, __be16 proto, __u64 flags)', 32: 'long bpf_skb_change_type(struct __sk_buff *skb, __u32 type)', 33: 'long bpf_skb_under_cgroup(struct __sk_buff *skb, void *map, __u32 index)', 34: '__u32 bpf_get_hash_recalc(struct __sk_buff *skb)', 35: '__u64 bpf_get_current_task(void)', 36: 'long bpf_probe_write_user(void *dst, const void *src, __u32 len)', 37: 'long bpf_current_task_under_cgroup(void *map, __u32 index)', 38: 'long bpf_skb_change_tail(struct __sk_buff *skb, __u32 len, __u64 flags)', 39: 'long bpf_skb_pull_data(struct __sk_buff *skb, __u32 len)', 40: '__s64 bpf_csum_update(struct __sk_buff *skb, __wsum csum)', 41: 'void bpf_set_hash_invalid(struct __sk_buff *skb)', 42: 'long bpf_get_numa_node_id(void)', 43: 'long bpf_skb_change_head(struct __sk_buff *skb, __u32 len, __u64 flags)', 44: 'long bpf_xdp_adjust_head(struct xdp_md *xdp_md, int delta)', 45: 'long bpf_probe_read_str(void *dst, __u32 size, const void *unsafe_ptr)', 46: '__u64 bpf_get_socket_cookie(void *ctx)', 47: '__u32 bpf_get_socket_uid(struct __sk_buff *skb)', 48: 'long bpf_set_hash(struct __sk_buff *skb, __u32 hash)', 49: 'long bpf_setsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)', 50: 'long bpf_skb_adjust_room(struct __sk_buff *skb, __s32 len_diff, __u32 mode, __u64 flags)', 51: 'long bpf_redirect_map(void *map, __u32 key, __u64 flags)', 52: 'long bpf_sk_redirect_map(struct __sk_buff *skb, void *map, __u32 key, __u64 flags)', 53: 'long bpf_sock_map_update(struct bpf_sock_ops *skops, void *map, void *key, __u64 flags)', 54: 'long bpf_xdp_adjust_meta(struct xdp_md *xdp_md, int delta)', 55: 'long bpf_perf_event_read_value(void *map, __u64 flags, struct bpf_perf_event_value *buf, __u32 buf_size)', 56: 'long bpf_perf_prog_read_value(struct bpf_perf_event_data *ctx, struct bpf_perf_event_value *buf, __u32 buf_size)', 57: 'long bpf_getsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)', 58: 'long bpf_override_return(struct pt_regs *regs, __u64 rc)', 59: 'long bpf_sock_ops_cb_flags_set(struct bpf_sock_ops *bpf_sock, int argval)', 60: 'long bpf_msg_redirect_map(struct sk_msg_md *msg, void *map, __u32 key, __u64 flags)', 61: 'long bpf_msg_apply_bytes(struct sk_msg_md *msg, __u32 bytes)', 62: 'long bpf_msg_cork_bytes(struct sk_msg_md *msg, __u32 bytes)', 63: 'long bpf_msg_pull_data(struct sk_msg_md *msg, __u32 start, __u32 end, __u64 flags)', 64: 'long bpf_bind(struct bpf_sock_addr *ctx, struct sockaddr *addr, int addr_len)', 65: 'long bpf_xdp_adjust_tail(struct xdp_md *xdp_md, int delta)', 66: 'long bpf_skb_get_xfrm_state(struct __sk_buff *skb, __u32 index, struct bpf_xfrm_state *xfrm_state, __u32 size, __u64 flags)', 67: 'long bpf_get_stack(void *ctx, void *buf, __u32 size, __u64 flags)', 68: 'long bpf_skb_load_bytes_relative(const void *skb, __u32 offset, void *to, __u32 len, __u32 start_header)', 69: 'long bpf_fib_lookup(void *ctx, struct bpf_fib_lookup *params, int plen, __u32 flags)', 70: 'long bpf_sock_hash_update(struct bpf_sock_ops *skops, void *map, void *key, __u64 flags)', 71: 'long bpf_msg_redirect_hash(struct sk_msg_md *msg, void *map, void *key, __u64 flags)', 72: 'long bpf_sk_redirect_hash(struct __sk_buff *skb, void *map, void *key, __u64 flags)', 73: 'long bpf_lwt_push_encap(struct __sk_buff *skb, __u32 type, void *hdr, __u32 len)', 74: 'long bpf_lwt_seg6_store_bytes(struct __sk_buff *skb, __u32 offset, const void *from, __u32 len)', 75: 'long bpf_lwt_seg6_adjust_srh(struct __sk_buff *skb, __u32 offset, __s32 delta)', 76: 'long bpf_lwt_seg6_action(struct __sk_buff *skb, __u32 action, void *param, __u32 param_len)', 77: 'long bpf_rc_repeat(void *ctx)', 78: 'long bpf_rc_keydown(void *ctx, __u32 protocol, __u64 scancode, __u32 toggle)', 79: '__u64 bpf_skb_cgroup_id(struct __sk_buff *skb)', 80: '__u64 bpf_get_current_cgroup_id(void)', 81: 'void *bpf_get_local_storage(void *map, __u64 flags)', 82: 'long bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, void *map, void *key, __u64 flags)', 83: '__u64 bpf_skb_ancestor_cgroup_id(struct __sk_buff *skb, int ancestor_level)', 84: 'struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, __u32 tuple_size, __u64 netns, __u64 flags)', 85: 'struct bpf_sock *bpf_sk_lookup_udp(void *ctx, struct bpf_sock_tuple *tuple, __u32 tuple_size, __u64 netns, __u64 flags)', 86: 'long bpf_sk_release(void *sock)', 87: 'long bpf_map_push_elem(void *map, const void *value, __u64 flags)', 88: 'long bpf_map_pop_elem(void *map, void *value)', 89: 'long bpf_map_peek_elem(void *map, void *value)', 90: 'long bpf_msg_push_data(struct sk_msg_md *msg, __u32 start, __u32 len, __u64 flags)', 91: 'long bpf_msg_pop_data(struct sk_msg_md *msg, __u32 start, __u32 len, __u64 flags)', 92: 'long bpf_rc_pointer_rel(void *ctx, __s32 rel_x, __s32 rel_y)', 93: 'long bpf_spin_lock(struct bpf_spin_lock *lock)', 94: 'long bpf_spin_unlock(struct bpf_spin_lock *lock)', 95: 'struct bpf_sock *bpf_sk_fullsock(struct bpf_sock *sk)', 96: 'struct bpf_tcp_sock *bpf_tcp_sock(struct bpf_sock *sk)', 97: 'long bpf_skb_ecn_set_ce(struct __sk_buff *skb)', 98: 'struct bpf_sock *bpf_get_listener_sock(struct bpf_sock *sk)', 99: 'struct bpf_sock *bpf_skc_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, __u32 tuple_size, __u64 netns, __u64 flags)', 100: 'long bpf_tcp_check_syncookie(void *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len)', 101: 'long bpf_sysctl_get_name(struct bpf_sysctl *ctx, char *buf, unsigned long buf_len, __u64 flags)', 102: 'long bpf_sysctl_get_current_value(struct bpf_sysctl *ctx, char *buf, unsigned long buf_len)', 103: 'long bpf_sysctl_get_new_value(struct bpf_sysctl *ctx, char *buf, unsigned long buf_len)', 104: 'long bpf_sysctl_set_new_value(struct bpf_sysctl *ctx, const char *buf, unsigned long buf_len)', 105: 'long bpf_strtol(const char *buf, unsigned long buf_len, __u64 flags, long *res)', 106: 'long bpf_strtoul(const char *buf, unsigned long buf_len, __u64 flags, unsigned long *res)', 107: 'void *bpf_sk_storage_get(void *map, void *sk, void *value, __u64 flags)', 108: 'long bpf_sk_storage_delete(void *map, void *sk)', 109: 'long bpf_send_signal(__u32 sig)', 110: '__s64 bpf_tcp_gen_syncookie(void *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len)', 111: 'long bpf_skb_output(void *ctx, void *map, __u64 flags, void *data, __u64 size)', 112: 'long bpf_probe_read_user(void *dst, __u32 size, const void *unsafe_ptr)', 113: 'long bpf_probe_read_kernel(void *dst, __u32 size, const void *unsafe_ptr)', 114: 'long bpf_probe_read_user_str(void *dst, __u32 size, const void *unsafe_ptr)', 115: 'long bpf_probe_read_kernel_str(void *dst, __u32 size, const void *unsafe_ptr)', 116: 'long bpf_tcp_send_ack(void *tp, __u32 rcv_nxt)', 117: 'long bpf_send_signal_thread(__u32 sig)', 118: '__u64 bpf_jiffies64(void)', 119: 'long bpf_read_branch_records(struct bpf_perf_event_data *ctx, void *buf, __u32 size, __u64 flags)', 120: 'long bpf_get_ns_current_pid_tgid(__u64 dev, __u64 ino, struct bpf_pidns_info *nsdata, __u32 size)', 121: 'long bpf_xdp_output(void *ctx, void *map, __u64 flags, void *data, __u64 size)', 122: '__u64 bpf_get_netns_cookie(void *ctx)', 123: '__u64 bpf_get_current_ancestor_cgroup_id(int ancestor_level)', 124: 'long bpf_sk_assign(void *ctx, void *sk, __u64 flags)', 125: '__u64 bpf_ktime_get_boot_ns(void)', 126: 'long bpf_seq_printf(struct seq_file *m, const char *fmt, __u32 fmt_size, const void *data, __u32 data_len)', 127: 'long bpf_seq_write(struct seq_file *m, const void *data, __u32 len)', 128: '__u64 bpf_sk_cgroup_id(void *sk)', 129: '__u64 bpf_sk_ancestor_cgroup_id(void *sk, int ancestor_level)', 130: 'long bpf_ringbuf_output(void *ringbuf, void *data, __u64 size, __u64 flags)', 131: 'void *bpf_ringbuf_reserve(void *ringbuf, __u64 size, __u64 flags)', 132: 'void bpf_ringbuf_submit(void *data, __u64 flags)', 133: 'void bpf_ringbuf_discard(void *data, __u64 flags)', 134: '__u64 bpf_ringbuf_query(void *ringbuf, __u64 flags)', 135: 'long bpf_csum_level(struct __sk_buff *skb, __u64 level)', 136: 'struct tcp6_sock *bpf_skc_to_tcp6_sock(void *sk)', 137: 'struct tcp_sock *bpf_skc_to_tcp_sock(void *sk)', 138: 'struct tcp_timewait_sock *bpf_skc_to_tcp_timewait_sock(void *sk)', 139: 'struct tcp_request_sock *bpf_skc_to_tcp_request_sock(void *sk)', 140: 'struct udp6_sock *bpf_skc_to_udp6_sock(void *sk)', 141: 'long bpf_get_task_stack(struct task_struct *task, void *buf, __u32 size, __u64 flags)', 142: 'long bpf_load_hdr_opt(struct bpf_sock_ops *skops, void *searchby_res, __u32 len, __u64 flags)', 143: 'long bpf_store_hdr_opt(struct bpf_sock_ops *skops, const void *from, __u32 len, __u64 flags)', 144: 'long bpf_reserve_hdr_opt(struct bpf_sock_ops *skops, __u32 len, __u64 flags)', 145: 'void *bpf_inode_storage_get(void *map, void *inode, void *value, __u64 flags)', 146: 'int bpf_inode_storage_delete(void *map, void *inode)', 147: 'long bpf_d_path(struct path *path, char *buf, __u32 sz)', 148: 'long bpf_copy_from_user(void *dst, __u32 size, const void *user_ptr)', 149: 'long bpf_snprintf_btf(char *str, __u32 str_size, struct btf_ptr *ptr, __u32 btf_ptr_size, __u64 flags)', 150: 'long bpf_seq_printf_btf(struct seq_file *m, struct btf_ptr *ptr, __u32 ptr_size, __u64 flags)', 151: '__u64 bpf_skb_cgroup_classid(struct __sk_buff *skb)', 152: 'long bpf_redirect_neigh(__u32 ifindex, struct bpf_redir_neigh *params, int plen, __u64 flags)', 153: 'void *bpf_per_cpu_ptr(const void *percpu_ptr, __u32 cpu)', 154: 'void *bpf_this_cpu_ptr(const void *percpu_ptr)', 155: 'long bpf_redirect_peer(__u32 ifindex, __u64 flags)', 156: 'void *bpf_task_storage_get(void *map, struct task_struct *task, void *value, __u64 flags)', 157: 'long bpf_task_storage_delete(void *map, struct task_struct *task)', 158: 'struct task_struct *bpf_get_current_task_btf(void)', 159: 'long bpf_bprm_opts_set(struct linux_binprm *bprm, __u64 flags)', 160: '__u64 bpf_ktime_get_coarse_ns(void)', 161: 'long bpf_ima_inode_hash(struct inode *inode, void *dst, __u32 size)', 162: 'struct socket *bpf_sock_from_file(struct file *file)', 163: 'long bpf_check_mtu(void *ctx, __u32 ifindex, __u32 *mtu_len, __s32 len_diff, __u64 flags)', 164: 'long bpf_for_each_map_elem(void *map, void *callback_fn, void *callback_ctx, __u64 flags)', 165: 'long bpf_snprintf(char *str, __u32 str_size, const char *fmt, __u64 *data, __u32 data_len)'}
print("Scanning all known function instructions for eBPF helper call instructions")
for ea in Functions():
func = get_func(ea)
func_name = ida_funcs.get_func_name(func.start_ea)
print(f"scanning function: {func_name}")
if func:
for i in FuncItems(func.start_ea):
insn = ida_ua.insn_t()
if ida_ua.decode_insn(insn, i):
feature = insn.get_canon_feature()
if feature & CF_CALL:
# TODO: check that we're a helper call, not a bpf tail call
try:
helper_signature = helper_id_to_signature[insn[0].value]
except KeyError:
helper_signature = "UNKNOWN. Update list of helper function signatures"
Warning(f"Unknown eBPF helper {insn[0].value:#x}. Check for updates, or use generate_helper_lookup.sh with newer kernel version and manually update this script.")
idc.set_cmt(i, helper_signature, False)