It’s Frida, Frida, Got to get down on Fridaaa!

Estimated difficulty: 💜💜💜🤍🤍

I must say, this months post had me struck with a little bit of writers block. Life has been busy, and I may or may not have frequented a BBQ or two whilst we have been blessed with a few rays of sunshine and a bank holiday weekend. Either way, the blog must go on!

This month I turned to my old Android Attack posts and work colleagues for inspiration, and what came of it? Frida… again! Last time we looked into what the tool was, how to install it, and how it worked. Today we will cover how to use Frida to pull information from a compiled application running on your desktop. Heads up, please make sure you have your frida-tools installed! If you are stuck on how to do this, then please feel free to refer to my previous post, or even the Frida documentation.

Creating the Program

Thankfully Frida has a Tutorial on their site, with a number of different hooking experiments, so we don’t have to completely re-invent the wheel. In this case, we will be stealing their hello.c program and running it on our local host or virtual machine (VM), that part is completely up to you. Personally I will be running this in my Kali VM. See below for the C program code:

#include <stdio.h>
#include <unistd.h>

void
f (int n)
{
  printf ("Number: %d\n", n);
}

int
main (int argc,
      char * argv[])
{
  int i = 0;

  printf ("f() is at %p\n", f);

  while (1)
  {
    f (i++);
    sleep (1);
  }
}

Top Tip! Visual Studio Code is a great IDE for writing, storing and interacting with your code.

Now we have the code, we need to compile the C program. By doing so, we will make it possible to run the program. Make sure you have GCC installed, the GNU Compiler Collection to compile the code and then run the below command. To install GCC on my Kali VM, I used the below apt command, before running the command to compile. To install on Windows, there are a number of blogs to follow, such as the dev.to blog, however, you may encounter issues such as null output when using a Windows machine (I may or may not have already been through this when writing this blog). This is because certain functions such as enumerateSymbols, are not yet supported on Windows hosts.

$ sudo apt install gcc -y
$ gcc -Wall hello.c -o hello

After running the command to compile the program using GCC, you will see your very own executable program!

Now the program has been compiled to an executable file, we can run it.

./hello

Other than seeing the count and function pointer address output onto our terminal, post running the application, we should also be able to see the program in the Frida process list. Run frida-ps in the command line to get the process ID.

frida-ps

As you can see the hello process is now running and we can retrieve our process ID in order to hook into the application. To do this we can use -p to point to the process ID with the Frida tool.

frida -p <process ID>

Now we have hooked into the process we can start pulling information from the app!

Reading the Program Modules

Since we are in the Frida prompt, we can interact with the program a little more. We can use the Frida API to enumerate modules and pull other information about the program. Our current goal is to find out the pointer to the function, like the one output when the program runs, in order to hook into the f() function printed out the number values and modify its output.

Enumerate Modules

We can begin to enumerate our modules using the command Process.enumerateModules and Process.enumerateModulesSync in the frida command line to try and identify any modules loaded at runtime. We want to use the Process module in Frida to enumerate the modules, as that will return information from the currently instrumented process.

Running Process.enumerateModules provided us with the output of, function. This is not overly helpful to us, as there is no verbose information or even a function name here, as we might otherwise see in other running programs. This could be due to the size of the program or the fact that it does not contain exported functions.

When passing in the argument Process.enumerateModules(“hello”) or Process.enumerateModulesSync(“hello”), we do not get any more verbose information, but rather an error as Frida did not get what it was expecting.

The Process module provides information from the instrumented process, this covers obtaining the architecture, pointer sizes, code signing policies, thread IDs… But is also able to provide information about loaded modules, their addresses and enumerating memory ranges. It is also able to set a process-wide exception handler.

src: learnfrida.info

Find Module

Since out latest attempt at pulling information on the functions running in our hello executable was not successful, we can go back to the Frida docs for more information. Luckily for us, there is another call, shown below, which “returns a Module whose address or name matches the one specified”.

Process.findModuleByName('hello')

From the output we can view the base address, module name (that we specified) and where it is running from, alongside other interesting information.

The base address seems a little closer to our goal of finding the pointer for the f() function in order to hook it. Currently by passing in the base address to our program, the hook will never work, as it is not where the actual function is running in memory. We have a little more digging to do…

Enumerate Symbols

Shovel’s down! This may have just been the ticket. Again from the docs, we can see that there is an enumerateSymbols call for the module, Module. By running the command shown below, we are able to determine the memory address, isGlobal boolean, name of function, section info, size and type of the symbols running for the module specified by us.

Module.enumerateSymbols('hello')

Hoorah! We can see the address of the f() function.

This command in Frida provides us with the addresses of the functions we may want to target, and we can now use this information to create our Frida script to hook into said function.

Frida Script

Since we have been able to find our pointer address for the function, we can now easily create our script to hook it. See script below:

var func_pointer = "0x55f04cc3a149"
console.log(func_pointer)

Interceptor.attach(ptr(func_pointer), {
    onEnter(args) {
        console.log("Original Output: " + parseInt(args[0]))
        //Modify the arg to be the value 1337.
        args[0] = ptr("1337");
        console.log("New Output: " + parseInt(args[0]))
    }
});

The output was as follows:

From the script we can see the original number from the counter… This is high, as it has been running for a little while… And we can also see our New Output: parameter also logging to the screen our value of 1337. Imagine what we could do with other programs and messing with the return values. Even just knowing how to enumerate the functions is great for debugging programs, or logging data that is otherwise not shown to you.

The sky is the limit with Frida, and this is but only a little bit of what it can do.


I hope you have enjoyed this slightly different take on Frida, rather than our usual Android spiel! If anything is unclear, then please do comment. If you have any other tips, I may have missed then also feel free to share. Ideas are always welcome.

Sarah <3

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.