Tools for analysis: dex2jar + jd-gui + ida 6.1 + ExamDiff Pro
The class selected to add protect shell is:
Lcn/com/fmsh/cube/a/a;
When use dex2jar to analyse it, I can see there are only 2 functions in this class have called a and b in jd-gui.
Then I upload my APK to APKProtect, encrypt it and download the new APK. Let's check whether the most important file classes.dex has changed.
Before encryption, the size of classes.dex is 2,925,772 bytes;
After encryption, the size of classes.dex is 2,926,676 bytes.
After that, I analyse the code manually:
First, I use ida to reverse the encrypted dex file. In order to check whether there are changes happened on the bytecode of "a" in selected classes, I use "cn.com.fmsh.cube.a.a.a(" to find the function entry in IDA.
Before encryption:
![]()
After encryption:
![]()
We can see after encryption, code IDA can not be reversed completely. Therefore we can sure this protect shell has indeed encrypted the bytecode in classes.dex.
Then I check what have added in the new APK. I matching the catalogue of the new APK and the unencrypted APK by ExamDiff, and find only a library file named "libapkprotect.so" is new added.
Then I use ida to analyse library file "libapkprotect.so" and find there are only 5 jni entry functions, i.e., JNI_OnLoad, _d, _a, Java_com_apkprotect_Init and Java_com_apkprotect_Version. We can sure that this library has added with protect shell by check the assembler code of jni layer function's code. I have never seen the shell of so, therefore the way to remove this shell needs to explore. So I have to bypass this step. But through this library, we can infer:
If Java layer calls this library, then it must call the function "System.loadLibrary". So I anaylise encrypted dex file by using IDA and find a Java class named "apkprotect". The code in this class has no other functions except <clinit> and <init> function. Therefore we can sure the code in this class should be:
public class apkprotect
{
static
{
System.loadLibrary("apkprotect");
}
public native int Init();
public native int Version();
}
From the function name in the above code, we can also infer that the most possible called function should be Init. Therefore I use "apkprotect.Init(" to search dex code, and get the following calling points:
1. com.lakala.android.bll.receiver.AlarmReceiver.onRe ceive
2. com.lakala.android.bll.receiver.BroadcastReceiver. onReceive
3. com.lakala.android.bll.receiver.LoginoutReceiver.o nReceive
4. com.lakala.android.bll.receiver.StatisticReceiver. onReceive
5. com.lakala.android.common.ApplicationExtension.<cl init>
6. com.lakala.android.common.service.DownloadAppServi ce.onCreate
7. com.lakala.android.common.service.DownloadFileServ ice.onCreate
8. com.zch.safelottery.broadcast.SafelotteryBroadcast Receiver.onReceive
My personal opinions are:
If you want a program executes normally, it has to decrypt the encrypted bytecode before run it, or use your own method to execute the encrypted classes by take over the system's executing interface. This protect shell may be the former. Because the size of the accompanying library file "libapkprotect.so" is not big. It must have more codes if it executes decryption itself.
This is the download link of my test APK:
Download test APK
This is the online encryption website of my test:
http://www.apkprotect.com/
Any suggestions are welcomed!
The class selected to add protect shell is:
Lcn/com/fmsh/cube/a/a;
When use dex2jar to analyse it, I can see there are only 2 functions in this class have called a and b in jd-gui.
Then I upload my APK to APKProtect, encrypt it and download the new APK. Let's check whether the most important file classes.dex has changed.
Before encryption, the size of classes.dex is 2,925,772 bytes;
After encryption, the size of classes.dex is 2,926,676 bytes.
After that, I analyse the code manually:
First, I use ida to reverse the encrypted dex file. In order to check whether there are changes happened on the bytecode of "a" in selected classes, I use "cn.com.fmsh.cube.a.a.a(" to find the function entry in IDA.
Before encryption:

After encryption:

We can see after encryption, code IDA can not be reversed completely. Therefore we can sure this protect shell has indeed encrypted the bytecode in classes.dex.
Then I check what have added in the new APK. I matching the catalogue of the new APK and the unencrypted APK by ExamDiff, and find only a library file named "libapkprotect.so" is new added.
Then I use ida to analyse library file "libapkprotect.so" and find there are only 5 jni entry functions, i.e., JNI_OnLoad, _d, _a, Java_com_apkprotect_Init and Java_com_apkprotect_Version. We can sure that this library has added with protect shell by check the assembler code of jni layer function's code. I have never seen the shell of so, therefore the way to remove this shell needs to explore. So I have to bypass this step. But through this library, we can infer:
If Java layer calls this library, then it must call the function "System.loadLibrary". So I anaylise encrypted dex file by using IDA and find a Java class named "apkprotect". The code in this class has no other functions except <clinit> and <init> function. Therefore we can sure the code in this class should be:
public class apkprotect
{
static
{
System.loadLibrary("apkprotect");
}
public native int Init();
public native int Version();
}
From the function name in the above code, we can also infer that the most possible called function should be Init. Therefore I use "apkprotect.Init(" to search dex code, and get the following calling points:
1. com.lakala.android.bll.receiver.AlarmReceiver.onRe ceive
2. com.lakala.android.bll.receiver.BroadcastReceiver. onReceive
3. com.lakala.android.bll.receiver.LoginoutReceiver.o nReceive
4. com.lakala.android.bll.receiver.StatisticReceiver. onReceive
5. com.lakala.android.common.ApplicationExtension.<cl init>
6. com.lakala.android.common.service.DownloadAppServi ce.onCreate
7. com.lakala.android.common.service.DownloadFileServ ice.onCreate
8. com.zch.safelottery.broadcast.SafelotteryBroadcast Receiver.onReceive
My personal opinions are:
If you want a program executes normally, it has to decrypt the encrypted bytecode before run it, or use your own method to execute the encrypted classes by take over the system's executing interface. This protect shell may be the former. Because the size of the accompanying library file "libapkprotect.so" is not big. It must have more codes if it executes decryption itself.
This is the download link of my test APK:
Download test APK
This is the online encryption website of my test:
http://www.apkprotect.com/
Any suggestions are welcomed!