{"id":196,"date":"2013-09-03T13:29:22","date_gmt":"2013-09-03T21:29:22","guid":{"rendered":"http:\/\/www.android-decompiler.com\/blog\/?p=196"},"modified":"2019-02-14T22:00:39","modified_gmt":"2019-02-15T06:00:39","slug":"decompiled-java-code-manipulation-using-jeb-api-part-1-removing-junk-code","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/decompiled-java-code-manipulation-using-jeb-api-part-1-removing-junk-code\/","title":{"rendered":"Decompiled Java Code Manipulation using JEB API &#8211; Part 1: Removing Junk Code"},"content":{"rendered":"<p>This is the first post of a 3-part blogs series that will demonstrate the new features of JEB&#8217;s\u00a0<a href=\"https:\/\/www.pnfsoftware.com\/jeb1\/apidoc\/jeb\/api\/ast\/package-summary.html\">jeb.api.ast<\/a> API package.<\/p>\n<p>Classes of this package allow read and write access on the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Abstract_syntax_tree\">Abstract Syntax Trees<\/a> (AST) of the decompiled Java code produced by JEB. In a \u00a0nutshell, <strong>it allows power users to implement complex deobfuscation schemes<\/strong> or their own optimizations strategies.<\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/jeb1\/viewer.php?file1=scripts\/ASTRemoveDummySwitch.py\">Download the script<\/a><br \/>\n<a href=\"https:\/\/www.youtube.com\/watch?v=HukvPgUv6O0\">Demo video<\/a><br \/>\n<iframe loading=\"lazy\" src=\"https:\/\/www.youtube.com\/embed\/HukvPgUv6O0\" width=\"480\" height=\"360\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n<p>Let&#8217;s jump straight to the crux of the matter: this piece of code has been obfuscating by a well-known Android\/Java protector software:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/*.method public constructor (Context, AttributeSet, I)V\n          .registers 8\n          const\/4                 v3, 0x1\n          const\/4                 v2, 0x0\n          invoke-direct           View-&amp;amp;amp;gt;(Context, AttributeSet, I)V, p0, p1, p2, p3\n          new-instance            v0, Paint\n:E\n          packed-switch           v3, :90\n:14\n          packed-switch           v2, :A0\n:1A\n          goto                    :14\n:1C\n          invoke-direct           Paint-&amp;amp;amp;gt;()V, v0\n          iput-object             v0, p0, TileView-&amp;amp;amp;gt;b0431\u0431\u04310431\u04310431:Paint\n:26\n          packed-switch           v2, :B0\n:2C\n          packed-switch           v2, :C0\n:32\n          goto                    :2C\n:34\n          sget-object             v0, xxxkkk$xkkxkk-&amp;amp;amp;gt;b04310431\u04310431\u04310431:&#x5B;I\n          invoke-virtual          Context-&amp;amp;amp;gt;obtainStyledAttributes(AttributeSet, &#x5B;I)TypedArray, p1, p2, v0\n          move-result-object      v0\n          const\/16                v1, 0xC\n          invoke-virtual          TypedArray-&amp;amp;amp;gt;getInt(I, I)I, v0, v2, v1\n          move-result             v1\n:4C\n          packed-switch           v2, : D0\n:52\n          packed-switch           v2, :E0\n:58\n          goto                    :52\n:5A\n          packed-switch           v2, :F0\n:60\n          packed-switch           v3, :FC\n:66\n          packed-switch           v3, :10C\n:6C\n          goto                    :66\n:6E\n          packed-switch           v2, :11C\n:74\n          packed-switch           v3, :12C\n:7A\n          goto                    :74\n:7C\n          packed-switch           v2, :13C\n:82\n          sput                    v1, TileView-&amp;amp;amp;gt;b\u04310431\u0431\u0431\u04310431:I\n          invoke-virtual          TypedArray-&amp;amp;amp;gt;recycle()V, v0\n          return-void\n          .packed-switch 0x0\n              :E\n              :1C\n          .end packed-switch\n          .packed-switch 0x0\n              :1C\n              :E\n          .end packed-switch\n          .packed-switch 0x0\n              :34\n              :26\n          .end packed-switch\n          .packed-switch 0x0\n              :34\n              :26\n          .end packed-switch\n          .packed-switch 0x0\n              :5A\n              :4C\n          .end packed-switch\n          .packed-switch 0x0\n              :5A\n              :4C\n          .end packed-switch\n          .packed-switch 0x0\n              :60\n          .end packed-switch\n          .packed-switch 0x0\n              :4C\n              :6E\n          .end packed-switch\n          .packed-switch 0x0\n              :4C\n              :6E\n          .end packed-switch\n          .packed-switch 0x0\n              :7C\n              :4C\n          .end packed-switch\n          .packed-switch 0x0\n              :4C\n              :7C\n          .end packed-switch\n          .packed-switch 0x0\n              :82\n          .end packed-switch\n.end method*\/\n<\/pre>\n<p>JEB decompiles this Dalvik bytecode to the following Java code:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n    public TileView(Context arg5, AttributeSet arg6, int arg7) {\n        super(arg5, arg6, arg7);\n    label_3:\n        switch(1) {\n            case 0: {\n                goto label_3;\n            }\n            case 1: {\n                goto label_6;\n            }\n        }\n\n        while(true) {\n            switch(0) {\n                case 0: {\n                    goto label_6;\n                }\n                case 1: {\n                    goto label_3;\n                }\n            }\n        }\n\n    label_6:\n        this.b0431\u0431\u04310431\u04310431 = new Paint();\n    label_8:\n        switch(0) {\n            case 0: {\n                goto label_11;\n            }\n            case 1: {\n                goto label_8;\n            }\n        }\n\n        while(true) {\n            switch(0) {\n                case 0: {\n                    goto label_11;\n                }\n                case 1: {\n                    goto label_8;\n                }\n            }\n        }\n\n    label_11:\n        TypedArray v0 = arg5.obtainStyledAttributes(arg6,\n                xkkxkk.b04310431\u04310431\u04310431);\n        int v1 = v0.getInt(0, 12);\n    label_15:\n        switch(0) {\n            case 0: {\n                goto label_18;\n            }\n            case 1: {\n                goto label_15;\n            }\n        }\n\n        while(true) {\n            switch(0) {\n                case 0: {\n                    goto label_18;\n                }\n                case 1: {\n                    goto label_15;\n                }\n            }\n        }\n\n    label_18:\n        switch(1) {\n            case 0: {\n                goto label_15;\n            }\n            case 1: {\n                goto label_21;\n            }\n        }\n\n        while(true) {\n            switch(1) {\n                case 0: {\n                    goto label_15;\n                }\n                case 1: {\n                    goto label_21;\n                }\n            }\n        }\n\n    label_21:\n        switch(0) {\n            case 0: {\n                goto label_24;\n            }\n            case 1: {\n                goto label_15;\n            }\n        }\n\n        while(true) {\n            switch(1) {\n                case 0: {\n                    goto label_15;\n                }\n                case 1: {\n                    goto label_24;\n                }\n            }\n        }\n\n    label_24:\n        TileView.b\u04310431\u0431\u0431\u04310431 = v1;\n        v0.recycle();\n    }\n<\/pre>\n<p>As one can see, dummy switches as well as pseudo-infinite loops have been inserted within the original Java code, in order to produce <strong>flow obfuscation<\/strong>. Using the AST API, we&#8217;re going to <strong>implement a JEB plugin that cleans the obfuscated code<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/08\/1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-209\" src=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/08\/1.png\" alt=\"1\" width=\"314\" height=\"328\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/08\/1.png 524w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/08\/1-287x300.png 287w\" sizes=\"auto, (max-width: 314px) 100vw, 314px\" \/><\/a><\/p>\n<p>A dummy switch construct looks like the following:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nswitch(X) {\ncase X:\n  goto next;\ncase Y:\n  goto label_fake1:\ncase Z:\n  goto label_fake2:\n}\n...\nnext:\n<\/pre>\n<p>The above piece of code is equivalent to:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\ngoto next;\n...\nnext:\n<\/pre>\n<p>Which can be reduced to a single label:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nnext:\n<\/pre>\n<p>In order to find the dummy switches, the JEB script is going to do the following:<\/p>\n<ol>\n<li>Recursively enumerate the statements of a method body, looking for <strong>SwitchStm<\/strong> elements<\/li>\n<li>Check that the switch is a dummy switch:\n<ol>\n<li>The switched expression must be a <strong>Constant<\/strong><\/li>\n<li>The case block associated with that constant must start with a <strong>Goto<\/strong> statement<\/li>\n<\/ol>\n<\/li>\n<li>Replace the switch by the goto<\/li>\n<li>Find the first <strong>Label<\/strong> that follows the (now replaced) switch<\/li>\n<li>If a label is found, is at the same block level as the switch, and is the label pointed to by the goto that replaced the switch, then all the expressions between the goto and the label can be discarded<\/li>\n<li>Finally, apply standard JEB optimizations that remove the remaining useless gotos and labels<\/li>\n<\/ol>\n<p>This algorithm fits in a less than a 100-line Python script. Download the script, experiment with it, and get accustomed to the API.<\/p>\n<p>The cleaned-up code is this very simple, more readable method:<\/p>\n<pre><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n    public TileView(Context arg5, AttributeSet arg6, int arg7) {\n        super(arg5, arg6, arg7);\n        this.b0431\u0431\u04310431\u04310431 = new Paint();\n        TypedArray v0 = arg5.obtainStyledAttributes(arg6,\n                xkkxkk.b04310431\u04310431\u04310431);\n        int v1 = v0.getInt(0, 12);\n        TileView.b\u04310431\u0431\u0431\u04310431 = v1;\n        v0.recycle();\n    }\n<\/pre>\n<p>In Part <em>Deux<\/em>, we will show how the AST API can be leveraged to <strong>decrypt encrypted strings of a protected piece of code<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the first post of a 3-part blogs series that will demonstrate the new features of JEB&#8217;s\u00a0jeb.api.ast API package. Classes of this package allow read and write access on the Abstract Syntax Trees (AST) of the decompiled Java code produced by JEB. In a \u00a0nutshell, it allows power users to implement complex deobfuscation schemes &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/decompiled-java-code-manipulation-using-jeb-api-part-1-removing-junk-code\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Decompiled Java Code Manipulation using JEB API &#8211; Part 1: Removing Junk Code<\/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":[7,3],"tags":[],"class_list":["post-196","post","type-post","status-publish","format-standard","hentry","category-api-jeb1","category-decompilation"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/196","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=196"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/196\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}