- 1 public static void main(String args[])
- 2 {
- 3 try
- 4 {
- 5 //---------获取文件
- 6 //获取需要加密的源apk程序
- 7 File payloadSrcFile = new File("xxxx/abc.apk");
- 8 System.out.println("SrcAPK size:"+payloadSrcFile.length());
- 9 //获取脱壳(解密)程序的DEX文件,需要提前把脱壳程序的DEX文件解压出来
- 10 File unshellDexFile = new File("yyyy/classes.dex");
- 11
- 12 //---------加密源apk文件
- 13 /*
- 14 以二进制形式读取apk,并加密,存到payloadArray数组中
- 15 readFileBytes是以二进制形式读取文件
- 16 encrpt()是自定义的对二进制流加密的函数
- 17 */
- 18 byte[] payloadArray = encrpt(readFileBytes(payloadSrcFile));
- 19 //以二进制形式读取脱壳dex
- 20 byte[] unshellDexArray = readFileBytes(unshellDexFile);
- 21
- 22 //---------合并
- 23 //***1.计算出新Dex文件的总长度
- 24 int payloadLen = payloadArray.length(); //加密APK的长度
- 25 int unshellDexLen = unshellDexArray.length(); //脱壳Dex的长度
- 26 int totalLen = payloadLen+unshellDexLen=4 //新的Dex文件长度,最后+4是为了用于存储payloadLen值的
- 27 //***2.定义新dex文件
- 28 //先定义新dex文件的长度
- 29 byte[] newDex = new byte[totalLen];
- 30 //***3.开始合并
- 31 //将脱壳dex文件的内容写入新dex
- 32 System.arraycopy(unshellDexArray,0,newDex,0,unshellDexLen);
- 33 //再将加密后的源APK内容连接在后面
- 34 /*
- 35 arraycopy(arr1,x,arr2,y,m)表示将数组arr1从索引为x开始的元素,复制m个元素到数组arr2中去,从arr2的y索引开始粘贴
- 36 */
- 37 System.arraycopy(payloadArray,0,newDex,unshellDexLen,payloadLen);
- 38 //最后将将加密后的apk长度记录在新dex文件末尾
- 39 /*
- 40 intToByte()将int类型数据转换成Byte
- 41 total是int类型的,newDex是Byte类型
- 42 total是脱壳dex长度+加密apk长度+4,所以,最后是从newDex的第total-4索引开始写入payload的长度
- 43 一个byte是1个字节,即8位;一个int是4个字节,即32位;所以最后的4表示写入intToByte(payloadLen)的4个元素
- 44 */
- 45 System.arraycopy(intToByte(payloadLen),0,newDex,totalLen-4,4);
- 46
- 47 //---------修改新dex文件的头部信息
- 48 //修改file_size字段
- 49 fixFileSizeHeader(newDex);
- 50 //修改signature字段
- 51 fixSHA1Header(newDex);
- 52 //修改checksum字段
- 53 fixCheckSumHeader(newDex);
- 54 //---------生成新dex文件
- 55 //定义要生成文件的路径及名称并创建空文件
- 56 String str = "zzzz/classes.dex";
- 57 File file = new File(str);
- 58 if (!file.exists())
- 59 {
- 60 file.createNewFile();
- 61 }
- 62 //将合并好的数据写入文件
- 63 FileOutputStream localFileOutputStream = new FileOutputStream(str);
- 64 localFileOutputStream.write(newDex);
- 65 localFileOutputStream.flush();
- 66 localFileOutputStream.close();
- 67 }catch (Exception e) {
- 68 e.printStackTrace();
- 69 }
- 70 }
- 71
- 72 //加密函数encrpt()的定义
- 73 private static byte[] encrpt(byte data[])
- 74 {
- 75 //加密算法实现,这里就不写了
- 76 return data;
- 77 }