reverse-engineeringfrida

How can I get the return value of function in Frida as a readable string


I'm using Frida to reverse-engineer an Android app that uses a library (libapp.so). I have a list of function names and their offsets, and I'm successfully hooking them

My goal is to log the return value of these native functions as a readable string.

Here’s my current script

Java.perform(function () {
    var libapp = null;
    const libName = "libapp.so";
    const checkInterval = 200;
    const maxWaitTime = 10000;
    let waited = 0;
    const waitForLibApp = setInterval(function () {
        libapp = Module.findBaseAddress(libName);
        if (libapp !== null || waited > maxWaitTime) {
            clearInterval(waitForLibApp);
            if (libapp === null) {
                console.log("[-] libapp.so not found in memory.");
                return;
            }
            console.log("[+] libapp.so loaded at", libapp);
            hookTargetFunctions(libapp);
        }
        waited += checkInterval;
    }, checkInterval);
    function hookTargetFunctions(base) {
        const functionList = [
            { name: "addData", offset: 0x795b4c },
            { name: "getData", offset: 0x795cbc },
        ];
        functionList.forEach(func => {
            try {
                const addr = base.add(ptr(func.offset));
                Interceptor.attach(addr, {
                    onEnter: function (args) {
                        console.log(`[+] Called ${func.name} @ ${addr}`);
                    },
                    onLeave: function (retval) {
                        // This is where I want to convert the return value to a readable string
                    }
                });
            } catch (err) {
                console.error(`[-] Error hooking ${func.name}:`, err);
            }
        });
    }
});


Solution

  • Your question does miss some details so I had to guess:

    I assume the return value is pointer to a common null terminated string containing ASCII or UTF-8 characters. In Frida those strings are called "CString" and "Utf8String".

    Interceptor.attach(addr, {
        onEnter: function (args) {
            console.log(`[+] Called ${func.name} @ ${addr}`);
        },
        onLeave: function (retval) {
            let str = retval.readCString();
            console.log(`returned string: ${str}`);
        }
    });
    

    Depending on the string type to be read Frida has this functions:

    See also Frida documentation on NativePointer