APK 加固原理

来源:互联网 发布:螺纹钢理论重量表算法 编辑:程序博客网 时间:2024/05/22 23:20

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文件

  1. /** 
  2.      * @param args 
  3.      */  
  4.     public static void main(String[] args) {  
  5.         // TODO Auto-generated method stub  
  6.         try {  
  7.             File payloadSrcFile = new File("force/ForceApkObj.apk");   //需要加壳的程序  
  8.             System.out.println("apk size:"+payloadSrcFile.length());  
  9.             File unShellDexFile = new File("force/ForceApkObj.dex");    //解客dex  
  10.             byte[] payloadArray = encrpt(readFileBytes(payloadSrcFile));//以二进制形式读出apk,并进行加密处理//对源Apk进行加密操作  
  11.             byte[] unShellDexArray = readFileBytes(unShellDexFile);//以二进制形式读出dex  
  12.             int payloadLen = payloadArray.length;  
  13.             int unShellDexLen = unShellDexArray.length;  
  14.             int totalLen = payloadLen + unShellDexLen +4;//多出4字节是存放长度的。  
  15.             byte[] newdex = new byte[totalLen]; // 申请了新的长度  
  16.             //添加解壳代码  
  17.             System.arraycopy(unShellDexArray, 0, newdex, 0, unShellDexLen);//先拷贝dex内容  
  18.             //添加加密后的解壳数据  
  19.             System.arraycopy(payloadArray, 0, newdex, unShellDexLen, payloadLen);//再在dex内容后面拷贝apk的内容  
  20.             //添加解壳数据长度  
  21.             System.arraycopy(intToByte(payloadLen), 0, newdex, totalLen-44);//最后4为长度  
  22.             //修改DEX file size文件头  
  23.             fixFileSizeHeader(newdex);  
  24.             //修改DEX SHA1 文件头  
  25.             fixSHA1Header(newdex);  
  26.             //修改DEX CheckSum文件头  
  27.             fixCheckSumHeader(newdex);  
  28.   
  29.             String str = "force/classes.dex";  
  30.             File file = new File(str);  
  31.             if (!file.exists()) {  
  32.                 file.createNewFile();  
  33.             }  
  34.               
  35.             FileOutputStream localFileOutputStream = new FileOutputStream(str);  
  36.             localFileOutputStream.write(newdex);  
  37.             localFileOutputStream.flush();  
  38.             localFileOutputStream.close();  
  39.   
  40.   
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.     }  

2、读取新的APK,安装

通过反射置换android.app.ActivityThread 中的mClassLoader为加载解密出APK的DexClassLoader,该DexClassLoader一方面加载了源程序、另一方面以原mClassLoader为父节点,这就保证了即加载了源程序又没有放弃原先加载的资源与系统代码。

找到源程序的Application,通过反射建立并运行。

这里需要注意的是,我们现在是加载一个完整的Apk,让他运行起来,那么我们知道一个Apk运行的时候都是有一个Application对象的,这个也是一个程序运行之后的全局类。所以我们必须找到解密之后的源Apk的Application类,运行的他的onCreate方法,这样源Apk才开始他的运行生命周期。这里我们如何得到源Apk的Application的类呢?这个我们后面会说道。使用meta标签进行设置。


原创粉丝点击