{"id":3624,"date":"2020-02-10T15:05:17","date_gmt":"2020-02-10T23:05:17","guid":{"rendered":"https:\/\/www.pnfsoftware.com\/blog\/?p=3624"},"modified":"2021-09-10T14:17:44","modified_gmt":"2021-09-10T22:17:44","slug":"jeb-lambda-recovery-and-generic-string-decryption","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/jeb-lambda-recovery-and-generic-string-decryption\/","title":{"rendered":"JEB Android Updates &#8211; Generic String Decryption, Lambda Recovery, Unreflecting Code, and More"},"content":{"rendered":"\n<p><em>Updated on March 11.<\/em><\/p>\n\n\n\n<p>A note about 2020 Q1 updates (versions 3.10 to 3.16) regarding the DEX\/Dalvik decompiler modules:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Generic String Decryption <\/li><li>Lambda Recovery<\/li><li>Unreflecting Code<\/li><li>Decompiling Java Bytecode<\/li><li>Auto-Rename All<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"generic-deobfuscator\">Generic String Decryption<\/h2>\n\n\n\n<p>JEB ships with a generic deobfuscator that can perform on-the-fly string decryption and other complex optimizations. Although this optimizer performs safe (i.e., guaranteed) optimizations in most cases, it is unsafe in the general case case and therefore, may be disabled in the options. Refer to the Engines options <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/manual\/engines-configuration\/#parsersdcmp_dexenabledeobfuscators\">.parsers.dcmp_dex.EnableDeobfuscators<\/a> and <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/manual\/engines-configuration\/#parsersdcmp_dexemulationsupport\">.parsers.dcmp_dex.EmulationSupport<\/a>.<\/p>\n\n\n\n<p>Many code protectors offer options to replace immediate string constants by method invocations that perform on-the-fly decryption.<\/p>\n\n\n\n<p>A variety of techniques exist, ranging from simple one-off trivial decryptor methods, to complex schemes involving object(s) creation, complicated decryptors injected in third-party packages, non-trivial logic, junk code meant to slow down analyzers, use of opaque predicates, etc. They are implemented in an infinite number of ways. JEB&#8217;s generic deobfuscator can perform quick, safe emulation of the intermediate representation to provide a replacement. It may sometimes fail or bail out due to several reasons, such as performance or pitfalls like anti-emulation and anti-sandboxing techniques. <\/p>\n\n\n\n<p><span style=\"text-decoration: underline;\">Example 1<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"546\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9-1024x546.png\" alt=\"\" class=\"wp-image-3639\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9-1024x546.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9-300x160.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9-768x409.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-9.png 1426w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption> The string decryptor is a static method reading encrypted string data in a class byte array. Also note that code reflection is used. <\/figcaption><\/figure>\n\n\n\n<p>The above code (blue box) ends up being deobfuscated to:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"216\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10-1024x216.png\" alt=\"\" class=\"wp-image-3640\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10-1024x216.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10-300x63.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10-768x162.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-10.png 1174w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Example 2:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"129\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-1024x129.png\" alt=\"\" class=\"wp-image-3641\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-1024x129.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-300x38.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-768x97.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-1536x193.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-11-2048x258.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>The decryption methods were injected into library packages, e.g. Gson&#8217;s<\/figcaption><\/figure>\n\n\n\n<p>The above code is deobfuscated to:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"185\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13-1024x185.png\" alt=\"\" class=\"wp-image-3643\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13-1024x185.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13-300x54.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13-768x139.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-13.png 1524w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>With the generic string decryptor optimizer ON<\/figcaption><\/figure>\n\n\n\n<p>Below, a decryptor that had been injected into the com.google.gson.Gson() class:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"250\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12-1024x250.png\" alt=\"\" class=\"wp-image-3642\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12-1024x250.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12-300x73.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12-768x188.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12-1536x375.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-12.png 1560w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>The concat(String, int) method is not part of standard Gson, of course. It was injected by the protector and is used by (some) code to perform on-the-fly string decryption.<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Example 3:<\/span><\/p>\n\n\n\n<p>One last example, which was involuntarily &#8211; yet, quite timely! &#8211; provided by a user:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"938\" height=\"98\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-14.png\" alt=\"\" class=\"wp-image-3645\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-14.png 938w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-14-300x31.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-14-768x80.png 768w\" sizes=\"auto, (max-width: 938px) 100vw, 938px\" \/><figcaption>Static fields initialized with decrypted strings.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"92\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-15.png\" alt=\"\" class=\"wp-image-3646\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-15.png 554w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-15-300x50.png 300w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><figcaption>After decryption.<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Decrypting all strings:<\/span> The decryptor kicks in when decompiling methods only. At the moment, if a string happens to be successfully decrypted, the optimizer does not attempt to recover all similarly encrypted strings in the code, although it is most certainly an addition that will make it in a future software update.<\/p>\n\n\n\n<p><span style=\"text-decoration: underline;\">Rendering:<\/span> You may quickly identify decrypted strings in the client as they are rendered using a special color associated with the itemId STRING_GENERATED, by default rendered in a flashy pink color in light and dark themes. Hovering over such items will bring up a pop-up with additional origin information, like the underlying code that would have generated that string:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"387\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17-1024x387.png\" alt=\"\" class=\"wp-image-3658\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17-1024x387.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17-300x113.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17-768x290.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-17.png 1334w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Auto-decrypted strings in pink; overlays with source\/origin information.<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">API:<\/span><br>&#8211; From a DEX perspective: Generated strings are artificial. Therefore, <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/reference\/com\/pnfsoftware\/jeb\/core\/units\/code\/ICodeItem.html#isArtificial()\"><code>IDexString.isArtificial()<\/code><\/a> would return true.<br>&#8211; From a Java\/AST perspective: IJavaConstant objects that embed origin information do so using the &#8220;origin&#8221; tag. Use <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/reference\/com\/pnfsoftware\/jeb\/core\/units\/code\/java\/IJavaElement.html#getTags()\"><code>IJavaConstant.getTags().get(\"origin\")<\/code><\/a> to retrieve it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lambda Recovery<\/h2>\n\n\n\n<p> JEB attempts to perform Java 8 style lambda recovery and reconstruction.  <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Desugared Lambdas<\/h3>\n\n\n\n<p>Recovery and reconstruction does not rely on any type of metadata <sup class='footnote'><a href='#fn-3624-1' id='fnref-3624-1' onclick='return fdfootnote_show(3624)'>1<\/a><\/sup>, such as special prefixes <code>-$$Lambda$<\/code> for classes and methods implementing desugared lambdas in dex 37-.<\/p>\n\n\n\n<p>You may therefore see constructs like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"99\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1024x99.png\" alt=\"\" class=\"wp-image-3629\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1024x99.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-300x29.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-768x74.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1536x148.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image.png 1780w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>This DEX file contains desugared, non-obfuscated lambdas.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"107\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1-1024x107.png\" alt=\"\" class=\"wp-image-3630\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1-1024x107.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1-300x31.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1-768x80.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1-1536x161.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-1.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>This DEX file contained desugared, obfuscated lambdas<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Options:<\/span> Lambda reconstruction can be disabled in the options (Edit, Options, Engines, &#8230;). Lambda rendering can also be disabled in the options, as well as on-demand by right-clicking a decompiled view, <em>Rendering Options<\/em>&#8230;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"217\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2-1024x217.png\" alt=\"\" class=\"wp-image-3631\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2-1024x217.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2-300x64.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2-768x163.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2-1536x326.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-2.png 1960w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Lambdas options<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">API Note:<\/span> In the above cases, the underlying Java AST may be a IJavaNew or IJavaStaticField node. This is not the case for real (not desugared) lambdas, which map to an IJavaCall node &#8211; see below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Real Lambdas<\/h3>\n\n\n\n<p>Lambda reconstruction also takes place when the code has not been desugared (which is rare!), i.e. code relying on <a href=\"https:\/\/www.pnfsoftware.com\/blog\/android-o-and-dex-version-38-new-dalvik-opcodes-to-support-dynamic-invocation\/\">dex38&#8217;s invoke-custom and invoke-polymorphic<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"70\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-1024x70.png\" alt=\"\" class=\"wp-image-3632\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-1024x70.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-300x20.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-768x52.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-1536x104.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-3-2048x139.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption> This DEX file contains real lambdas implemented via invoke-custom<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">API Note:<\/span> Such lambdas map to an IJavaCall node for which <em>isCustomCall()<\/em> will return true.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unreflecting Code<\/h2>\n\n\n\n<p>Many code protectors make heavy use of reflection &#8211; combined with string encryption, as we&#8217;ll see below &#8211; to obfuscate code. In practice, reflection is limited to method invocation (static and virtual), static and non-static field setting and getting, and new instance creation. A few examples:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">v = Class.forName(\"java.lang.Integer\").getMethod(\"valueOf\",\n        String.class).invoke(null, str);\n\/\/ instead of \nv = Integer.valueOf(str);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">Class.forName(\"SomeClassName\").getField(\"b\").setInt(x, 4);\n\/\/ instead of \nx.b = 4;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">Class.forName(\"java.lang.String\").getConstructor(byte[].class)\n        .newInstance(val);\n\/\/ instead of\nnew String(arg6);<\/pre>\n\n\n\n<p>Such code is generally protected by a catch-all handler that forwards the cause of any exception raised by a reflection issue:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">try {\n    \/\/ ...\n}\ncatch(Throwable e) {\n    throw e.getCause();\n}<\/pre>\n\n\n\n<p>By default, JEB will attempt to unreflect code. This deobfuscator is potentially unsafe and may be disabled in the options. Note that you always have the ability to choose, for a particular decompilation, whether some options should be temporarily enabled or disabled, by pressing CTRL+TAB (or COMMAND+TAB on macOS) to decompile (same as menu <em>Action, Decompile with options<\/em>&#8230;).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"226\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4-1024x226.png\" alt=\"\" class=\"wp-image-3633\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4-1024x226.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4-300x66.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4-768x169.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4-1536x339.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-4.png 1647w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Unsafe deobfuscators can be globally disabled.<\/figcaption><\/figure>\n\n\n\n<p>So, in a nutshell, code normally decompiled to:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"188\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5-1024x188.png\" alt=\"\" class=\"wp-image-3634\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5-1024x188.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5-300x55.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5-768x141.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5-1536x282.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-5.png 1886w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Reflection, not cleaned (malware was obfuscated)<\/figcaption><\/figure>\n\n\n\n<p>will be decompiled to:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"119\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6-1024x119.png\" alt=\"\" class=\"wp-image-3635\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6-1024x119.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6-300x35.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6-768x89.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-6.png 1215w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>With reflection cleaned<\/figcaption><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Technical Note:<\/span> This optimizer works on the Intermediate Representation manipulated by the decompiler, not to be confused with the AST rendered as its output. (The <a href=\"https:\/\/www.pnfsoftware.com\/blog\/decompiled-java-code-manipulation-using-jeb-api-part-3-defeating-reflection\/\">AST cleaner that was described in an older post<\/a> is more limited than this IR optimizer.)<\/p>\n\n\n\n<p><span style=\"text-decoration: underline;\">Last-step failures:<\/span> Successfully unreflecting code eventually depends on being able to find the intended target method or field matching the provided description (method parameter types or field type). Failure to do so will generate a log like <code>\"A candidate field\/method\/constructor for unreflection was not found\"<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Decompiling Java Bytecode<\/h2>\n\n\n\n<p>JEB supports JLS bytecode decompilation for *.class files and jar-like archives (jar, war, ear, etc.). The Java bytecode is converted to Dalvik using Android&#8217;s <em>dx<\/em> by default. Users may choose to use d8 (not recommended for now) instead by selecting so in <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/manual\/engines-configuration\/#parsersjavaclassused8fordexconversion\">the Options<\/a>.<\/p>\n\n\n\n<p>The resulting DEX file(s) are processed as usual.<\/p>\n\n\n\n<p>You may use this to decompile Android Library files (*.aar files) in JEB.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"477\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-1024x477.png\" alt=\"\" class=\"wp-image-3647\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-1024x477.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-300x140.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-768x358.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-1536x715.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-16-2048x953.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Examining the android-arch-core-runtime library<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Auto-Rename All<\/h2>\n\n\n\n<p>JEB 3.13 introduced a new generic action, <a href=\"https:\/\/www.pnfsoftware.com\/jeb\/apidoc\/reference\/com\/pnfsoftware\/jeb\/core\/actions\/Actions.html#AUTO_RENAME_ALL\">Auto-Rename All<\/a>. Its implementation is at the discretion of code plugins. The DEX plugin implements it, therefore users may execute Action, Auto-Rename All&#8230; at any time (generally after processing an obfuscated file) in order to rename code items such as field, method, or class names, to something more easily processable for our -limited- human brains.<\/p>\n\n\n\n<p>Look at this horrendous obfuscation scheme below. It&#8217;s using right-to-left unicode characters to seriously mess up rendering:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"695\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-1024x695.png\" alt=\"\" class=\"wp-image-3659\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-1024x695.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-300x204.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-768x521.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-1536x1042.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-18-2048x1389.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Obfuscated name using RTL Arabic characters<\/figcaption><\/figure>\n\n\n\n<p>Let&#8217;s run <em>Action, Auto-Rename All&#8230;<\/em> on this file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20-1024x490.png\" alt=\"\" class=\"wp-image-3661\" width=\"554\" height=\"264\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20-1024x490.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20-300x143.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20-768x367.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-20.png 1437w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><\/a><figcaption>Auto-Renaming capabilities are provided (optionally) by plugins.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"642\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-1024x642.png\" alt=\"\" class=\"wp-image-3662\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-1024x642.png 1024w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-300x188.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-768x481.png 768w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-1536x963.png 1536w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2020\/02\/image-21-2048x1283.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>After auto-renaming code items in the above file. Not clearer in terms of meaning, but at least, it&#8217;s something we can start working on.<\/figcaption><\/figure>\n\n\n\n<p>As usual, feel free to join us on Slack, message us on Twitter, or email us privately at <a href=\"mailto:support@pnfsoftware.com\">support@pnfsoftware.com<\/a>.<\/p>\n\n\n\n<p>Until next time!<\/p>\n\n\n\n<p>&#8211;<\/p>\n\n\n<div class='footnotes' id='footnotes-3624'><div class='footnotedivider'><\/div><ol><li id='fn-3624-1'>  Relying on metadata leads to false negatives in the best case &#8211; e.g., when the code has been minified by something like ProGuard; it leads to false positives in the worst case &#8211; e.g. forged metadata to incite the decompiler to generate inaccurate or wrong code. <span class='footnotereverse'><a href='#fnref-3624-1'>&#8617;<\/a><\/span><\/li><\/ol><\/div>","protected":false},"excerpt":{"rendered":"<p>Updated on March 11. A note about 2020 Q1 updates (versions 3.10 to 3.16) regarding the DEX\/Dalvik decompiler modules: Generic String Decryption Lambda Recovery Unreflecting Code Decompiling Java Bytecode Auto-Rename All Generic String Decryption JEB ships with a generic deobfuscator that can perform on-the-fly string decryption and other complex optimizations. Although this optimizer performs safe &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/jeb-lambda-recovery-and-generic-string-decryption\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">JEB Android Updates &#8211; Generic String Decryption, Lambda Recovery, Unreflecting Code, and More<\/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,21,18,5],"tags":[],"class_list":["post-3624","post","type-post","status-publish","format-standard","hentry","category-android","category-api-jeb3","category-jeb3","category-obfuscation"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/3624","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=3624"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/3624\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=3624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=3624"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=3624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}