MASTG-TECH-0045: Runtime Reverse Engineering
Runtime reverse engineering can be seen as the on-the-fly version of reverse engineering where you don't have the binary data to your host computer. Instead, you'll analyze it straight from the memory of the app.
We'll keep using the HelloWorld JNI app, open a session with r2frida r2 frida://usb//sg.vantagepoint.helloworldjni
and you can start by displaying the target binary information by using the :i
command:
[0x00000000]> :i
arch arm
bits 64
os linux
pid 13215
uid 10096
objc false
runtime V8
java true
cylang false
pageSize 4096
pointerSize 8
codeSigningPolicy optional
isDebuggerAttached false
cwd /
dataDir /data/user/0/sg.vantagepoint.helloworldjni
codeCacheDir /data/user/0/sg.vantagepoint.helloworldjni/code_cache
extCacheDir /storage/emulated/0/Android/data/sg.vantagepoint.helloworldjni/cache
obbDir /storage/emulated/0/Android/obb/sg.vantagepoint.helloworldjni
filesDir /data/user/0/sg.vantagepoint.helloworldjni/files
noBackupDir /data/user/0/sg.vantagepoint.helloworldjni/no_backup
codePath /data/app/sg.vantagepoint.helloworldjni-1/base.apk
packageName sg.vantagepoint.helloworldjni
androidId c92f43af46f5578d
cacheDir /data/local/tmp
jniEnv 0x7d30a43c60
Search all symbols of a certain module with :is <lib>
, e.g. :is libnative-lib.so
.
[0x00000000]> :is libnative-lib.so
[0x00000000]>
Which are empty in this case. Alternatively, you might prefer to look into the imports/exports. For example, list the imports with :ii <lib>
:
[0x00000000]> :ii libnative-lib.so
0x7dbe1159d0 f __cxa_finalize /system/lib64/libc.so
0x7dbe115868 f __cxa_atexit /system/lib64/libc.so
And list the exports with :iE <lib>
:
[0x00000000]> :iE libnative-lib.so
0x7d1c49954c f Java_sg_vantagepoint_helloworldjni_MainActivity_stringFromJNI
For big binaries it's recommended to pipe the output to the internal less program by appending
~..
, i.e.:ii libandroid_runtime.so~..
(if not, for this binary, you'd get almost 2500 lines printed to your terminal).
The next thing you might want to look at are the currently loaded Java classes:
[0x00000000]> :ic~sg.vantagepoint.helloworldjni
sg.vantagepoint.helloworldjni.MainActivity
List class fields:
[0x00000000]> :ic sg.vantagepoint.helloworldjni.MainActivity~sg.vantagepoint.helloworldjni
public native java.lang.String sg.vantagepoint.helloworldjni.MainActivity.stringFromJNI()
public sg.vantagepoint.helloworldjni.MainActivity()
Note that we've filtered by package name as this is the MainActivity
and it includes all methods from Android's Activity
class.
You can also display information about the class loader:
[0x00000000]> :icL
dalvik.system.PathClassLoader[
DexPathList[
[
directory "."]
,
nativeLibraryDirectories=[
/system/lib64,
/vendor/lib64,
/system/lib64,
/vendor/lib64]
]
]
[email protected][
DexPathList[
[
zip file "/data/app/sg.vantagepoint.helloworldjni-1/base.apk"]
,
nativeLibraryDirectories=[
/data/app/sg.vantagepoint.helloworldjni-1/lib/arm64,
/data/app/sg.vantagepoint.helloworldjni-1/base.apk!/lib/arm64-v8a,
/system/lib64,
/vendor/lib64]
]
]
Next, imagine that you are interested into the method exported by libnative-lib.so 0x7d1c49954c f Java_sg_vantagepoint_helloworldjni_MainActivity_stringFromJNI
. You can seek to that address with s 0x7d1c49954c
, analyze that function af
and print 10 lines of its disassembly pd 10
:
[0x7d1c49954c]> pdf
;-- sym.fun.Java_sg_vantagepoint_helloworldjni_MainActivity_stringFromJNI:
╭ (fcn) fcn.7d1c49954c 18
│ fcn.7d1c49954c (int32_t arg_40f942h);
│ ; arg int32_t arg_40f942h @ x29+0x40f942
│ 0x7d1c49954c 080040f9 ldr x8, [x0]
│ 0x7d1c499550 01000090 adrp x1, 0x7d1c499000
│ 0x7d1c499554 21801591 add x1, x1, 0x560 ; hit0_4
│ 0x7d1c499558 029d42f9 ldr x2, [x8, 0x538] ; [0x538:4]=-1 ; 1336
│ 0x7d1c49955c 4000 invalid
Note that the line tagged with ; hit0_4
corresponds to the string that we've previously found: 0x7d1c499560 hit0_4 Hello from C++
.
To learn more, please refer to the r2frida wiki.