github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/hooker/hooker.go (about) 1 package hooker 2 3 import ( 4 "sort" 5 "unsafe" 6 7 "github.com/Rookout/GoSDK/pkg/augs" 8 "github.com/Rookout/GoSDK/pkg/rookoutErrors" 9 "github.com/Rookout/GoSDK/pkg/services/instrumentation/module" 10 "github.com/Rookout/GoSDK/pkg/services/safe_hook_installer" 11 "github.com/Rookout/GoSDK/pkg/services/safe_hook_validator" 12 ) 13 14 type Address = uint64 15 16 type Hooker interface { 17 StartWritingBreakpoint(bpInstance *augs.BreakpointInstance) (hookContext BreakpointFlowRunner, err error) 18 StartErasingBreakpoint(bpInstance *augs.BreakpointInstance) (hookContext BreakpointFlowRunner, err error) 19 StartCopyingFunction(f *augs.Function) (hookContext BreakpointFlowRunner, err error) 20 } 21 22 type hookerImpl struct { 23 bpCallback unsafe.Pointer 24 api NativeHookerAPI 25 } 26 27 type NativeHookerAPI interface { 28 RegisterFunctionBreakpointsState(functionEntry Address, functionEnd Address, breakpoints []*augs.BreakpointInstance, bpCallback uintptr, prologue []byte, hasStackFrame bool) (stateID int, err error) 29 GetInstructionMapping(functionEntry Address, functionEnd Address, stateID int) (addressMappings []module.AddressMapping, offsetMappings []module.AddressMapping, err error) 30 GetStateEntryAddr(functionEntry Address, functionEnd Address, stateID int) (uintptr, error) 31 ApplyBreakpointsState(functionEntry Address, functionEnd Address, stateID int) (err error) 32 GetHookAddress(functionEntry uint64, functionEnd uint64, stateID int) (uintptr, rookoutErrors.RookoutError) 33 GetFunctionType(functionEntry uint64, functionEnd uint64) (safe_hook_validator.FunctionType, error) 34 TriggerWatchDog(timeoutMS uint64) error 35 DefuseWatchDog() 36 } 37 38 func New(bpCallback unsafe.Pointer) Hooker { 39 return &hookerImpl{ 40 bpCallback: bpCallback, 41 api: NewNativeAPI(), 42 } 43 } 44 45 func sortSlice(slice []uint64) []uint64 { 46 sort.Slice(slice, func(i, j int) bool { 47 return slice[i] < slice[j] 48 }) 49 50 return slice 51 } 52 53 func (h *hookerImpl) StartCopyingFunction(f *augs.Function) (BreakpointFlowRunner, error) { 54 return NewFlowRunner(h.api, BreakpointFlowRunnerInitializationInfo{Function: f}, []*augs.BreakpointInstance{}, safe_hook_installer.NewSafeHookInstaller) 55 } 56 57 func (h *hookerImpl) StartWritingBreakpoint(bpInstance *augs.BreakpointInstance) (BreakpointFlowRunner, error) { 58 initInfo := BreakpointFlowRunnerInitializationInfo{ 59 Function: bpInstance.Function, 60 BPCallback: uintptr(h.bpCallback), 61 } 62 allBPs := append(bpInstance.Function.GetBreakpointInstances(), bpInstance) 63 64 baseCtxt, err := NewFlowRunner(h.api, initInfo, allBPs, safe_hook_installer.NewSafeHookInstaller) 65 if err != nil { 66 return nil, err 67 } 68 return baseCtxt, nil 69 } 70 71 func (h *hookerImpl) StartErasingBreakpoint(bpInstance *augs.BreakpointInstance) (BreakpointFlowRunner, error) { 72 initInfo := BreakpointFlowRunnerInitializationInfo{ 73 Function: bpInstance.Function, 74 BPCallback: uintptr(h.bpCallback), 75 } 76 var allBPs []*augs.BreakpointInstance 77 78 for _, bp := range bpInstance.Function.GetBreakpointInstances() { 79 if bp.Addr == bpInstance.Addr { 80 continue 81 } 82 allBPs = append(allBPs, bp) 83 } 84 85 baseCtxt, err := NewFlowRunner(h.api, initInfo, allBPs, safe_hook_installer.NewSafeHookInstaller) 86 if err != nil { 87 return nil, err 88 } 89 return baseCtxt, nil 90 } 91 92 func (h *hookerImpl) getNativeAPI() NativeHookerAPI { 93 return h.api 94 }