Recently in the study of the Android platform Shell Technology, previously thought only the original layer of code can be shell, looked at the information on the Internet, only to find that the original Java layer can also be added shell, although with the traditional shell some differences, but in the final effect, the purpose of anti-static analysis is achieved.
Most of the current apk Protection in the Android Market is the Java Layer Code Confusion, the key data in the original layer, and then the traditional shell method for so File to Shell, the flaw in this way is that Java Layer code security is completely dependent on code obfuscation, in fact, as long as the familiarity with the smali syntax, the meaning of code confusion is not as large as imagined, Reverse Smali can be a lot easier than retrace in a bunch of assembler code for those senior C + + Reverse Engineers .
How the traditional PE file is added to the shell
Look at the snow.PEDocument Shell Interpretation is very detailed, not much elaboration, the general principle is the sourcePEafter the file is encrypted or compressed, the data is embedded inside the shell, and the shell executes the sourcePEfile decryption load, and then skip to sourcePEthe entry of the file (OEP) execution. Static Analysis shell program, you can only see the shell and the source of encryptionPEfile. If you want to get the sourcePEfile (shelled), you can only run the shell to have the sourcePEthe file is decrypted and then foundOEP, the decryptedPEfiles from memoryDumpdown, rebuild the input table, generate the shelledPEfile. Software security engineers can use reverse debugging on the shell(Anti-debug)and complex control flow techniques to stop the cracker from looking forOEP.
As can be seen, a traditional "shell" needs to have the following characteristics:
1, the source program is compressed or encrypted embedded inside the shell program;
2. The shell program runs before the source program and decrypts the source program;
3, the decrypted data must be stored in memory;
4, the source program to be able to run normally after loading;
The most critical is the 3 Point, it is necessary to understand that as long as enough time, the shell will eventually be cracked, the meaning of the shell is actually to increase the cost of cracking, as long as possible to delay the crack time, to do this, We must put the key point of confrontation with the cracker to analyze the difficulty of the decryption logic of the shell, if the cracker has a way to bypass the analysis shell procedure, directly get the decrypted source program, then this shell is invalid. If the decrypted data is left in the file system, the cracker can get to the source program directly. Why do you have to put this issue alone, the traditional shell loading source program, as long as the decryption, the relocation to OEP , Androga load executable but need to use the class loader dexclassloader , the prototype is as follows:
Public Dexclassloader (String Dexpath, String optimizeddirectory, String LibraryPath, ClassLoader loader)
The first parameter, Dexpath , represents a path, meaning thatdexclassloader can only load executables that reside in the file system. The problem comes out, just said, we can't put the decrypted source program on the filesystem, but to load the android executable with Dexclassloader Dex You must first store it on the file system, which is the biggest difficulty in adding shells to the Dex file.
In order to solve this problem, I think of two ways, the first method is to reduce the time exposure in the file system,Dexclassloaderafter the source program is loaded, it is removed from the file system immediately, so that the cracker must debug dynamically, before the source program is deleted to get the source program. But this approach is still very insecure, and we need a way to completely leave no traces of the file system. Just look back .Dexclassloader, although it only provides the path as a parameter, its loading process must eventually have a step to convert the file into an input stream and then map to memory, that is,DexclassloaderEventually, you will load the source program from memory. The information was checked on the internet and eventuallyhttp://www.strazzere.com/papers/DexEducation-PracticingSafeDex.pdffound the answer, the original Android4.0The following versions do not support memory loadingDex,4.0the above version actually provides abytean interface that is an array of parametersOpendexfileto load the class from memory, except that the interface is not open toSDK, so you need to useJavaThe reflection mechanism to invoke. Details and so on later, this article first talk about how to achieve the first method.
Embed the source APK into the shell Dex
We know apk is an Android installation package, essentially a zip apk classes.dex is the real executable, why embed classes.dex classes.dex classes.dex
specifically embedded apk The method references this blog: http://blog.csdn.net/androidsecurity/article/details/ 8678399 apk after encryption, Added to the shell classes.dex tail , then add apk file length, last modified classes.dex dex file header. This part is very simple, the blogger also provides the source code, so it is not elaborated.
apk shell classes.dex put directly into the shell apk Span style= "font-family: the song Body;" > In the case of a mobile phone installation, it will go wrong because it destroys the signature, need to put the shell apk meta-inf signapk.jar re-signing, my signapk.jar http://www.uzzf.com/soft/60860.html
Peel the source in the shell APK
After the shell is run, thegetapplicationinfo (). SourceDircan get to the shell itself.APKaddress, open it as a file and enter it into aZipinputstreamstream, and then traverseZipFindClasses.dex, enter it into abyteArray, usingbytethe length of the array-4get the embedded sourceAPKthe length of the file, and the last callsystem.arraycopythe sourceapkcopy it, decrypt it, and output it to the filesystem. the code to read the shell itself APK is as follows:
1 New Bytearrayoutputstream (); 2 New Zipinputstream (3 New Bufferedinputstream (new fileinputstream (4this . Getapplicationinfo (). SourceDir));
dynamic load Source APK with Dexclassloader
Android is allowed without installing theapkin the case of the callapkexecutable file, to achieve this, you have to use theDexclassloader, this is an Android-specific class loader thatAPKpath as a parameter, locateAPKin theClasses.dexfile, load the class inside, so we can call the sourceAPKthe code in the. It should be noted that the direct use ofDexclassloaderthe loaded Android component class is dead, does not have a life cycle, is not different from the normal class, that is, we can not directly call the same way as normal calls to the Android componentDexclassloaderload the incoming component. Online for a while, inhttp://blog.csdn.net/singwhatiwanna/article/details/22597587found a solution that binds the component in the source apk to the life cycle of the component that called the apk , which is equivalent to the source apk Life cycle simulation, this call technology can be used to implement the APK plugin, but there are many limitations, the most effective solution is the proxy/ Delegate frame: http://blogs.360.cn/blog/proxydelegate-application/This solution is to call theAPKof theApplicationdynamic substitution for sourceAPKof theApplication(Proxywith theDelegate) and apply it to theDexfile on the shell, so that the equivalent of replacing the application environment, the running shell becomes the source program, as long as the source program to call theapplication.oncreate (), the source program is started. In addition, the source program needs to beapplication.oncreate ()into the boot.mainactivitythe code, otherwisemainactivityis not actively activated.
To be Continued ...
Research on the technology of the Android Dex Shell (1)