static void test_thumb_relocator_fixture_setup (TestThumbRelocatorFixture * fixture, gconstpointer data) { fixture->output = (guint8 *) gum_alloc_n_pages (1, GUM_PAGE_RW); gum_thumb_writer_init (&fixture->tw, fixture->output); }
static void gum_write_thunk (gpointer thunk, GumCodeDeflectorDispatcher * dispatcher) { # if defined (HAVE_ARM) GumThumbWriter tw; gum_thumb_writer_init (&tw, thunk); tw.pc = GUM_ADDRESS (dispatcher->thunk); gum_thumb_writer_put_push_regs (&tw, 2, ARM_REG_R9, ARM_REG_R12); gum_thumb_writer_put_call_address_with_arguments (&tw, GUM_ADDRESS (gum_code_deflector_dispatcher_lookup), 2, GUM_ARG_ADDRESS, GUM_ADDRESS (dispatcher), GUM_ARG_REGISTER, ARM_REG_LR); gum_thumb_writer_put_pop_regs (&tw, 2, ARM_REG_R9, ARM_REG_R12); gum_thumb_writer_put_bx_reg (&tw, ARM_REG_R0); gum_thumb_writer_clear (&tw); # elif defined (HAVE_ARM64) GumArm64Writer aw; gum_arm64_writer_init (&aw, thunk); aw.pc = GUM_ADDRESS (dispatcher->thunk); /* push {q0-q7} */ gum_arm64_writer_put_instruction (&aw, 0xadbf1fe6); gum_arm64_writer_put_instruction (&aw, 0xadbf17e4); gum_arm64_writer_put_instruction (&aw, 0xadbf0fe2); gum_arm64_writer_put_instruction (&aw, 0xadbf07e0); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X17, ARM64_REG_X18); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X15, ARM64_REG_X16); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X13, ARM64_REG_X14); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X11, ARM64_REG_X12); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X9, ARM64_REG_X10); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X7, ARM64_REG_X8); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X5, ARM64_REG_X6); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X3, ARM64_REG_X4); gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X1, ARM64_REG_X2); gum_arm64_writer_put_call_address_with_arguments (&aw, GUM_ADDRESS (gum_code_deflector_dispatcher_lookup), 2, GUM_ARG_ADDRESS, GUM_ADDRESS (dispatcher), GUM_ARG_REGISTER, ARM64_REG_LR); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X1, ARM64_REG_X2); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X3, ARM64_REG_X4); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X5, ARM64_REG_X6); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X7, ARM64_REG_X8); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X9, ARM64_REG_X10); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X11, ARM64_REG_X12); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X13, ARM64_REG_X14); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X15, ARM64_REG_X16); gum_arm64_writer_put_pop_reg_reg (&aw, ARM64_REG_X17, ARM64_REG_X18); /* pop {q0-q7} */ gum_arm64_writer_put_instruction (&aw, 0xacc107e0); gum_arm64_writer_put_instruction (&aw, 0xacc10fe2); gum_arm64_writer_put_instruction (&aw, 0xacc117e4); gum_arm64_writer_put_instruction (&aw, 0xacc11fe6); gum_arm64_writer_put_br_reg (&aw, ARM64_REG_X0); gum_arm64_writer_clear (&aw); # else (void) gum_code_deflector_dispatcher_lookup; # endif }
static void gum_insert_deflector (gpointer cave, GumInsertDeflectorContext * ctx) { # if defined (HAVE_ARM) GumCodeDeflectorDispatcher * dispatcher = ctx->dispatcher; GumThumbWriter tw; if (ctx->dedicated_target != NULL) { gboolean owner_is_arm; owner_is_arm = (GPOINTER_TO_SIZE (ctx->return_address) & 1) == 0; if (owner_is_arm) { GumArmWriter aw; gum_arm_writer_init (&aw, cave); aw.pc = ctx->pc; gum_arm_writer_put_ldr_reg_address (&aw, ARM_REG_PC, GUM_ADDRESS (ctx->dedicated_target)); gum_arm_writer_flush (&aw); g_assert (gum_arm_writer_offset (&aw) <= ctx->max_size); gum_arm_writer_clear (&aw); dispatcher->trampoline = GSIZE_TO_POINTER (ctx->pc); return; } gum_thumb_writer_init (&tw, cave); tw.pc = ctx->pc; gum_thumb_writer_put_ldr_reg_address (&tw, ARM_REG_PC, GUM_ADDRESS (ctx->dedicated_target)); } else { gum_thumb_writer_init (&tw, cave); tw.pc = ctx->pc; gum_thumb_writer_put_ldr_reg_address (&tw, ARM_REG_PC, GUM_ADDRESS (dispatcher->thunk) + 1); } gum_thumb_writer_flush (&tw); g_assert (gum_thumb_writer_offset (&tw) <= ctx->max_size); gum_thumb_writer_clear (&tw); dispatcher->trampoline = GSIZE_TO_POINTER (ctx->pc + 1); # elif defined (HAVE_ARM64) GumCodeDeflectorDispatcher * dispatcher = ctx->dispatcher; GumArm64Writer aw; gum_arm64_writer_init (&aw, cave); aw.pc = ctx->pc; if (ctx->dedicated_target != NULL) { gum_arm64_writer_put_push_reg_reg (&aw, ARM64_REG_X0, ARM64_REG_LR); gum_arm64_writer_put_ldr_reg_address (&aw, ARM64_REG_X0, GUM_ADDRESS (ctx->dedicated_target)); gum_arm64_writer_put_br_reg (&aw, ARM64_REG_X0); } else { gum_arm64_writer_put_ldr_reg_address (&aw, ARM64_REG_X0, GUM_ADDRESS (dispatcher->thunk)); gum_arm64_writer_put_br_reg (&aw, ARM64_REG_X0); } gum_arm64_writer_flush (&aw); g_assert (gum_arm64_writer_offset (&aw) <= ctx->max_size); gum_arm64_writer_clear (&aw); dispatcher->trampoline = GSIZE_TO_POINTER (ctx->pc); # else (void) gum_code_deflector_dispatcher_lookup; # endif }