Objective
APK security has been criticized in Android applications, the market is flooded with a variety of cracked or Chinese application, the cracker can be very simple through the hack tool can be anti-compilation, cracking, Chinese and so on, so you can modify the original code logic, add new code, add or modify resources, Or even implant viruses and so on, thus destroying the security and user experience of the original apk, and ultimately harming the user and the original developer.
And things are there are two aspects of the spear has a shield, for Android application security programs came into being, we are more familiar with the general is a variety of shell reinforcement tools, we can use these tools to protect our apk, shell reinforcement is another topic, we do not introduce the shell reinforcement, Follow-up if there is a chance to open a separate topic discussion, we can in the development process through Proguard or dexguard to protect our code, so as to achieve relative code security, but our resources? We tend to ignore the protection of resource files, and what we're going to share here is to protect the resource files in the APK using the usual way.
Resource security
The topic of resource security is not too high at present, in comparison, we are more concerned about code security, currently on the market all kinds of apps are basically using Proguard to protect the security code, but the protection of resources files is not very small, in fact, the resource file is a relatively large security risks, What are the security implications of the resource? Here's a simple example of how important it is to protect a resource file.
We first use the most common Apktool tool to decompile an application to see, by running the following command to be able to decompile;
apktool d -s xxx.apk
After the successful anti-compilation, we look at the file structure of the anti-compilation (see);
Through the directory structure, we can see that the application's resource files are: Anim, drawable, Layout, menu, values and so on, we can modify these folders under the resource file, and through Apktool to compile (Apktool b command) to create a modified APK app, such as the layout file that we modified in the red line, to add something of our own to the original APK's payment information (guessing the layout's intentions based on the resource name);
This problem is mainly because we advocate naming in the development process of the normative, generally requires to be named in the name of the understanding, so that it is convenient for us to understand and maintain, but at the same time this also facilitates the cracker, the cracker can easily based on the file name to guess the intention and role of the file, so as to make destructive changes.
Through this example we can see the importance of the current resource security, how to achieve the security of resources? Security is relative, there is no absolute security, and what we are going to discuss next is a similar proguard way of protecting our resources. We mainly modify the AAPT tool to protect the resources, in order to facilitate understanding, the following first talk about how the Android application to find resources.
The process of finding resources on Android
in Android, each application typically has a lot of resources configured to fit screens of different densities, sizes and orientations, and to adapt to different countries, regions, and languages, and so on. These resources are automatically adapted to the device's current configuration information when the application is running. This means that given an identical resource ID, a different resource may be found under different device configurations.
This lookup process is completely transparent to the application, and this process is done primarily by the Android resource Management framework, The Android resource management framework is actually implemented by the Assetmanager and resources two classes. Where the resources class can find the resource based on the ID, and the Assetmanager class finds the resource based on the file name. In fact, if a resource ID corresponds to a file, the resources class first finds the resource file name based on the ID, and then gives the file name to the Assetmanager class to open the corresponding file. Basic flow such as:
Through the RESOURCES.ARSC, we can see that the resources are converted to the name of the resource file by the resource and then loaded by Assetmanager.
And RESOURCES.ARSC This file is stored in the APK package, he is generated by the AAPT tool in the packaging process, he is a resource Index table, inside the maintainer resource ID, Name, path or value of the corresponding relationship, Assetmanager through this index table, the resource ID can be used to find the corresponding file or data.
AAPT Introduction
AAPT is an abbreviation for the Android Asset Packaging tool, which is stored in the tools/directory of the SDK, and AAPT is powerful and can be used to view, create, update compressed files (such as. zip files,. jar files,. apk files), It can also compile resources into binary files, and generate RESOURCES.ARSC, aapt This tool in the APK packaging process played a very important role in the packaging process using AAPT to use the resources used to package the APK, there is no aapt this tool to do too much discussion, Just look at aapt. This tool plays a role in the packaging process and is the AAPT packaging process:
AAPT This tool mainly does the following tasks in the packaging process:
- assets" and "Res/raw" All resources under the directory are packaged (either compressed or uncompressed depending on the file suffix), and other resources in the "res/" directory are compiled or otherwise processed (depending on the file suffix, for example: ". xml" is compiled into a binary file, ". png" Files are optimized and so on) before they are packaged;
-
- compile androidmanifest.xml into binary XML file;
- The results of the above 3 steps are saved in a *.AP_ file, and each resource ID constant is defined in a r.java;
. ap_ This file will be placed in the APK package when the APK is generated . AP_ The file itself is a ZIP package that contains RESOURCES.ARSC, androidmanifest.xml, assets, and all the resource files, After the unzip:
You can see *.AP_ This file contains the content, this file is stored in the Build/intermediates/res directory, is the path of this file storage:
Resource Protection
We refer to the Proguard Obfuscator method, the APK in the resource file name using a short meaningless name substitution, to create difficulties for the cracker, so as to achieve the relative security of resources; We can see that the resources are protected by modifying the AAPT to replace the name of the resource file when generating RESOURCES.ARSC and *.AP_.
by reading the code of AAPT compiled resources, we found that modifying AAPT in processing resource files related to the source is able to do the resource file name substitution, The following is a modified code snippet for Makefileresources () in Resource.cpp:
Static status_t makefileresources (bundle* Bundle, const sp<aaptassets>& assets, resourcetable* table, const sp<resourcetypeset>& Set, Const char* restype) {String8 type8 (restype); String16 Type16 (restype); BOOL hasErrors = false; Resourcediriterator It (set, String8 (ResType)); ssize_t Res; while ((Res=it.next ()) = = No_error) {if (Bundle->getverbose ()) {printf ("(New Resource I D%s from%s) \ n ", It.getbasename (). String (), It.getfile ()->getprintablesource (). String ()); } String16 BaseName (It.getbasename ()); Const char16_t* str = basename.string (); Const char16_t* CONST END = str + basename.size (); while (Str < end) {if (! ( (*str >= ' a ' && *str <= ' z ') || (*str >= ' 0 ' && *str <= ' 9 ') | | *str = = ' _ ' | | *str = = '. ')) {fprintf (stderr, "%s:invalid file name:must contain only [a-z0-9_.] \ n ", It.getpath (). String ()); HasErrors = true; } str++; } String8 Respath = It.getpath (); Respath.converttorespath (); String8 Obfuscationname; String8 Obfuscationpath = Getobfuscationname (Respath, obfuscationname); Table->addentry (Sourcepos (It.getpath (), 0), String16 (Assets->getpackage ()), Type16, BaseName,//String16 (Obfuscationname), String16 (Obfuscationpath),//Res Path NULL, &it.getparams ()); Assets->addresource (It.getleafname (), obfuscationpath/*respath*/, It.getfile (), type8); } Return hasErrors? Unknown_error:no_error; }
The code above is to add a resource file in resourcetable and assets, modify the name of the resource file, this will be able to replace the resource file name, so that by using the modified AAPT compiled resources and packaging, We re-compile the apktool with the above-mentioned tool:
Have you found anything different? In the Res directory, the familiar layout, drawable, Anim, menu and other folders are missing, then where did they go? Because the Apktool tool puts them under the Unknown folder, see:
Let's take a look at the Unknown folder, and you'll find that the resource file name has been replaced by a short, meaningless name, which gives the anti-compiler the difficulty of making the understanding, and the anti-compiler needs to spend some time figuring out what these resource files do. Another benefit of resource obfuscation is the ability to significantly reduce the size of the APK, resource confusion both to protect the security of the resource file and to reduce the size of the installation package, then why not?
By modifying the AAPT, we can achieve relative resource security on the basis of code 0 modification, of course, security is relative, and there is no absolute security.
The practice of confusing and protecting Android resources in US