structssl_data_event_t{enumssl_data_event_typetype;u64timestamp_ns;u32pid;u32tid;chardata[MAX_DATA_SIZE_OPENSSL];s32data_len;charcomm[TASK_COMM_LEN];u32fd;};// BPF programs are limited to a 512-byte stack. We store this value per CPU
// and use it as a heap allocated value.
struct{__uint(type,BPF_MAP_TYPE_PERCPU_ARRAY);__type(key,u32);__type(value,structssl_data_event_t);__uint(max_entries,1);}data_buffer_heapSEC(".maps");
// Function signature being probed:
// int SSL_write(SSL *ssl, const void *buf, int num);
SEC("uprobe/SSL_write")intprobe_entry_SSL_write(structpt_regs*ctx){u64current_pid_tgid=bpf_get_current_pid_tgid();u32pid=current_pid_tgid>>32;#ifndef KERNEL_LESS_5_2
// if target_ppid is 0 then we target all pids
if(target_pid!=0&&target_pid!=pid){return0;}#endif
void*ssl=(void*)PT_REGS_PARM1(ctx);// https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/crypto/bio/bio_local.h
structssl_stssl_info;bpf_probe_read_user(&ssl_info,sizeof(ssl_info),ssl);structBIObio_w;bpf_probe_read_user(&bio_w,sizeof(bio_w),ssl_info.wbio);// get fd ssl->wbio->num
u32fd=bio_w.num;// debug_bpf_printk("openssl uprobe SSL_write FD:%d\n", fd);
constchar*buf=(constchar*)PT_REGS_PARM2(ctx);structactive_ssl_bufactive_ssl_buf_t;__builtin_memset(&active_ssl_buf_t,0,sizeof(active_ssl_buf_t));active_ssl_buf_t.fd=fd;active_ssl_buf_t.buf=buf;bpf_map_update_elem(&active_ssl_write_args_map,¤t_pid_tgid,&active_ssl_buf_t,BPF_ANY);return0;}
SEC("uretprobe/SSL_write")intprobe_ret_SSL_write(structpt_regs*ctx){u64current_pid_tgid=bpf_get_current_pid_tgid();u32pid=current_pid_tgid>>32;#ifndef KERNEL_LESS_5_2
// if target_ppid is 0 then we target all pids
if(target_pid!=0&&target_pid!=pid){return0;}#endif
// debug_bpf_printk("openssl uretprobe/SSL_write pid :%d\n", pid);
structactive_ssl_buf*active_ssl_buf_t=bpf_map_lookup_elem(&active_ssl_write_args_map,¤t_pid_tgid);if(active_ssl_buf_t!=NULL){constchar*buf;u32fd=active_ssl_buf_t->fd;bpf_probe_read(&buf,sizeof(constchar*),&active_ssl_buf_t->buf);process_SSL_data(ctx,current_pid_tgid,kSSLWrite,buf,fd);}bpf_map_delete_elem(&active_ssl_write_args_map,¤t_pid_tgid);return0;}
funcPerfEventReader(errChanchanerror,em*ebpf.Map,ctxcontext.Context){rd,err:=perf.NewReader(em,os.Getpagesize()*64)iferr!=nil{errChan<-fmt.Errorf("creating %s reader dns: %s",em.String(),err)return}deferrd.Close()for{//判断ctx是不是结束
select{case_=<-ctx.Done():logrus.Printf("readEvent received close signal from context.Done.")returndefault:}record,err:=rd.Read()iferr!=nil{iferrors.Is(err,perf.ErrClosed){return}errChan<-fmt.Errorf("reading from perf event reader: %s",err)return}ifrecord.LostSamples!=0{logrus.Printf("perf event ring buffer full, dropped %d samples",record.LostSamples)continue}varsslEvent=&SSLDataEvent{}err=sslEvent.Decode(record.RawSample)iferr!=nil{log.Printf("decode error:%v",err)continue}// 打印数据
str:=sslEvent.String()fmt.Println(str)}}