日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

018 Android加固之实现dex加载器

發布時間:2025/3/21 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 018 Android加固之实现dex加载器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • Android APK加固-安全人員角度
    • 關于類加載器
      • 類加載器
      • 類加載器的種類和個數
      • 創建類加載實例
      • 類加載器DexClassLoader和PathClassLoader
    • 使用類加載器動態加載dex文件
      • 制作dex文件
      • 動態加載dex文件
      • 完整步驟回顧

Android APK加固-安全人員角度

Android安全人員對APK加固采取的角度大概分為以下幾個方面:

  • 將可執行代碼dex文件加密,能夠動態解密并執行
  • 能夠檢測當前狀態是被調試,想盡一切辦法反調試
  • 那如果繼續再細分一下,實現一個初級的APK加固:

  • 使用類加載器動態加載dex文件
  • 設計傀儡dex替換原dex,動態加載dex
  • 在傀儡dex中的各種地方增加反調試代碼
  • 接下來就是從類加載器開始一步步完成APK加固

    關于類加載器

    類加載器

    在JAVA開發中動態加載的技術主要用于加載jar包,使軟件具備動態添加插件的功能,Java代碼都是寫在Class里的,程序運行在虛擬機上時,虛擬機需要把需要的Class加載進來才能創建實例對象并工作,而完成這一加載工作的角色就是ClassLoader。

    Android的Dalvik/ART虛擬機如同標準JAVA的JVM虛擬機一樣,在運行程序時首先需要將對應的類加載到內存中。因此我們可以利用這一點,在程序運行時手動加載Class,從而達到代碼動態加載可執行文件的目的。

    Android的Dalvik/ART虛擬機雖然與標準Java的JVM虛擬機不一樣,ClassLoader具體的加載細節不一樣,但是工作機制是類似的,也就是說在Android中同樣可以采取類似的動態加載jar或者dex的功能,只是在Android應用中動態加載一個jar或者dex的工作要比Eclipse加載一個插件復雜許多

    類加載器的種類和個數

    動態加載的基礎是ClassLoader,從名字可以看出ClassLoader就是專門用來處理類加載工作的,所以這個類也叫類加載器,而且一個運行中的APP不僅有一個類加載器。

    其實在Android系統啟動的時候會創建一個Boot類型的ClassLoader實例,用于加載一些系統Framework層級需要的類,我們的Android應用里也需要用到一些系統的類,所以APP啟動的時候也會把Boot類型的ClassLoader傳進來。此外,APP也有自己的類。

    這些類保存在APK的dex文件里面,所以APP啟動的時候,也會創建一個自己的ClassLoader實例,用于加載自己dex文件中的類。下面我們在項目里驗證看看。

    public void enmuClassLoader(){int count=0;//獲取當前包的ClassLoaderClassLoader classLoader=getClassLoader();if (classLoader!=null){Log.d("GuiShou","[onCreate] classLoader"+count++ +":"+classLoader.toString());}while (classLoader.getParent()!=null){classLoader=classLoader.getParent();Log.d("GuiShou","[onCreate] classLoader"+count++ +":"+classLoader.toString());}}

    可以看見有兩個ClassLoader實例,一個是BootClassLoader,系統啟動時候創建的,一個是PathClassLoader,應用啟動時創建的。由此也可以看出,一個運行的Android應用至少有兩個ClassLoader。

    創建類加載實例

    動態加載外部Dex文件的時候,我們也可以使用自己創建的ClassLoader實例來加載dex里面的class,不過ClassLoader的創建方式有點特殊,我們先來看看它的構造方法

    private ClassLoader(Void unused,ClassLoader parent){this.parent=parent; }

    創建一個ClassLoader的時候,需要使用一個現有的ClassLoader的實例作為新創建的實例的Parent。這樣一來,一個Android應用,甚至整個Android系統里所有的ClassLoader實例都會被一棵樹關聯起來,這也是ClassLoader的雙親代理模型(Parent-Delegation Model)的特點

    類加載器DexClassLoader和PathClassLoader

    在Android中,ClassLoader是一個抽象類,在實際開發過程中,我們一般是使用其子類DexClassLoader和PathClassLoader來加載類的。

    它們的不同之處是:

    • DexClassLoader可以加載jar/dex/apk,可以從SD卡中加載未安裝的APK
    • PathClassLoader只能加載系統中已經安裝過的APK

    根據功能,我們更加傾向于使用DexClassLoader,所以接下來先使用DexClassLoader來加載一個簡單的dex文件

    使用類加載器動態加載dex文件

    制作dex文件

    為了能與Android的類有互動,先寫這樣一段代碼

    public class TestActivity {public void CreateVew(Activity ac){//創建一個TextViewTextView tv=new TextView(ac);//創建布局 設置參數FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);//設置控件到頂端的距離params.topMargin=0;//設置控件的位置params.gravity= Gravity.TOP|Gravity.CENTER_HORIZONTAL;tv.setText("TestActivity View");//添加TextView到Avtivity中ac.addContentView(tv,params);} }

    這段代碼的效果就是顯示一段TextView到Activity中

    這次代碼直接在Android項目中編譯,然后在app的目錄中查找class文件復制到自己的目錄中即可。類所在的目錄是app/build/intermediates/classes/debug/包名

    接下來把當前的這個Activity進行反編譯得到的smali文件轉成一個dex文件放到這個工程的資源文件里

    將apk用AndroidKiller打開,分析完成后打開smali文件路徑,復制出一份副本

    刪除其余的smali文件,只保留我們自己寫的TestActivity類的smali,然后通過smali.jar將其轉成dex文件

    然后在main文件夾下新建一個assets文件夾,將dex文件復制到里面,并且刪除TestActivity類

    動態加載dex文件

    現在我們已經有了一個制作好的dex文件,接著就需要將這個dex文件動態加載進來。想要動態加載dex,需要下面幾個步驟。

  • 將dex文件從自定義資源文件夾拷貝到程序目錄下
  • 創建一個DexClassLoader,加載dex
  • 調用加載的dex中的class方法
  • 首先拷貝dex文件

    public String CopyDex(String dexName){//獲取Asserts目錄管理器AssetManager as=getAssets();//合成路徑 data/data/包名/files/dex名稱String path=getFilesDir()+ File.separator+dexName;Log.d("GuiShou",path);//創建文件流try {FileOutputStream out=new FileOutputStream(path);//打開文件InputStream is=as.open(dexName);//循環讀取文件,拷貝到目標路徑byte[] buffer=new byte[1024];int len=0;while ((len=is.read(buffer))!=-1){out.write(buffer,0,len);}//關閉文件out.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return path;}

    接著創建DexClassLoader

    public DexClassLoader GetLoader(String path){//創建dex的類加載器,返回DexClassLoader對象DexClassLoader dexClassLoader=new DexClassLoader(path, //dex文件路徑getCacheDir().toString(), //優化后的dex文件路徑null, //原生庫路徑getClassLoader() //父類加載器);return dexClassLoader;}

    最后調用加載的dex中的class方法

    public void execClassMethod(DexClassLoader dex,String ClassName, String MethodName){try {//獲取加載的類信息Class TestDex=dex.loadClass(ClassName);//獲取構造方法 無參構造Constructor localConstructor=TestDex.getConstructor(new Class[]{});//調用構造方法 創建對象Object instance=localConstructor.newInstance(new Object[]{});//獲取成員方法Method methodTest=TestDex.getDeclaredMethod(MethodName,new Class[]{Activity.class});//取消java訪問檢查,提高反射速度methodTest.setAccessible(true);//調用方法 this指針傳進去methodTest.invoke(instance,new Object[]{this});} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}

    最后調用以上三個函數

    //加載dexpublic void loadDex(){//拷貝自定義資源中的dex到程序目錄下String dexPath=CopyDex("test.dex");//創建一個DexClassLoader,加載dexDexClassLoader dexClassLoader=GetLoader(dexPath);//調用加載dex中的class方法execClassMethod(dexClassLoader,"com.example.classloaderdemo.TestActivity","CreateVew");}

    到這里,代碼就已經全部完成了。

    接著運行程序,

    效果和之前寫的dex文件代碼一致,那么就說明我們已經完成了動態加載dex文件的過程。

    完整步驟回顧

  • 新建一個工程,創建TestActivity類,實現一個創建view的方法
  • 編譯生成apk,使用AndroidKiller反編譯,將除了TestActivity.smali代碼外的全部smali文件刪除,編譯生成dex文件
  • 在項目main文件夾創建asserts文件夾,將生成的dex拷貝到這個目錄下
  • 在代碼中完成以下步驟
  • 拷貝自定義資源中的dex到程序目錄下
  • 創建一個dexClassLoader加載dex
  • 調用加載dex中的class方法
  • 總結

    以上是生活随笔為你收集整理的018 Android加固之实现dex加载器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。