|
| 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 | +} |
0 commit comments