Skip to content

Instantly share code, notes, and snippets.

@romainthomas
Created October 6, 2019 13:20
Show Gist options
  • Save romainthomas/f02d7110ddd5a40043d956effac04d1b to your computer and use it in GitHub Desktop.
Save romainthomas/f02d7110ddd5a40043d956effac04d1b to your computer and use it in GitHub Desktop.
QBDI & Frida: Better together
#include "frida-core.h"
#include "frida-gum.h"
uintptr_t handler(void) {
auto interceptor = gum_interceptor_obtain();
GumInvocationContext* ctx = gum_interceptor_get_current_invocation();
uintptr_t func_addr = reinterpret_cast<uintptr_t>(gum_invocation_context_get_replacement_data(ctx));
// Remove Frida trampoline
gum_interceptor_begin_transaction(interceptor);
gum_interceptor_revert(interceptor, reinterpret_cast<void*>(func_addr));
gum_interceptor_end_transaction(interceptor);
// Initialize QBDI VM state from Frida's context
QBDI::VM vm;
QBDI::GPRState* state = vm.getGPRState();
QBDI::FPRState* fpstate = vm.getFPRState();
state->x0 = ctx->cpu_context->x[0];
state->x1 = ctx->cpu_context->x[1];
state->x2 = ctx->cpu_context->x[2];
state->x3 = ctx->cpu_context->x[3];
state->x4 = ctx->cpu_context->x[4];
state->x5 = ctx->cpu_context->x[5];
state->x6 = ctx->cpu_context->x[6];
state->x7 = ctx->cpu_context->x[7];
state->x8 = ctx->cpu_context->x[8];
state->x9 = ctx->cpu_context->x[9];
state->x10 = ctx->cpu_context->x[10];
state->x11 = ctx->cpu_context->x[11];
state->x12 = ctx->cpu_context->x[12];
state->x13 = ctx->cpu_context->x[13];
state->x14 = ctx->cpu_context->x[14];
state->x15 = ctx->cpu_context->x[15];
state->x16 = ctx->cpu_context->x[16];
state->x17 = ctx->cpu_context->x[17];
state->x18 = ctx->cpu_context->x[18];
state->x19 = ctx->cpu_context->x[19];
state->x20 = ctx->cpu_context->x[20];
state->x21 = ctx->cpu_context->x[21];
state->x22 = ctx->cpu_context->x[22];
state->x23 = ctx->cpu_context->x[23];
state->x24 = ctx->cpu_context->x[24];
state->x25 = ctx->cpu_context->x[25];
state->x26 = ctx->cpu_context->x[26];
state->x27 = ctx->cpu_context->x[27];
state->x28 = ctx->cpu_context->x[28];
state->x29 = ctx->cpu_context->fp;
state->sp = ctx->cpu_context->sp;
GumInvocationStack* stk = gum_interceptor_get_current_stack();
uintptr_t ret_addr = ctx->cpu_context->lr;
if (stk != nullptr) {
ret_addr = reinterpret_cast<uintptr_t>(gum_invocation_stack_translate(stk, reinterpret_cast<void*>(ret_addr)));
}
state->lr = ret_addr;
state->pc = func_addr
vm.setGPRState(state);
vm.setFPRState(fpstate);
vm.addInstrumentedModuleFromAddr(state->pc);
// Run the Function in QBDI
// ========================
vm.run(state->pc, state->lr);
// ========================
// Restore Hook
gum_interceptor_begin_transaction(interceptor);
GumReplaceReturn replace_ret = gum_interceptor_replace(
interceptor,
reinterpret_cast<void*>(func_addr),
reinterpret_cast<GumInvocationListener*>(&handler),
reinterpret_cast<void*>(func_addr)
);
gum_interceptor_end_transaction(interceptor);
// Forward x8
asm volatile (R"delim(
mov x8, %0;
)delim"
: "=r"(vm.getGPRState()->x8)
:
: );
return vm.getGPRState()->x0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment