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_2d80040129c  uint64_t result0040129c  bool cond:10040129c  0040129c  if ((*(*arg1 + 0x30))(arg1, &var_2d8, 0x10004) == 0)004012a8      int64_t* x19_1 = var_2d8004012c0      void var_e0004012c0      sub_401138(&data_400b5c, &var_e0, 0x41)004012d4      void* var_90 = &var_e00040129c  else004012a0      result = 0xffffe0c0004012a0  
  jint JNI_OnLoad(JavaVM* vm, void* reserved)00401270  uint64_t x21 = _ReadMSR(tpidr_el0)00401284  int64_t var_48 = *(x21 + 0x28)0040129c  JNIEnv* env0040129c  int32_t result0040129c  bool cond:10040129c  0040129c  if ((*vm)->GetEnv(vm, &env, 0x10004) == 0)004012a8      JNIEnv* env_1 = env004012c0      void var_e0004012c0      sub_401138(&data_400b5c, &var_e0, 0x41)004012d4      JNINativeMethod var_900040129c  else004012a0      result = -0x1f40004012a0  

Functions 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 arg2, int64_t arg3, int32_t arg4)0000108c  uint64_t x26 = _ReadMSR(tpidr_el0)00001090  int64_t x8 = *(x26 + 0x28)00001094  int64_t result = 000001094  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))(arg1, arg3, 0, zx.q(arg4), x0_3)  {"ed_size"}00001114      00001138      if ((ss_encrypt(x0_3, zx.q(arg4), &data_9830, strlen(&data_9830), x0_5) & 0x80000000)00001138              != 0)00001190          result = 000001138      else00001154          result = (*(*arg1 + 0x580))(arg1, zx.q(x0_1))00001170          (*(*arg1 + 0x680))(arg1, result, 0, zx.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 result000011c0  000011c4  __stack_chk_fail()000011c4  noreturn
  jbyteArray Java_com_bytedance_sdk_component_embedapplog_PangleEncryptUtils_ttEncrypt(JNIEnv* env,     jobject thiz, jbyteArray arg3, jsize arg4)0000108c  uint64_t x26 = _ReadMSR(tpidr_el0)00001090  int64_t x8 = *(x26 + 0x28)00001094  jbyteArray result = nullptr00001094  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(env, arg3, 0, arg4, x0_3)00001114      00001138      if ((ss_encrypt(x0_3, zx.q(arg4), &data_9830, strlen(&data_9830), x0_5) & 0x80000000)00001138              != 0)00001190          result = nullptr00001138      else00001154          result = (*env)->NewByteArray(env, x0_1)00001170          (*env)->SetByteArrayRegion(env, result, 0, x0_1, x0_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 result000011c0  000011c4  __stack_chk_fail()000011c4  noreturn