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