Skip to content

Instantly share code, notes, and snippets.

@oleavr
Last active July 8, 2025 03:11
Show Gist options
  • Save oleavr/3edc47c9f69eb048de9d70ed45998f9c to your computer and use it in GitHub Desktop.
Save oleavr/3edc47c9f69eb048de9d70ed45998f9c to your computer and use it in GitHub Desktop.

Revisions

  1. oleavr revised this gist Mar 31, 2016. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions 00-README.md
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,7 @@
    [*] close(-1)
    [*] listener got 4 calls
    [*] listener still has 4 calls
    $

    ## frida-gumjs-example.c

    @@ -17,6 +18,9 @@
    [*] close(7)
    [*] open("/etc/fstab")
    [*] close(-1)
    $

    ## frida-core-example.c

    $ clang -Wall -Os -pipe -g3 frida-core-example.c -o frida-core-example -L. -lfrida-core -lresolv -Wl,-framework,Foundation -Wl,-framework,AppKit -Wl,-dead_strip -Wl,-no_compact_unwind
    $ ./frida-core-example
  2. oleavr created this gist Mar 31, 2016.
    43 changes: 43 additions & 0 deletions 00-README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    ## frida-gum-example.c

    $ clang -Wall -Os -pipe -g3 frida-gum-example.c -o frida-gum-example -L. -lfrida-gum -lresolv -Wl,-dead_strip -Wl,-no_compact_unwind
    $ ./frida-gum-example
    [*] open("/etc/hosts")
    [*] close(3)
    [*] open("/etc/fstab")
    [*] close(-1)
    [*] listener got 4 calls
    [*] listener still has 4 calls

    ## frida-gumjs-example.c

    $ clang -Wall -Os -pipe -g3 frida-gumjs-example.c -o frida-gumjs-example -L. -lfrida-gumjs -lresolv -Wl,-dead_strip -Wl,-no_compact_unwind
    $ ./frida-gumjs-example
    [*] open("/etc/hosts")
    [*] close(7)
    [*] open("/etc/fstab")
    [*] close(-1)

    $ clang -Wall -Os -pipe -g3 frida-core-example.c -o frida-core-example -L. -lfrida-core -lresolv -Wl,-framework,Foundation -Wl,-framework,AppKit -Wl,-dead_strip -Wl,-no_compact_unwind
    $ ./frida-core-example
    Usage: ./frida-core-example <pid>
    $ pgrep -lf Twitter
    52140 /Applications/Twitter.app/Contents/MacOS/Twitter
    $ ./frida-core-example 52140
    [*] Found device: "Local System"
    [*] Found device: "Local TCP"
    [*] Found device: "iPhone"
    [*] Attached
    [*] Script loaded
    [*] open("/Users/oleavr/Library/Containers/com.twitter.twitter-mac/Data/Library/Caches/com.crashlytics.data/com.twitter.twitter-mac/v3/active/e6eef9908f0e4350a75edbb90a568569/internal_incremental_kv.clsrecord")
    [*] close(56)
    [*] open("/private/var/folders/gp/fb5425zj0lsbnncn3_2zxsww0000gn/T/com.twitter.twitter-mac/TemporaryItems/(A Document Being Saved By Twitter)/0.log")
    [*] close(56)
    [*] open("/Users/oleavr/Library/Containers/com.twitter.twitter-mac/Data/Library/Caches/com.crashlytics.data/com.twitter.twitter-mac/analytics/v1/ACTIVE/1459386280643_e6eef9908f0e4350a75edbb90a568569/1459386281286_AE473844-B15D-4D3D-AE95-A43A1D9449E9/0.log")
    [*] open("/Users/oleavr/Library/Containers/com.twitter.twitter-mac/Data/Library/Caches/com.crashlytics.data/com.twitter.twitter-mac/analytics/v1/PACKAGED")
    (snip)
    ^C[*] Stopped
    [*] Unloaded
    [*] Detached
    [*] Closed
    $
    167 changes: 167 additions & 0 deletions frida-core-example.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,167 @@
    /*
    * Compile with:
    *
    * clang -Wall -Os -pipe -g3 frida-core-example.c -o frida-core-example -L. -lfrida-core -lresolv -Wl,-framework,Foundation -Wl,-framework,AppKit -Wl,-dead_strip -Wl,-no_compact_unwind
    */

    #include "frida-core.h"

    #include <stdlib.h>
    #include <string.h>

    static void on_message (FridaScript * script, const gchar * message, const gchar * data, gint data_size, gpointer user_data);
    static void on_signal (int signo);
    static gboolean stop (gpointer user_data);

    static GMainLoop * loop = NULL;

    int
    main (int argc,
    char * argv[])
    {
    guint target_pid;
    FridaDeviceManager * manager;
    GError * error = NULL;
    FridaDeviceList * devices;
    gint num_devices, i;
    FridaDevice * local_device;
    FridaSession * session;

    if (argc != 2 || (target_pid = atoi (argv[1])) == 0)
    {
    g_printerr ("Usage: %s <pid>\n", argv[0]);
    return 1;
    }

    frida_init ();

    loop = g_main_loop_new (NULL, TRUE);

    signal (SIGINT, on_signal);
    signal (SIGTERM, on_signal);

    manager = frida_device_manager_new ();

    devices = frida_device_manager_enumerate_devices_sync (manager, &error);
    g_assert (error == NULL);

    local_device = NULL;
    num_devices = frida_device_list_size (devices);
    for (i = 0; i != num_devices; i++)
    {
    FridaDevice * device = frida_device_list_get (devices, i);

    g_print ("[*] Found device: \"%s\"\n", frida_device_get_name (device));

    if (frida_device_get_dtype (device) == FRIDA_DEVICE_TYPE_LOCAL)
    local_device = g_object_ref (device);

    g_object_unref (device);
    }
    g_assert (local_device != NULL);

    frida_unref (devices);
    devices = NULL;

    session = frida_device_attach_sync (local_device, target_pid, &error);
    if (error == NULL)
    {
    FridaScript * script;

    g_print ("[*] Attached\n");

    script = frida_session_create_script_sync (session, "example",
    "Interceptor.attach(Module.findExportByName(null, \"open\"), {\n"
    " onEnter: function (args) {\n"
    " console.log(\"[*] open(\\\"\" + Memory.readUtf8String(args[0]) + \"\\\")\");\n"
    " }\n"
    "});\n"
    "Interceptor.attach(Module.findExportByName(null, \"close\"), {\n"
    " onEnter: function (args) {\n"
    " console.log(\"[*] close(\" + args[0].toInt32() + \")\");\n"
    " }\n"
    "});",
    &error);
    g_assert (error == NULL);

    g_signal_connect (script, "message", G_CALLBACK (on_message), NULL);

    frida_script_load_sync (script, &error);
    g_assert (error == NULL);

    g_print ("[*] Script loaded\n");

    if (g_main_loop_is_running (loop))
    g_main_loop_run (loop);

    g_print ("[*] Stopped\n");

    frida_script_unload_sync (script, NULL);
    frida_unref (script);
    g_print ("[*] Unloaded\n");

    frida_session_detach_sync (session);
    frida_unref (session);
    g_print ("[*] Detached\n");
    }
    else
    {
    g_printerr ("Failed to attach: %s\n", error->message);
    g_error_free (error);
    }

    frida_unref (local_device);

    frida_device_manager_close_sync (manager);
    frida_unref (manager);
    g_print ("[*] Closed\n");

    g_main_loop_unref (loop);

    return 0;
    }

    static void
    on_message (FridaScript * script,
    const gchar * message,
    const gchar * data,
    gint data_size,
    gpointer user_data)
    {
    JsonParser * parser;
    JsonObject * root;
    const gchar * type;

    parser = json_parser_new ();
    json_parser_load_from_data (parser, message, -1, NULL);
    root = json_node_get_object (json_parser_get_root (parser));

    type = json_object_get_string_member (root, "type");
    if (strcmp (type, "log") == 0)
    {
    const gchar * log_message;

    log_message = json_object_get_string_member (root, "payload");
    g_print ("%s\n", log_message);
    }
    else
    {
    g_print ("on_message: %s\n", message);
    }

    g_object_unref (parser);
    }

    static void
    on_signal (int signo)
    {
    g_idle_add (stop, NULL);
    }

    static gboolean
    stop (gpointer user_data)
    {
    g_main_loop_quit (loop);

    return FALSE;
    }
    126 changes: 126 additions & 0 deletions frida-gum-example.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,126 @@
    /*
    * Compile with:
    *
    * clang -Wall -Os -pipe -g3 frida-gum-example.c -o frida-gum-example -L. -lfrida-gum -lresolv -Wl,-dead_strip -Wl,-no_compact_unwind
    */

    #include "frida-gum.h"

    #include <fcntl.h>
    #include <unistd.h>

    typedef struct _ExampleListener ExampleListener;
    typedef enum _ExampleHookId ExampleHookId;

    struct _ExampleListener
    {
    GObject parent;

    guint num_calls;
    };

    enum _ExampleHookId
    {
    EXAMPLE_HOOK_OPEN,
    EXAMPLE_HOOK_CLOSE
    };

    static void example_listener_iface_init (gpointer g_iface, gpointer iface_data);

    #define EXAMPLE_TYPE_LISTENER (example_listener_get_type ())
    G_DECLARE_FINAL_TYPE (ExampleListener, example_listener, EXAMPLE, LISTENER, GObject)
    G_DEFINE_TYPE_EXTENDED (ExampleListener,
    example_listener,
    G_TYPE_OBJECT,
    0,
    G_IMPLEMENT_INTERFACE (GUM_TYPE_INVOCATION_LISTENER,
    example_listener_iface_init))

    int
    main (int argc,
    char * argv[])
    {
    GumInterceptor * interceptor;
    GumInvocationListener * listener;

    gum_init ();

    interceptor = gum_interceptor_obtain ();
    listener = g_object_new (EXAMPLE_TYPE_LISTENER, NULL);

    gum_interceptor_begin_transaction (interceptor);
    gum_interceptor_attach_listener (interceptor,
    GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "open")),
    listener,
    GSIZE_TO_POINTER (EXAMPLE_HOOK_OPEN));
    gum_interceptor_attach_listener (interceptor,
    GSIZE_TO_POINTER (gum_module_find_export_by_name (NULL, "close")),
    listener,
    GSIZE_TO_POINTER (EXAMPLE_HOOK_CLOSE));
    gum_interceptor_end_transaction (interceptor);

    close (open ("/etc/hosts", O_RDONLY));
    close (open ("/etc/fstab", O_RDONLY));

    g_print ("[*] listener got %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);

    gum_interceptor_detach_listener (interceptor, listener);

    close (open ("/etc/hosts", O_RDONLY));
    close (open ("/etc/fstab", O_RDONLY));

    g_print ("[*] listener still has %u calls\n", EXAMPLE_LISTENER (listener)->num_calls);

    g_object_unref (listener);
    g_object_unref (interceptor);

    return 0;
    }

    static void
    example_listener_on_enter (GumInvocationListener * listener,
    GumInvocationContext * ic)
    {
    ExampleListener * self = EXAMPLE_LISTENER (listener);
    ExampleHookId hook_id = GUM_LINCTX_GET_FUNC_DATA (ic, ExampleHookId);

    switch (hook_id)
    {
    case EXAMPLE_HOOK_OPEN:
    g_print ("[*] open(\"%s\")\n", gum_invocation_context_get_nth_argument (ic, 0));
    break;
    case EXAMPLE_HOOK_CLOSE:
    g_print ("[*] close(%d)\n", (int) gum_invocation_context_get_nth_argument (ic, 0));
    break;
    }

    self->num_calls++;
    }

    static void
    example_listener_on_leave (GumInvocationListener * listener,
    GumInvocationContext * ic)
    {
    }

    static void
    example_listener_class_init (ExampleListenerClass * klass)
    {
    (void) EXAMPLE_IS_LISTENER;
    (void) glib_autoptr_cleanup_ExampleListener;
    }

    static void
    example_listener_iface_init (gpointer g_iface,
    gpointer iface_data)
    {
    GumInvocationListenerIface * iface = (GumInvocationListenerIface *) g_iface;

    iface->on_enter = example_listener_on_enter;
    iface->on_leave = example_listener_on_leave;
    }

    static void
    example_listener_init (ExampleListener * self)
    {
    }
    89 changes: 89 additions & 0 deletions frida-gumjs-example.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    /*
    * Compile with:
    *
    * clang -Wall -Os -pipe -g3 frida-gumjs-example.c -o frida-gumjs-example -L. -lfrida-gumjs -lresolv -Wl,-dead_strip -Wl,-no_compact_unwind
    */

    #include "frida-gumjs.h"

    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>

    static void on_message (GumScript * script, const gchar * message, GBytes * data, gpointer user_data);

    int
    main (int argc,
    char * argv[])
    {
    GumScriptBackend * backend;
    GCancellable * cancellable = NULL;
    GError * error = NULL;
    GumScript * script;
    GMainContext * context;

    gum_init ();

    backend = gum_script_backend_obtain_duk ();

    script = gum_script_backend_create_sync (backend, "example",
    "Interceptor.attach(Module.findExportByName(null, \"open\"), {\n"
    " onEnter: function (args) {\n"
    " console.log(\"[*] open(\\\"\" + Memory.readUtf8String(args[0]) + \"\\\")\");\n"
    " }\n"
    "});\n"
    "Interceptor.attach(Module.findExportByName(null, \"close\"), {\n"
    " onEnter: function (args) {\n"
    " console.log(\"[*] close(\" + args[0].toInt32() + \")\");\n"
    " }\n"
    "});",
    cancellable, &error);
    g_assert (error == NULL);

    gum_script_set_message_handler (script, on_message, NULL, NULL);

    gum_script_load_sync (script, cancellable);

    close (open ("/etc/hosts", O_RDONLY));
    close (open ("/etc/fstab", O_RDONLY));

    context = g_main_context_get_thread_default ();
    while (g_main_context_pending (context))
    g_main_context_iteration (context, FALSE);

    gum_script_unload_sync (script, cancellable);

    g_object_unref (script);

    return 0;
    }

    static void
    on_message (GumScript * script,
    const gchar * message,
    GBytes * data,
    gpointer user_data)
    {
    JsonParser * parser;
    JsonObject * root;
    const gchar * type;

    parser = json_parser_new ();
    json_parser_load_from_data (parser, message, -1, NULL);
    root = json_node_get_object (json_parser_get_root (parser));

    type = json_object_get_string_member (root, "type");
    if (strcmp (type, "log") == 0)
    {
    const gchar * log_message;

    log_message = json_object_get_string_member (root, "payload");
    g_print ("%s\n", log_message);
    }
    else
    {
    g_print ("on_message: %s\n", message);
    }

    g_object_unref (parser);
    }