Selaa lähdekoodia

Feature #TASK_QT-18250 改bug

rock.wu 9 kuukautta sitten
vanhempi
säilyke
fb72ea8734
1 muutettua tiedostoa jossa 65 lisäystä ja 33 poistoa
  1. 65 33
      ebpftracer/tracer/inject/inject_linux_amd64.go

+ 65 - 33
ebpftracer/tracer/inject/inject_linux_amd64.go

@@ -171,7 +171,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
 		pc += uint64(inst.Len)
 	}
 	j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
-	j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:5]
+	j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:12]
 	return nil
 }
 
@@ -360,22 +360,54 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
 	if err != nil {
 		return fmt.Errorf("readMemory error in checkReleaseFuncSymAfterChange <%v>", err)
 	}
-	inst, err := x86asm.Decode(code[0:], 64)
-	if err != nil {
-		return fmt.Errorf("Decode error in checkReleaseFuncSymAfterChange <%v>", err)
+	
+	// 原函数内容注释掉
+	// inst, err := x86asm.Decode(code[0:], 64)
+	// if err != nil {
+	// 	return fmt.Errorf("Decode error in checkReleaseFuncSymAfterChange <%v>", err)
+	// }
+	// if inst.Op != x86asm.JMP {
+	// 	return fmt.Errorf("The instruction does not JMP.")
+	// }
+	// relOffset, ok := inst.Args[0].(x86asm.Rel)
+	// if !ok {
+	// 	return fmt.Errorf("The instruction does not use RIP-relative addressing.")
+	// }
+	// // 验证target与Debug入口是否一致
+	// targetAddress := funcAbsAddress + uint64(inst.Len) + uint64(relOffset)
+	// if targetAddress != j.DebugLibNetInfo.FuncSymbol.SymAddr {
+	// 	return fmt.Errorf("Function entry jmp address does not match expectations.")
+	// }
+	
+	// 新的验证逻辑:验证指令序列:movabs $imm64,%rax 和 jmp *%rax
+	if len(code) < 13 { // movabs(10字节) + jmp(3字节) = 13字节
+		return fmt.Errorf("Instruction sequence too short, expected at least 13 bytes, got %d", len(code))
 	}
-	if inst.Op != x86asm.JMP {
-		return fmt.Errorf("The instruction does not JMP.")
+	
+	// 验证第一个指令:movabs $imm64,%rax
+	// movabs 指令格式:48 B8 + 8字节立即数 (RAX寄存器)
+	// 48 B8 = movabs rax, imm64
+	if code[0] != 0x48 || code[1] != 0xB8 {
+		return fmt.Errorf("First instruction is not movabs rax, imm64. Got: 0x%02x 0x%02x", code[0], code[1])
 	}
-	relOffset, ok := inst.Args[0].(x86asm.Rel)
-	if !ok {
-		return fmt.Errorf("The instruction does not use RIP-relative addressing.")
+	
+	// 提取立即数值 (小端序)
+	imm64 := uint64(code[2]) | uint64(code[3])<<8 | uint64(code[4])<<16 | uint64(code[5])<<24 |
+		     uint64(code[6])<<32 | uint64(code[7])<<40 | uint64(code[8])<<48 | uint64(code[9])<<56
+	
+	// 验证立即数是否与 Debug 函数地址一致
+	expectedAddr := j.DebugLibNetInfo.FuncSymbol.SymAddr
+	if imm64 != expectedAddr {
+		return fmt.Errorf("movabs immediate value mismatch. Expected: 0x%x (Debug function addr), Got: 0x%x", expectedAddr, imm64)
 	}
-	// 验证target与Debug入口是否一致
-	targetAddress := funcAbsAddress + uint64(inst.Len) + uint64(relOffset)
-	if targetAddress != j.DebugLibNetInfo.FuncSymbol.SymAddr {
-		return fmt.Errorf("Function entry jmp address does not match expectations.")
+	
+	// 验证第二个指令:jmp *%rax
+	// jmp *%rax 指令格式:FF E0
+	if code[10] != 0xFF || code[11] != 0xE0 {
+		return fmt.Errorf("Second instruction is not jmp *%%rax. Got: 0x%02x 0x%02x", code[10], code[11])
 	}
+	
+	klog.Infof("[checkReleaseFuncSymAfterChange] Successfully verified instruction sequence: movabs $0x%x,%%rax; jmp *%%rax", imm64)
 	return nil
 }
 
@@ -741,8 +773,8 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
 	originalData[offset+2] = byte(getTTLOffset32 >> 8)
 	originalData[offset+3] = byte(getTTLOffset32 >> 16)
 	originalData[offset+4] = byte(getTTLOffset32 >> 24)
-	originalData[offset+5] = 0x90
-	originalData[offset+6] = 0x90
+	originalData[offset+5] = 0x90				//nop
+	originalData[offset+6] = 0x90				//nop
 
 	err = writeDataBytes(pid, insertAddr, originalData)
 	if err != nil {
@@ -771,8 +803,8 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
 	TTLOriginalData[offset+11] = 0x48
 	TTLOriginalData[offset+12] = 0x8b
 	TTLOriginalData[offset+13] = 0x10
-	TTLOriginalData[offset+14] = 0x58
-	TTLOriginalData[offset+15] = 0xc3
+	TTLOriginalData[offset+14] = 0x58				//pop rax
+	TTLOriginalData[offset+15] = 0xc3				//ret
 
 	err = writeDataBytes(pid, getTTLFunctionAddr, TTLOriginalData)
 	if err != nil {
@@ -1092,22 +1124,22 @@ func JvmInject(jvmInjector *JvmInjector) error {
 		return err
 	}
 	// 校验jmp地址修改正确 临时注释
-	// klog.Infof("checkReleaseFuncSymAfterChange")
-	// errReleaseFuncSymAfterChange := jvmInjector.checkReleaseFuncSymAfterChange()
-	// if errReleaseFuncSymAfterChange != nil {
-	// 	klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
-	// 	// 回滚
-	// 	if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 5 {
-	// 		err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
-	// 		if err != nil {
-	// 			klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
-	// 			PtraceDetach(pid)
-	// 			return err
-	// 		}
-	// 	}
-	// 	//PtraceDetach(pid)
-	// 	//return errReleaseFuncSymAfterChange
-	// }
+	klog.Infof("checkReleaseFuncSymAfterChange")
+	errReleaseFuncSymAfterChange := jvmInjector.checkReleaseFuncSymAfterChange()
+	if errReleaseFuncSymAfterChange != nil {
+		klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
+		// 回滚
+		if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 5 {
+			err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
+			if err != nil {
+				klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
+				PtraceDetach(pid)
+				return err
+			}
+		}
+		//PtraceDetach(pid)
+		//return errReleaseFuncSymAfterChange
+	}
 
 	return PtraceDetach(pid)
 }