Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

elf-module: Wire up import slots #782

Merged
merged 4 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 68 additions & 2 deletions gum/gumelfmodule.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2023 Ole André Vadla Ravnås <[email protected]>
* Copyright (C) 2010-2024 Ole André Vadla Ravnås <[email protected]>
* Copyright (C) 2019 Jon Wilson <[email protected]>
* Copyright (C) 2021 Paul Schmidt <[email protected]>
*
Expand Down Expand Up @@ -124,6 +124,9 @@ struct _GumElfEnumerateImportsContext
{
GumFoundImportFunc func;
gpointer user_data;

GHashTable * slots;
guint32 jump_slot_type;
};

struct _GumElfEnumerateExportsContext
Expand Down Expand Up @@ -177,6 +180,10 @@ static gboolean gum_elf_module_emit_relocations (GumElfModule * self,
gpointer user_data);
static gboolean gum_emit_elf_import (const GumElfSymbolDetails * details,
gpointer user_data);
static gboolean gum_try_get_jump_slot_relocation_type_for_machine (
GumElfMachine machine, guint32 * type);
static gboolean gum_maybe_collect_import_slot_from_relocation (
const GumElfRelocationDetails * details, gpointer user_data);
static gboolean gum_emit_elf_export (const GumElfSymbolDetails * details,
gpointer user_data);
static void gum_elf_module_parse_symbol (GumElfModule * self,
Expand Down Expand Up @@ -1397,6 +1404,8 @@ gum_elf_module_emit_relocations (GumElfModule * self,
g_assert_not_reached ();
}

d.address = gum_elf_module_translate_to_online (self, d.address);

if (sym_index != GUM_STN_UNDEF)
{
gconstpointer sym_start, sym_end;
Expand Down Expand Up @@ -1473,7 +1482,17 @@ gum_elf_module_enumerate_imports (GumElfModule * self,
ctx.func = func;
ctx.user_data = user_data;

ctx.slots = g_hash_table_new (g_str_hash, g_str_equal);
if (gum_try_get_jump_slot_relocation_type_for_machine (self->ehdr.machine,
&ctx.jump_slot_type))
{
gum_elf_module_enumerate_relocations (self,
gum_maybe_collect_import_slot_from_relocation, &ctx);
}

gum_elf_module_enumerate_dynamic_symbols (self, gum_emit_elf_import, &ctx);

g_hash_table_unref (ctx.slots);
}

static gboolean
Expand All @@ -1494,7 +1513,7 @@ gum_emit_elf_import (const GumElfSymbolDetails * details,
d.name = details->name;
d.module = NULL;
d.address = 0;
d.slot = 0; /* TODO */
d.slot = GUM_ADDRESS (g_hash_table_lookup (ctx->slots, details->name));

if (!ctx->func (&d, ctx->user_data))
return FALSE;
Expand All @@ -1503,6 +1522,53 @@ gum_emit_elf_import (const GumElfSymbolDetails * details,
return TRUE;
}

static gboolean
gum_try_get_jump_slot_relocation_type_for_machine (GumElfMachine machine,
guint32 * type)
{
switch (machine)
{
case GUM_ELF_MACHINE_386:
*type = GUM_ELF_IA32_JMP_SLOT;
break;
case GUM_ELF_MACHINE_X86_64:
*type = GUM_ELF_X64_JUMP_SLOT;
break;
case GUM_ELF_MACHINE_ARM:
*type = GUM_ELF_ARM_JUMP_SLOT;
break;
case GUM_ELF_MACHINE_AARCH64:
*type = GUM_ELF_ARM64_JUMP_SLOT;
break;
case GUM_ELF_MACHINE_MIPS:
case GUM_ELF_MACHINE_MIPS_RS3_LE:
case GUM_ELF_MACHINE_MIPS_X:
*type = GUM_ELF_MIPS_JUMP_SLOT;
break;
default:
*type = G_MAXUINT32;
return FALSE;
}

return TRUE;
}

static gboolean
gum_maybe_collect_import_slot_from_relocation (
const GumElfRelocationDetails * details,
gpointer user_data)
{
GumElfEnumerateImportsContext * ctx = user_data;

if (details->type == ctx->jump_slot_type && details->symbol != NULL)
{
g_hash_table_insert (ctx->slots, (gpointer) details->symbol->name,
GSIZE_TO_POINTER (details->address));
}

return TRUE;
}

void
gum_elf_module_enumerate_exports (GumElfModule * self,
GumFoundExportFunc func,
Expand Down
10 changes: 6 additions & 4 deletions tests/core/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,12 +733,14 @@ TESTCASE (module_import_slot_should_contain_correct_value)

unsupported_on_this_os = slot == NULL;
if (unsupported_on_this_os)
{
g_print ("<skipping, not yet supported on this OS> ");
return;
}

actual_value =
gum_strip_code_address (GPOINTER_TO_SIZE (*slot));
expected_value =
gum_strip_code_address (gum_module_find_export_by_name (NULL, "malloc"));
actual_value = gum_strip_code_address (GPOINTER_TO_SIZE (*slot));
expected_value = gum_strip_code_address (gum_module_find_export_by_name (
gum_process_query_libc_name (), "malloc"));

g_assert_cmphex (actual_value, ==, expected_value);
}
Expand Down