Skip to content
Physics edited this page Jun 5, 2021 · 10 revisions

Frida for Android

Python squeleton

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import time
try:
    import frida
except ImportError:
    sys.exit('install frida\nsudo python3 -m pip install frida')

def err(msg):
    sys.stderr.write(msg + '\n')

def on_message(message, data):
    if message['type'] == 'error':
        err('[!] ' + message['stack'])
    elif message['type'] == 'send':
        print('[+] ' + message['payload'])
    else:
        print(message)

def kill_process(target_process):
    cmd = 'adb shell pm clear {} 1> /dev/null'.format(target_process)
    os.system(cmd)

def main():
    target_process = sys.argv[1]
    #kill_process(target_process)
    device = frida.get_usb_device()
    try:
        started = False
        session = device.attach(target_process)
    except frida.ProcessNotFoundError:
        print('Starting process {}...\n'.format(target_process))
        started = True
        try:
            pid = device.spawn([target_process])
        except frida.NotSupportedError as e:
            sys.exit('An error ocurred while attaching with the procces: {}\n'.format(e))
        session = device.attach(pid)

    script = session.create_script("""

Java.perform(function () {

    <Your Javascript Code>
});
""")
    script.on('message', on_message)
    print('[!] Press <Enter> at any time to detach from instrumented program.\n\n')
    script.load()
    if started:
        device.resume(pid)
    input()
    session.detach()

if __name__ == '__main__':
    if len(sys.argv) != 2:
        usage = 'usage {} <process name or PID>\n\n'.format(__file__)
        sys.exit(usage)
    main()

Override a method

var someClass = Java.use('some.package.class');

someClass.methodName.implementation = function (param1) {
    var returned = this.methodName.apply(this, arguments);
    console.log('method was called with the param: ' + param1 + ' and returned: ' + returned);
    console.log('');
    return returned;
}

Override a method of a class inside another class

Java example:

package some.package;

class A {
    class B {
        public C {
            ...
        }
    }
}

javascript:

var b_var = Java.use('some.package.A$B');

b_var.C.implementation = function () {
    var returned = this.methodName.apply(this, arguments);
    console.log('C was called');
    console.log('');
    return returned;
}

Create an instance

var someClass = Java.use('some.package.class');

obj = someClass.$new();
obj.instanceMethod(null);

Search for an instance

Java.choose('some.package.class' , {
    onMatch : function(instance){ //This function will be called for every instance found by frida
        console.log('Found instance: ' + instance);
    },
    onComplete:function(){}
});

Override the instantiation of an object

var URL = Java.use('java.net.URL');
URL.$init.overload('java.lang.String').implementation = function (stringUrl) {
    console.log(stringUrl);
    console.log('');
    return this.$init(stringUrl);
};

Pass a string from python to javascript

     ...
     textParam = input()
    script = session.create_script("""
Java.perform(function () {
    someTextFromPython = "%s";
    console.log(someTextFromPython);
});
""" % textParam)

Pass data from javascript to python

Send data

Java.perform(function () {
    var someClass = Java.use('some.package.someClass');
    var result = someClass.someClassMethod();
    send(result);
});

Recive data

def on_message(message, data):
    if message['type'] == 'error':
        err('[!] ' + message['stack'])
    elif message['type'] == 'send':
        resultFromInstrumentedClass =  message['payload'] #   <---- handle the recived data
    else:
        print(message)

Pass data from python to javascript

script = session.create_script("""
    ...
    // function that handles the data
    recv('input', function(data) {
        console.log(data.payload)
    });
    ...
""")
script.on('message', on_message)
script.load()
...
script.post({'type': 'input', 'payload': someData}) # <-- send the data

Get some info about some unknown object

someUnknownObject = class.method(param1,param2);
console.log(JSON.stringify(someUnknownObject));