|
|
@@ -0,0 +1,137 @@
|
|
|
+
|
|
|
+// #include "common.h"
|
|
|
+
|
|
|
+// #include "bpf_tracing.h"
|
|
|
+// #include "bpf_helpers.h"
|
|
|
+// #include <asm/ptrace.h>
|
|
|
+// #include "bpf_base.h"
|
|
|
+// #define ROCK_MAX_BUFFER_SIZE 65536
|
|
|
+
|
|
|
+static long (*bpf_probe_read_user_str)(void *dst, __u32 size, const void *unsafe_ptr) = (void *) 114;
|
|
|
+#define ROCK_MAX_LEN 1022
|
|
|
+
|
|
|
+struct sock_t {
|
|
|
+ int size;
|
|
|
+ int header_offset_idx;
|
|
|
+ char payload[ROCK_MAX_LEN];
|
|
|
+};
|
|
|
+
|
|
|
+struct {
|
|
|
+ __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
|
|
+ __type(key, int);
|
|
|
+ __type(value, struct sock_t);
|
|
|
+ __uint(max_entries, 1);
|
|
|
+} socket_heap SEC(".maps");
|
|
|
+
|
|
|
+struct {
|
|
|
+ __uint(type, BPF_MAP_TYPE_ARRAY);
|
|
|
+ __type(key, int); // 键类型为int
|
|
|
+ __uint(value_size, 124); // 数组的值的大小
|
|
|
+ __uint(max_entries, 1);
|
|
|
+} large_array_map SEC(".maps");
|
|
|
+
|
|
|
+static __inline int is_http_header(const char *data)
|
|
|
+{
|
|
|
+ int header_off = 0 ;
|
|
|
+ for (int i = 0; i < 512; i++)
|
|
|
+ {
|
|
|
+ if (data[i] == 'H' &&
|
|
|
+ data[i+1] == 'T' &&
|
|
|
+ data[i+2] == 'T' &&
|
|
|
+ data[i+3] == 'P' &&
|
|
|
+ data[i+4] == '/' &&
|
|
|
+ data[i+5] == '1' &&
|
|
|
+ data[i+6] == '.'&&
|
|
|
+ data[i+7] == '1'&& data[i+8] == '\r' && data[i + 9] == '\n')
|
|
|
+ {
|
|
|
+ header_off = i+10;
|
|
|
+ if(data[header_off] == 'c' &&
|
|
|
+ data[header_off+1] == 'w' &&
|
|
|
+ data[header_off+2] == 't' &&
|
|
|
+ data[header_off+3] == 'r' &&
|
|
|
+ data[header_off+4] == 'a' &&
|
|
|
+ data[header_off+5] == 'c' &&
|
|
|
+ data[header_off+6] == 'e')
|
|
|
+ {
|
|
|
+ return header_off + 9;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return header_off;
|
|
|
+}
|
|
|
+
|
|
|
+SEC("uprobe/Java_sun_nio_ch_FileDispatcherImpl_read0")
|
|
|
+int uprobe_Java_sun_nio_ch_FileDispatcherImpl_read0(struct pt_regs *ctx) {
|
|
|
+ //计算 rbp-0x30
|
|
|
+ bpf_printk("enter the uprobe_Java_sun_nio_ch_FileDispatcherImpl_read0\n");
|
|
|
+ unsigned long jhttpdata_ptr;
|
|
|
+ jhttpdata_ptr = (ctx)->rbp;
|
|
|
+ jhttpdata_ptr = jhttpdata_ptr - 0x70;
|
|
|
+ // bpf_printk("enter rbp is %llx.\n", jhttpdata_ptr);
|
|
|
+ jhttpdata_ptr = jhttpdata_ptr - 0x30;
|
|
|
+ //p rbp - 0x30
|
|
|
+ // bpf_printk("enter rbp -0x30 to rcx is %llx.\n", jhttpdata_ptr);
|
|
|
+
|
|
|
+ // x/1gx (p rbp-0x30)
|
|
|
+ unsigned long jbytechar_ptr;
|
|
|
+ long ret = bpf_probe_read_user(&jbytechar_ptr, sizeof(unsigned long), (void *) jhttpdata_ptr);
|
|
|
+ // bpf_printk("x/1gx (p rbp-0x30) value is %llx.\n", jbytechar_ptr);
|
|
|
+ bpf_printk("enter the uprobe_Java_sun_nio_ch_FileDispatcherImpl_read0 ------22222222\n");
|
|
|
+ if (ret != 0) {
|
|
|
+ // bpf_printk("Failed to read first level ptr: %d\n", ret);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (!jbytechar_ptr) {
|
|
|
+ // bpf_printk("First level pointer is null.\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ bpf_printk("enter the uprobe_Java_sun_nio_ch_FileDispatcherImpl_read0 ----111111111\n");
|
|
|
+
|
|
|
+ //x/s addr
|
|
|
+ int key = 0;
|
|
|
+ struct sock_t *map_data = bpf_map_lookup_elem(&socket_heap, &key);
|
|
|
+ if (!map_data) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ long err = bpf_probe_read_user_str(map_data->payload, sizeof(map_data->payload), (void *) (jbytechar_ptr));
|
|
|
+ if (err < 0) {
|
|
|
+ // bpf_printk("bpf_probe_read_user failed with return code: %d\n", err);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ bpf_printk("read data is : %s\n", map_data->payload);
|
|
|
+ // if (!is_http_request2(httpdata, 1024))
|
|
|
+ // {
|
|
|
+ // bpf_printk("not a http request\n");
|
|
|
+ // return 0;
|
|
|
+ // }
|
|
|
+
|
|
|
+
|
|
|
+ int offset = is_http_header(map_data->payload);
|
|
|
+ bpf_printk("found the header, %d\n", offset);
|
|
|
+ char *data;
|
|
|
+ data = bpf_map_lookup_elem(&large_array_map, &key);
|
|
|
+ if (!data)
|
|
|
+ return 0;
|
|
|
+ struct apm_span_context cw_parent_span_context = {};
|
|
|
+ if(offset > 0 && offset < 512 - 123)
|
|
|
+ {
|
|
|
+ __builtin_memcpy(data, &(map_data->payload[offset]), 123);
|
|
|
+ bpf_printk("found the data, %s\n", data);
|
|
|
+
|
|
|
+ cw_string_to_span_context(data, &cw_parent_span_context);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ generate_random_bytes(cw_parent_span_context.trace_id, TRACE_ID_SIZE);
|
|
|
+ }
|
|
|
+ // 保存 trace_id 到psc
|
|
|
+ cw_save_parent_tracking_span(&cw_parent_span_context);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+// char __license[] SEC("license") = "Dual MIT/GPL";
|