Skip to content

Commit

Permalink
darwin: Resolve import trampolines on arm64
Browse files Browse the repository at this point in the history
So we can hook targets such as sigaction().
  • Loading branch information
oleavr committed Dec 18, 2023
1 parent f083e8b commit fa1c7d8
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 23 deletions.
95 changes: 75 additions & 20 deletions gum/arch-arm64/gumarm64reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,90 @@ gpointer
gum_arm64_reader_try_get_relative_jump_target (gconstpointer address)
{
gpointer result = NULL;
csh capstone;
cs_insn * insn;
cs_arm64_op * op;
const uint8_t * code;
size_t size;
uint64_t pc;
const cs_arm64_op * ops;

insn = gum_arm64_reader_disassemble_instruction_at (address);
if (insn == NULL)
return NULL;
cs_arch_register_arm64 ();
cs_open (CS_ARCH_ARM64, GUM_DEFAULT_CS_ENDIAN, &capstone);
cs_option (capstone, CS_OPT_DETAIL, CS_OPT_ON);

op = &insn->detail->arm64.operands[0];
if (insn->id == ARM64_INS_B && op->type == ARM64_OP_IMM)
result = GSIZE_TO_POINTER (op->imm);
insn = cs_malloc (capstone);

cs_free (insn, 1);
code = address;
size = 16;
pc = GPOINTER_TO_SIZE (address);

return result;
}
#define GUM_DISASM_NEXT() \
if (!cs_disasm_iter (capstone, &code, &size, &pc, insn)) \
goto beach; \
ops = insn->detail->arm64.operands
#define GUM_CHECK_ID(i) \
if (insn->id != G_PASTE (ARM64_INS_, i)) \
goto beach
#define GUM_CHECK_OP_TYPE(n, t) \
if (ops[n].type != G_PASTE (ARM64_OP_, t)) \
goto beach
#define GUM_CHECK_OP_REG(n, r) \
if (ops[n].reg != G_PASTE (ARM64_REG_, r)) \
goto beach
#define GUM_CHECK_OP_MEM(n, b, i, d) \
if (ops[n].mem.base != G_PASTE (ARM64_REG_, b)) \
goto beach; \
if (ops[n].mem.index != G_PASTE (ARM64_REG_, i)) \
goto beach; \
if (ops[n].mem.disp != d) \
goto beach

cs_insn *
gum_arm64_reader_disassemble_instruction_at (gconstpointer address)
{
csh capstone;
cs_insn * insn = NULL;
GUM_DISASM_NEXT ();

cs_arch_register_arm64 ();
cs_open (CS_ARCH_ARM64, GUM_DEFAULT_CS_ENDIAN, &capstone);
cs_option (capstone, CS_OPT_DETAIL, CS_OPT_ON);
switch (insn->id)
{
case ARM64_INS_B:
result = GSIZE_TO_POINTER (ops[0].imm);
break;
#ifdef HAVE_DARWIN
case ARM64_INS_ADRP:
{
GumAddress target;

GUM_CHECK_OP_REG (0, X17);
target = ops[1].imm;

GUM_DISASM_NEXT ();
GUM_CHECK_ID (ADD);
GUM_CHECK_OP_REG (0, X17);
GUM_CHECK_OP_REG (1, X17);
GUM_CHECK_OP_TYPE (2, IMM);
target += ops[2].imm;

GUM_DISASM_NEXT ();
GUM_CHECK_ID (LDR);
GUM_CHECK_OP_REG (0, X16);
GUM_CHECK_OP_TYPE (1, MEM);
GUM_CHECK_OP_MEM (1, X17, INVALID, 0);

cs_disasm (capstone, address, 16, GPOINTER_TO_SIZE (address), 1, &insn);
GUM_DISASM_NEXT ();
GUM_CHECK_ID (BRAA);
GUM_CHECK_OP_REG (0, X16);
GUM_CHECK_OP_REG (1, X17);

result = *((gpointer *) GSIZE_TO_POINTER (target));

break;
}
#endif
default:
break;
}

beach:
cs_free (insn, 1);

cs_close (&capstone);

return insn;
return result;
}
4 changes: 1 addition & 3 deletions gum/arch-arm64/gumarm64reader.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Ole André Vadla Ravnås <oleavr@nowsecure.com>
* Copyright (C) 2015-2023 Ole André Vadla Ravnås <oleavr@nowsecure.com>
*
* Licence: wxWindows Library Licence, Version 3.1
*/
Expand All @@ -15,8 +15,6 @@ G_BEGIN_DECLS

GUM_API gpointer gum_arm64_reader_try_get_relative_jump_target (
gconstpointer address);
GUM_API cs_insn * gum_arm64_reader_disassemble_instruction_at (
gconstpointer address);

G_END_DECLS

Expand Down

0 comments on commit fa1c7d8

Please sign in to comment.