package ebpftracer import ( "debug/elf" "errors" "fmt" "log" "os" "github.com/cilium/ebpf/link" "github.com/coroot/coroot-node-agent/ebpftracer/tracer/aotinject" . "github.com/coroot/coroot-node-agent/utils/modelse" klog "github.com/sirupsen/logrus" ) func (t *Tracer) AttachJavaAotNioReadUprobes(pid uint32, codeType CodeType, rootfs string) ([]link.Link, error) { if t.DisableL7Tracing() { return nil, nil } var links []link.Link var bpath string // 根据进程 pid 获取进程的可执行文件路径 bpath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) if err != nil { log.Fatalf("Failed to read proc path: %v", err) } fmt.Printf("procPath: %s\n", bpath) //bpath = rootfs + bpath klog.Infof("[attach] find the nio.so path is %s", bpath) readInfo, _ := aotinject.GetProcessFunctionInfo(int(pid), bpath, symbolsocketRead0) if readInfo == nil { return nil, fmt.Errorf("can not find %s", symbolsocketRead0) } // 打印 readInfo klog.Infof("[attach] AttachJavaAotNioReadUprobes readInfo %v", readInfo) ef, err := elf.Open(bpath) if err != nil { klog.Errorf("[attach] open elf: %v", err) return nil, err } defer ef.Close() textSection := ef.Section(".text") if textSection == nil { return nil, errors.New("can not find .text section") } textSectionData, err := textSection.Data() if err != nil { return nil, err } textSectionLen := uint64(len(textSectionData) - 1) // 打印 textSectionLen klog.Infof("[attach] AttachJavaAotNioReadUprobes textSectionLen %d{0x%x}", textSectionLen, textSection.Addr) sStart := readInfo.Offset - textSection.Addr sEnd := sStart + readInfo.Size if sEnd > textSectionLen { klog.Infof("[attach] AttachJavaAotNioReadUprobes sEnd > textSectionLen %d, %d", textSectionLen, sEnd) return nil, fmt.Errorf("can not find %s", symbolsocketRead0) } sBytes := textSectionData[sStart:sEnd] // 打印 sBytes returnOffsets := getCallNextMoveOffsets(ef.Machine, sBytes) if len(returnOffsets) == 0 { return nil, fmt.Errorf("failed to find call in uprobe_ret_Java_sun_nio_ch_FileDispatcherImpl_read0") } klog.Infof("[attach] java symbol offset is %v", returnOffsets) for _, offset := range returnOffsets { klog.Infof("[attach] java symbol offset is %d", offset) ex, err := link.OpenExecutable(bpath) if err != nil { klog.Errorf("[attach] open executable: %v", err) return nil, err } l, err := ex.Uprobe(readInfo.Name, t.uprobes["uprobe_ret_Java_sun_nio_ch_FileDispatcherImpl_read0"], &link.UprobeOptions{Address: readInfo.Offset, Offset: uint64(offset), PID: int(pid)}) if err != nil { return nil, fmt.Errorf("failed to attach uprobe_ret_Java_sun_nio_ch_FileDispatcherImpl_read0 uprobe") } links = append(links, l) } if len(links) == 0 { return nil, fmt.Errorf("no links found for %s", bpath) } klog.WithField("pid", pid).Infof("[attach] libnio attached!") return links, nil } func (t *Tracer) AttachJavaAotNetWriteUprobes(pid uint32, rootfs string) ([]link.Link, error) { if t.DisableL7Tracing() { return nil, nil } // 根据进程 pid 获取进程的可执行文件路径 procPath, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) if err != nil { log.Fatalf("Failed to read proc path: %v", err) } fmt.Printf("procPath: %s\n", procPath) sendFunctionName := "NET_Send" injectFunctionName := "Java_java_net_SocketOutputStream_socketWrite0" // NETCoreAOTInject aotInjector := aotinject.AOTInjector{ PID: int(pid), SendFunctionLibPath: procPath, SendFunctionName: sendFunctionName, InjectLibPath: procPath, InjectFunctionName: injectFunctionName, CWLibName: "libmylib.so", CWFunctionName: "asmnop", CWLibPath: "/data/roger/ebpfdemo/mylib/libmylib.so", } // 打印 aotInjector fmt.Printf("aotInjector: %v\n", aotInjector) hookOffset, err := aotinject.AotInject(aotInjector) // 打印 hookOffset fmt.Printf("hookOffset: %d\n", hookOffset) if (hookOffset == 0) || (err != nil) { fmt.Println("failed to inject SystemNative_Send", err) return nil, err } var links []link.Link ex, err := link.OpenExecutable(aotInjector.CWLibPath) if err != nil { return nil, err } opt := link.UprobeOptions{ Offset: uint64(hookOffset), PID: int(pid), } upread02, err := ex.Uprobe(aotInjector.CWFunctionName, t.uprobes["javaaot_asmnop"], &opt) if err != nil { return nil, err } links = append(links, upread02) if len(links) == 0 { return nil, nil } fmt.Println("netcore client uprobes attached", pid) return links, nil }