|
@@ -72,7 +72,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
Inst: inst,
|
|
Inst: inst,
|
|
|
//IntelInst: x86asm.IntelSyntax(inst, 0, nil),
|
|
//IntelInst: x86asm.IntelSyntax(inst, 0, nil),
|
|
|
}
|
|
}
|
|
|
- if pc == 0 && inst.Op == x86asm.JMP {
|
|
|
|
|
|
|
+ if pc == 10 && inst.Op == x86asm.JMP {
|
|
|
// 已经被修改过的首指令
|
|
// 已经被修改过的首指令
|
|
|
j.PreCheck.EbpfCanInjection = true
|
|
j.PreCheck.EbpfCanInjection = true
|
|
|
j.Uprobe.ELFPath = j.DebugLibNetInfo.LibPath
|
|
j.Uprobe.ELFPath = j.DebugLibNetInfo.LibPath
|
|
@@ -171,7 +171,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
|
|
|
pc += uint64(inst.Len)
|
|
pc += uint64(inst.Len)
|
|
|
}
|
|
}
|
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
|
|
|
- j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:5]
|
|
|
|
|
|
|
+ j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:12]
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -360,22 +360,54 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return fmt.Errorf("readMemory error in checkReleaseFuncSymAfterChange <%v>", err)
|
|
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
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -612,6 +644,24 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
|
|
|
return fmt.Errorf("Error getting function offset: %v", err)
|
|
return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ functionConvert0Sym, err := GetFunctionOffset(j.DebugLibNetInfo.LibPath, j.DebugLibNetInfo.FuncConvert0Symbol.SymName)
|
|
|
|
|
+ // 计算函数的实际内存地址
|
|
|
|
|
+ j.DebugLibNetInfo.FuncConvert0Symbol.SymAddr = baseAddress + functionConvert0Sym.Value
|
|
|
|
|
+ j.DebugLibNetInfo.FuncConvert0Symbol.SymSize = functionConvert0Sym.Size
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ functionGetTTLSym, err := GetFunctionOffset(j.DebugLibNetInfo.LibPath, j.DebugLibNetInfo.FuncGetTTLSymbol.SymName)
|
|
|
|
|
+ // 计算函数的实际内存地址
|
|
|
|
|
+ j.DebugLibNetInfo.FuncGetTTLSymbol.SymAddr = baseAddress + functionGetTTLSym.Value
|
|
|
|
|
+ j.DebugLibNetInfo.FuncGetTTLSymbol.SymSize = functionGetTTLSym.Size
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return fmt.Errorf("Error getting function offset: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
_, err = j.findDebugAddressInfoFromMem()
|
|
_, err = j.findDebugAddressInfoFromMem()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return fmt.Errorf("Error finding first CALL instuction: %v", err)
|
|
return fmt.Errorf("Error finding first CALL instuction: %v", err)
|
|
@@ -672,59 +722,217 @@ func writeData(pid int, addr uintptr, data uint64) error {
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func modifyIoFdTargetAddr(pid int, insertAddr, distAddr uintptr) error {
|
|
|
|
|
- newOffset := distAddr - (insertAddr + 7)
|
|
|
|
|
- targetAddr := insertAddr + 3
|
|
|
|
|
- // 获取目标地址处的数据
|
|
|
|
|
- originalData, err := readData(pid, targetAddr)
|
|
|
|
|
|
|
+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, getTTLFunctionAddr uintptr) error {
|
|
|
|
|
+ // newOffset := distAddr - (insertAddr + 7)
|
|
|
|
|
+ // targetAddr := insertAddr + 3
|
|
|
|
|
+ // // 获取目标地址处的数据
|
|
|
|
|
+ // originalData, err := readData(pid, targetAddr)
|
|
|
|
|
+ // if err != nil {
|
|
|
|
|
+ // return err
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // // 更新数据中的目标偏移
|
|
|
|
|
+ // updatedData := (originalData & 0xFFFFFFFF00000000) | uint64(newOffset&0xFFFFFFFF)
|
|
|
|
|
+ // err = writeData(pid, targetAddr, updatedData)
|
|
|
|
|
+ // if err != nil {
|
|
|
|
|
+ // return err
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ getTTLOffset := getTTLFunctionAddr - insertAddr - 5
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 读取原始数据
|
|
|
|
|
+ // alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
+ originalData, err := readDataBytes(pid, insertAddr, 7)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 更新数据中的目标偏移
|
|
|
|
|
- updatedData := (originalData & 0xFFFFFFFF00000000) | uint64(newOffset&0xFFFFFFFF)
|
|
|
|
|
- err = writeData(pid, targetAddr, updatedData)
|
|
|
|
|
|
|
+ // offset := insertAddr % uintptr(unsafe.Sizeof(uintptr(0)))
|
|
|
|
|
+ offset := 0
|
|
|
|
|
+
|
|
|
|
|
+ // 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
|
|
|
+ var getTTLOffset32 uint32 = uint32(getTTLOffset)
|
|
|
|
|
+ originalData[offset] = 0xE8 // call
|
|
|
|
|
+ originalData[offset+1] = byte(getTTLOffset32)
|
|
|
|
|
+ originalData[offset+2] = byte(getTTLOffset32 >> 8)
|
|
|
|
|
+ originalData[offset+3] = byte(getTTLOffset32 >> 16)
|
|
|
|
|
+ originalData[offset+4] = byte(getTTLOffset32 >> 24)
|
|
|
|
|
+ originalData[offset+5] = 0x90 //nop
|
|
|
|
|
+ originalData[offset+6] = 0x90 //nop
|
|
|
|
|
+
|
|
|
|
|
+ err = writeDataBytes(pid, insertAddr, originalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ //以上是先跳转到2GB内存的无用函数中
|
|
|
|
|
+ //以下来写真正的跳转函数
|
|
|
|
|
+
|
|
|
|
|
+ TTLOriginalData, err := readDataBytes(pid, getTTLFunctionAddr, 16)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ TTLOriginalData[offset] = 0x50
|
|
|
|
|
+ TTLOriginalData[offset+1] = 0x48
|
|
|
|
|
+ TTLOriginalData[offset+2] = 0xb8
|
|
|
|
|
+ TTLOriginalData[offset+3] = byte(distAddr)
|
|
|
|
|
+ TTLOriginalData[offset+4] = byte(distAddr >> 8)
|
|
|
|
|
+ TTLOriginalData[offset+5] = byte(distAddr >> 16)
|
|
|
|
|
+ TTLOriginalData[offset+6] = byte(distAddr >> 24)
|
|
|
|
|
+ TTLOriginalData[offset+7] = byte(distAddr >> 32)
|
|
|
|
|
+ TTLOriginalData[offset+8] = byte(distAddr >> 40)
|
|
|
|
|
+ TTLOriginalData[offset+9] = byte(distAddr >> 48)
|
|
|
|
|
+ TTLOriginalData[offset+10] = byte(distAddr >> 56)
|
|
|
|
|
+ TTLOriginalData[offset+11] = 0x48
|
|
|
|
|
+ TTLOriginalData[offset+12] = 0x8b
|
|
|
|
|
+ TTLOriginalData[offset+13] = 0x10
|
|
|
|
|
+ TTLOriginalData[offset+14] = 0x58 //pop rax
|
|
|
|
|
+ TTLOriginalData[offset+15] = 0xc3 //ret
|
|
|
|
|
+
|
|
|
|
|
+ err = writeDataBytes(pid, getTTLFunctionAddr, TTLOriginalData)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr uintptr) error {
|
|
|
|
|
- sendOffset := sendReleaseAddr - sendDebugAddr - 5
|
|
|
|
|
|
|
+func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0FunctionAddr uintptr) error {
|
|
|
|
|
+ // sendOffset := sendReleaseAddr - sendDebugAddr - 5
|
|
|
|
|
+
|
|
|
|
|
+ // // 读取原始数据
|
|
|
|
|
+ // alignedAddr := sendDebugAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
+ // originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
+ // if err != nil {
|
|
|
|
|
+ // return err
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
+ // offsetLocation := (sendDebugAddr % uintptr(unsafe.Sizeof(uintptr(0)))) + 1
|
|
|
|
|
+ // *(*uint32)(unsafe.Pointer(&bytes[offsetLocation])) = uint32(sendOffset)
|
|
|
|
|
+
|
|
|
|
|
+ // err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
+ // if err != nil {
|
|
|
|
|
+ // return err
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
- // 读取原始数据
|
|
|
|
|
- alignedAddr := sendDebugAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
- originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
|
|
+ convert0Offset := convert0FunctionAddr - sendDebugAddr - 5
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 读取原始数据
|
|
|
|
|
+ // alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
+ originalData, err := readDataBytes(pid, sendDebugAddr, 5)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
- offsetLocation := (sendDebugAddr % uintptr(unsafe.Sizeof(uintptr(0)))) + 1
|
|
|
|
|
- *(*uint32)(unsafe.Pointer(&bytes[offsetLocation])) = uint32(sendOffset)
|
|
|
|
|
|
|
+ // offset := insertAddr % uintptr(unsafe.Sizeof(uintptr(0)))
|
|
|
|
|
+ offset := 0
|
|
|
|
|
+
|
|
|
|
|
+ // 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
|
|
|
|
|
+ var convert0Offset32 uint32 = uint32(convert0Offset)
|
|
|
|
|
+ originalData[offset] = 0xE8 // call
|
|
|
|
|
+ originalData[offset+1] = byte(convert0Offset32)
|
|
|
|
|
+ originalData[offset+2] = byte(convert0Offset32 >> 8)
|
|
|
|
|
+ originalData[offset+3] = byte(convert0Offset32 >> 16)
|
|
|
|
|
+ originalData[offset+4] = byte(convert0Offset32 >> 24)
|
|
|
|
|
|
|
|
- err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
|
|
+ err = writeDataBytes(pid, sendDebugAddr, originalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ convert0OriginalData, err := readDataBytes(pid, convert0FunctionAddr, 13)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ convert0OriginalData[offset] = 0x48
|
|
|
|
|
+ convert0OriginalData[offset+1] = 0xb8
|
|
|
|
|
+ convert0OriginalData[offset+2] = byte(sendReleaseAddr)
|
|
|
|
|
+ convert0OriginalData[offset+3] = byte(sendReleaseAddr >> 8)
|
|
|
|
|
+ convert0OriginalData[offset+4] = byte(sendReleaseAddr >> 16)
|
|
|
|
|
+ convert0OriginalData[offset+5] = byte(sendReleaseAddr >> 24)
|
|
|
|
|
+ convert0OriginalData[offset+6] = byte(sendReleaseAddr >> 32)
|
|
|
|
|
+ convert0OriginalData[offset+7] = byte(sendReleaseAddr >> 40)
|
|
|
|
|
+ convert0OriginalData[offset+8] = byte(sendReleaseAddr >> 48)
|
|
|
|
|
+ convert0OriginalData[offset+9] = byte(sendReleaseAddr >> 56)
|
|
|
|
|
+ convert0OriginalData[offset+10] = 0xff
|
|
|
|
|
+ convert0OriginalData[offset+11] = 0xd0
|
|
|
|
|
+ convert0OriginalData[offset+12] = 0xc3
|
|
|
|
|
+
|
|
|
|
|
+ err = writeDataBytes(pid, convert0FunctionAddr, convert0OriginalData)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) error {
|
|
|
|
|
- offset := debugEnterAddr - (originEnterAddr + 5)
|
|
|
|
|
|
|
+// func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) error {
|
|
|
|
|
+// offset := debugEnterAddr - (originEnterAddr + 5)
|
|
|
|
|
+
|
|
|
|
|
+// // 读取原始数据
|
|
|
|
|
+// alignedAddr := originEnterAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
+// originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
+// if err != nil {
|
|
|
|
|
+// return err
|
|
|
|
|
+// }
|
|
|
|
|
+
|
|
|
|
|
+// bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
+// bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0)))] = 0xe9
|
|
|
|
|
+// *(*uint32)(unsafe.Pointer(&bytes[(originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0))))+1])) = uint32(offset)
|
|
|
|
|
+// err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
+// if err != nil {
|
|
|
|
|
+// return err
|
|
|
|
|
+// }
|
|
|
|
|
+// return nil
|
|
|
|
|
+// }
|
|
|
|
|
|
|
|
- // 读取原始数据
|
|
|
|
|
|
|
+func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) error {
|
|
|
|
|
+ // 读取原始数据 - 需要12字节来存储完整的跳转指令
|
|
|
alignedAddr := originEnterAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
alignedAddr := originEnterAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
- originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
|
|
+ originalData, err := readDataBytes(pid, alignedAddr, 12)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
- bytes[originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0)))] = 0xe9
|
|
|
|
|
- *(*uint32)(unsafe.Pointer(&bytes[(originEnterAddr%uintptr(unsafe.Sizeof(uintptr(0))))+1])) = uint32(offset)
|
|
|
|
|
- err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
|
|
+ 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 {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -732,18 +940,26 @@ func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) er
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func restoreOriginalInstructions(pid int, addr uintptr, instructions []byte) error {
|
|
func restoreOriginalInstructions(pid int, addr uintptr, instructions []byte) error {
|
|
|
- alignedAddr := addr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
- originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
|
|
+ // alignedAddr := addr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
|
|
|
|
|
+ // originalData, err := readData(pid, alignedAddr)
|
|
|
|
|
+ originalData, err := readDataBytes(pid, addr, len(instructions))
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
|
|
+ // bytes := (*[8]byte)(unsafe.Pointer(&originalData))
|
|
|
|
|
+ // for i := 0; i < len(instructions); i++ {
|
|
|
|
|
+ // bytes[addr%uintptr(unsafe.Sizeof(uintptr(0)))+uintptr(i)] = instructions[i]
|
|
|
|
|
+ // }
|
|
|
|
|
+
|
|
|
|
|
+ // offset := addr % uintptr(unsafe.Sizeof(uintptr(0)))
|
|
|
|
|
+
|
|
|
for i := 0; i < len(instructions); i++ {
|
|
for i := 0; i < len(instructions); i++ {
|
|
|
- bytes[addr%uintptr(unsafe.Sizeof(uintptr(0)))+uintptr(i)] = instructions[i]
|
|
|
|
|
|
|
+ originalData[i] = instructions[i]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
|
|
+ // err = writeData(pid, alignedAddr, originalData)
|
|
|
|
|
+ err = writeDataBytes(pid, addr, originalData)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
@@ -850,6 +1066,8 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
}
|
|
}
|
|
|
// 修改
|
|
// 修改
|
|
|
debugFuncEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
debugFuncEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncSymbol.SymAddr)
|
|
|
|
|
+ debugFuncGetTTLEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncGetTTLSymbol.SymAddr)
|
|
|
|
|
+ debugFuncConvert0EnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncConvert0Symbol.SymAddr)
|
|
|
debugIoFdAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.SymAddr)
|
|
debugIoFdAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.SymAddr)
|
|
|
debugNetSendAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.NET_Send.SymAddr)
|
|
debugNetSendAddr := uintptr(jvmInjector.DebugLibNetInfo.InnerSymbol.NET_Send.SymAddr)
|
|
|
|
|
|
|
@@ -860,6 +1078,9 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
|
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
|
|
|
|
|
+ fmt.Printf("conver0 -> <0x%x>\n", debugFuncConvert0EnterAddr)
|
|
|
|
|
+ fmt.Printf("getttl -> <0x%x>\n", debugFuncGetTTLEnterAddr)
|
|
|
|
|
+
|
|
|
|
|
|
|
|
// 附加到目标进程
|
|
// 附加到目标进程
|
|
|
klog.Infof("attach")
|
|
klog.Infof("attach")
|
|
@@ -877,7 +1098,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
//time.Now().UnixNano()
|
|
//time.Now().UnixNano()
|
|
|
// 修改目标的内存
|
|
// 修改目标的内存
|
|
|
klog.Infof("modifyIoFdTargetAddr")
|
|
klog.Infof("modifyIoFdTargetAddr")
|
|
|
- err = modifyIoFdTargetAddr(pid, debugIoFdAddr, ioFdReleaseTargetAddr)
|
|
|
|
|
|
|
+ err = modifyIoFdTargetAddr(pid, debugIoFdAddr, ioFdReleaseTargetAddr, debugFuncGetTTLEnterAddr)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
klog.Error(err)
|
|
klog.Error(err)
|
|
|
PtraceDetach(pid)
|
|
PtraceDetach(pid)
|
|
@@ -885,7 +1106,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
klog.Infof("modifyNetSetTargetAddr")
|
|
klog.Infof("modifyNetSetTargetAddr")
|
|
|
- err = modifyNetSetTargetAddr(pid, debugNetSendAddr, netSendReleaseTargetAddr)
|
|
|
|
|
|
|
+ err = modifyNetSetTargetAddr(pid, debugNetSendAddr, netSendReleaseTargetAddr, debugFuncConvert0EnterAddr)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
klog.Error(err)
|
|
klog.Error(err)
|
|
|
PtraceDetach(pid)
|
|
PtraceDetach(pid)
|
|
@@ -910,13 +1131,13 @@ func JvmInject(jvmInjector *JvmInjector) error {
|
|
|
PtraceDetach(pid)
|
|
PtraceDetach(pid)
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- // 校验jmp地址修改正确
|
|
|
|
|
|
|
+ // 校验jmp地址修改正确 临时注释
|
|
|
klog.Infof("checkReleaseFuncSymAfterChange")
|
|
klog.Infof("checkReleaseFuncSymAfterChange")
|
|
|
errReleaseFuncSymAfterChange := jvmInjector.checkReleaseFuncSymAfterChange()
|
|
errReleaseFuncSymAfterChange := jvmInjector.checkReleaseFuncSymAfterChange()
|
|
|
if errReleaseFuncSymAfterChange != nil {
|
|
if errReleaseFuncSymAfterChange != nil {
|
|
|
klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
|
|
klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
|
|
|
// 回滚
|
|
// 回滚
|
|
|
- if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 5 {
|
|
|
|
|
|
|
+ if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 12 {
|
|
|
err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
|
|
err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
|
|
klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")
|