{"id":4563,"date":"2023-04-03T12:03:39","date_gmt":"2023-04-03T20:03:39","guid":{"rendered":"https:\/\/www.pnfsoftware.com\/blog\/?p=4563"},"modified":"2023-04-04T13:29:20","modified_gmt":"2023-04-04T21:29:20","slug":"android-jni-and-native-code-emulation","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/android-jni-and-native-code-emulation\/","title":{"rendered":"Android JNI and Native Code Emulation"},"content":{"rendered":"\n<p>JEB 4.29 finally bridges the gap between the dex analysis modules in charge of code emulation (<em>dexdec<\/em>&#8216;s <code>IDState<\/code> and co.) and their counterparts in the native code analysis pipeline (<em>gendec<\/em>&#8216;s <code>EEmulator<\/code>, <code>EState<\/code> and co.).<\/p>\n\n\n\n<p>The emulation of JNI routines from <em>dexdec<\/em> unlocks use-cases that are now becoming commonplace, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>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.<\/li>\n\n\n\n<li>General app tweaking done on the native side, such as field setting, field reading, method invocation, object creation, etc.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example<\/h3>\n\n\n\n<p>Here is an example of what could not be done by JEB &lt;4.29:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\n\/\/ dex code:\n\/\/\n\npackage a.b;\n\nclass X {\n  ...\n  native String decrypt(char&#91;] array, int key1, int key2);\n  ...\n  void f() {\n    return decrypt(new char&#91;]{'K', 'F', 'C'}, 4, 3);\n  }\n  ...\n}\n\n\/\/\n\/\/ native code:\n\/\/\n\n\/\/ pseudo-code for method `dec` mapping to `a.b.X.decrypt`\njstring dec(JNIEnv* env, jobject this, jcharArray array, int a, int b) {\n  int len = (*env)-&gt;GetArrayLength(env, array);\n  uint16_t out&#91;len];\n  for(int i = 0; i &lt; len; i++) {\n    out&#91;i] = array&#91;i] - (a - b);\n  }\n  return (*env)-&gt;NewString(env, out, len);\n}<\/code><\/pre>\n\n\n\n<p>JEB used to decompile <code>X.f()<\/code> to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void f() {\n  return decrypt(new char&#91;]{'K', 'F', 'C'}, 4, 3);\n}<\/code><\/pre>\n\n\n\n<p>JEB 4.29, if the native emulator is enabled, is able to return a simpler version:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void f() {\n  return \"JEB\";\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Preparation<\/h3>\n\n\n\n<p>Currently, the native emulator is disabled by default. In order to let <em>dexdec<\/em> use it, edit your <strong>dexdec-emu.cfg<\/strong> file (located in your <code>coreplugins\/<\/code> folder, or in the GUI, <em>Android<\/em> menu, handler <em>Emulator Settings&#8230;<\/em>):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mandatory: set <code>enable_native_code_emulator<\/code> to <code>true<\/code><\/li>\n\n\n\n<li>Recommended: increase the values of <code>emu_max_duration<\/code> and <code>emu_max_itercount<\/code> (the reason being the the analysis of native images by the native code plugins can be quite time-consuming).<\/li>\n<\/ul>\n\n\n\n<p>You will also need a <strong>JEB Pro<\/strong> license to use this feature.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Output<\/h3>\n\n\n\n<p>As usual, the auto-decryption of an item will also emit an event, which can be collected programmatically, and visible in the Decompiler&#8217;s &#8220;Events&#8221; fragment in the GUI.<\/p>\n\n\n\n<p>Items whose address is formatted as <code>@LIB:&lt;lib.so&gt;@NativeAddress<\/code> are decrypted native items that were found in the SO image at some point.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"325\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1-1024x325.png\" alt=\"\" class=\"wp-image-4566\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1-1024x325.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1-300x95.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1-768x243.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1-1536x487.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-1.png 1574w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Decrypted strings collected by the decompiler<\/figcaption><\/figure>\n\n\n\n<p>Similarly, decrypted items found in decompiled code are rendered using a purple&#8217;ish pink (by default) in the GUI.<\/p>\n\n\n\n<p>If native code was involved in the decryption, the on-hover pop-up will let you know:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"862\" height=\"331\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-2.png\" alt=\"\" class=\"wp-image-4567\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-2.png 862w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-2-300x115.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2023\/04\/image-2-768x295.png 768w\" sizes=\"auto, (max-width: 862px) 100vw, 862px\" \/><\/a><figcaption class=\"wp-element-caption\">Decryption of that string required emulation of native code<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">API<\/h3>\n\n\n\n<p>The native emulator(s) managed by a <em>dexdec<\/em>&#8216;s <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/reference\/com\/pnfsoftware\/jeb\/core\/units\/code\/android\/ir\/IDState.html\"><code>IDState<\/code><\/a> can be customized with the following newly-added methods and types:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li> <code>enableNativeCodeEmulator<\/code> \/ <code>isNativeCodeEmulatorEnabled<\/code> : enable or disable the native emulator (the master setting is pulled from your config file, <code>dexdec-emu.cfg<\/code>)<\/li>\n\n\n\n<li><code>registerNativeEmulatorHooks<\/code> \/ <code>unregisterNativeEmulatorHooks<\/code> : hooks into the evaluation (emulation) of the native code &#8211; refer to the appropriate hooks interfaces. The hooks receives a reference to the controlling <code>EEmulator<\/code>.<\/li>\n\n\n\n<li><code>unregisterNativeEmulatorHooks<\/code> \/ <code>ununregisterNativeEmulatorHooks<\/code> : hooks into the memory accesses of the emulator&#8217;s state &#8211; refer to the appropriate hooks interfaces. The hooks receives a reference to the target <code>EState<\/code> object.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>Interfacing both emulators offers many possibilities to improve the reverse-engineering experience of complex binaries and applications.<\/p>\n\n\n\n<p>There is more that can be done, which will be discussed further blog posts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Retrieval of statically registered natives (through JNIEnv&#8217;s <code>RegisterNatives<\/code>) as opposed to native routines automatically resolved using the JNI naming conventions.<\/li>\n\n\n\n<li>Automatic unpacking of native code. <\/li>\n\n\n\n<li>Use of the native emulator in custom scripts and plugins.<\/li>\n<\/ul>\n\n\n\n<p>Note that this feature is currently limited to JEB Pro.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>Until next time, and once again, thank you to our amazing users for their continued support and kind words \ud83d\ude42 &#8212; Nicolas.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JEB 4.29 finally bridges the gap between the dex analysis modules in charge of code emulation (dexdec&#8216;s IDState and co.) and their counterparts in the native code analysis pipeline (gendec&#8216;s EEmulator, EState and co.). The emulation of JNI routines from dexdec unlocks use-cases that are now becoming commonplace, such as: Example Here is an example &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/android-jni-and-native-code-emulation\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Android JNI and Native Code Emulation<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,3,22],"tags":[],"class_list":["post-4563","post","type-post","status-publish","format-standard","hentry","category-android","category-decompilation","category-jeb4"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/4563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=4563"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/4563\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=4563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=4563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=4563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}