Skip to content

Commit c612aba

Browse files
authored
🤖 Merge PR DefinitelyTyped#75060 frida-gum: Add Interceptor instrumentation options by @oleavr
1 parent d64d9fa commit c612aba

3 files changed

Lines changed: 110 additions & 7 deletions

File tree

‎types/frida-gum/frida-gum-tests.ts‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,38 @@ Interceptor.attach(puts, {
269269
},
270270
});
271271

272+
Interceptor.attach({
273+
target: puts,
274+
scratchRegister: "x15",
275+
scenario: "online",
276+
relocation: "checked",
277+
}, {
278+
onEnter(args) {
279+
// $ExpectType InvocationArguments
280+
args;
281+
},
282+
});
283+
272284
Interceptor.flush();
273285

274286
// $ExpectType void
275287
Interceptor.replace(ptr("0x1234"), new NativeCallback(() => {}, "void", []));
276288

289+
// $ExpectType void
290+
Interceptor.replace(
291+
{ target: ptr("0x1234"), scratchRegister: "x15", relocation: "unchecked" },
292+
new NativeCallback(() => {}, "void", []),
293+
);
294+
277295
// $ExpectType NativePointer
278296
Interceptor.replaceFast(ptr("0x1234"), new NativeCallback(() => {}, "void", []));
279297

298+
// $ExpectType NativePointer
299+
Interceptor.replaceFast(
300+
{ target: ptr("0x1234"), scenario: "offline", relocation: "forced" },
301+
new NativeCallback(() => {}, "void", []),
302+
);
303+
280304
const ccode = `
281305
#include <gum/gumstalker.h>
282306

‎types/frida-gum/index.d.ts‎

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,13 +3215,18 @@ declare namespace Interceptor {
32153215
* to specify a `InstructionProbeCallback` if `target` is not the first
32163216
* instruction of a function.
32173217
*
3218-
* @param target Address of function/instruction to intercept.
3218+
* The `target` may be specified either as a bare address, or as an object
3219+
* carrying the address alongside instrumentation options such as which
3220+
* scratch register to use.
3221+
*
3222+
* @param target Address of function/instruction to intercept, optionally
3223+
* wrapped together with instrumentation options.
32193224
* @param callbacksOrProbe Callbacks or instruction-level probe callback.
32203225
* @param data User data exposed to `NativeInvocationListenerCallbacks`
32213226
* through the `GumInvocationContext *`.
32223227
*/
32233228
function attach(
3224-
target: NativePointerValue,
3229+
target: NativePointerValue | InstrumentationTarget,
32253230
callbacksOrProbe: InvocationListenerCallbacks | InstructionProbeCallback,
32263231
data?: NativePointerValue,
32273232
): InvocationListener;
@@ -3240,13 +3245,22 @@ declare namespace Interceptor {
32403245
* your implementation. Interceptor uses thread-local state to determine
32413246
* that it should call the original in that case.
32423247
*
3243-
* @param target Address of function to replace.
3248+
* The `target` may be specified either as a bare address, or as an object
3249+
* carrying the address alongside instrumentation options such as which
3250+
* scratch register to use.
3251+
*
3252+
* @param target Address of function to replace, optionally wrapped together
3253+
* with instrumentation options.
32443254
* @param replacement Replacement implementation.
32453255
* @param data User data exposed to native replacement through the
32463256
* `GumInvocationContext *`, obtained using
32473257
* `gum_interceptor_get_current_invocation()`.
32483258
*/
3249-
function replace(target: NativePointerValue, replacement: NativePointerValue, data?: NativePointerValue): void;
3259+
function replace(
3260+
target: NativePointerValue | InstrumentationTarget,
3261+
replacement: NativePointerValue,
3262+
data?: NativePointerValue,
3263+
): void;
32503264

32513265
/**
32523266
* Replaces function at `target` with implementation at `replacement`.
@@ -3258,11 +3272,19 @@ declare namespace Interceptor {
32583272
* means that you need to use the returned pointer if you want to call the
32593273
* original implementation.
32603274
*
3261-
* @param target Address of function to replace.
3275+
* The `target` may be specified either as a bare address, or as an object
3276+
* carrying the address alongside instrumentation options such as which
3277+
* scratch register to use.
3278+
*
3279+
* @param target Address of function to replace, optionally wrapped together
3280+
* with instrumentation options.
32623281
* @param replacement Replacement implementation.
32633282
* @returns Address of trampoline that lets you call the original function.
32643283
*/
3265-
function replaceFast(target: NativePointerValue, replacement: NativePointerValue): NativePointer;
3284+
function replaceFast(
3285+
target: NativePointerValue | InstrumentationTarget,
3286+
replacement: NativePointerValue,
3287+
): NativePointer;
32663288

32673289
/**
32683290
* Reverts the previously replaced function at `target`.
@@ -3282,6 +3304,63 @@ declare namespace Interceptor {
32823304
let breakpointKind: "soft" | "hard";
32833305
}
32843306

3307+
/**
3308+
* Target to instrument, carrying the address alongside optional knobs that
3309+
* control how the inline hook is set up.
3310+
*/
3311+
interface InstrumentationTarget {
3312+
/**
3313+
* Address of function/instruction to instrument.
3314+
*/
3315+
target: NativePointerValue;
3316+
3317+
/**
3318+
* Register that Interceptor may clobber when building the trampoline.
3319+
*
3320+
* Only supported on architectures that expose scratch registers, i.e.
3321+
* arm64 and mips.
3322+
*/
3323+
scratchRegister?: Arm64Register | MipsRegister | undefined;
3324+
3325+
/**
3326+
* Whether another thread might be executing the target while it is being
3327+
* instrumented.
3328+
*
3329+
* Use `online` when calls may be in flight, i.e. a thread could have
3330+
* executed an instruction with call semantics (CALL/BL/etc.) but not yet
3331+
* returned. Use `offline` when that cannot happen — e.g. after `spawn()`
3332+
* but before `resume()`, or when no calls will occur until some external
3333+
* input you control. The `offline` scenario allows writing past the end of
3334+
* such an instruction, which would be unsafe online.
3335+
*
3336+
* Defaults to `online`.
3337+
*/
3338+
scenario?: InstrumentationScenario | undefined;
3339+
3340+
/**
3341+
* How to deal with relocation of the instructions overwritten by the hook.
3342+
*
3343+
* Defaults to `checked`.
3344+
*/
3345+
relocation?: RelocationPolicy | undefined;
3346+
}
3347+
3348+
type InstrumentationScenario = "online" | "offline";
3349+
3350+
/**
3351+
* How aggressively Interceptor may rewrite the function being instrumented.
3352+
*
3353+
* - `checked`: verify that the chosen scratch register (default or
3354+
* user-specified) is not used in the function's early prologue, that there
3355+
* are no branches back into the overwritten instruction(s), and similar
3356+
* constraints.
3357+
* - `unchecked`: skip those checks.
3358+
* - `forced`: like `unchecked`, but also allow overwriting past the end of the
3359+
* function — for cases where you know it is safe, e.g. because of alignment
3360+
* padding between this function and the next.
3361+
*/
3362+
type RelocationPolicy = "checked" | "unchecked" | "forced";
3363+
32853364
declare class InvocationListener {
32863365
/**
32873366
* Detaches listener previously attached through `Interceptor#attach()`.

‎types/frida-gum/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"name": "@types/frida-gum",
4-
"version": "19.1.9999",
4+
"version": "19.2.9999",
55
"nonNpm": true,
66
"nonNpmDescription": "frida-gum",
77
"projects": [

0 commit comments

Comments
 (0)