{"id":111,"date":"2013-04-07T19:12:11","date_gmt":"2013-04-08T03:12:11","guid":{"rendered":"http:\/\/www.android-decompiler.com\/blog\/?p=111"},"modified":"2021-09-10T14:08:00","modified_gmt":"2021-09-10T22:08:00","slug":"android-app-assets-encryption","status":"publish","type":"post","link":"https:\/\/www.pnfsoftware.com\/blog\/android-app-assets-encryption\/","title":{"rendered":"Android app assets encryption"},"content":{"rendered":"<p>Continuing <a href=\"https:\/\/www.pnfsoftware.com\/blog\/a-look-inside-dexguard\/\">part 1<\/a>, let&#8217;s have a look at another feature, assets encryption.<\/p>\n<p>Let&#8217;s have a look at an app containing a protected asset, <strong>1.png<\/strong>. The hexdump below shows the encrypted 1.png. The PNG header is gone, as this is the encrypted version of the file.<\/p>\n<p><a href=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-113\" src=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/11.png\" alt=\"1\" width=\"630\" height=\"145\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/11.png 630w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/11-300x69.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/11-624x143.png 624w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>The decryption routine is easy to spot: it appears the AssetManager.open() call was replaced by inline code that uses encrypted strings and reflection to instantiate a Cipher class and decrypt the asset file. We will use the script from the <a href=\"https:\/\/www.pnfsoftware.com\/blog\/a-look-inside-dexguard\/\">previous post<\/a> to decode the strings and determine exactly what is happening. The screenshot below shows the decompiled routine in question, after it was marked up and commented using JEB (try-catch have been disabled for improved clarity, as they do not help understand how the routine works):<\/p>\n<p><a href=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/13.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-119\" src=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/13.png\" alt=\"1\" width=\"1023\" height=\"388\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/13.png 1023w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/13-300x113.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/13-624x236.png 624w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/a><\/p>\n<p>The references to the <strong>AssetManager<\/strong> class, <strong>open<\/strong>\u00a0method, asset filename <strong>1.png<\/strong> as well as cipher type <strong>AES-CFB<\/strong> have been encrypted using the string encryption feature. The decryption is achieved using standard Android classes, and the scheme used is AES with a random key and IV (outlined in red in.)<\/p>\n<p>The final call to InputStream.available() is actually what the original method was doing. Therefore, the protection mechanism replaced AssetManager.open() by the following section of code:<\/p>\n<p><a href=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/22.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-120\" src=\"http:\/\/www.android-decompiler.com\/blog\/wp-content\/uploads\/2013\/04\/22.png\" alt=\"2\" width=\"1023\" height=\"388\" srcset=\"https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/22.png 1023w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/22-300x113.png 300w, https:\/\/www.pnfsoftware.com\/blog\/wp-content\/uploads\/2013\/04\/22-624x236.png 624w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/a><\/p>\n<p>We conclude that manually restoring protected assets is not difficult, although it cannot be easily automated. One way to improve that protection scheme would be to use custom decryption routines instead of SDK-provided classes, and\/or generalize the use of reflection to reference the decryption code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Continuing part 1, let&#8217;s have a look at another feature, assets encryption. Let&#8217;s have a look at an app containing a protected asset, 1.png. The hexdump below shows the encrypted 1.png. The PNG header is gone, as this is the encrypted version of the file. The decryption routine is easy to spot: it appears the &hellip; <a href=\"https:\/\/www.pnfsoftware.com\/blog\/android-app-assets-encryption\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Android app assets encryption<\/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,5],"tags":[],"class_list":["post-111","post","type-post","status-publish","format-standard","hentry","category-android","category-obfuscation"],"_links":{"self":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/111","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=111"}],"version-history":[{"count":0,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/posts\/111\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pnfsoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}