JEB 4.29 finally bridges the gap between the dex analysis modules in charge of code emulation (dexdec‘s IDState
and co.) and their counterparts in the native code analysis pipeline (gendec‘s EEmulator
, EState
and co.).
The emulation of JNI routines from dexdec unlocks use-cases that are now becoming commonplace, such as:
- Object consumption relying on native code calls to make reverse-engineering harder. The typical case is the retrieval of encrypted strings where part of the decryption code is bytecode, part is native code.
- General app tweaking done on the native side, such as field setting, field reading, method invocation, object creation, etc.
Example
Here is an example of what could not be done by JEB <4.29:
//
// dex code:
//
package a.b;
class X {
...
native String decrypt(char[] array, int key1, int key2);
...
void f() {
return decrypt(new char[]{'K', 'F', 'C'}, 4, 3);
}
...
}
//
// native code:
//
// pseudo-code for method `dec` mapping to `a.b.X.decrypt`
jstring dec(JNIEnv* env, jobject this, jcharArray array, int a, int b) {
int len = (*env)->GetArrayLength(env, array);
uint16_t out[len];
for(int i = 0; i < len; i++) {
out[i] = array[i] - (a - b);
}
return (*env)->NewString(env, out, len);
}
JEB used to decompile X.f()
to:
void f() {
return decrypt(new char[]{'K', 'F', 'C'}, 4, 3);
}
JEB 4.29, if the native emulator is enabled, is able to return a simpler version:
void f() {
return "JEB";
}
Preparation
Currently, the native emulator is disabled by default. In order to let dexdec use it, edit your dexdec-emu.cfg file (located in your coreplugins/
folder, or in the GUI, Android menu, handler Emulator Settings…):
- Mandatory: set
enable_native_code_emulator
totrue
- Recommended: increase the values of
emu_max_duration
andemu_max_itercount
(the reason being the the analysis of native images by the native code plugins can be quite time-consuming).
You will also need a JEB Pro license to use this feature.
Output
As usual, the auto-decryption of an item will also emit an event, which can be collected programmatically, and visible in the Decompiler’s “Events” fragment in the GUI.
Items whose address is formatted as @LIB:<lib.so>@NativeAddress
are decrypted native items that were found in the SO image at some point.
Similarly, decrypted items found in decompiled code are rendered using a purple’ish pink (by default) in the GUI.
If native code was involved in the decryption, the on-hover pop-up will let you know:
API
The native emulator(s) managed by a dexdec‘s IDState
can be customized with the following newly-added methods and types:
-
enableNativeCodeEmulator
/isNativeCodeEmulatorEnabled
: enable or disable the native emulator (the master setting is pulled from your config file,dexdec-emu.cfg
) registerNativeEmulatorHooks
/unregisterNativeEmulatorHooks
: hooks into the evaluation (emulation) of the native code – refer to the appropriate hooks interfaces. The hooks receives a reference to the controllingEEmulator
.unregisterNativeEmulatorHooks
/ununregisterNativeEmulatorHooks
: hooks into the memory accesses of the emulator’s state – refer to the appropriate hooks interfaces. The hooks receives a reference to the targetEState
object.
Conclusion
Interfacing both emulators offers many possibilities to improve the reverse-engineering experience of complex binaries and applications.
There is more that can be done, which will be discussed further blog posts:
- Retrieval of statically registered natives (through JNIEnv’s
RegisterNatives
) as opposed to native routines automatically resolved using the JNI naming conventions. - Automatic unpacking of native code.
- Use of the native emulator in custom scripts and plugins.
Note that this feature is currently limited to JEB Pro.
The JNI native code emulator will work with x86, x64, and arm64 code (we may add support for arm in the near future). Needless to say, it is still in experimental mode! Therefore, you may encounter strange results or problems while analyzing code making use of it. Please send us error reports to support@pnfsoftware.com.
Until next time, and once again, thank you to our amazing users for their continued support and kind words 🙂 — Nicolas.
One thought on “Android JNI and Native Code Emulation”