Skip to content

Instantly share code, notes, and snippets.

@oleavr
Created May 19, 2020 02:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oleavr/45dd1a866668d5fec7e5b424992fac1f to your computer and use it in GitHub Desktop.
Save oleavr/45dd1a866668d5fec7e5b424992fac1f to your computer and use it in GitHub Desktop.
Simplified Interceptor reimplemented in TypeScript
const THUMB_HOOK_REDIRECT_SIZE = 8;
const THUMB_BIT_REMOVAL_MASK = ptr(1).not();
const trampolines: NativePointer[] = [];
const replacements: NativePointer[] = [];
export function makeTrampoline(target: NativePointer): NativePointer {
const targetAddress = target.and(THUMB_BIT_REMOVAL_MASK);
const trampoline = Memory.alloc(Process.pageSize);
Memory.patchCode(trampoline, 128, code => {
const writer = new ThumbWriter(code, { pc: trampoline });
const relocator = new ThumbRelocator(targetAddress, writer);
let n: number;
do {
n = relocator.readOne();
} while (n < THUMB_HOOK_REDIRECT_SIZE);
relocator.writeAll();
if (!relocator.eoi) {
writer.putLdrRegAddress(ArmRegister.Pc, target.add(n));
}
writer.flush();
});
trampolines.push(trampoline);
return trampoline.or(1);
}
export function replace(target: NativePointer, replacement: NativePointer): void {
const targetAddress = target.and(THUMB_BIT_REMOVAL_MASK);
Memory.patchCode(targetAddress, 128, code => {
const writer = new ThumbWriter(code, { pc: targetAddress });
writer.putLdrRegAddress(ArmRegister.Pc, replacement);
writer.flush();
});
replacements.push(replacement);
}
@Syrou
Copy link

Syrou commented Nov 5, 2020

How with an "attach" implementation look like with this?

@oleavr
Copy link
Author

oleavr commented Apr 19, 2022

@Syrou (Oops, sorry for the delay here!) It would need to generate another trampoline that saves registers/flags, calls the user's onEnter, and restores registers/flags. Beside that it would also need to replace the return address with that of a similar trampoline so it can trap the return and do the same dance for onLeave. That logic would also need to maintain a per-thread stack of return addresses. Maybe I'll get around to fleshing that out someday.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment