github.com/bytedance/mockey@v1.2.10/internal/monkey/fn/copy_darwin_amd64.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package fn 18 19 import ( 20 "unsafe" 21 22 "github.com/bytedance/mockey/internal/monkey/common" 23 "github.com/bytedance/mockey/internal/tool" 24 "golang.org/x/arch/x86/x86asm" 25 ) 26 27 func copyCode(targetCode, oriCode []byte) { 28 var ( 29 inst x86asm.Inst // current code 30 n int // length of total codes 31 callIdx []int // index list of call instruction 32 err error 33 ) 34 for inst.Op != x86asm.RET { 35 inst, err = x86asm.Decode(oriCode[n:], 64) 36 tool.Assert(err == nil, err) 37 tool.DebugPrintf("copyCode: inst: %v\n", inst) 38 if inst.Op == x86asm.CALL { 39 callIdx = append(callIdx, n) 40 tool.DebugPrintf("copyCode: call code: 0x%x\n", oriCode[n:n+5]) 41 } 42 n += inst.Len 43 } 44 // copy function codes to the target 45 i := copy(targetCode, oriCode[:n]) 46 tool.DebugPrintf("copyCode: oriCode len(%v), copied len(%v)\n", n, i) 47 // replace the relative call addresses 48 callOffset := int32(common.PtrOf(oriCode) - common.PtrOf(targetCode)) 49 tool.DebugPrintf("copyCode: offset: %x\n", callOffset) 50 for _, idx := range callIdx { 51 *(*int32)(unsafe.Pointer(&targetCode[idx+1])) += callOffset 52 } 53 }