static void gum_duk_invocation_listener_on_enter (GumInvocationListener * listener, GumInvocationContext * ic) { GumDukInvocationListener * self = GUM_DUK_INVOCATION_LISTENER_CAST (listener); if (gum_script_backend_is_ignoring ( gum_invocation_context_get_thread_id (ic))) return; if (self->on_enter != NULL) { GumDukInterceptor * module = self->module; GumDukCore * core = module->core; duk_context * ctx = core->ctx; GumDukScope scope; GumDukInvocationContext * jic; GumDukInvocationArgs * args; _gum_duk_scope_enter (&scope, core); jic = _gum_duk_interceptor_obtain_invocation_context (module); _gum_duk_invocation_context_reset (jic, ic); args = gum_duk_interceptor_obtain_invocation_args (module); gum_duk_invocation_args_reset (args, ic); duk_push_heapptr (ctx, self->on_enter); duk_push_heapptr (ctx, jic->object); duk_push_heapptr (ctx, args->object); _gum_duk_scope_call_method (&scope, 1); duk_pop (ctx); gum_duk_invocation_args_reset (args, NULL); gum_duk_interceptor_release_invocation_args (module, args); _gum_duk_invocation_context_reset (jic, NULL); if (self->on_leave != NULL) { *GUM_LINCTX_GET_FUNC_INVDATA (ic, GumDukHeapPtr) = jic; } else { _gum_duk_interceptor_release_invocation_context (module, jic); } _gum_duk_scope_leave (&scope); } }
static void gum_duk_invocation_listener_on_leave (GumInvocationListener * listener, GumInvocationContext * ic) { GumDukInvocationListener * self = GUM_DUK_INVOCATION_LISTENER_CAST (listener); if (gum_script_backend_is_ignoring ( gum_invocation_context_get_thread_id (ic))) return; if (self->on_leave != NULL) { GumDukInterceptor * module = self->module; GumDukCore * core = module->core; duk_context * ctx = core->ctx; GumDukScope scope; GumDukInvocationContext * jic; GumDukInvocationReturnValue * retval; _gum_duk_scope_enter (&scope, core); jic = (self->on_enter != NULL) ? *GUM_LINCTX_GET_FUNC_INVDATA (ic, GumDukInvocationContext *) : NULL; if (jic == NULL) { jic = _gum_duk_interceptor_obtain_invocation_context (module); } _gum_duk_invocation_context_reset (jic, ic); retval = gum_duk_interceptor_obtain_invocation_return_value (module); gum_duk_invocation_return_value_reset (retval, ic); duk_push_heapptr (ctx, self->on_leave); duk_push_heapptr (ctx, jic->object); duk_push_heapptr (ctx, retval->object); _gum_duk_scope_call_method (&scope, 1); duk_pop (ctx); gum_duk_invocation_return_value_reset (retval, NULL); gum_duk_interceptor_release_invocation_return_value (module, retval); _gum_duk_invocation_context_reset (jic, NULL); _gum_duk_interceptor_release_invocation_context (module, jic); _gum_duk_scope_leave (&scope); }
static gboolean gum_emit_thread (const GumThreadDetails * details, gpointer user_data) { GumJscMatchContext * mc = user_data; GumJscCore * core = mc->self->core; GumJscScope scope = GUM_JSC_SCOPE_INIT (core); JSContextRef ctx = mc->ctx; JSObjectRef thread; JSValueRef result; gboolean proceed; gchar * str; if (gum_script_backend_is_ignoring (GUM_SCRIPT_BACKEND (core->backend), details->id)) return TRUE; thread = JSObjectMake (ctx, NULL, NULL); _gumjs_object_set_uint (ctx, thread, "id", details->id); _gumjs_object_set_string (ctx, thread, "state", _gumjs_thread_state_to_string (details->state)); _gumjs_object_set (ctx, thread, "context", _gumjs_cpu_context_new (ctx, (GumCpuContext *) &details->cpu_context, GUM_CPU_CONTEXT_READONLY, core)); result = JSObjectCallAsFunction (ctx, mc->on_match, NULL, 1, (JSValueRef *) &thread, &scope.exception); _gum_jsc_scope_flush (&scope); proceed = TRUE; if (result != NULL && _gumjs_string_try_get (ctx, result, &str, NULL)) { proceed = strcmp (str, "stop") != 0; g_free (str); } return proceed; }
static gboolean gum_emit_thread (const GumThreadDetails * details, gpointer user_data) { GumDukMatchContext * mc = user_data; GumDukScope * scope = mc->scope; duk_context * ctx = scope->ctx; gboolean proceed = TRUE; if (gum_script_backend_is_ignoring (details->id)) return TRUE; duk_push_heapptr (ctx, mc->on_match); duk_push_object (ctx); duk_push_uint (ctx, details->id); duk_put_prop_string (ctx, -2, "id"); duk_push_string (ctx, _gum_duk_thread_state_to_string (details->state)); duk_put_prop_string (ctx, -2, "state"); _gum_duk_push_cpu_context (ctx, (GumCpuContext *) &details->cpu_context, GUM_CPU_CONTEXT_READONLY, scope->core); duk_put_prop_string (ctx, -2, "context"); if (_gum_duk_scope_call_sync (scope, 1)) { if (duk_is_string (ctx, -1)) proceed = strcmp (duk_require_string (ctx, -1), "stop") != 0; } else { proceed = FALSE; } duk_pop (ctx); return proceed; }