github.com/tencent/goom@v1.0.1/internal/patch/monkey_arm64.go (about) 1 package patch 2 3 import ( 4 "unsafe" 5 ) 6 7 const ( 8 _0b1 = 1 // _0b1 9 _0b10 = 2 // 0b10 10 _0b11 = 3 // 0b11 11 _0b100101 = 37 // 0b100101 12 ) 13 14 // nopOpcode 空指令插入到原函数开头第一个字节, 用于判断原函数是否已经被Patch过 15 var nopOpcode = []byte{0xD5, 0x03, 0x20, 0x1F} 16 17 func jmpToFunctionValue(_, double uintptr) []byte { 18 //func buildJmpDirective(double uintptr) []byte { 19 res := make([]byte, 0, 24) 20 d0d1 := double & 0xFFFF 21 d2d3 := double >> 16 & 0xFFFF 22 d4d5 := double >> 32 & 0xFFFF 23 d6d7 := double >> 48 & 0xFFFF 24 25 res = append(res, movImm(_0b10, 0, d0d1)...) // MOVZ x26, double[16:0] 26 res = append(res, movImm(_0b11, 1, d2d3)...) // MOVK x26, double[32:16] 27 res = append(res, movImm(_0b11, 2, d4d5)...) // MOVK x26, double[48:32] 28 res = append(res, movImm(_0b11, 3, d6d7)...) // MOVK x26, double[64:48] 29 res = append(res, []byte{0x4A, 0x03, 0x40, 0xF9}...) // LDR x10, [x26] 30 res = append(res, []byte{0x40, 0x01, 0x1F, 0xD6}...) // BR x10 31 32 return res 33 } 34 35 func movImm(opc, shift int, val uintptr) []byte { 36 var m uint32 = 26 // rd 37 m |= uint32(val) << 5 // imm16 38 m |= uint32(shift&3) << 21 // hw 39 m |= _0b100101 << 23 // const 40 m |= uint32(opc&0x3) << 29 // opc 41 m |= _0b1 << 31 // sf 42 43 res := make([]byte, 4) 44 *(*uint32)(unsafe.Pointer(&res[0])) = m 45 46 return res 47 } 48 49 // jmpToOriginFunctionValue Assembles a jump to a function value 50 func jmpToOriginFunctionValue(_, _ uintptr) (value []byte) { 51 panic("not support yet") 52 } 53 54 // checkAlreadyPatch 检测是否已经patch 55 func checkAlreadyPatch(origin []byte) bool { 56 for i := 0; i < len(nopOpcode); i++ { 57 if origin[i] != nopOpcode[i] { 58 return false 59 } 60 } 61 return true 62 }