diff --git a/gum/gumswiftapiresolver.c b/gum/gumswiftapiresolver.c index 0b07f232e..b733b865c 100644 --- a/gum/gumswiftapiresolver.c +++ b/gum/gumswiftapiresolver.c @@ -26,6 +26,8 @@ typedef struct _GumModuleMetadata GumModuleMetadata; typedef struct _GumFunctionMetadata GumFunctionMetadata; typedef size_t (* GumSwiftDemangle) (const char * name, char * output, size_t length); +typedef struct _GumTargetContextDescriptor GumTargetContextDescriptor; +typedef struct _GumTargetTypeContextDescriptor GumTargetTypeContextDescriptor; struct _GumSwiftApiResolver { @@ -56,6 +58,26 @@ struct _GumFunctionMetadata GumAddress address; }; +struct _GumTargetContextDescriptor +{ + guint32 flags; + gint32 parent_delta; +}; + +struct _GumTargetTypeContextDescriptor +{ + GumTargetContextDescriptor target_ctx; + gint32 name_delta; + gint32 access_function_ptr_delta; + gint32 fields_delta; +}; + +enum _GumContextDescriptorKind +{ + GUM_CONTEXT_DESCRIPTOR_CLASS = 16, + GUM_CONTEXT_DESCRIPTOR_STRUCT, +}; + static void gum_swift_api_resolver_iface_init (gpointer g_iface, gpointer iface_data); static void gum_swift_api_resolver_finalize (GObject * object); @@ -65,6 +87,8 @@ static void gum_swift_api_resolver_enumerate_matches ( static void gum_module_metadata_unref (GumModuleMetadata * module); static GArray * gum_module_metadata_get_functions (GumModuleMetadata * self); +static gboolean gum_module_metadata_collect_section ( + const GumSectionDetails * details, gpointer user_data); static gboolean gum_module_metadata_collect_export ( const GumExportDetails * details, gpointer user_data); @@ -234,7 +258,7 @@ gum_swift_api_resolver_enumerate_matches (GumApiResolver * resolver, functions = gum_module_metadata_get_functions (module); - for (i = 0; i != functions->len; i++) + for (i = 0; carry_on && i != functions->len; i++) { const GumFunctionMetadata * f = &g_array_index (functions, GumFunctionMetadata, i); @@ -305,13 +329,60 @@ gum_module_metadata_get_functions (GumModuleMetadata * self) self->functions = g_array_new (FALSE, FALSE, sizeof (GumFunctionMetadata)); g_array_set_clear_func (self->functions, (GDestroyNotify) gum_function_metadata_free); + g_printerr ("collecting exports of %s\n", self->path); + gum_module_enumerate_sections (self->path, + gum_module_metadata_collect_section, self); + g_printerr (">>>\n"); gum_module_enumerate_exports (self->path, gum_module_metadata_collect_export, self); + g_printerr ("<<<\n"); } return self->functions; } +static gboolean +gum_module_metadata_collect_section (const GumSectionDetails * details, + gpointer user_data) +{ + gsize n, i; + gint32 * type_deltas; + + if (strcmp (details->name, "__swift5_types") != 0) + return TRUE; + + n = details->size / sizeof (gint32); + g_printerr ("n=%zu\n", n); + + type_deltas = GSIZE_TO_POINTER (details->address); + + for (i = 0; i != n; i++) + { + const GumTargetTypeContextDescriptor * type = + (const GumTargetTypeContextDescriptor *) ( + (const guint8 *) &type_deltas[i] + type_deltas[i]); + const gchar * name; + guint8 kind; + + name = (const gchar *) &type->name_delta + type->name_delta; + kind = type->target_ctx.flags & 0x1f; + + switch (kind) + { + case GUM_CONTEXT_DESCRIPTOR_CLASS: + g_printerr ("\t[class] %s\n", name); + break; + case GUM_CONTEXT_DESCRIPTOR_STRUCT: + g_printerr ("\t[struct] %s\n", name); + break; + default: + break; + } + } + + return TRUE; +} + static gboolean gum_module_metadata_collect_export (const GumExportDetails * details, gpointer user_data) diff --git a/tests/core/apiresolver.c b/tests/core/apiresolver.c index aaa27abb6..dca573e61 100644 --- a/tests/core/apiresolver.c +++ b/tests/core/apiresolver.c @@ -257,8 +257,10 @@ TESTCASE (swift_method_can_be_resolved) return; } + g_printerr (">>>\n"); gum_api_resolver_enumerate_matches (fixture->resolver, - "*!*", resolve_method_impl, &address, &error); + "*CoreDevice!*RSDDeviceInfo*", resolve_method_impl, &address, &error); + g_printerr ("<<<\n"); g_assert_no_error (error); } @@ -268,9 +270,11 @@ resolve_method_impl (const GumApiDetails * details, { GumAddress * address = user_data; + g_printerr ("Found: %s\n", details->name); *address = details->address; - return FALSE; + //return FALSE; + return TRUE; } #endif