lucky1928
lucky1928

Reputation: 8849

Frida - hook android native C++ api

Say android mediaserver has below API:

$ nm --demangle --dynamic libmediaplayerservice.so  |grep setDataSourceAsync
0005c6f0 T android::NuPlayer::setDataSourceAsync(android::sp<android::DataSource> const&)
0005c008 T android::NuPlayer::setDataSourceAsync(android::sp<android::IStreamSource> const&)
0005c18c T android::NuPlayer::setDataSourceAsync(android::sp<android::IMediaHTTPService> const&, char const*, android::KeyedVector<android::String8, android::String8> const*)
0005c49c T android::NuPlayer::setDataSourceAsync(int, long long, long long)

$ nm -D libmediaplayerservice.so |grep setDataSourceAsync
0005c6f0 T _ZN7android8NuPlayer18setDataSourceAsyncERKNS_2spINS_10DataSourceEEE
0005c008 T _ZN7android8NuPlayer18setDataSourceAsyncERKNS_2spINS_13IStreamSourceEEE
0005c18c T _ZN7android8NuPlayer18setDataSourceAsyncERKNS_2spINS_17IMediaHTTPServiceEEEPKcPKNS_11KeyedVectorINS_7String8ES9_EE
0005c49c T _ZN7android8NuPlayer18setDataSourceAsyncEixx

Now I wish to hook the last one:

0005c49c T android::NuPlayer::setDataSourceAsync(int, long long, long long)

Below code will work but the API name is mangled:

var libname = "libmediaplayerservice.so";
var funame = "_ZN7android8NuPlayer18setDataSourceAsyncEixx";

Interceptor.attach(Module.getExportByName(libname, funame), {
    onEnter: function(args) {
      console.log("onEnter: call fun enter");
    },
    onLeave: function(retval) {
      console.log("onLeave: call fun leave");
    }
});

Two questions:

  1. Is it possible to use demangled name just like below in javascript code:

    android::NuPlayer::setDataSourceAsync(int, long long, long long)

  2. The first argument int is a file descriptor just like open returned value. how can I use this fd to dump the file to disk in javascript?

Upvotes: 1

Views: 3666

Answers (1)

James W.
James W.

Reputation: 3055

1. Is it possible to use demangled name just like below in javascript code:

You will need to bind with Python, use send('mangle:' + func_name)

In python's side - on_message extract the func_name and mangle using subprocess to execute g++

def on_message(msg, _data):
    if msg['type'] == 'send':
        if msg['payload'].startswith('mangle:'):
            # mangle
echo "class android{ void setDataSourceAsync(int, long long, long long) {}};void setDataSourceAsync(int,long long, long long){} " |\
 g++ -x c++ -S - -o- |\
 grep "^_.*:$" | sed -e 's/:$//'

It's tedious work ><

2. The first argument int is a file descriptor just like open returned value. how can I use this fd to dump the file to disk in javascript?

You want to save every byte that goes into the fd?

To not interfere the app execution, I suggest to use dup2, read from it and send to python's side or write to sdcard

var fopen = new NativeFunction(Module.findExportByName('libc.so', 'fopen'), 'pointer', ['pointer', 'pointer']);
var our_fd = fopen('/sdcard/tmpfile');
var dup2 = new NativeFunction(Module.findExportByName('libc.so', 'dup2'), 'pointer', ['pointer', 'pointer']);
dup2(fd, our_fd);
// use same technique to read from our_fd 

Upvotes: 1

Related Questions