diff --git a/gum/guminterceptor.c b/gum/guminterceptor.c index aa0a7f6f1..bd70c0adf 100644 --- a/gum/guminterceptor.c +++ b/gum/guminterceptor.c @@ -2061,3 +2061,23 @@ gum_page_address_compare (gconstpointer a, { return GPOINTER_TO_SIZE (a) - GPOINTER_TO_SIZE (b); } + +void +gum_interceptor_with_lock_held (GumInterceptor * self, + GumInterceptorLockedFunc func, + gpointer user_data) +{ + GUM_INTERCEPTOR_LOCK (self); + func (user_data); + GUM_INTERCEPTOR_UNLOCK (self); +} + +gboolean +gum_interceptor_is_locked (GumInterceptor * self) +{ + if (!g_rec_mutex_trylock (&self->mutex)) + return TRUE; + + GUM_INTERCEPTOR_UNLOCK (self); + return FALSE; +} diff --git a/gum/guminterceptor.h b/gum/guminterceptor.h index eba2e73dc..658eef2ba 100644 --- a/gum/guminterceptor.h +++ b/gum/guminterceptor.h @@ -17,6 +17,7 @@ G_BEGIN_DECLS GUM_DECLARE_FINAL_TYPE (GumInterceptor, gum_interceptor, GUM, INTERCEPTOR, GObject) +typedef void (* GumInterceptorLockedFunc) (gpointer user_data); typedef GArray GumInvocationStack; typedef guint GumInvocationState; @@ -76,6 +77,9 @@ GUM_API gpointer gum_invocation_stack_translate (GumInvocationStack * self, GUM_API void gum_interceptor_save (GumInvocationState * state); GUM_API void gum_interceptor_restore (GumInvocationState * state); +GUM_API void gum_interceptor_with_lock_held (GumInterceptor * self, + GumInterceptorLockedFunc func, gpointer user_data); +GUM_API gboolean gum_interceptor_is_locked (GumInterceptor * self); G_END_DECLS #endif diff --git a/vapi/frida-gum-1.0.vapi b/vapi/frida-gum-1.0.vapi index 833d7414b..bfeae26b7 100644 --- a/vapi/frida-gum-1.0.vapi +++ b/vapi/frida-gum-1.0.vapi @@ -154,6 +154,11 @@ namespace Gum { public void ignore_other_threads (); public void unignore_other_threads (); + + public void with_lock_held (Gum.Interceptor.LockedFunc func); + public bool is_locked (); + + public delegate void LockedFunc (); } [CCode (type_cname = "GumInvocationListenerInterface")]