Skip to content

Commit

Permalink
[WIP] Handle extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
oleavr committed Sep 20, 2023
1 parent 0e75b58 commit 8438cc6
Showing 1 changed file with 138 additions and 21 deletions.
159 changes: 138 additions & 21 deletions gum/gumswiftapiresolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@

typedef struct _GumModuleMetadata GumModuleMetadata;
typedef struct _GumFunctionMetadata GumFunctionMetadata;
typedef size_t (* GumSwiftDemangle) (const char * name, char * output,
size_t length);
typedef gsize (* GumSwiftDemangle) (const gchar * name, gchar * output,
gsize length);

typedef struct _GumClass GumClass;

Expand All @@ -78,6 +78,7 @@ typedef struct _GumOverrideTableHeader GumOverrideTableHeader;
typedef struct _GumMethodOverrideDescriptor GumMethodOverrideDescriptor;

typedef gint32 GumRelativeDirectPtr;
typedef gint32 GumRelativeIndirectPtr;
typedef gint32 GumRelativeIndirectablePtr;

struct _GumSwiftApiResolver
Expand All @@ -88,8 +89,6 @@ struct _GumSwiftApiResolver

GumModuleMap * all_modules;
GHashTable * module_by_name;

GumSwiftDemangle demangle;
};

struct _GumModuleMetadata
Expand Down Expand Up @@ -306,6 +305,8 @@ static gconstpointer gum_resolve_method_implementation (

static gchar * gum_compute_context_descriptor_name (
const GumContextDescriptor * cd);
static void gum_append_demangled_context_name (GString * result,
const gchar * mangled_name);

static void gum_skip_generic_type_trailers (gconstpointer * trailer_ptr,
const GumTypeContextDescriptor * t);
Expand All @@ -316,22 +317,31 @@ static void gum_skip_metadata_initialization_trailers (

static gconstpointer gum_resolve_relative_direct_ptr (
const GumRelativeDirectPtr * delta);
static gconstpointer gum_resolve_relative_indirect_ptr (
const GumRelativeIndirectPtr * delta);
static gconstpointer gum_resolve_relative_indirectable_ptr (
const GumRelativeIndirectablePtr * delta);

static gchar * gum_demangle (const gchar * name);

G_DEFINE_TYPE_EXTENDED (GumSwiftApiResolver,
gum_swift_api_resolver,
G_TYPE_OBJECT,
0,
G_IMPLEMENT_INTERFACE (GUM_TYPE_API_RESOLVER,
gum_swift_api_resolver_iface_init))

static GumSwiftDemangle gum_demangle_impl;

static void
gum_swift_api_resolver_class_init (GumSwiftApiResolverClass * klass)
{
GObjectClass * object_class = G_OBJECT_CLASS (klass);

object_class->finalize = gum_swift_api_resolver_finalize;

gum_demangle_impl = GUM_POINTER_TO_FUNCPTR (GumSwiftDemangle,
gum_module_find_export_by_name (NULL, "swift_demangle_getDemangledName"));
}

static void
Expand Down Expand Up @@ -374,9 +384,6 @@ gum_swift_api_resolver_init (GumSwiftApiResolver * self)
g_hash_table_insert (self->module_by_name, g_strdup (module->name), module);
g_hash_table_insert (self->module_by_name, g_strdup (module->path), module);
}

self->demangle = GUM_POINTER_TO_FUNCPTR (GumSwiftDemangle,
gum_module_find_export_by_name (NULL, "swift_demangle_getDemangledName"));
}

static void
Expand Down Expand Up @@ -423,7 +430,7 @@ gum_swift_api_resolver_enumerate_matches (GumApiResolver * resolver,
gboolean carry_on;
GumModuleMetadata * module;

if (self->demangle == NULL)
if (gum_demangle_impl == NULL)
goto unsupported_runtime;

g_regex_match (self->query_pattern, query, 0, &query_info);
Expand Down Expand Up @@ -689,22 +696,21 @@ gum_module_metadata_collect_export (const GumExportDetails * details,
gpointer user_data)
{
GumModuleMetadata * self = user_data;
gchar name[512];
size_t len;
gchar * name;
GumFunctionMetadata func;

if (details->type != GUM_EXPORT_FUNCTION)
goto skip;

len = self->resolver->demangle (details->name, name, sizeof (name));
if (len == 0)
name = gum_demangle (details->name);
if (name == NULL)
goto skip;

func.name = g_strdup (name);
func.name = name;
func.address = details->address;
g_array_append_val (self->functions, func);

gum_module_metadata_maybe_ingest_thunk (self, func.name, func.address);
gum_module_metadata_maybe_ingest_thunk (self, name, func.address);

skip:
return TRUE;
Expand Down Expand Up @@ -1030,11 +1036,12 @@ gum_compute_context_descriptor_name (const GumContextDescriptor * cd)
{
GString * name;
const GumContextDescriptor * cur;
gboolean reached_toplevel;

name = g_string_sized_new (16);

for (cur = cd;
cur != NULL;
for (cur = cd, reached_toplevel = FALSE;
cur != NULL && !reached_toplevel;
cur = gum_resolve_relative_indirectable_ptr (&cur->parent))
{
GumContextDescriptorKind kind = GUM_DESCRIPTOR_FLAGS_KIND (cur->flags);
Expand All @@ -1050,18 +1057,37 @@ gum_compute_context_descriptor_name (const GumContextDescriptor * cd)
g_string_prepend (name, gum_resolve_relative_direct_ptr (&m->name));
break;
}
#if 0
case GUM_CONTEXT_DESCRIPTOR_EXTENSION:
{
const GumExtensionContextDescriptor * e =
(const GumExtensionContextDescriptor *) cur;
if (name->len != 0)
g_string_prepend_c (name, '.');
g_string_prepend (name,
GString * part;
gchar * parent;

part = g_string_sized_new (64);
g_string_append (part, "(extension in ");

parent = gum_compute_context_descriptor_name (
gum_resolve_relative_indirectable_ptr (&cur->parent));
g_string_append (part, parent);
g_free (parent);

g_string_append (part, "):");

gum_append_demangled_context_name (part,
gum_resolve_relative_direct_ptr (&e->extended_context));

if (name->len != 0)
g_string_append_c (part, '.');

g_string_prepend (name, part->str);

g_string_free (part, TRUE);

reached_toplevel = TRUE;

break;
}
#endif
case GUM_CONTEXT_DESCRIPTOR_ANONYMOUS:
break;
default:
Expand All @@ -1083,6 +1109,65 @@ gum_compute_context_descriptor_name (const GumContextDescriptor * cd)
return g_string_free (name, FALSE);
}

static void
gum_append_demangled_context_name (GString * result,
const gchar * mangled_name)
{
switch (mangled_name[0])
{
case '\x01':
{
const GumContextDescriptor * cd;
gchar * name;

cd = gum_resolve_relative_direct_ptr (
(const GumRelativeDirectPtr *) (mangled_name + 1));
name = gum_compute_context_descriptor_name (cd);
g_string_append (result, name);
g_free (name);

break;
}
case '\x02':
{
const GumContextDescriptor * cd;
gchar * name;

cd = gum_resolve_relative_indirect_ptr (
(const GumRelativeIndirectPtr *) (mangled_name + 1));
name = gum_compute_context_descriptor_name (cd);
g_string_append (result, name);
g_free (name);

break;
}
default:
{
GString * buf;
gchar * name;

buf = g_string_sized_new (32);
g_string_append (buf, "$s");
g_string_append (buf, mangled_name);

name = gum_demangle (buf->str);
if (name != NULL)
{
g_string_append (result, name);
g_free (name);
}
else
{
g_string_append (result, "<unsupported mangled name>");
}

g_string_free (buf, TRUE);

break;
}
}
}

static void
gum_skip_generic_type_trailers (gconstpointer * trailer_ptr,
const GumTypeContextDescriptor * t)
Expand Down Expand Up @@ -1171,6 +1256,17 @@ gum_resolve_relative_direct_ptr (const GumRelativeDirectPtr * delta)
return (const guint8 *) delta + val;
}

static gconstpointer
gum_resolve_relative_indirect_ptr (const GumRelativeIndirectPtr * delta)
{
GumRelativeIndirectablePtr val = *delta;
gconstpointer * target;

target = (gconstpointer *) ((const guint8 *) delta + val);

return *target;
}

static gconstpointer
gum_resolve_relative_indirectable_ptr (const GumRelativeIndirectablePtr * delta)
{
Expand All @@ -1185,4 +1281,25 @@ gum_resolve_relative_indirectable_ptr (const GumRelativeIndirectablePtr * delta)
return *target;
}

static gchar *
gum_demangle (const gchar * name)
{
gchar buf[512];
gsize n, capacity;
gchar * dbuf;

n = gum_demangle_impl (name, buf, sizeof (buf));
if (n == 0)
return NULL;

if (n < sizeof (buf))
return g_strdup (buf);

capacity = n + 1;
dbuf = g_malloc (capacity);
gum_demangle_impl (name, dbuf, capacity);

return dbuf;
}

#endif

0 comments on commit 8438cc6

Please sign in to comment.