github.com/tencent/goom@v1.0.1/internal/patch/monkey_amd64.go (about) 1 package patch 2 3 import "unsafe" 4 5 // nopOpcode 空指令插入到原函数开头第一个字节, 用于判断原函数是否已经被 Patch 过 6 const nopOpcode byte = 0x90 7 8 // jmpToFunctionValue Assembles a jump to a function value 9 func jmpToFunctionValue(_, to uintptr) (value []byte) { 10 return []byte{ 11 0x90, // NOP 12 0x48, 0xBA, 13 byte(to), 14 byte(to >> 8), 15 byte(to >> 16), 16 byte(to >> 24), 17 byte(to >> 32), 18 byte(to >> 40), 19 byte(to >> 48), 20 byte(to >> 56), // movabs rdx,to 21 0xFF, 0x22, // jmp QWORD PTR [rdx] 22 } 23 } 24 25 // jmpToOriginFunctionValue Assembles a jump to a function value 26 func jmpToOriginFunctionValue(from, to uintptr) (value []byte) { 27 if relative(from, to) { 28 var dis uint32 29 if to > from { 30 dis = uint32(int32(to-from) - 5) 31 } else { 32 dis = uint32(-int32(from-to) - 5) 33 } 34 35 return []byte{ 36 0xe9, 37 byte(dis), 38 byte(dis >> 8), 39 byte(dis >> 16), 40 byte(dis >> 24), 41 } 42 } 43 44 return []byte{ 45 0x48, 0xBA, 46 byte(to), 47 byte(to >> 8), 48 byte(to >> 16), 49 byte(to >> 24), 50 byte(to >> 32), 51 byte(to >> 40), 52 byte(to >> 48), 53 byte(to >> 56), // movabs rdx,to 54 0xFF, 0x22, // jmp QWORD PTR [rdx] 55 } 56 } 57 58 // relative 判断两个指针间隔是否可以用相对地址表示 59 func relative(from uintptr, to uintptr) bool { 60 delta := int64(from - to) 61 if unsafe.Sizeof(uintptr(0)) == unsafe.Sizeof(int32(0)) { 62 delta = int64(int32(from - to)) 63 } 64 65 // 跨度大于2G 时 66 relative := delta <= 0x7fffffff 67 68 if delta < 0 { 69 delta = -delta 70 relative = delta <= 0x80000000 71 } 72 return relative 73 } 74 75 // checkAlreadyPatch 检测是否已经 patch 76 func checkAlreadyPatch(origin []byte) bool { 77 return origin[0] == nopOpcode 78 }