Skip to content

frida-trace does not hook any functions that are loaded with dlopen #177

Description

@jyn514

Steps to reproduce:

  1. Create a project like this:
  // main.c
  #include <dlfcn.h>
  #include <stdio.h>
  #include <error.h>

  int main() {
    void *handle = dlopen("./shared.so", RTLD_NOW);
    if (!handle) error(1, 0, "%s", dlerror());
    // Clear dlerror.
    dlerror();
    char *(*foo)() = dlsym(handle, "foo");
    char *last_error = dlerror();
    if (last_error) error(1, 0, "%s", last_error);
    puts(foo());
  }

─────────────────────────────────────────────────────────────

  // shared.c
  char *foo() {
    return "shared function";
  }
  1. Build the project: gcc -g -shared -o shared.so shared.c && gcc -g -o main main.c
  2. Run main under frida-trace: frida-trace -s foo -- ./main. Observe that it says "Started tracing 0 functions."

I think this code here needs to also run whenever dlopen is called (and maybe also on dlclose?): https://github.com/frida/frida-tools/blob/main/agents/tracer/agent.ts#L198-L217

I tried this patch but I couldn't get frida-tools to build locally.

diff --git a/agents/tracer/agent.ts b/agents/tracer/agent.ts
index db24781..7030d01 100644
--- a/agents/tracer/agent.ts
+++ b/agents/tracer/agent.ts
@@ -31,13 +31,28 @@ class Agent {
             }
         }
 
-        this.start(spec).catch(e => {
+        let start = () => this.start(spec).catch(e => {
             send({
                 type: "agent:error",
                 message: e.message
             });
         });
 
+        start();
+
+        Interceptor.attach(Module.getExportByName('libc.so', 'dlopen'), {
+            onEnter: function (args) {
+                let path = args[0].readCString();
+                console.log(`rehook functions on dlopen(${path})`);
+            },
+            onLeave: async function (retval) {
+                if(!retval.isNull()) {
+                    await start();
+                    console.log("hooked dlopen");
+                }
+            }
+        });
+
         return {
             id: Process.id,
             platform: Process.platform,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions