现在的位置: 首页 > 综合 > 正文

Android APK加壳技术方案【2】

2013年10月28日 ⁄ 综合 ⁄ 共 3733字 ⁄ 字号 评论关闭

本文章由Jack_Jia编写,转载请注明出处。  

文章链接:http://blog.csdn.net/jiazhijun/article/details/8809542

作者:Jack_Jia    邮箱: 309zhijun@163.com

 一、序言

        在上篇“Android APK加壳技术方案”(http://blog.csdn.net/jiazhijun/article/details/8678399)博文中,根据加壳数据在解壳程序Dex文件所处的位置,我提出了两种Android Dex加壳技术实现方案,本片博文将对方案1代码实现进行讲解。博友可以根据方案1的代码实现原理对方案2自行实现。

       在方案1的代码实现过程中,各种不同的问题接踵出现,最初的方案也在不同问题的出现、解决过程中不断的得到调整、优化。

       本文的代码实现了对整个APK包的加壳处理。加壳程序不会对源程序有任何的影响。

二、代码实现

     本程序基于Android2.3代码实现,因为牵扯到系统代码的反射修改,本程序不保证在其它android版本正常工作,博友可以根据实现原理,自行实现对其它Android版本的兼容性开发。

     1、 加壳程序流程及代码实现

                  1、加密源程序APK为解壳数据

                  2、把解壳数据写入解壳程序DEX文件末尾,并在文件尾部添加解壳数据的大小。

                  3、修改解壳程序DEX头中checksum、signature
和file_size头信息。


       代码实现如下:

[java] view
plain
copy

  1. package com.android.dexshell;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.security.MessageDigest;  
  8. import java.security.NoSuchAlgorithmException;  
  9. import java.util.zip.Adler32;  
  10.   
  11. public class DexShellTool {  
  12.     /** 
  13.      * @param args 
  14.      */  
  15.     public static void main(String[] args) {  
  16.         // TODO Auto-generated method stub  
  17.         try {  
  18.             File payloadSrcFile = new File("g:/payload.apk");  
  19.             File unShellDexFile = new File("g:/unshell.dex");  
  20.             byte[] payloadArray = encrpt(readFileBytes(payloadSrcFile));  
  21.             byte[] unShellDexArray = readFileBytes(unShellDexFile);  
  22.             int payloadLen = payloadArray.length;  
  23.             int unShellDexLen = unShellDexArray.length;  
  24.             int totalLen = payloadLen + unShellDexLen +4;  
  25.             byte[] newdex = new byte[totalLen];  
  26.             //添加解壳代码  
  27.             System.arraycopy(unShellDexArray, 0, newdex, 0, unShellDexLen);  
  28.             //添加加密后的解壳数据  
  29.             System.arraycopy(payloadArray, 0, newdex, unShellDexLen,  
  30.                     payloadLen);  
  31.             //添加解壳数据长度  
  32.             System.arraycopy(intToByte(payloadLen), 0, newdex, totalLen-44);  
  33.                         //修改DEX file size文件头  
  34.             fixFileSizeHeader(newdex);  
  35.             //修改DEX SHA1 文件头  
  36.             fixSHA1Header(newdex);  
  37.             //修改DEX CheckSum文件头  
  38.             fixCheckSumHeader(newdex);  
  39.   
  40.   
  41.             String str = "g:/classes.dex";  
  42.             File file = new File(str);  
  43.             if (!file.exists()) {  
  44.                 file.createNewFile();  
  45.             }  
  46.               
  47.             FileOutputStream localFileOutputStream = new FileOutputStream(str);  
  48.             localFileOutputStream.write(newdex);  
  49.             localFileOutputStream.flush();  
  50.             localFileOutputStream.close();  
  51.   
  52.   
  53.         } catch (Exception e) {  
  54.             // TODO Auto-generated catch block  
  55.             e.printStackTrace();  
  56.         }  
  57.     }  
  58.       
  59.     //直接返回数据,读者可以添加自己加密方法  
  60.     private static byte[] encrpt(byte[] srcdata){  
  61.         return srcdata;  
  62.     }  
  63.   
  64.   
  65.     private static void fixCheckSumHeader(byte[] dexBytes) {  
  66.         Adler32 adler = new Adler32();  
  67.         adler.update(dexBytes, 12, dexBytes.length - 12);  
  68.         long value = adler.getValue();  
  69.         int va = (int) value;  
  70.         byte[] newcs = intToByte(va);  
  71.         byte[] recs = new byte[4];  
  72.         for (int i = 0; i < 4; i++) {  
  73.             recs[i] = newcs[newcs.length - 1 - i];  
  74.             System.out.println(Integer.toHexString(newcs[i]));  
  75.         }  
  76.         System.arraycopy(recs, 0, dexBytes, 84);  
  77.         System.out.println(Long.toHexString(value));  
  78.         System.out.println();  
  79.     }  
  80.   
  81.   
  82.     public static byte[] intToByte(int number) {  
  83.         byte[] b = new byte[4];  
  84.         for (int i = 3; i >= 0; i--) {  
  85.             b[i] = (byte) (number % 256);  
  86.             number >>= 8;  
  87.         }  
  88.         return b;  
  89.     }  
  90.   
  91.   
  92.     private static

抱歉!评论已关闭.