github.com/undefinedlabs/go-mpatch@v1.0.8-0.20230904093002-fbac8a0d7853/patcher_arm64.go (about) 1 //go:build arm64 2 // +build arm64 3 4 package mpatch 5 6 import "unsafe" 7 8 // Code from: https://github.com/agiledragon/gomonkey/blob/master/jmp_arm64.go 9 10 // Gets the jump function rewrite bytes 11 // 12 //go:nosplit 13 func getJumpFuncBytes(to unsafe.Pointer) ([]byte, error) { 14 res := make([]byte, 0, 24) 15 d0d1 := uintptr(to) & 0xFFFF 16 d2d3 := uintptr(to) >> 16 & 0xFFFF 17 d4d5 := uintptr(to) >> 32 & 0xFFFF 18 d6d7 := uintptr(to) >> 48 & 0xFFFF 19 20 res = append(res, movImm(0b10, 0, d0d1)...) // MOVZ x26, double[16:0] 21 res = append(res, movImm(0b11, 1, d2d3)...) // MOVK x26, double[32:16] 22 res = append(res, movImm(0b11, 2, d4d5)...) // MOVK x26, double[48:32] 23 res = append(res, movImm(0b11, 3, d6d7)...) // MOVK x26, double[64:48] 24 res = append(res, []byte{0x4A, 0x03, 0x40, 0xF9}...) // LDR x10, [x26] 25 res = append(res, []byte{0x40, 0x01, 0x1F, 0xD6}...) // BR x10 26 27 return res, nil 28 } 29 30 func movImm(opc, shift int, val uintptr) []byte { 31 var m uint32 = 26 // rd 32 m |= uint32(val) << 5 // imm16 33 m |= uint32(shift&3) << 21 // hw 34 m |= 0b100101 << 23 // const 35 m |= uint32(opc&0x3) << 29 // opc 36 m |= 0b1 << 31 // sf 37 38 res := make([]byte, 4) 39 *(*uint32)(unsafe.Pointer(&res[0])) = m 40 41 return res 42 }