From bdaea281bc1224024fd1a54d72539409b45acaa5 Mon Sep 17 00:00:00 2001 From: s1341 Date: Tue, 14 Jan 2025 12:24:13 +0200 Subject: [PATCH] Bump frida to version 16.6.2 (#191) * Bump frida to version 16.6.1 * Rework Module * Fix ci * Fix cI * Fix cI * fix ci * Clippy * Fix CI * Remove unnecessary code * Bump version to 16.6.2 * fix documentation --- .github/workflows/build.yml | 3 + FRIDA_VERSION | 2 +- frida-gum-sys/FRIDA_VERSION | 2 +- frida-gum-sys/include/frida-gumjs.h | 496 +++++++++++++--------------- frida-gum/src/module.rs | 197 ++++------- frida-gum/src/module_map.rs | 187 ++--------- frida-gum/src/process.rs | 23 +- frida-sys/FRIDA_VERSION | 2 +- 8 files changed, 337 insertions(+), 575 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index adcc6a6..efd9491 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,6 +73,9 @@ jobs: os: [ubuntu-latest, macOS-latest, windows-latest] arch: [x86, x86_64] include: + - arch: aarch64 + os: macOS-latest + target: aarch64-apple-darwin - arch: x86 os: ubuntu-latest target: i686-unknown-linux-gnu diff --git a/FRIDA_VERSION b/FRIDA_VERSION index b5b922b..357607e 100644 --- a/FRIDA_VERSION +++ b/FRIDA_VERSION @@ -1 +1 @@ -16.5.6 +16.6.2 diff --git a/frida-gum-sys/FRIDA_VERSION b/frida-gum-sys/FRIDA_VERSION index b5b922b..357607e 100644 --- a/frida-gum-sys/FRIDA_VERSION +++ b/frida-gum-sys/FRIDA_VERSION @@ -1 +1 @@ -16.5.6 +16.6.2 diff --git a/frida-gum-sys/include/frida-gumjs.h b/frida-gum-sys/include/frida-gumjs.h index 3565202..59d0a7e 100644 --- a/frida-gum-sys/include/frida-gumjs.h +++ b/frida-gum-sys/include/frida-gumjs.h @@ -6632,6 +6632,7 @@ typedef unsigned long guintptr; #define G_VA_COPY va_copy +#define G_VA_COPY_AS_ARRAY 1 #define G_HAVE_ISO_VARARGS 1 @@ -61670,7 +61671,7 @@ G_END_DECLS #endif /* __G_IO_H__ */ /* - * Copyright (C) 2008-2023 Ole André Vadla Ravnås + * Copyright (C) 2008-2024 Ole André Vadla Ravnås * * Licence: wxWindows Library Licence, Version 3.1 */ @@ -61695,8 +61696,6 @@ G_END_DECLS #ifndef __GUM_ENUM_TYPES_H__ #define __GUM_ENUM_TYPES_H__ -#ifndef GUM_DIET - G_BEGIN_DECLS @@ -61752,6 +61751,16 @@ GType gum_attach_return_get_type (void) G_GNUC_CONST; GType gum_replace_return_get_type (void) G_GNUC_CONST; #define GUM_TYPE_REPLACE_RETURN (gum_replace_return_get_type ()) +/* Enumerations from "gummodule.h" */ +GType gum_import_type_get_type (void) G_GNUC_CONST; +#define GUM_TYPE_IMPORT_TYPE (gum_import_type_get_type ()) +GType gum_export_type_get_type (void) G_GNUC_CONST; +#define GUM_TYPE_EXPORT_TYPE (gum_export_type_get_type ()) +GType gum_symbol_type_get_type (void) G_GNUC_CONST; +#define GUM_TYPE_SYMBOL_TYPE (gum_symbol_type_get_type ()) +GType gum_dependency_type_get_type (void) G_GNUC_CONST; +#define GUM_TYPE_DEPENDENCY_TYPE (gum_dependency_type_get_type ()) + /* Enumerations from "gumprocess.h" */ GType gum_teardown_requirement_get_type (void) G_GNUC_CONST; #define GUM_TYPE_TEARDOWN_REQUIREMENT (gum_teardown_requirement_get_type ()) @@ -61763,12 +61772,8 @@ GType gum_thread_state_get_type (void) G_GNUC_CONST; #define GUM_TYPE_THREAD_STATE (gum_thread_state_get_type ()) GType gum_watch_conditions_get_type (void) G_GNUC_CONST; #define GUM_TYPE_WATCH_CONDITIONS (gum_watch_conditions_get_type ()) -GType gum_dependency_type_get_type (void) G_GNUC_CONST; -#define GUM_TYPE_DEPENDENCY_TYPE (gum_dependency_type_get_type ()) G_END_DECLS -#endif - #endif /* __GUM_ENUM_TYPES_H__ */ /* Generated data ends here */ @@ -62297,60 +62302,6 @@ enum _GumRelocationScenario (((gint64) (i)) >= (gint64) G_MININT32 && \ ((gint64) (i)) <= (gint64) G_MAXINT32) -#ifndef GUM_DIET - -# define GUM_DECLARE_FINAL_TYPE(ModuleObjName, module_obj_name, MODULE, \ - OBJ_NAME, ParentName) \ - G_DECLARE_FINAL_TYPE (ModuleObjName, module_obj_name, MODULE, OBJ_NAME, \ - ParentName) -# define GUM_DECLARE_INTERFACE(ModuleObjName, module_obj_name, MODULE, \ - OBJ_NAME, PrerequisiteName) \ - G_DECLARE_INTERFACE (ModuleObjName, module_obj_name, MODULE, OBJ_NAME, \ - PrerequisiteName) -# define GUM_DEFINE_BOXED_TYPE(TypeName, type_name, copy_func, free_func) \ - G_DEFINE_BOXED_TYPE (TypeName, type_name, copy_func, free_func) -# define gum_object_ref(object) g_object_ref (object) -# define gum_object_unref(object) g_object_unref (object) -# define gum_clear_object(object_ptr) \ - g_clear_pointer ((object_ptr), g_object_unref) - -#else - -# define GUM_DECLARE_FINAL_TYPE(ModuleObjName, module_obj_name, MODULE, \ - OBJ_NAME, ParentName) \ - typedef struct _##ModuleObjName ModuleObjName; \ - \ - G_GNUC_UNUSED static inline ModuleObjName * MODULE##_##OBJ_NAME ( \ - gpointer obj) \ - { \ - return obj; \ - } -# define GUM_DECLARE_INTERFACE(ModuleObjName, module_obj_name, MODULE, \ - OBJ_NAME, PrerequisiteName) \ - typedef struct _##ModuleObjName ModuleObjName; \ - \ - G_GNUC_UNUSED static inline ModuleObjName * MODULE##_##OBJ_NAME ( \ - gpointer obj) \ - { \ - return obj; \ - } -# define GUM_DEFINE_BOXED_TYPE(TypeName, type_name, copy_func, free_func) -# define gum_clear_object(object_ptr) \ - g_clear_pointer ((object_ptr), gum_object_unref) - -typedef struct _GumObject GumObject; - -struct _GumObject -{ - gint ref_count; - void (* finalize) (GumObject * object); -}; - -GUM_API gpointer gum_object_ref (gpointer object); -GUM_API void gum_object_unref (gpointer object); - -#endif - #ifdef G_NORETURN # define GUM_NORETURN G_NORETURN #else @@ -62372,9 +62323,7 @@ GUM_API gpointer gum_cpu_context_get_return_value (GumCpuContext * self); GUM_API void gum_cpu_context_replace_return_value (GumCpuContext * self, gpointer value); -#ifndef GUM_DIET GUM_API GType gum_address_get_type (void) G_GNUC_CONST; -#endif G_END_DECLS @@ -62395,16 +62344,14 @@ G_BEGIN_DECLS #define GUM_API_SIZE_NONE -1 #define GUM_TYPE_API_RESOLVER (gum_api_resolver_get_type ()) -GUM_DECLARE_INTERFACE (GumApiResolver, gum_api_resolver, GUM, API_RESOLVER, - GObject) +G_DECLARE_INTERFACE (GumApiResolver, gum_api_resolver, GUM, API_RESOLVER, + GObject) typedef struct _GumApiDetails GumApiDetails; typedef gboolean (* GumFoundApiFunc) (const GumApiDetails * details, gpointer user_data); -#ifndef GUM_DIET - struct _GumApiResolverInterface { GTypeInterface parent; @@ -62413,8 +62360,6 @@ struct _GumApiResolverInterface GumFoundApiFunc func, gpointer user_data, GError ** error); }; -#endif - struct _GumApiDetails { const gchar * name; @@ -62487,9 +62432,7 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_BACKTRACER (gum_backtracer_get_type ()) -GUM_DECLARE_INTERFACE (GumBacktracer, gum_backtracer, GUM, BACKTRACER, GObject) - -#ifndef GUM_DIET +G_DECLARE_INTERFACE (GumBacktracer, gum_backtracer, GUM, BACKTRACER, GObject) struct _GumBacktracerInterface { @@ -62499,8 +62442,6 @@ struct _GumBacktracerInterface GumReturnAddressArray * return_addresses, guint limit); }; -#endif - GUM_API GumBacktracer * gum_backtracer_make_accurate (void); GUM_API GumBacktracer * gum_backtracer_make_fuzzy (void); @@ -62525,7 +62466,7 @@ G_END_DECLS #define __GUM_CLOAK_H__ /* - * Copyright (C) 2008-2022 Ole André Vadla Ravnås + * Copyright (C) 2008-2024 Ole André Vadla Ravnås * Copyright (C) 2008 Christian Berentsen * * Licence: wxWindows Library Licence, Version 3.1 @@ -62552,7 +62493,9 @@ typedef guint GumRwxSupport; typedef guint GumMemoryOperation; typedef guint GumPageProtection; typedef struct _GumAddressSpec GumAddressSpec; +typedef struct _GumRangeDetails GumRangeDetails; typedef struct _GumMemoryRange GumMemoryRange; +typedef struct _GumFileMapping GumFileMapping; typedef struct _GumMatchPattern GumMatchPattern; typedef gboolean (* GumMemoryIsNearFunc) (gpointer memory, gpointer address); @@ -62593,12 +62536,28 @@ struct _GumAddressSpec gsize max_distance; }; +struct _GumRangeDetails +{ + const GumMemoryRange * range; + GumPageProtection protection; + const GumFileMapping * file; +}; + struct _GumMemoryRange { GumAddress base_address; gsize size; }; +struct _GumFileMapping +{ + const gchar * path; + guint64 offset; + gsize size; +}; + +typedef gboolean (* GumFoundRangeFunc) (const GumRangeDetails * details, + gpointer user_data); typedef void (* GumMemoryPatchApplyFunc) (gpointer mem, gpointer user_data); typedef gboolean (* GumMemoryScanMatchFunc) (GumAddress address, gsize size, gpointer user_data); @@ -62629,9 +62588,7 @@ GUM_API void gum_memory_scan (const GumMemoryRange * range, const GumMatchPattern * pattern, GumMemoryScanMatchFunc func, gpointer user_data); -#ifndef GUM_DIET GUM_API GType gum_match_pattern_get_type (void) G_GNUC_CONST; -#endif GUM_API GumMatchPattern * gum_match_pattern_new_from_string ( const gchar * pattern_str); GUM_API GumMatchPattern * gum_match_pattern_ref (GumMatchPattern * pattern); @@ -62689,9 +62646,7 @@ GUM_API gboolean gum_memory_decommit (gpointer address, gsize size); GUM_API gboolean gum_address_spec_is_satisfied_by (const GumAddressSpec * spec, gconstpointer address); -#ifndef GUM_DIET GUM_API GType gum_memory_range_get_type (void) G_GNUC_CONST; -#endif GUM_API GumMemoryRange * gum_memory_range_copy (const GumMemoryRange * range); GUM_API void gum_memory_range_free (GumMemoryRange * range); @@ -62699,7 +62654,7 @@ G_END_DECLS #endif /* - * Copyright (C) 2008-2023 Ole André Vadla Ravnås + * Copyright (C) 2008-2024 Ole André Vadla Ravnås * Copyright (C) 2020-2024 Francesco Tamagni * Copyright (C) 2023 Grant Douglas * Copyright (C) 2024 Håvard Sørbø @@ -62710,88 +62665,53 @@ G_END_DECLS #ifndef __GUM_PROCESS_H__ #define __GUM_PROCESS_H__ +/* + * Copyright (C) 2008-2024 Ole André Vadla Ravnås + * + * Licence: wxWindows Library Licence, Version 3.1 + */ -#define GUM_THREAD_ID_INVALID ((GumThreadId) -1) +#ifndef __GUM_MODULE_H__ +#define __GUM_MODULE_H__ -#define GUM_TYPE_MODULE_DETAILS (gum_module_details_get_type ()) G_BEGIN_DECLS -typedef guint GumProcessId; -typedef gsize GumThreadId; -typedef struct _GumThreadDetails GumThreadDetails; -typedef struct _GumModuleDetails GumModuleDetails; -typedef guint GumImportType; -typedef guint GumExportType; -typedef guint GumSymbolType; +#define GUM_TYPE_MODULE (gum_module_get_type ()) +G_DECLARE_INTERFACE (GumModule, gum_module, GUM, MODULE, GObject) + typedef struct _GumImportDetails GumImportDetails; typedef struct _GumExportDetails GumExportDetails; typedef struct _GumSymbolDetails GumSymbolDetails; typedef struct _GumSymbolSection GumSymbolSection; -typedef struct _GumRangeDetails GumRangeDetails; -typedef struct _GumFileMapping GumFileMapping; typedef struct _GumSectionDetails GumSectionDetails; typedef struct _GumDependencyDetails GumDependencyDetails; -typedef struct _GumMallocRangeDetails GumMallocRangeDetails; - -typedef enum { - GUM_TEARDOWN_REQUIREMENT_FULL, - GUM_TEARDOWN_REQUIREMENT_MINIMAL -} GumTeardownRequirement; - -typedef enum { - GUM_CODE_SIGNING_OPTIONAL, - GUM_CODE_SIGNING_REQUIRED -} GumCodeSigningPolicy; - -typedef enum { - GUM_MODIFY_THREAD_FLAGS_NONE = 0, - GUM_MODIFY_THREAD_FLAGS_ABORT_SAFELY = (1 << 0), -} GumModifyThreadFlags; -typedef enum { - GUM_THREAD_RUNNING = 1, - GUM_THREAD_STOPPED, - GUM_THREAD_WAITING, - GUM_THREAD_UNINTERRUPTIBLE, - GUM_THREAD_HALTED -} GumThreadState; - -struct _GumThreadDetails -{ - GumThreadId id; - const gchar * name; - GumThreadState state; - GumCpuContext cpu_context; -}; +typedef gboolean (* GumFoundImportFunc) (const GumImportDetails * details, + gpointer user_data); +typedef gboolean (* GumFoundExportFunc) (const GumExportDetails * details, + gpointer user_data); +typedef gboolean (* GumFoundSymbolFunc) (const GumSymbolDetails * details, + gpointer user_data); +typedef gboolean (* GumFoundSectionFunc) (const GumSectionDetails * details, + gpointer user_data); +typedef gboolean (* GumFoundDependencyFunc) ( + const GumDependencyDetails * details, gpointer user_data); +typedef GumAddress (* GumResolveExportFunc) (const char * module_name, + const char * symbol_name, gpointer user_data); typedef enum { - GUM_WATCH_READ = (1 << 0), - GUM_WATCH_WRITE = (1 << 1), -} GumWatchConditions; - -struct _GumModuleDetails -{ - const gchar * name; - const GumMemoryRange * range; - const gchar * path; -}; - -enum _GumImportType -{ GUM_IMPORT_UNKNOWN, GUM_IMPORT_FUNCTION, GUM_IMPORT_VARIABLE -}; +} GumImportType; -enum _GumExportType -{ +typedef enum { GUM_EXPORT_FUNCTION = 1, GUM_EXPORT_VARIABLE -}; +} GumExportType; -enum _GumSymbolType -{ +typedef enum { /* Common */ GUM_SYMBOL_UNKNOWN, GUM_SYMBOL_SECTION, @@ -62808,6 +62728,32 @@ enum _GumSymbolType GUM_SYMBOL_FILE, GUM_SYMBOL_COMMON, GUM_SYMBOL_TLS, +} GumSymbolType; + +struct _GumModuleInterface +{ + GTypeInterface parent; + + const gchar * (* get_name) (GumModule * self); + const gchar * (* get_path) (GumModule * self); + const GumMemoryRange * (* get_range) (GumModule * self); + void (* ensure_initialized) (GumModule * self); + void (* enumerate_imports) (GumModule * self, GumFoundImportFunc func, + gpointer user_data); + void (* enumerate_exports) (GumModule * self, GumFoundExportFunc func, + gpointer user_data); + void (* enumerate_symbols) (GumModule * self, GumFoundSymbolFunc func, + gpointer user_data); + void (* enumerate_ranges) (GumModule * self, GumPageProtection prot, + GumFoundRangeFunc func, gpointer user_data); + void (* enumerate_sections) (GumModule * self, GumFoundSectionFunc func, + gpointer user_data); + void (* enumerate_dependencies) (GumModule * self, + GumFoundDependencyFunc func, gpointer user_data); + GumAddress (* find_export_by_name) (GumModule * self, + const gchar * symbol_name); + GumAddress (* find_symbol_by_name) (GumModule * self, + const gchar * symbol_name); }; struct _GumImportDetails @@ -62842,20 +62788,6 @@ struct _GumSymbolSection GumPageProtection protection; }; -struct _GumRangeDetails -{ - const GumMemoryRange * range; - GumPageProtection protection; - const GumFileMapping * file; -}; - -struct _GumFileMapping -{ - const gchar * path; - guint64 offset; - gsize size; -}; - struct _GumSectionDetails { const gchar * id; @@ -62877,6 +62809,84 @@ struct _GumDependencyDetails GumDependencyType type; }; +GUM_API GumModule * gum_module_load (const gchar * module_name, + GError ** error); + +GUM_API const gchar * gum_module_get_name (GumModule * self); +GUM_API const gchar * gum_module_get_path (GumModule * self); +GUM_API const GumMemoryRange * gum_module_get_range (GumModule * self); + +GUM_API void gum_module_ensure_initialized (GumModule * self); +GUM_API void gum_module_enumerate_imports (GumModule * self, + GumFoundImportFunc func, gpointer user_data); +GUM_API void gum_module_enumerate_exports (GumModule * self, + GumFoundExportFunc func, gpointer user_data); +GUM_API void gum_module_enumerate_symbols (GumModule * self, + GumFoundSymbolFunc func, gpointer user_data); +GUM_API void gum_module_enumerate_ranges (GumModule * self, + GumPageProtection prot, GumFoundRangeFunc func, gpointer user_data); +GUM_API void gum_module_enumerate_sections (GumModule * self, + GumFoundSectionFunc func, gpointer user_data); +GUM_API void gum_module_enumerate_dependencies (GumModule * self, + GumFoundDependencyFunc func, gpointer user_data); +GUM_API GumAddress gum_module_find_export_by_name (GumModule * self, + const gchar * symbol_name); +GUM_API GumAddress gum_module_find_global_export_by_name ( + const gchar * symbol_name); +GUM_API GumAddress gum_module_find_symbol_by_name (GumModule * self, + const gchar * symbol_name); + +G_END_DECLS + +#endif + +#define GUM_THREAD_ID_INVALID ((GumThreadId) -1) + +#define GUM_TYPE_MODULE_DETAILS (gum_module_details_get_type ()) + +G_BEGIN_DECLS + +typedef guint GumProcessId; +typedef gsize GumThreadId; +typedef struct _GumThreadDetails GumThreadDetails; +typedef struct _GumMallocRangeDetails GumMallocRangeDetails; + +typedef enum { + GUM_TEARDOWN_REQUIREMENT_FULL, + GUM_TEARDOWN_REQUIREMENT_MINIMAL +} GumTeardownRequirement; + +typedef enum { + GUM_CODE_SIGNING_OPTIONAL, + GUM_CODE_SIGNING_REQUIRED +} GumCodeSigningPolicy; + +typedef enum { + GUM_MODIFY_THREAD_FLAGS_NONE = 0, + GUM_MODIFY_THREAD_FLAGS_ABORT_SAFELY = (1 << 0), +} GumModifyThreadFlags; + +typedef enum { + GUM_THREAD_RUNNING = 1, + GUM_THREAD_STOPPED, + GUM_THREAD_WAITING, + GUM_THREAD_UNINTERRUPTIBLE, + GUM_THREAD_HALTED +} GumThreadState; + +struct _GumThreadDetails +{ + GumThreadId id; + const gchar * name; + GumThreadState state; + GumCpuContext cpu_context; +}; + +typedef enum { + GUM_WATCH_READ = (1 << 0), + GUM_WATCH_WRITE = (1 << 1), +} GumWatchConditions; + struct _GumMallocRangeDetails { const GumMemoryRange * range; @@ -62886,24 +62896,10 @@ typedef void (* GumModifyThreadFunc) (GumThreadId thread_id, GumCpuContext * cpu_context, gpointer user_data); typedef gboolean (* GumFoundThreadFunc) (const GumThreadDetails * details, gpointer user_data); -typedef gboolean (* GumFoundModuleFunc) (const GumModuleDetails * details, - gpointer user_data); -typedef gboolean (* GumFoundImportFunc) (const GumImportDetails * details, - gpointer user_data); -typedef gboolean (* GumFoundExportFunc) (const GumExportDetails * details, - gpointer user_data); -typedef gboolean (* GumFoundSymbolFunc) (const GumSymbolDetails * details, +typedef gboolean (* GumFoundModuleFunc) (GumModule * module, gpointer user_data); -typedef gboolean (* GumFoundRangeFunc) (const GumRangeDetails * details, - gpointer user_data); -typedef gboolean (* GumFoundSectionFunc) (const GumSectionDetails * details, - gpointer user_data); -typedef gboolean (* GumFoundDependencyFunc) ( - const GumDependencyDetails * details, gpointer user_data); typedef gboolean (* GumFoundMallocRangeFunc) ( const GumMallocRangeDetails * details, gpointer user_data); -typedef GumAddress (* GumResolveExportFunc) (const char * module_name, - const char * symbol_name, gpointer user_data); GUM_API GumOS gum_process_get_native_os (void); GUM_API GumTeardownRequirement gum_process_get_teardown_requirement (void); @@ -62911,7 +62907,6 @@ GUM_API void gum_process_set_teardown_requirement ( GumTeardownRequirement requirement); GUM_API GumCodeSigningPolicy gum_process_get_code_signing_policy (void); GUM_API void gum_process_set_code_signing_policy (GumCodeSigningPolicy policy); -GUM_API const gchar * gum_process_query_libc_name (void); GUM_API gboolean gum_process_is_debugger_attached (void); GUM_API GumProcessId gum_process_get_id (void); GUM_API GumThreadId gum_process_get_current_thread_id (void); @@ -62920,9 +62915,10 @@ GUM_API gboolean gum_process_modify_thread (GumThreadId thread_id, GumModifyThreadFunc func, gpointer user_data, GumModifyThreadFlags flags); GUM_API void gum_process_enumerate_threads (GumFoundThreadFunc func, gpointer user_data); -GUM_API const GumModuleDetails * gum_process_get_main_module (void); -GUM_API gboolean gum_process_resolve_module_pointer (gconstpointer ptr, - gchar ** path, GumMemoryRange * range); +GUM_API GumModule * gum_process_get_main_module (void); +GUM_API GumModule * gum_process_get_libc_module (void); +GUM_API GumModule * gum_process_find_module_by_name (const gchar * name); +GUM_API GumModule * gum_process_find_module_by_address (GumAddress address); GUM_API void gum_process_enumerate_modules (GumFoundModuleFunc func, gpointer user_data); GUM_API void gum_process_enumerate_ranges (GumPageProtection prot, @@ -62944,36 +62940,10 @@ GUM_API gboolean gum_thread_set_hardware_watchpoint (GumThreadId thread_id, GError ** error); GUM_API gboolean gum_thread_unset_hardware_watchpoint (GumThreadId thread_id, guint watchpoint_id, GError ** error); -GUM_API gboolean gum_module_load (const gchar * module_name, GError ** error); -GUM_API gboolean gum_module_ensure_initialized (const gchar * module_name); -GUM_API void gum_module_enumerate_imports (const gchar * module_name, - GumFoundImportFunc func, gpointer user_data); -GUM_API void gum_module_enumerate_exports (const gchar * module_name, - GumFoundExportFunc func, gpointer user_data); -GUM_API void gum_module_enumerate_symbols (const gchar * module_name, - GumFoundSymbolFunc func, gpointer user_data); -GUM_API void gum_module_enumerate_ranges (const gchar * module_name, - GumPageProtection prot, GumFoundRangeFunc func, gpointer user_data); -GUM_API void gum_module_enumerate_sections (const gchar * module_name, - GumFoundSectionFunc func, gpointer user_data); -GUM_API void gum_module_enumerate_dependencies (const gchar * module_name, - GumFoundDependencyFunc func, gpointer user_data); -GUM_API GumAddress gum_module_find_base_address (const gchar * module_name); -GUM_API GumAddress gum_module_find_export_by_name (const gchar * module_name, - const gchar * symbol_name); -GUM_API GumAddress gum_module_find_symbol_by_name (const gchar * module_name, - const gchar * symbol_name); GUM_API const gchar * gum_code_signing_policy_to_string ( GumCodeSigningPolicy policy); -#ifndef GUM_DIET -GUM_API GType gum_module_details_get_type (void) G_GNUC_CONST; -#endif -GUM_API GumModuleDetails * gum_module_details_copy ( - const GumModuleDetails * module); -GUM_API void gum_module_details_free (GumModuleDetails * module); - GUM_API const gchar * gum_symbol_type_to_string (GumSymbolType type); G_END_DECLS @@ -63077,18 +63047,14 @@ GUM_API GumCodeSlice * gum_code_allocator_alloc_slice (GumCodeAllocator * self); GUM_API GumCodeSlice * gum_code_allocator_try_alloc_slice_near ( GumCodeAllocator * self, const GumAddressSpec * spec, gsize alignment); GUM_API void gum_code_allocator_commit (GumCodeAllocator * self); -#ifndef GUM_DIET GUM_API GType gum_code_slice_get_type (void) G_GNUC_CONST; -#endif GUM_API GumCodeSlice * gum_code_slice_ref (GumCodeSlice * slice); GUM_API void gum_code_slice_unref (GumCodeSlice * slice); GUM_API GumCodeDeflector * gum_code_allocator_alloc_deflector ( GumCodeAllocator * self, const GumAddressSpec * caller, gpointer return_address, gpointer target, gboolean dedicated); -#ifndef GUM_DIET GUM_API GType gum_code_deflector_get_type (void) G_GNUC_CONST; -#endif GUM_API GumCodeDeflector * gum_code_deflector_ref ( GumCodeDeflector * deflector); GUM_API void gum_code_deflector_unref (GumCodeDeflector * deflector); @@ -63150,8 +63116,8 @@ typedef enum { } GumDarwinGrafterFlags; #define GUM_TYPE_DARWIN_GRAFTER (gum_darwin_grafter_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumDarwinGrafter, gum_darwin_grafter, GUM, - DARWIN_GRAFTER, GObject) +G_DECLARE_FINAL_TYPE (GumDarwinGrafter, gum_darwin_grafter, GUM, DARWIN_GRAFTER, + GObject) GUM_API GumDarwinGrafter * gum_darwin_grafter_new_from_file ( const gchar * path, GumDarwinGrafterFlags flags); @@ -63179,8 +63145,8 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_DARWIN_MODULE (gum_darwin_module_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumDarwinModule, gum_darwin_module, GUM, DARWIN_MODULE, - GObject) +G_DECLARE_FINAL_TYPE (GumDarwinModule, gum_darwin_module, GUM, DARWIN_MODULE, + GObject) #define GUM_TYPE_DARWIN_MODULE_IMAGE (gum_darwin_module_image_get_type ()) @@ -63277,11 +63243,7 @@ typedef struct _GumChainedPtrArm64eAuthBind24 GumChainedPtrArm64eAuthBind24; struct _GumDarwinModule { -#ifndef GUM_DIET GObject parent; -#else - GumObject parent; -#endif GumDarwinModuleFiletype filetype; gchar * name; @@ -63308,6 +63270,7 @@ struct _GumDarwinModule GArray * segments; GArray * text_ranges; + gsize text_size; const guint8 * rebases; const guint8 * rebases_end; @@ -63819,9 +63782,7 @@ GUM_API gboolean gum_darwin_module_ensure_image_loaded (GumDarwinModule * self, GUM_API void gum_darwin_threaded_item_parse (guint64 value, GumDarwinThreadedItem * result); -#ifndef GUM_DIET GUM_API GType gum_darwin_module_image_get_type (void) G_GNUC_CONST; -#endif GUM_API GumDarwinModuleImage * gum_darwin_module_image_new (void); GUM_API GumDarwinModuleImage * gum_darwin_module_image_dup ( const GumDarwinModuleImage * other); @@ -63843,7 +63804,7 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_ELF_TYPE_MODULE (gum_elf_module_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumElfModule, gum_elf_module, GUM_ELF, MODULE, GObject) +G_DECLARE_FINAL_TYPE (GumElfModule, gum_elf_module, GUM_ELF, MODULE, GObject) typedef enum { GUM_ELF_NONE, @@ -64931,21 +64892,19 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_EVENT_SINK (gum_event_sink_get_type ()) -GUM_DECLARE_INTERFACE (GumEventSink, gum_event_sink, GUM, EVENT_SINK, GObject) +G_DECLARE_INTERFACE (GumEventSink, gum_event_sink, GUM, EVENT_SINK, GObject) #define GUM_TYPE_DEFAULT_EVENT_SINK (gum_default_event_sink_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumDefaultEventSink, gum_default_event_sink, GUM, - DEFAULT_EVENT_SINK, GObject) +G_DECLARE_FINAL_TYPE (GumDefaultEventSink, gum_default_event_sink, GUM, + DEFAULT_EVENT_SINK, GObject) #define GUM_TYPE_CALLBACK_EVENT_SINK (gum_callback_event_sink_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumCallbackEventSink, gum_callback_event_sink, GUM, - CALLBACK_EVENT_SINK, GObject) +G_DECLARE_FINAL_TYPE (GumCallbackEventSink, gum_callback_event_sink, GUM, + CALLBACK_EVENT_SINK, GObject) typedef void (* GumEventSinkCallback) (const GumEvent * event, GumCpuContext * cpu_context, gpointer user_data); -#ifndef GUM_DIET - struct _GumEventSinkInterface { GTypeInterface parent; @@ -64958,8 +64917,6 @@ struct _GumEventSinkInterface void (* stop) (GumEventSink * self); }; -#endif - GUM_API GumEventType gum_event_sink_query_mask (GumEventSink * self); GUM_API void gum_event_sink_start (GumEventSink * self); GUM_API void gum_event_sink_process (GumEventSink * self, @@ -64989,7 +64946,7 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_EXCEPTOR (gum_exceptor_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumExceptor, gum_exceptor, GUM, EXCEPTOR, GObject) +G_DECLARE_FINAL_TYPE (GumExceptor, gum_exceptor, GUM, EXCEPTOR, GObject) #if defined (G_OS_WIN32) || defined (__APPLE__) # define GUM_NATIVE_SETJMP(env) setjmp (env) @@ -65246,14 +65203,12 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_INVOCATION_LISTENER (gum_invocation_listener_get_type ()) -GUM_DECLARE_INTERFACE (GumInvocationListener, gum_invocation_listener, GUM, - INVOCATION_LISTENER, GObject) +G_DECLARE_INTERFACE (GumInvocationListener, gum_invocation_listener, GUM, + INVOCATION_LISTENER, GObject) typedef void (* GumInvocationCallback) (GumInvocationContext * context, gpointer user_data); -#ifndef GUM_DIET - struct _GumInvocationListenerInterface { GTypeInterface parent; @@ -65264,21 +65219,6 @@ struct _GumInvocationListenerInterface GumInvocationContext * context); }; -#else - -struct _GumInvocationListener -{ - GumObject parent; - - GumInvocationCallback on_enter; - GumInvocationCallback on_leave; - - gpointer data; - GDestroyNotify data_destroy; -}; - -#endif - GUM_API GumInvocationListener * gum_make_call_listener ( GumInvocationCallback on_enter, GumInvocationCallback on_leave, gpointer data, GDestroyNotify data_destroy); @@ -65297,8 +65237,8 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_INTERCEPTOR (gum_interceptor_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumInterceptor, gum_interceptor, GUM, INTERCEPTOR, - GObject) +G_DECLARE_FINAL_TYPE (GumInterceptor, gum_interceptor, GUM, INTERCEPTOR, + GObject) typedef GArray GumInvocationStack; typedef guint GumInvocationState; @@ -65370,7 +65310,7 @@ G_END_DECLS #endif /* - * Copyright (C) 2015-2021 Ole André Vadla Ravnås + * Copyright (C) 2015-2024 Ole André Vadla Ravnås * * Licence: wxWindows Library Licence, Version 3.1 */ @@ -65382,6 +65322,7 @@ G_END_DECLS G_BEGIN_DECLS typedef struct _GumKernelModuleRangeDetails GumKernelModuleRangeDetails; +typedef struct _GumKernelModuleDetails GumKernelModuleDetails; struct _GumKernelModuleRangeDetails { @@ -65391,8 +65332,17 @@ struct _GumKernelModuleRangeDetails GumPageProtection protection; }; +struct _GumKernelModuleDetails +{ + const gchar * name; + const GumMemoryRange * range; + const gchar * path; +}; + typedef gboolean (* GumFoundKernelModuleRangeFunc) ( const GumKernelModuleRangeDetails * details, gpointer user_data); +typedef gboolean (* GumFoundKernelModuleFunc) ( + const GumKernelModuleDetails * details, gpointer user_data); GUM_API gboolean gum_kernel_api_is_available (void); GUM_API guint gum_kernel_query_page_size (void); @@ -65412,7 +65362,7 @@ GUM_API void gum_kernel_enumerate_ranges (GumPageProtection prot, GUM_API void gum_kernel_enumerate_module_ranges (const gchar * module_name, GumPageProtection prot, GumFoundKernelModuleRangeFunc func, gpointer user_data); -GUM_API void gum_kernel_enumerate_modules (GumFoundModuleFunc func, +GUM_API void gum_kernel_enumerate_modules (GumFoundKernelModuleFunc func, gpointer user_data); GUM_API GumAddress gum_kernel_find_base_address (void); GUM_API void gum_kernel_set_base_address (GumAddress base); @@ -65452,8 +65402,8 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_MEMORY_ACCESS_MONITOR (gum_memory_access_monitor_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumMemoryAccessMonitor, gum_memory_access_monitor, GUM, - MEMORY_ACCESS_MONITOR, GObject) +G_DECLARE_FINAL_TYPE (GumMemoryAccessMonitor, gum_memory_access_monitor, GUM, + MEMORY_ACCESS_MONITOR, GObject) typedef struct _GumMemoryAccessDetails GumMemoryAccessDetails; @@ -65498,7 +65448,7 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_MEMORY_MAP (gum_memory_map_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumMemoryMap, gum_memory_map, GUM, MEMORY_MAP, GObject) +G_DECLARE_FINAL_TYPE (GumMemoryMap, gum_memory_map, GUM, MEMORY_MAP, GObject) GUM_API GumMemoryMap * gum_memory_map_new (GumPageProtection prot); @@ -65660,8 +65610,8 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_MODULE_API_RESOLVER (gum_module_api_resolver_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumModuleApiResolver, gum_module_api_resolver, GUM, - MODULE_API_RESOLVER, GObject) +G_DECLARE_FINAL_TYPE (GumModuleApiResolver, gum_module_api_resolver, GUM, + MODULE_API_RESOLVER, GObject) GUM_API GumApiResolver * gum_module_api_resolver_new (void); @@ -65669,7 +65619,7 @@ G_END_DECLS #endif /* - * Copyright (C) 2015-2022 Ole André Vadla Ravnås + * Copyright (C) 2015-2024 Ole André Vadla Ravnås * * Licence: wxWindows Library Licence, Version 3.1 */ @@ -65681,21 +65631,21 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_MODULE_MAP (gum_module_map_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumModuleMap, gum_module_map, GUM, MODULE_MAP, GObject) +G_DECLARE_FINAL_TYPE (GumModuleMap, gum_module_map, GUM, MODULE_MAP, GObject) -typedef gboolean (* GumModuleMapFilterFunc) (const GumModuleDetails * details, +typedef gboolean (* GumModuleMapFilterFunc) (GumModule * module, gpointer user_data); GUM_API GumModuleMap * gum_module_map_new (void); GUM_API GumModuleMap * gum_module_map_new_filtered (GumModuleMapFilterFunc func, gpointer data, GDestroyNotify data_destroy); -GUM_API const GumModuleDetails * gum_module_map_find (GumModuleMap * self, +GUM_API GumModule * gum_module_map_find (GumModuleMap * self, GumAddress address); GUM_API void gum_module_map_update (GumModuleMap * self); -GUM_API GArray * gum_module_map_get_values (GumModuleMap * self); +GUM_API GPtrArray * gum_module_map_get_values (GumModuleMap * self); G_END_DECLS @@ -84307,29 +84257,29 @@ G_END_DECLS G_BEGIN_DECLS #define GUM_TYPE_STALKER (gum_stalker_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumStalker, gum_stalker, GUM, STALKER, GObject) +G_DECLARE_FINAL_TYPE (GumStalker, gum_stalker, GUM, STALKER, GObject) #define GUM_TYPE_STALKER_TRANSFORMER (gum_stalker_transformer_get_type ()) -GUM_DECLARE_INTERFACE (GumStalkerTransformer, gum_stalker_transformer, GUM, - STALKER_TRANSFORMER, GObject) +G_DECLARE_INTERFACE (GumStalkerTransformer, gum_stalker_transformer, GUM, + STALKER_TRANSFORMER, GObject) #define GUM_TYPE_DEFAULT_STALKER_TRANSFORMER \ (gum_default_stalker_transformer_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumDefaultStalkerTransformer, - gum_default_stalker_transformer, - GUM, DEFAULT_STALKER_TRANSFORMER, - GObject) +G_DECLARE_FINAL_TYPE (GumDefaultStalkerTransformer, + gum_default_stalker_transformer, + GUM, DEFAULT_STALKER_TRANSFORMER, + GObject) #define GUM_TYPE_CALLBACK_STALKER_TRANSFORMER \ (gum_callback_stalker_transformer_get_type ()) -GUM_DECLARE_FINAL_TYPE (GumCallbackStalkerTransformer, - gum_callback_stalker_transformer, - GUM, CALLBACK_STALKER_TRANSFORMER, - GObject) +G_DECLARE_FINAL_TYPE (GumCallbackStalkerTransformer, + gum_callback_stalker_transformer, + GUM, CALLBACK_STALKER_TRANSFORMER, + GObject) #define GUM_TYPE_STALKER_OBSERVER (gum_stalker_observer_get_type ()) -GUM_DECLARE_INTERFACE (GumStalkerObserver, gum_stalker_observer, GUM, - STALKER_OBSERVER, GObject) +G_DECLARE_INTERFACE (GumStalkerObserver, gum_stalker_observer, GUM, + STALKER_OBSERVER, GObject) typedef struct _GumStalkerIterator GumStalkerIterator; typedef struct _GumStalkerOutput GumStalkerOutput; @@ -84354,8 +84304,6 @@ typedef void (* GumCallProbeCallback) (GumCallDetails * details, typedef void (* GumStalkerRunOnThreadFunc) (const GumCpuContext * cpu_context, gpointer user_data); -#ifndef GUM_DIET - struct _GumStalkerTransformerInterface { GTypeInterface parent; @@ -84419,8 +84367,6 @@ struct _GumStalkerObserverInterface GumStalkerSwitchCallbackFunc switch_callback; }; -#endif - union _GumStalkerWriter { gpointer instance; diff --git a/frida-gum/src/module.rs b/frida-gum/src/module.rs index 37bca9d..27c3b43 100644 --- a/frida-gum/src/module.rs +++ b/frida-gum/src/module.rs @@ -13,13 +13,17 @@ allow(clippy::unnecessary_cast) )] +use crate::MemoryRange; +#[cfg(feature = "std")] +use std::{ffi::CStr, string::ToString}; + use { crate::{Gum, NativePointer, PageProtection, RangeDetails}, core::{ffi::c_void, fmt}, cstr_core::CString, frida_gum_sys as gum_sys, frida_gum_sys::{ - gboolean, gpointer, GumExportDetails, GumModuleDetails, GumSectionDetails, GumSymbolDetails, + gboolean, gpointer, GumExportDetails, GumModule, GumSectionDetails, GumSymbolDetails, }, }; @@ -40,8 +44,8 @@ extern "C" fn enumerate_ranges_callout( #[derive(Clone, FromPrimitive, Debug)] #[repr(u32)] pub enum ExportType { - Function = gum_sys::_GumExportType_GUM_EXPORT_FUNCTION as u32, - Variable = gum_sys::_GumExportType_GUM_EXPORT_VARIABLE as u32, + Function = gum_sys::GumExportType_GUM_EXPORT_FUNCTION as u32, + Variable = gum_sys::GumExportType_GUM_EXPORT_VARIABLE as u32, } impl fmt::Display for ExportType { @@ -53,37 +57,6 @@ impl fmt::Display for ExportType { } } -impl ModuleDetailsOwned { - pub unsafe fn from_module_details(details: *const GumModuleDetails) -> Self { - let name: String = NativePointer((*details).name as *mut _) - .try_into() - .unwrap_or_default(); - let path: String = NativePointer((*details).path as *mut _) - .try_into() - .unwrap_or_default(); - let range = (*details).range; - let base_address = (*range).base_address as usize; - let size = (*range).size as usize; - - ModuleDetailsOwned { - name, - path, - base_address, - size, - } - } -} - -impl fmt::Display for ModuleDetailsOwned { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - fmt, - "{{\n\tbase: 0x{:x}\n\tname: {}\n\tpath: {}\n\tsize: {}\n}}", - self.base_address, self.name, self.path, self.size - ) - } -} - /// Module symbol details returned by [`Module::enumerate_symbols`]. pub struct SymbolDetails { pub name: String, @@ -106,51 +79,66 @@ pub struct ExportDetails { pub address: usize, } -/// Module details returned by [`Module::enumerate_modules`]. -pub struct ModuleDetailsOwned { - pub name: String, - pub path: String, - pub base_address: usize, - pub size: usize, +impl Drop for Module { + fn drop(&mut self) { + unsafe { + gum_sys::g_object_unref(self.inner as _); + } + } } -pub struct Module<'a> { - // This is to verify that Gum is initialized before using any Module methods which requires - // intialization. - // Note that Gum is expected to be initialized via OnceCell which provides &Gum for every - // instance. - _gum: &'a Gum, +pub struct Module { + inner: *mut GumModule, } -impl Module<'_> { - pub fn obtain(gum: &Gum) -> Module { - Module { _gum: gum } +impl Module { + pub(crate) fn from_raw(module: *mut GumModule) -> Self { + Self { inner: module } + } + /// Load a module by name + pub fn load(_gum: &Gum, module_name: &str) -> Self { + let module_name = CString::new(module_name).unwrap(); + Self { + inner: unsafe { + gum_sys::gum_module_load(module_name.as_ptr().cast(), core::ptr::null_mut()) + }, + } + } + + #[cfg(feature = "std")] + /// Get the name of this module + pub fn name(&self) -> String { + unsafe { + CStr::from_ptr(gum_sys::gum_module_get_name(self.inner)) + .to_string_lossy() + .to_string() + } + } + + #[cfg(feature = "std")] + /// Get the path of this module + pub fn path(&self) -> String { + unsafe { + CStr::from_ptr(gum_sys::gum_module_get_path(self.inner)) + .to_string_lossy() + .to_string() + } + } + + /// Get the range of this module + pub fn range(&self) -> MemoryRange { + MemoryRange::from_raw(unsafe { gum_sys::gum_module_get_range(self.inner) }) } /// The absolute address of the export. In the event that no such export /// could be found, returns NULL. - pub fn find_export_by_name( - &self, - module_name: Option<&str>, - symbol_name: &str, - ) -> Option { + pub fn find_export_by_name(&self, symbol_name: &str) -> Option { let symbol_name = CString::new(symbol_name).unwrap(); - let ptr = match module_name { - None => unsafe { - gum_sys::gum_module_find_export_by_name( - core::ptr::null_mut(), - symbol_name.as_ptr().cast(), - ) - }, - Some(name) => unsafe { - let module_name = CString::new(name).unwrap(); - gum_sys::gum_module_find_export_by_name( - module_name.as_ptr().cast(), - symbol_name.as_ptr().cast(), - ) - }, - } as *mut c_void; + let ptr = unsafe { + gum_sys::gum_module_find_export_by_name(self.inner, symbol_name.as_ptr().cast()) + as *mut c_void + }; if ptr.is_null() { None @@ -161,19 +149,11 @@ impl Module<'_> { /// The absolute address of the symbol. In the event that no such symbol /// could be found, returns NULL. - pub fn find_symbol_by_name( - &self, - module_name: &str, - symbol_name: &str, - ) -> Option { + pub fn find_symbol_by_name(&self, symbol_name: &str) -> Option { let symbol_name = CString::new(symbol_name).unwrap(); - let module_name = CString::new(module_name).unwrap(); let ptr = unsafe { - gum_sys::gum_module_find_symbol_by_name( - module_name.as_ptr().cast(), - symbol_name.as_ptr().cast(), - ) + gum_sys::gum_module_find_symbol_by_name(self.inner, symbol_name.as_ptr().cast()) } as *mut c_void; if ptr.is_null() { @@ -183,34 +163,19 @@ impl Module<'_> { } } - /// Returns the base address of the specified module. In the event that no - /// such module could be found, returns NULL. - pub fn find_base_address(&self, module_name: &str) -> NativePointer { - let module_name = CString::new(module_name).unwrap(); - - unsafe { - NativePointer( - gum_sys::gum_module_find_base_address(module_name.as_ptr().cast()) as *mut c_void, - ) - } - } - /// Enumerates memory ranges satisfying protection given. pub fn enumerate_ranges( &self, - module_name: &str, prot: PageProtection, callout: impl FnMut(RangeDetails) -> bool, ) { - let module_name = CString::new(module_name).unwrap(); - unsafe { let user_data = Box::leak(Box::new( Box::new(callout) as Box bool> )) as *mut _ as *mut c_void; gum_sys::gum_module_enumerate_ranges( - module_name.as_ptr().cast(), + self.inner, prot as u32, Some(enumerate_ranges_callout), user_data, @@ -220,32 +185,8 @@ impl Module<'_> { } } - /// Enumerates modules. - pub fn enumerate_modules(&self) -> Vec { - let result: Vec = vec![]; - - unsafe extern "C" fn callback( - details: *const GumModuleDetails, - user_data: gpointer, - ) -> gboolean { - let res = &mut *(user_data as *mut Vec); - res.push(ModuleDetailsOwned::from_module_details(details)); - - 1 - } - - unsafe { - frida_gum_sys::gum_process_enumerate_modules( - Some(callback), - &result as *const _ as *mut c_void, - ); - } - - result - } - /// Enumerates exports in module. - pub fn enumerate_exports(&self, module_name: &str) -> Vec { + pub fn enumerate_exports(&self) -> Vec { let result: Vec = vec![]; unsafe extern "C" fn callback( @@ -264,11 +205,9 @@ impl Module<'_> { 1 } - let module_name = CString::new(module_name).unwrap(); - unsafe { frida_gum_sys::gum_module_enumerate_exports( - module_name.as_ptr().cast(), + self.inner, Some(callback), &result as *const _ as *mut c_void, ); @@ -277,7 +216,7 @@ impl Module<'_> { } /// Enumerates symbols in module. - pub fn enumerate_symbols(&self, module_name: &str) -> Vec { + pub fn enumerate_symbols(&self) -> Vec { let result: Vec = vec![]; unsafe extern "C" fn callback( details: *const GumSymbolDetails, @@ -301,11 +240,9 @@ impl Module<'_> { 1 } - let module_name = CString::new(module_name).unwrap(); - unsafe { frida_gum_sys::gum_module_enumerate_symbols( - module_name.as_ptr().cast(), + self.inner, Some(callback), &result as *const _ as *mut c_void, ); @@ -314,7 +251,7 @@ impl Module<'_> { } /// Enumerates sections of module. - pub fn enumerate_sections(&self, module_name: &str) -> Vec { + pub fn enumerate_sections(&self) -> Vec { let result: Vec = vec![]; unsafe extern "C" fn callback( @@ -343,11 +280,9 @@ impl Module<'_> { 1 } - let module_name = CString::new(module_name).unwrap(); - unsafe { frida_gum_sys::gum_module_enumerate_sections( - module_name.as_ptr().cast(), + self.inner, Some(callback), &result as *const _ as *mut c_void, ); diff --git a/frida-gum/src/module_map.rs b/frida-gum/src/module_map.rs index a661fe2..a52c741 100644 --- a/frida-gum/src/module_map.rs +++ b/frida-gum/src/module_map.rs @@ -11,178 +11,45 @@ )] use { - crate::{Gum, MemoryRange}, - core::{ - ffi::{c_void, CStr}, - slice::from_raw_parts, - }, + crate::{Gum, Module}, + core::{ffi::c_void, slice::from_raw_parts}, frida_gum_sys as gum_sys, }; #[cfg(not(feature = "std"))] -use alloc::{ - boxed::Box, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{boxed::Box, vec::Vec}; #[cfg(feature = "module-names")] use std::path::Path; -#[cfg(feature = "module-names")] -struct SaveModuleDetailsByNameContext { - name: String, - details: *mut gum_sys::GumModuleDetails, -} - -struct SaveModuleDetailsByAddressContext { - address: u64, - details: *mut gum_sys::GumModuleDetails, -} - -#[cfg(feature = "module-names")] -unsafe extern "C" fn save_module_details_by_name( - details: *const gum_sys::GumModuleDetails, - context: *mut c_void, -) -> i32 { - let context = &mut *(context as *mut SaveModuleDetailsByNameContext); - let path_string = CStr::from_ptr((*details).path as *const _) - .to_string_lossy() - .to_string(); - if (context.name.starts_with('/') && path_string.eq(&context.name)) - || (context.name.contains('/') - && Path::new(&path_string) - .file_name() - .unwrap_or_default() - .to_string_lossy() - .eq(&context.name)) - { - context.details = gum_sys::gum_module_details_copy(details); - return 0; - } - - 1 -} - -unsafe extern "C" fn save_module_details_by_address( - details: *const gum_sys::GumModuleDetails, - context: *mut c_void, -) -> i32 { - let context = &mut *(context as *mut SaveModuleDetailsByAddressContext); - let range = (*details).range; - let start = (*range).base_address as u64; - let end = start + (*range).size as u64; - if start <= context.address && context.address < end { - context.details = gum_sys::gum_module_details_copy(details); - return 0; - } - - 1 -} - -pub struct ModuleDetails { - module_details: *const gum_sys::GumModuleDetails, -} - -/// Represents a loaded module -impl ModuleDetails { - pub(crate) fn from_raw(module_details: *const gum_sys::_GumModuleDetails) -> Self { - Self { module_details } - } - - /// Get a new [`ModuleDetails`] instance for the module matching the given name. The name may - /// be a full path, in which case the matching module must have the same full path, or a - /// file name, in which case only the file name portion of the module must match. - #[cfg(feature = "module-names")] - pub fn with_name(name: String) -> Option { - let mut context = SaveModuleDetailsByNameContext { - name, - details: core::ptr::null_mut(), - }; - - unsafe { - gum_sys::gum_process_enumerate_modules( - Some(save_module_details_by_name), - &mut context as *mut _ as *mut c_void, - ); - } - - if context.details.is_null() { - None - } else { - Some(Self::from_raw(context.details)) - } - } - - /// Get a new [`ModuleDetails`] instance for the module containing the given address. - pub fn with_address(address: u64) -> Option { - let mut context = SaveModuleDetailsByAddressContext { - address, - details: core::ptr::null_mut(), - }; - - unsafe { - gum_sys::gum_process_enumerate_modules( - Some(save_module_details_by_address), - &mut context as *mut _ as *mut c_void, - ); - } - - if context.details.is_null() { - None - } else { - Some(Self::from_raw(context.details)) - } - } - - /// Get the name of this module - pub fn name(&self) -> String { - unsafe { - CStr::from_ptr((*self.module_details).name) - .to_string_lossy() - .to_string() - } - } - - /// Get the path of this module - pub fn path(&self) -> String { - unsafe { - CStr::from_ptr((*self.module_details).path) - .to_string_lossy() - .to_string() - } - } - - /// Get the range of this module - pub fn range(&self) -> MemoryRange { - MemoryRange::from_raw(unsafe { (*self.module_details).range }) - } -} - -pub struct ModuleMap { +pub struct ModuleMap<'a> { + _gum: &'a Gum, pub(crate) module_map: *mut gum_sys::GumModuleMap, } -impl ModuleMap { - pub(crate) fn from_raw(module_map: *mut gum_sys::GumModuleMap) -> Self { - Self { module_map } +impl<'a> ModuleMap<'a> { + pub(crate) fn from_raw(gum: &'a Gum, module_map: *mut gum_sys::GumModuleMap) -> Self { + Self { + _gum: gum, + module_map, + } } /// Create a new [`ModuleMap`] - pub fn new(_gum: &Gum) -> Self { - Self::from_raw(unsafe { gum_sys::gum_module_map_new() }) + pub fn new(_gum: &'a Gum) -> Self { + Self::from_raw(_gum, unsafe { gum_sys::gum_module_map_new() }) } /// Create a new [`ModuleMap`] with a filter function - pub fn new_with_filter(_gum: &Gum, filter: &mut dyn FnMut(ModuleDetails) -> bool) -> Self { + pub fn new_with_filter(_gum: &'a Gum, filter: &mut dyn FnMut(Module) -> bool) -> Self { unsafe extern "C" fn module_map_filter( - details: *const gum_sys::_GumModuleDetails, + details: *mut gum_sys::GumModule, callback: *mut c_void, ) -> i32 { - let callback = &mut *(callback as *mut Box<&mut dyn FnMut(ModuleDetails) -> bool>); - i32::from((callback)(ModuleDetails::from_raw(details))) + let callback = &mut *(callback as *mut Box<&mut dyn FnMut(Module) -> bool>); + i32::from((callback)(Module::from_raw(details))) } - Self::from_raw(unsafe { + Self::from_raw(_gum, unsafe { gum_sys::gum_module_map_new_filtered( Some(module_map_filter), &mut Box::new(filter) as *mut _ as *mut c_void, @@ -193,8 +60,8 @@ impl ModuleMap { /// Create a new [`ModuleMap`] from a list of names #[cfg(feature = "module-names")] - pub fn new_from_names(gum: &Gum, names: &[&str]) -> Self { - Self::new_with_filter(gum, &mut |details: ModuleDetails| { + pub fn new_from_names(gum: &'a Gum, names: &[&str]) -> Self { + Self::new_with_filter(gum, &mut |details: Module| { for name in names { if (name.starts_with('/') && details.path().eq(name)) || (name.contains('/') @@ -212,28 +79,28 @@ impl ModuleMap { }) } /// Find the given address in the [`ModuleMap`] - pub fn find(&self, address: u64) -> Option { + pub fn find(&self, address: u64) -> Option { let res = unsafe { gum_sys::gum_module_map_find(self.module_map, address) }; if res.is_null() { None } else { - Some(ModuleDetails::from_raw(res)) + Some(Module::from_raw(res)) } } - /// Get an array of the [`ModuleDetails`] which make up this [`ModuleMap`] - pub fn values(&self) -> Vec { + /// Get an array of the [`Module`] which make up this [`ModuleMap`] + pub fn values(&self) -> Vec { unsafe { let array = gum_sys::gum_module_map_get_values(self.module_map); let raw_module_details = from_raw_parts( - (*array).data as *mut gum_sys::_GumModuleDetails, + (*array).pdata as *const *mut gum_sys::GumModule, (*array).len as usize, ); raw_module_details .iter() - .map(|raw| ModuleDetails::from_raw(raw)) + .map(|raw| Module::from_raw(*raw)) .collect::>() } } @@ -244,7 +111,7 @@ impl ModuleMap { } } -impl Drop for ModuleMap { +impl Drop for ModuleMap<'_> { fn drop(&mut self) { unsafe { gum_sys::g_object_unref(self.module_map as *mut c_void) } } diff --git a/frida-gum/src/process.rs b/frida-gum/src/process.rs index e6b2982..040b5c0 100644 --- a/frida-gum/src/process.rs +++ b/frida-gum/src/process.rs @@ -6,10 +6,10 @@ allow(clippy::unnecessary_cast) )] -use crate::{FileMapping, NativePointer}; +use crate::{FileMapping, Module, NativePointer}; use { - crate::{module, Gum, PageProtection, RangeDetails}, + crate::{Gum, PageProtection, RangeDetails}, core::ffi::{c_char, c_void, CStr}, frida_gum_sys as gum_sys, frida_gum_sys::{gboolean, gpointer}, @@ -17,6 +17,7 @@ use { #[cfg(not(feature = "std"))] use alloc::{string::String, string::ToString, vec::Vec}; +use cstr_core::CString; extern "C" { pub fn _frida_g_get_home_dir() -> *const c_char; @@ -70,7 +71,7 @@ pub struct Process<'a> { /// existing code in memory and will not try to run unsigned code. pub code_signing_policy: CodeSigningPolicy, /// Contains a Module representing the main executable of the process. - pub main_module: module::ModuleDetailsOwned, + pub main_module: Module, } impl<'a> Process<'a> { @@ -84,9 +85,7 @@ impl<'a> Process<'a> { }) .unwrap(); - let main_module = unsafe { - module::ModuleDetailsOwned::from_module_details(gum_sys::gum_process_get_main_module()) - }; + let main_module = unsafe { Module::from_raw(gum_sys::gum_process_get_main_module()) }; Process { _gum: gum, @@ -97,6 +96,18 @@ impl<'a> Process<'a> { } } + pub fn find_module_by_name(&self, module_name: &str) -> Module { + let module_name = CString::new(module_name).unwrap(); + unsafe { + Module::from_raw(gum_sys::gum_process_find_module_by_name( + module_name.as_ptr().cast(), + )) + } + } + + pub fn find_module_by_address(&self, address: usize) -> Module { + unsafe { Module::from_raw(gum_sys::gum_process_find_module_by_address(address as u64)) } + } /// Returns a string specifying the filesystem path to the current working directory pub fn current_dir(&self) -> String { unsafe { diff --git a/frida-sys/FRIDA_VERSION b/frida-sys/FRIDA_VERSION index b5b922b..357607e 100644 --- a/frida-sys/FRIDA_VERSION +++ b/frida-sys/FRIDA_VERSION @@ -1 +1 @@ -16.5.6 +16.6.2