Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中的軟件安全和逆向分析[二]—apk反破解技術與安全保護機制

Android中的軟件安全和逆向分析[二]—apk反破解技術與安全保護機制

編輯:關於Android編程

  在Android應用開發中,當我們開發完軟件之後,我們不希望別人能夠反編譯破解我們的應用程序,不能修改我們的代碼邏輯。實際上,在應用程序的安全機制考慮中,我們希望自己的應用程序安全性高,通過各種加密操作等來增大競爭對手的反編譯破解成本。設想,競爭對手開發一個同樣的應用程序需要10天,而破解我們的軟件程序需要100天,那麼勢必會打消黑客程序員破解我們應用程序的念頭。如何增加對手的破解成本,就需要考驗我們應用程序的安全性有多高,加密技術有多強。一個優秀的應用程序,不僅能為用戶帶來利益,同時也能保護自己的核心技術。


  本文主要從以下幾個方面簡單介紹下Android應用程序的保護機制。

一、不讓程序安裝到模擬器上

  在上一篇文章中Android中的軟件安全和逆向分析[一]—apk反編譯破解以及java匯編代碼讀寫 裡面介紹了的大多數操作是Android裡的靜態反編譯破解apk文件。有些應用程序作了一些混淆,從SDK2.3開始我們可以看到在android-sdk-windows ools下面多了一個proguard文件夾,proguard是一個java代碼混淆的工具,具體介紹參考這篇博文,使的代碼邏輯比較復雜,此時我們如果還要靜態反編譯破解的話,就需要插入一些smali代碼動態的去調試觀察apk的邏輯。那麼如何保護自己的應用程序免受反編譯破解?我們需要阻止別的程序員反編譯,動態調試我的應用。換句話說,就是需要阻止黑客程序員安裝我的應用到模擬器上。
  一種方式是不讓自己的應用程序運行在模擬器上,當應用程序發現自己安裝到模擬器上的時候就會自殺。

package com.example.cracktest;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;

public class MainActivity1 extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (isEmulator()) {
            // 立刻自殺,發現自己運行在模擬器上,趕緊自殺
            android.os.Process.killProcess(android.os.Process.myPid());
        }
        setContentView(R.layout.activity_main);
    }

    /**
     * 判斷應用程序是否運行在模擬器上
     * 
     * @return
     */
    public boolean isEmulator() {
        // model:Android SDK built for x86
        //只要是在模擬器中,不管是什麼版本的模擬器,在它的MODEL信息裡就會帶有關鍵字參數sdk
        if (Build.MODEL.contains(sdk) || Build.MODEL.contains(SDK)) {
            return true;
        } else {
            return false;
        }
    }
}

  上述應用程序部署到真機上是可以運行的, 但是在模擬器上是打不開的,這樣就防止了黑客程序員動態調試我們的應用程序。

二、檢測應用程序的完整性

  第二種保護應用程序的安全機制是檢測應用程序的完整性,我們可以用jni技術校驗應用程序的完整性,也可以利用數字簽名的方式來檢測應用程序的完整性。我們知道當一個apk文件被反編譯破解、修改完代碼邏輯之後,要使用jarsigner工具來重新給apk簽名,才能運行修改後的apk文件。一個應用程序的簽名,是識別一個開發者的唯一標識,如果一個應用程序被別人反編譯,那麼這個應用程序的簽名肯定會改變。當發現程序的簽名改變時,我們使之自殺就可以避免程序帶來損失。下面我們來介紹下數字簽名的方式檢測應用程序的完整性。

package com.example.cracktest;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;

public class MainActivity2 extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println(getSignature());
    }

    /**
     * 獲得應用程序的數字簽名
     * 
     * @return
     */
    public String getSignature() {
        PackageManager pm = getPackageManager();
        try {
            // 得到當前應用程序的簽名
            PackageInfo info = pm.getPackageInfo(getPackageName(),
                    PackageManager.GET_SIGNATURES);
            return info.signatures[0].toCharsString();
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            return ;
        }
    }
}

  上述簡單實例代碼獲取到的應用程序的數字簽名為,
  這裡寫圖片描述
  任何一個對原apk的操作都會修改原apk的數字簽名,為了在程序中判斷方便,我們取數字簽名的MD5哈希值來判斷。
  <喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> package com.example.cracktest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5 { /** * 對字符串進行MD5加密 * @param content * @return */ public static String getMD5(String content) { try { MessageDigest digest = MessageDigest.getInstance(MD5); digest.update(content.getBytes()); return getHashString(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } private static String getHashString(MessageDigest digest) { StringBuilder builder = new StringBuilder(); for (byte b : digest.digest()) { builder.append(Integer.toHexString((b >> 4) & 0xf)); builder.append(Integer.toHexString(b & 0xf)); } return builder.toString(); } }

  這裡寫圖片描述
  我們在應用程序運行時,判斷當前的數字簽名的MD5哈希值是否等於上述圖片中的哈希值,如果等於,合法運行,如果不等於,就能夠證明apk文件被反編譯破解過,這個時候我們1.5s後自殺程序。
  

package com.example.cracktest;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity2 extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        System.out.println(getSignature());

        // 正確的簽名信息為77e980cae813e5dacc11fdb4c67988fd
        if (77e980cae813e5dacc11fdb4c67988fd.equals(getSignature())) {
            Toast.makeText(this, 自校驗完畢,合法正常運行。, 0).show();
        } else {
            Toast.makeText(this, 你敢破解我的代碼!, 0).show();
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    android.os.Process.killProcess(android.os.Process.myPid());
                };
            }.start();
        }
    }

    /**
     * 獲得應用程序的數字簽名
     * 
     * @return
     */
    public String getSignature() {
        PackageManager pm = getPackageManager();
        try {
            // 得到當前應用程序的簽名
            PackageInfo info = pm.getPackageInfo(getPackageName(),
                    PackageManager.GET_SIGNATURES);
            return MD5.getMD5(info.signatures[0].toCharsString());
        } catch (NameNotFoundException e) {
            e.printStackTrace();
            return ;
        }
    }
}

  具體的反編譯過程可以參見上一篇文章 Android中的軟件安全和逆向分析[一]—apk反編譯破解以及java匯編代碼讀寫 ,當反編譯apk,修改smali代碼,重新給apk簽名後,部署到模擬器上運行,發現1.5s後程序自殺。
  檢測包名,版本名和版本號,然後做判斷,與檢測數字簽名方法大同小異。有興趣的可以自己研究研究。

三、動態字節碼技術

  應用程序的運行字節碼不在本地,而是在網絡端,就是說我們的應用程序的關鍵性核心代碼不要放在本地,應該放在網絡服務器端上。而在網絡端的字節碼如何獲取呢?我們通過URLClassLoader從服務器上把字節碼下載到本地,然後編譯運行。這種動態從網絡獲取字節碼的技術可以防止黑客程序員本地靜態的反編譯我們的應用程序。

四、zip包加密

五、花指令加殼技術

  開發程序員先做一個so的殼,當做應用程序的運行環境,殼裡面運行著我們的程序代碼,相當於在java虛擬機的上層加了一個代碼監視器。也可以說是在加密後的虛擬機裡運行我們的應用程序,增加了安全性。

六、參考引用

使用jni技術進行android應用簽名信息核查及敏感信息保護 Android之防止反編譯技巧 防止android apk反編譯的技術分析淺談 Android如何防止apk程序被反編譯 proguard

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved