diff --git a/gum/gumswiftapiresolver.c b/gum/gumswiftapiresolver.c index bf77f698c..4107b91c6 100644 --- a/gum/gumswiftapiresolver.c +++ b/gum/gumswiftapiresolver.c @@ -43,7 +43,7 @@ ((flags & GUM_GENERIC_DESCRIPTOR_HAS_TYPE_PACKS) != 0) #define GUM_ALIGN(ptr, type) \ - GUM_ALIGN_POINTER (type, ptr, G_ALIGNOF (type)) + GUM_ALIGN_POINTER (type *, ptr, G_ALIGNOF (type)) typedef struct _GumModuleMetadata GumModuleMetadata; typedef struct _GumFunctionMetadata GumFunctionMetadata; @@ -65,6 +65,8 @@ typedef struct _GumMethodDescriptor GumMethodDescriptor; typedef struct _GumOverrideTableHeader GumOverrideTableHeader; typedef struct _GumMethodOverrideDescriptor GumMethodOverrideDescriptor; +typedef gint32 GumRelativeDirectPtr; + struct _GumSwiftApiResolver { GObject parent; @@ -122,15 +124,15 @@ enum _GumTypeMetadataInitializationKind struct _GumContextDescriptor { guint32 flags; - gint32 parent_delta; + GumRelativeDirectPtr parent; }; struct _GumTypeContextDescriptor { GumContextDescriptor target_ctx; - gint32 name_delta; - gint32 access_function_ptr_delta; - gint32 fields_delta; + GumRelativeDirectPtr name; + GumRelativeDirectPtr access_function_ptr; + GumRelativeDirectPtr fields; }; struct _GumGenericContextDescriptorHeader @@ -154,38 +156,38 @@ struct _GumGenericParamDescriptor struct _GumGenericRequirementDescriptor { guint32 flags; - guint32 param_delta; + GumRelativeDirectPtr param; + GumRelativeDirectPtr type_or_protocol_or_conformance_or_layout; }; struct _GumTypeGenericContextDescriptorHeader { - gint32 instantiation_cache_delta; - gint32 default_instantiation_pattern_delta; + GumRelativeDirectPtr instantiation_cache; + GumRelativeDirectPtr default_instantiation_pattern; GumGenericContextDescriptorHeader base; }; struct _GumClassDescriptor { GumTypeContextDescriptor target_type; - gint32 superclass_type_delta; + GumRelativeDirectPtr superclass_type; guint32 metadata_negative_size_in_words_or_resilient_metadata_bounds; guint32 metadata_positive_size_in_words_or_extra_class_flags; guint32 num_immediate_members; guint32 num_fields; - - guint32 padding; + guint32 field_offset_vector_offset; }; struct _GumSingletonMetadataInitialization { - gint32 initialization_cache_delta; - gint32 incomplete_metadata_or_resilient_pattern_delta; - gint32 completion_function_delta; + GumRelativeDirectPtr initialization_cache; + GumRelativeDirectPtr incomplete_metadata_or_resilient_pattern; + GumRelativeDirectPtr completion_function; }; struct _GumForeignMetadataInitialization { - gint32 completion_function_delta; + GumRelativeDirectPtr completion_function; }; struct _GumVTableDescriptorHeader @@ -197,7 +199,7 @@ struct _GumVTableDescriptorHeader struct _GumMethodDescriptor { guint32 flags; - gint32 impl_delta; + GumRelativeDirectPtr impl; }; struct _GumOverrideTableHeader @@ -207,9 +209,9 @@ struct _GumOverrideTableHeader struct _GumMethodOverrideDescriptor { - gint32 class_delta; - gint32 method_delta; - gint32 impl_delta; + GumRelativeDirectPtr class; + GumRelativeDirectPtr method; + GumRelativeDirectPtr impl; }; static void gum_swift_api_resolver_iface_init (gpointer g_iface, @@ -228,6 +230,9 @@ static gboolean gum_module_metadata_collect_export ( static void gum_function_metadata_free (GumFunctionMetadata * function); +static gconstpointer gum_resolve_relative_direct_ptr ( + const GumRelativeDirectPtr * delta); + G_DEFINE_TYPE_EXTENDED (GumSwiftApiResolver, gum_swift_api_resolver, G_TYPE_OBJECT, @@ -469,7 +474,7 @@ gum_module_metadata_get_functions (GumModuleMetadata * self) g_printerr ("sizeof (GumTypeContextDescriptor) == %zu\n", sizeof (GumTypeContextDescriptor)); g_printerr ("sizeof (GumClassDescriptor) == %zu\n", sizeof (GumClassDescriptor)); g_printerr ("offsetof (GumClassDescriptor, target_type) == %zu\n", G_STRUCT_OFFSET (GumClassDescriptor, target_type)); - g_printerr ("offsetof (GumClassDescriptor, superclass_type_delta) == %zu\n", G_STRUCT_OFFSET (GumClassDescriptor, superclass_type_delta)); + g_printerr ("offsetof (GumClassDescriptor, superclass_type) == %zu\n", G_STRUCT_OFFSET (GumClassDescriptor, superclass_type)); g_printerr ("collecting exports of %s\n", self->path); the_base = gum_module_find_base_address (self->path); gum_module_enumerate_sections (self->path, @@ -489,29 +494,27 @@ gum_module_metadata_collect_section (const GumSectionDetails * details, { GumModuleMetadata * module = user_data; gsize n, i; - gint32 * type_deltas; + GumRelativeDirectPtr * types; if (strcmp (details->name, "__swift5_types") != 0) return TRUE; n = details->size / sizeof (gint32); - g_printerr ("address=%p\n", (void *) details->address); - g_printerr ("offset=0x%x\n", (int) (details->address - the_base)); - g_printerr ("n=%zu\n", n); - type_deltas = GSIZE_TO_POINTER (details->address); + types = GSIZE_TO_POINTER (details->address); for (i = 0; i != n; i++) { - const GumTypeContextDescriptor * type = - (const GumTypeContextDescriptor *) ( - (const guint8 *) &type_deltas[i] + type_deltas[i]); - guint32 descriptor_flags = type->target_ctx.flags; + const GumTypeContextDescriptor * type; + guint32 descriptor_flags; const gchar * name; - name = (const gchar *) &type->name_delta + type->name_delta; + type = gum_resolve_relative_direct_ptr (&types[i]); + descriptor_flags = type->target_ctx.flags; + + name = gum_resolve_relative_direct_ptr (&type->name); g_printerr ("\n=== %s\n", name); - g_printerr ("\tflags=0x%08x\n", type->target_ctx.flags); + g_printerr ("\tflags=0x%08x\n", descriptor_flags); switch (GUM_DESCRIPTOR_FLAGS_KIND (descriptor_flags)) { @@ -526,18 +529,27 @@ gum_module_metadata_collect_section (const GumSectionDetails * details, if (GUM_DESCRIPTOR_FLAGS_IS_GENERIC (descriptor_flags)) { - const GumTypeGenericContextDescriptorHeader * h; - const GumGenericParamDescriptor * params; - const GumGenericRequirementDescriptor * reqs; + const GumTypeGenericContextDescriptorHeader * th; + const GumGenericContextDescriptorHeader * h; + + th = GUM_ALIGN (trailer, GumTypeGenericContextDescriptorHeader); + trailer = th + 1; - h = GUM_ALIGN (trailer, GumTypeGenericContextDescriptorHeader); - trailer = h + 1; + h = &th->base; - params = GUM_ALIGN (trailer, GumGenericParamDescriptor); - trailer = params + h->num_params; + if (h->num_params != 0) + { + const GumGenericParamDescriptor * params = + GUM_ALIGN (trailer, GumGenericParamDescriptor); + trailer = params + h->num_params; + } - reqs = GUM_ALIGN (trailer, GumGenericRequirementDescriptor); - trailer = reqs + h->num_requirements; + if (h->num_requirements != 0) + { + const GumGenericRequirementDescriptor * reqs = + GUM_ALIGN (trailer, GumGenericRequirementDescriptor); + trailer = reqs + h->num_requirements; + } if (GUM_GENERIC_DESCRIPTOR_FLAGS_HAS_TYPE_PACKS (h->flags)) { @@ -588,7 +600,7 @@ gum_module_metadata_collect_section (const GumSectionDetails * details, g_printerr ("\t\tmethods[%u]: 0x%08x, %p\n", i, method->flags, - (guint8 *) &method->impl_delta + method->impl_delta); + gum_resolve_relative_direct_ptr (&method->impl)); } trailer = methods + vth->vtable_size; @@ -612,7 +624,7 @@ gum_module_metadata_collect_section (const GumSectionDetails * details, g_printerr ("\t\tmethods[%u]: %p\n", i, - (guint8 *) &method->impl_delta + method->impl_delta); + gum_resolve_relative_direct_ptr (&method->impl)); } trailer = methods + oth->num_entries; @@ -675,4 +687,10 @@ gum_function_metadata_free (GumFunctionMetadata * function) g_free (function->name); } +static gconstpointer +gum_resolve_relative_direct_ptr (const GumRelativeDirectPtr * delta) +{ + return (const guint8 *) delta + *delta; +} + #endif