Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrCyclicReplacement returned if you want to perform replacements like "a"->"b" and "b"->"a". // Such replacements lead to infinite loop. ErrCyclicReplacement = fmt.Errorf("cyclic replacement detected") // ErrFunctionNotFound returned when provided function was not found. ErrFunctionNotFound = replacer.ErrFunctionNotFound // ErrUnsupportedArchitecture returned if cpu architecture currently unsupported. ErrUnsupportedArchitecture = replacer.ErrUnsupportedArchitecture // ErrShortFunction returned if function too short for trampoline. ErrShortFunction = replacer.ErrShortFunction // ErrLongDistance returned if functions located too far for trampoline. ErrLongDistance = replacer.ErrLongDistance )
Functions ¶
func RegisterReplacement ¶
RegisterReplacement registers function replacement in patcher. Defined as function because it's impossible to use different type parameters in methods. Note that arguments must be functions despite "any" used as constraint
because generics doesn't allow to specify that parameter must be "any function".
Types ¶
type PatchAndExecOption ¶
type PatchAndExecOption interface {
// contains filtered or unexported methods
}
func RemovePatchedExecutable ¶
func RemovePatchedExecutable() PatchAndExecOption
RemovePatchedExecutable enables automatic removal of patched executable.
func WithEnvVarName ¶
func WithEnvVarName(name string) PatchAndExecOption
WithEnvVarName sets a custom environment variable name to determine if code runs inside patched executable or not.
func WithEnvVarValue ¶
func WithEnvVarValue(value string) PatchAndExecOption
WithEnvVarValue sets exact value for environment variable used to determine if code runs inside patched executable or not. Without this option only presence of variable will be checked.
type Patcher ¶
type Patcher struct {
// contains filtered or unexported fields
}
Patcher is a registry of function replacements applied to executable
func (*Patcher) Apply ¶
Apply just calls callback with itself. This needed to support "flow-style" interface.
func (*Patcher) MustPatchAndExec ¶
func (p *Patcher) MustPatchAndExec(opts ...PatchAndExecOption)
MustPatchAndExec acts like PatchAndExec but panics on errors.
func (*Patcher) PatchAndExec ¶
func (p *Patcher) PatchAndExec(opts ...PatchAndExecOption) error
PatchAndExec makes patches according to registered replacements and re-runs executable. Algorithm: 0) Check if we are not running patched executable, otherwise go to 1. This made by checking presence (or exact value if specified) of special environment variable. 0.1) Remove itself if such option specified. 1) Copy current executable to temporary file 2) For each replacement: replace beginning of original function with "trampoline" to replacement function. 3) Run patched executable with special environment variable to avoid recursions (this is terminal condition). 'execve' system call used on *nix systems, 'exec.Command' with stdin/out/err attached and 'os.Exit' after termination on others. So on successful run all code after this function in original executable will become unreachable.