1、源APK A.apk
2、源APK解压之后得到的源dex文件
3、加解密工具。
思路:
1、 将A.apk解压,得到A.dex
2、将A.apk(加密)以及A.dex 以及A.apk的size 以二进制的形式写入到数组,最终将数组转换为new.dex(实际上名称还是class.dex文件,后边替换用到)文件
3、工zip工具或者rar工具,替换A.apk中的dex文件为上边新的到的class文件
关键方法:
1、生成新的class文件
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- try {
- File payloadSrcFile = new File("force/ForceApkObj.apk"); //需要加壳的程序
- System.out.println("apk size:"+payloadSrcFile.length());
- File unShellDexFile = new File("force/ForceApkObj.dex"); //解客dex
- byte[] payloadArray = encrpt(readFileBytes(payloadSrcFile));//以二进制形式读出apk,并进行加密处理//对源Apk进行加密操作
- byte[] unShellDexArray = readFileBytes(unShellDexFile);//以二进制形式读出dex
- int payloadLen = payloadArray.length;
- int unShellDexLen = unShellDexArray.length;
- int totalLen = payloadLen + unShellDexLen +4;//多出4字节是存放长度的。
- byte[] newdex = new byte[totalLen]; // 申请了新的长度
- //添加解壳代码
- System.arraycopy(unShellDexArray, 0, newdex, 0, unShellDexLen);//先拷贝dex内容
- //添加加密后的解壳数据
- System.arraycopy(payloadArray, 0, newdex, unShellDexLen, payloadLen);//再在dex内容后面拷贝apk的内容
- //添加解壳数据长度
- System.arraycopy(intToByte(payloadLen), 0, newdex, totalLen-4, 4);//最后4为长度
- //修改DEX file size文件头
- fixFileSizeHeader(newdex);
- //修改DEX SHA1 文件头
- fixSHA1Header(newdex);
- //修改DEX CheckSum文件头
- fixCheckSumHeader(newdex);
- String str = "force/classes.dex";
- File file = new File(str);
- if (!file.exists()) {
- file.createNewFile();
- }
- FileOutputStream localFileOutputStream = new FileOutputStream(str);
- localFileOutputStream.write(newdex);
- localFileOutputStream.flush();
- localFileOutputStream.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
2、读取新的APK,安装
通过反射置换android.app.ActivityThread 中的mClassLoader为加载解密出APK的DexClassLoader,该DexClassLoader一方面加载了源程序、另一方面以原mClassLoader为父节点,这就保证了即加载了源程序又没有放弃原先加载的资源与系统代码。
找到源程序的Application,通过反射建立并运行。
这里需要注意的是,我们现在是加载一个完整的Apk,让他运行起来,那么我们知道一个Apk运行的时候都是有一个Application对象的,这个也是一个程序运行之后的全局类。所以我们必须找到解密之后的源Apk的Application类,运行的他的onCreate方法,这样源Apk才开始他的运行生命周期。这里我们如何得到源Apk的Application的类呢?这个我们后面会说道。使用meta标签进行设置。