android apk 自我保護技術-完整性校驗


關於防止android apk被反編譯的技術我們前面已經講了四種。

加殼技術

運行時修改字節碼

偽加密

對抗JD-GUI

如果有不明白的可以查看我的博客的前四篇中關於這四種技術的介紹。接下來我們接着介紹另一種防止apk反編譯的技術-完整性校驗。

 

一、完整性校驗原理

所謂完整性校驗就是我們用各種算法來計算一個文件的完整性,防止這個文件被修改。其中常用的方法就是計算一個文件的CRC32的值或者計算一個文件的哈希值。我們在防止apk被反編譯的方法中也可以采用這種方法。我們知道apk生成的classes.dex主要由java文件生成的,它是整個apk的邏輯實現。所以我們可以對classes.dex文件進行完整性校驗,來保證整個程序的邏輯不被修改。如果我們想要保證整個apk文件的完整性,也可以對整個apk文件進行完整性校驗。下面我們分別來實現對classes.dex文件和apk文件的完整性校驗。

 

二、用crc32對classes.dex文件的完整性進行校驗

 

(1)可以打印出來我們的apk生的classes.dex文件的crc32的值,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MainActivity extendsActivity {
 
@Override
 
protected void onCreate(BundlesavedInstanceState) {
 
     super .onCreate(savedInstanceState);
 
     setContentView(R.layout.activity_main);
 
     String apkPath = getPackageCodePath();
 
     Long dexCrc = Long.parseLong(getString(R.string.classesdex_crc));
 
     try
 
     {
 
         ZipFile zipfile = new ZipFile(apkPath);
 
         ZipEntry dexentry = zipfile.getEntry( "classes.dex" );
 
         Log.i( "verification" , "classes.dexcrc=" +dexentry.getCrc());
 
         if (dexentry.getCrc() != dexCrc){
 
         Log.i( "verification" , "Dexhas been modified!" );
 
         } else {
 
         Log.i( "verification" , "Dex hasn't been modified!" );
 
         }
 
     } catch (IOException e) {
 
      // TODO Auto-generated catch block
 
      e.printStackTrace();
 
     }
 
    }
 
}



 

注意:R.string.classesdex_crc的值現在可以是個隨機數。

(2)運行程序打印結果,我的apk程序的classes.dex的crc32的值為713769644

(3)將上面程序的classes.dex文件的crc32的值,保存在資源文件字符串中classesdex_crc中(當然也可以保存在服務器上,然后通過網絡獲取校驗),然后再運行上面的apk程序,打印如下:

Dex hasn't beenmodified!

(4)這時我們在上面的代碼中隨便加一行或者一個空格,然后重新編譯運行會看到我們的程序的crc32的值改變了。程序打印如下:

Dex has beenmodified!

 

三、用哈希值對整個apk完整性進行校驗

由於我們要對整個apk的完整性進行校驗,所以我們的算出哈希值就不能存在資源文件中了因為apk中任何的改動都會引起最終apk生成的哈希值的不同。

(1)首先實現apk中計算自身哈希值的代碼,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class MainActivity extendsActivity {
 
@Override
 
protectedvoid onCreate(Bundle savedInstanceState) {
 
      super .onCreate(savedInstanceState);
 
      setContentView(R.layout.activity_main);
 
      String apkPath = getPackageCodePath();
 
      MessageDigest msgDigest = null ;
 
      try {
 
         msgDigest = MessageDigest.getInstance( "SHA-1" );
 
         byte [] bytes = new byte [ 1024 ];
 
         int byteCount;
 
         FileInputStream fis = new FileInputStream( new File(apkPath));
 
         while ((byteCount = fis.read(bytes)) > 0 )
 
         {
 
             msgDigest.update(bytes, 0 , byteCount);
 
         }
 
         BigInteger bi = new BigInteger( 1 , msgDigest.digest());
 
         String sha = bi.toString( 16 );
 
         fis.close();
 
         //這里添加從服務器中獲取哈希值然后進行對比校驗
 
         } catch (Exception e) {
 
             e.printStackTrace();
 
         }
 
     }
 
}



 

(2)用linux下的sha1sum命令計算我們的apk的哈希值,命令如下:

sha1sum verification.apk

(3)將(2)中生成的哈希值存到服務器上,然后在我們的代碼中從服務器獲取進行完整性比較。

 

上面我們用計算crc32和哈希值的方法分別對classes.dex文件和整個apk完整性進行了校驗,當然兩個校驗方法也可以互換使用。根據上面的講述相信大家對校驗文件完整性的方法有了一定的了解,下一篇我們將講解另一種android apk防止反編譯技術,期待大家的捧場。

如果對這篇講的技術有任何疑問及想要獲得這篇文章講的技術的工程源碼

歡迎關注個人微信公眾平台:程序員互動聯盟(coder_online),掃一掃下方二維碼或搜索微信號coder_online即可關注,我們可以在線交流。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM