Frida 101

Mahmoud Elfawair
3 min readApr 5, 2024

--

Hello you.

The last couple days I was learning about Frida, and it is super interesting. That’s why I’m writing this article, but before I start go and check out this repo, it’s the best I’ve ever read about Frida.

Setup

To set up Frida install frida-tools using pip3 install frida-tools and then download frida server to push it on our android emulator, you can find them here

There is so many releases but look for the frida-server and choose the one that suite your computer architecture.

Then we need to unzip the file and push it on our Android emulator, me personally I’m using genymotion

unzx frida-server-16.1.4-android-x86_64.xz
adb push frida-server-16.1.4-android-x86_64 /data/local/tmp/

make sure to have the latest version of XZ to avoid backdoors

However, now that we have pushed frida-server go and chmod +x and run it to start the magic.

Frida tools

To get the list of packages installed on your devices, we’ll use frida-ps

frida-ps -Uai 
frida-ps result

go the the manual page and check what these switches are used for.

Now, let’s attach frida with an application.

frida -U -f com.amaze.filemanager

After executing this command, you’ll notice that the file managerhas started.

Hooking

Hooking refers to the process of intercepting and modifying the behavior of functions or methods in an application or the Android system itself.

This is the template to hook a function

Java.perform(function() {

var <class_reference> = Java.use("<package_name>.<class>");
<class_reference>.<method_to_hook>.implementation = function(<args>) {

console.log(`meh`)
// continue editing on this function
// using the this here we can call the same function
ret_val = this.<method_to_hook>()
return ret_val;

}
})

if the function you are hooking needs arguments to function we can use the overload(arg_type) keyword.

<class_reference>.<method_to_hook>.overload('int', 'int').implementation = function(<args>)

Calling static function template

Java.perform(function() {

var <class_reference> = Java.use("<package_name>.<class>");
<class_reference>.<static_method>();

})

Changing static variable value template

Java.perform(function (){

var <class_reference> = Java.use("<package_name>.<class>");
<class_reference>.<variable>.value = <value>;

})

Instantiating a class template

Java.perform(function() {

var <class_reference> = Java.use("<package_name>.<class>");
var <class_instance> = <class_reference>.$new(); // Class Object
<class_instance>.<method>(); // Calling the method

})

Finding MainActivity instance template

Java.performNow(function() {
Java.choose('<Package>.<class_Name>', {
onMatch: function(instance) {

instance.<method>();

},
onComplete: function() {}
});
});

Hooking a class constructor template

Java.perform(function() {
var <class_reference> = Java.use("<package_name>.<class>");
<class_reference>.$init.implementation = function(<args>){

this.$init(<args>);
// ...
}
});

Hooking a native function template

Interceptor.attach(targetAddress, {
onEnter: function (args) {
console.log('Entering ' + functionName);

// Modify or log arguments if needed

// for reading a string from the memory we use
var arg0 = Memory.readUtf8String(args[0]);
console.log(`arg0 - ${arg0}`);
},
onLeave: function (retval) {
console.log('Leaving ' + functionName);
// Modify or log return value if needed

// to return a value of your choice
retval.replace(0xdeadbeef)
}
});

Note: to get the targetAddress you can use a number of Frida API calls such as:

Module.enumerateExports()
Module.getExportByName()
Module.findExportByName()
Module.enumerateImports()
Module.getBaseAddress()

Like this

[A10::com.ad2001.frida0x8 ]-> Module.enumerateExports('libfrida0x8.so')
[
{
"address": "0x78c2fb3898c0",
"name": "Java_com_ad2001_frida0x8_MainActivity_cmpstr",
"type": "function"
},
{
"address": "0x78c2fb389aa0",
"name": "_ZN7_JNIEnv17GetStringUTFCharsEP8_jstringPh",
"type": "function"
},
{
"address": "0x78c2fb389ae0",
"name": "_ZN7_JNIEnv21ReleaseStringUTFCharsEP8_jstringPKc",
"type": "function"
}
]

// then you can get the function address by doing this
[A10::com.ad2001.frida0x8 ]-> var addr = Module.enumerateExports('libfrida0x8.so')[0]['address']
[A10::com.ad2001.frida0x8 ]-> addr
"0x78c2fb3898c0"

That’s it for today, I really recommend you go and check this repo https://github.com/DERE-ad2001/Frida-Labs?tab=readme-ov-file they did a really amazing job demonstrating Frida and with hands-on labs. cya

--

--

Mahmoud Elfawair
Mahmoud Elfawair

Written by Mahmoud Elfawair

reverse engineering and linux enthusiast

No responses yet