Android JNI

This analyzer improves support for JNI functions in Android native libraries. It works by providing a BinaryNinja type library android-jni.bntl which is placed next to the plugin’s shared library:

.
├── lief-analysis-plugin-linux-x86_64.so
├── lief-dwarf-plugin-linux-x86_64.so
└── typelib
    └── aarch64
        └── android-jni.bntl

This type library should be installed in one of the following locations:

  • Linux: ~/.binaryninja/typelib/aarch64/android-jni.bntl

  • Windows: C:\Users\romain\AppData\Roaming\Binary Ninja\typelib\aarch64\android-jni.bntl

  • macOS: ~/Library/Application Support/Binary Ninja/typelib/aarch64/android-jni.bntl

After installation, select Plugins > LIEF > Enhance Analysis, the plugin will then import all types related to Android JNI.

In addition, it will automatically define the type for the JNI_OnLoad function:

  uint64_t JNI_OnLoad(int64_t* arg1) 00401270  uint64_t x21 = _ReadMSR(tpidr_el0) 00401284  int64_t var_48 = *(x21 + 0x28) 0040129c  int64_t* var_2d8 0040129c  uint64_t result 0040129c  bool cond:1 0040129c   0040129c  if ((*(*arg1 + 0x30))(arg1&var_2d80x10004) == 0) 004012a8      int64_t* x19_1 = var_2d8 004012c0      void var_e0 004012c0      sub_401138(&data_400b5c&var_e00x41) 004012d4      void* var_90 = &var_e0 0040129c  else 004012a0      result = 0xffffe0c0 004012a0  
  jint JNI_OnLoad(JavaVM* vmvoid* reserved) 00401270  uint64_t x21 = _ReadMSR(tpidr_el0) 00401284  int64_t var_48 = *(x21 + 0x28) 0040129c  JNIEnv* env 0040129c  int32_t result 0040129c  bool cond:1 0040129c   0040129c  if ((*vm)->GetEnv(vm&env0x10004) == 0) 004012a8      JNIEnv* env_1 = env 004012c0      void var_e0 004012c0      sub_401138(&data_400b5c&var_e00x41) 004012d4      JNINativeMethod var_90 0040129c  else 004012a0      result = -0x1f40 004012a0  

Functions that are tagged [1] with "LIEF - Android JNI Function" are also updated to expose the correct type in the first two arguments:

  int64_t Java_com_bytedance_sdk_component_embedapplog_PangleEncryptUtils_ttEncrypt(int64_t* arg1     int64_t arg2int64_t arg3int32_t arg4) 0000108c  uint64_t x26 = _ReadMSR(tpidr_el0) 00001090  int64_t x8 = *(x26 + 0x28) 00001094  int64_t result = 0 00001094   000010a8  if (arg3 != 0 && arg4 s>= 1) 000010b0      int128_t v0 = *"UK*@3oKpFlVVnads" 000010d4      __builtin_strncpy(&data_9830"UK*@3oKpFlVVnadsTfdA"0x14) 000010d8      int32_t x0_1 = ss_encrypted_size(zx.q(arg4)v0) 000010e4      int64_t x0_3 = malloc(zx.q(arg4)) 000010f0      int64_t x0_5 = malloc(sx.q(x0_1)) 00001114      (*(*arg1 + 0x640))(arg1arg30zx.q(arg4)x0_3)  {"ed_size"} 00001114       00001138      if ((ss_encrypt(x0_3zx.q(arg4)&data_9830strlen(&data_9830)x0_5) & 0x80000000) 00001138              != 0) 00001190          result = 0 00001138      else 00001154          result = (*(*arg1 + 0x580))(arg1zx.q(x0_1)) 00001170          (*(*arg1 + 0x680))(arg1result0zx.q(x0_1)x0_5)  {"ptUtils_ttDecrypt"} 00001170           00001174          if (x0_3 != 0) 0000117c              free(x0_3) 0000117c           00001180          if (x0_5 != 0) 00001188              free(x0_5) 00001188   000011a0  if (*(x26 + 0x28) == x8) 000011c0      return result 000011c0   000011c4  __stack_chk_fail() 000011c4  noreturn
  jbyteArray Java_com_bytedance_sdk_component_embedapplog_PangleEncryptUtils_ttEncrypt(JNIEnv* env     jobject thizjbyteArray arg3jsize arg4) 0000108c  uint64_t x26 = _ReadMSR(tpidr_el0) 00001090  int64_t x8 = *(x26 + 0x28) 00001094  jbyteArray result = nullptr 00001094   000010a8  if (arg3 != 0 && arg4 s>= 1) 000010b0      int128_t v0 = *"UK*@3oKpFlVVnads" 000010d4      __builtin_strncpy(&data_9830"UK*@3oKpFlVVnadsTfdA"0x14) 000010d8      jsize x0_1 = ss_encrypted_size(zx.q(arg4)v0) 000010e4      jbyte* x0_3 = malloc(zx.q(arg4)) 000010f0      jbyte* x0_5 = malloc(sx.q(x0_1)) 00001114      (*env)->GetByteArrayRegion(envarg30arg4x0_3) 00001114       00001138      if ((ss_encrypt(x0_3zx.q(arg4)&data_9830strlen(&data_9830)x0_5) & 0x80000000) 00001138              != 0) 00001190          result = nullptr 00001138      else 00001154          result = (*env)->NewByteArray(envx0_1) 00001170          (*env)->SetByteArrayRegion(envresult0x0_1x0_5) 00001170           00001174          if (x0_3 != 0) 0000117c              free(x0_3) 0000117c           00001180          if (x0_5 != 0) 00001188              free(x0_5) 00001188   000011a0  if (*(x26 + 0x28) == x8) 000011c0      return result 000011c0   000011c4  __stack_chk_fail() 000011c4  noreturn