Sfoglia il codice sorgente

Feature #TASK_QT-18250 改bug

rock.wu 9 mesi fa
parent
commit
77fa2d5c73
1 ha cambiato i file con 38 aggiunte e 22 eliminazioni
  1. 38 22
      ebpftracer/tracer/inject/inject_linux_amd64.go

+ 38 - 22
ebpftracer/tracer/inject/inject_linux_amd64.go

@@ -690,6 +690,21 @@ func writeData(pid int, addr uintptr, data uint64) error {
 	return nil
 }
 
+func readDataBytes(pid int, addr uintptr, size int) ([]byte, error) {
+	data := make([]byte, size)
+	if _, err := syscall.PtracePeekData(pid, addr, data); err != nil {
+		return nil, fmt.Errorf("ptrace PEEKDATA: %v", err)
+	}
+	return data, nil
+}
+
+func writeDataBytes(pid int, addr uintptr, data []byte) error {
+	if _, err := syscall.PtracePokeData(pid, addr, data); err != nil {
+		return fmt.Errorf("ptrace POKEDATA: %v", err)
+	}
+	return nil
+}
+
 func modifyIoFdTargetAddr(pid int, insertAddr, distAddr uintptr) error {
 	newOffset := distAddr - (insertAddr + 7)
 	targetAddr := insertAddr + 3
@@ -750,33 +765,34 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr uintptr) err
 // }
 
 func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) error {
-	// offset := debugEnterAddr - (originEnterAddr + 5)
-
-	// 读取原始数据
+	// 读取原始数据 - 需要12字节来存储完整的跳转指令
 	alignedAddr := originEnterAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
-	originalData, err := readData(pid, alignedAddr)
+	originalData, err := readDataBytes(pid, alignedAddr, 12)
 	if err != nil {
 		return err
 	}
 
-	bytes := (*[12]byte)(unsafe.Pointer(&originalData))
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0)))] = 0x48
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(1)))] = 0xb8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(2)))] = uint64(debugEnterAddr)
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(3)))] = uint64(debugEnterAddr) >> 1*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(4)))] = uint64(debugEnterAddr) >> 2*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(5)))] = uint64(debugEnterAddr) >> 3*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(6)))] = uint64(debugEnterAddr) >> 4*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(7)))] = uint64(debugEnterAddr) >> 5*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(8)))] = uint64(debugEnterAddr) >> 6*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(9)))] = uint64(debugEnterAddr) >> 7*8
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(10)))] = 0xff
-	bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(11)))] = 0xe0
-	// *(*uint32)(unsafe.Pointer(&bytes[(originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0))))+1])) = uint32(offset)
-	// err = writeData(pid, alignedAddr, originalData)
-	// if err != nil {
-	// 	return err
-	// }
+	offset := originEnterAddr % uintptr(unsafe.Sizeof(uintptr(0)))
+	
+	// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
+	originalData[offset] = 0x48                    // REX.W prefix
+	originalData[offset+1] = 0xb8                  // mov rax, imm64
+	// 按小端序写入64位地址
+	originalData[offset+2] = byte(debugEnterAddr)
+	originalData[offset+3] = byte(debugEnterAddr >> 8)
+	originalData[offset+4] = byte(debugEnterAddr >> 16)
+	originalData[offset+5] = byte(debugEnterAddr >> 24)
+	originalData[offset+6] = byte(debugEnterAddr >> 32)
+	originalData[offset+7] = byte(debugEnterAddr >> 40)
+	originalData[offset+8] = byte(debugEnterAddr >> 48)
+	originalData[offset+9] = byte(debugEnterAddr >> 56)
+	originalData[offset+10] = 0xff                 // jmp rax
+	originalData[offset+11] = 0xe0
+
+	err = writeDataBytes(pid, alignedAddr, originalData)
+	if err != nil {
+		return err
+	}
 	return nil
 }