| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- 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
- }
|