@@ -3296,6 +3296,15 @@ declare namespace Interceptor {
32963296 */
32973297 function flush ( ) : void ;
32983298
3299+ /**
3300+ * Default instrumentation options applied to every subsequent
3301+ * `attach()` / `replace()` / `replaceFast()` call.
3302+ *
3303+ * Options specified per call through `InstrumentationTarget` take
3304+ * precedence over these.
3305+ */
3306+ let defaults : InstrumentationOptions ;
3307+
32993308 /**
33003309 * The kind of breakpoints to use for non-inline hooks.
33013310 *
@@ -3308,12 +3317,20 @@ declare namespace Interceptor {
33083317 * Target to instrument, carrying the address alongside optional knobs that
33093318 * control how the inline hook is set up.
33103319 */
3311- interface InstrumentationTarget {
3320+ interface InstrumentationTarget extends InstrumentationOptions {
33123321 /**
33133322 * Address of function/instruction to instrument.
33143323 */
33153324 target : NativePointerValue ;
3325+ }
33163326
3327+ /**
3328+ * Knobs that control how an inline hook is set up.
3329+ *
3330+ * May be specified per call through `InstrumentationTarget`, or globally
3331+ * through `Interceptor.defaults`.
3332+ */
3333+ interface InstrumentationOptions {
33173334 /**
33183335 * Register that Interceptor may clobber when building the trampoline.
33193336 *
@@ -3343,8 +3360,85 @@ interface InstrumentationTarget {
33433360 * Defaults to `checked`.
33443361 */
33453362 relocation ?: RelocationPolicy | undefined ;
3363+
3364+ /**
3365+ * Callback that emits a custom redirect from the instrumented function or
3366+ * instruction to Interceptor's trampoline.
3367+ *
3368+ * The primary use-case is defeating fingerprinting: emitting a redirect
3369+ * that a RASP implementation won't recognize as an inline hook. It is also
3370+ * useful when space is tight and you want to locate a nearby code cave
3371+ * reachable through a short immediate branch, and then branch from there to
3372+ * the trampoline farther away.
3373+ *
3374+ * Throwing from the callback declines the redirect. There is no fallback to
3375+ * the default strategy in that case: the `attach()` / `replace()` /
3376+ * `replaceFast()` call fails as if the target had a signature that could
3377+ * not be instrumented.
3378+ */
3379+ writeRedirect ?: WriteRedirectCallback | undefined ;
3380+
3381+ /**
3382+ * Upper bound on the number of bytes that `writeRedirect` will need.
3383+ *
3384+ * Your callback may end up using less. Specifying a larger value means
3385+ * Interceptor has to explore further to determine that it is safe to use
3386+ * that much space — looking for back-branches, call return sites, etc. —
3387+ * which is more expensive.
3388+ *
3389+ * Defaults to the size needed for a full redirect, e.g. 16 bytes on arm64.
3390+ */
3391+ redirectSpaceHint ?: number | undefined ;
3392+ }
3393+
3394+ /**
3395+ * Callback that emits a custom redirect from the target to Interceptor's
3396+ * trampoline.
3397+ */
3398+ type WriteRedirectCallback = ( details : WriteRedirectDetails ) => void ;
3399+
3400+ /**
3401+ * Details passed to a `WriteRedirectCallback`.
3402+ */
3403+ interface WriteRedirectDetails {
3404+ /**
3405+ * Code writer to emit the redirect with.
3406+ *
3407+ * The concrete type depends on the architecture, e.g. an `X86Writer` on
3408+ * x86 and an `Arm64Writer` on arm64. On 32-bit ARM it may be either an
3409+ * `ArmWriter` or a `ThumbWriter`, depending on the instruction set at the
3410+ * instrumented site.
3411+ */
3412+ writer : DefaultInstructionWriter ;
3413+
3414+ /**
3415+ * Address of Interceptor's trampoline, i.e. where your redirect should
3416+ * branch to.
3417+ */
3418+ target : NativePointer ;
3419+
3420+ /**
3421+ * Scratch register that the redirect may clobber.
3422+ *
3423+ * Only present on architectures that expose scratch registers, i.e.
3424+ * arm64 and mips.
3425+ */
3426+ scratchRegister ?: Arm64Register | MipsRegister | undefined ;
3427+
3428+ /**
3429+ * Number of bytes available for the redirect.
3430+ */
3431+ capacity : number ;
33463432}
33473433
3434+ /**
3435+ * Default code writer for the current architecture.
3436+ *
3437+ * On 32-bit ARM this is either an `ArmWriter` or a `ThumbWriter`, depending on
3438+ * the instruction set at the instrumented site.
3439+ */
3440+ type DefaultInstructionWriter = X86Writer | ArmWriter | ThumbWriter | Arm64Writer | MipsWriter ;
3441+
33483442type InstrumentationScenario = "online" | "offline" ;
33493443
33503444/**
0 commit comments