Android逆向之Dex文件


Android逆向之Dex文件

最簡單的一個 dex 文件-HelloWorld

① 編譯 smali 為 dex java -jar smali.jar -o classes.dex HelloWorld.smali ② 查看設備信息 adb devices ③ 上傳文件 adb push HelloWorld.zip /data/local ④ 執行程序 adb shell dalvikvm -cp /data/local/HelloWorld.zip HelloWorld

最簡單的 dex 文件的分析,主要分為三大塊: ① Dex 文件頭 ② 各種數據的數組,包括字符串、類型、方法原型、字段、方法 ③ 類數據 ④ 其他

1569652289621

  1. Dex 文件頭

1569652302954

字段 1:dex_magic,表示 dex 文件的文件標識,特征字符串 字段 2:checksum, 表示校驗和,對文件求了 32 位的 hash 值(從字段 3 開始到文件末尾)

字段 3:signature[], 表示 SHA1(沙 one),對文件求 hash 值(從字段 4 開始到文件末尾) 字段 4:file_size, 表示文件大小

1569652324642

字段 5:dex 文件頭大小 字段 6:數據排列方式-小端方式

1569652338252

各種表的大小以及偏移 ① string_ids_size 和 string_ids_off ,字符串表的大小和偏移 ② type_ids_size 和 type_ids_off,類型表的大小和偏移 ③ proto_ids_size 和 proto_ids_off,原型表的大小和偏移 ④ field_ids_size 和 field_ids_off,字段表的大小和偏移 ⑤ method_ids_size 和 method_ids_off,方法表的大小和偏移 ⑥ class_defs_size 和 class_defs_off,類數據表的大小和偏移

  1. 各種數據的數組,包括字符串、類型、方法原型、字段、方法 ① 字符串表

1569652355940

字符串表項,是一個字符串數據的偏移,偏移指向的是一個 string_data 結構。 String_data 結構中有兩個字段:

字段 1: 代表長度,數據類型是 uleb128,變長的數據類型(1-5 字節) 字段 2: 存儲數據,字符串以 0 結尾。 ② 類型表

1569652383496

1569652389887

類型表表項,是一個索引值,類型描述符字符串在字符串表中的索引,圖中的索引是 1,表 示在字符串表中的數組索引 1 中的元素。

1569652401261

類型描述符包括基本數據類型的描述符和類類型的描述符。 LHelloWorld; 是 HelloWorld 類的類描述符。

③ 原型表

1569652420351

原型表項中存儲的是函數原型的各部分描述信息。包括短類型(shorty_idx)、返回類型 (return_type_idx)、參數的類型(parameters_off,最終還是一個指向字符串表的數組下標) 注意:字段為返回類型(return_type_idx)的值,是類型表中的索引。 ④ 字段表

1569652434076

字段表項中內容存儲的是字段的信息。包括字段所在類(class_idx)、字段的類型(type_idx)、 字段的名稱(name_idx), class_idx 是類型表中的索引,type_idx 是類型表中的索引,字段名稱 的索引是字符串表的數組下標。 ⑤ 方法表

1569652446266

方法表項中存儲的是方法的信息,包括方法所在的類(class_idx)、方法的原型(proto_idx)、方 法的名稱(name_idx),其中 class_idx 是類型表中的索引,proto_idx 是在原型表中的索引,方 法名稱的索引是字符串表的數組下標。

  1. 類數據 類數據也是一個數組,每一個元素就是一個類的相關信息。

1569652464015

在表項中的 class_data 中存儲的是類數據,包括類名索引、訪問屬性、父類索引、接口偏移、 源碼索引、注解偏移、類數據偏移。

1569652477701

在類數據中有存儲類中的字段和方法信息,在每一個方法中的 code_item 結構中有一個字段 insns 數組,存儲的是 dalvik 虛擬機指令。指令可以使用 baksmali 反匯編成 smali 代碼。 ushort insns[8] = 62 00 00 00 1A 01 00 00 6E 20 01 00 10 00 0E 00 第一字節:

1569652490833

指令 1:62 00 00 00 sget-object v0,field@0000

1569652502796

偽代碼:sget-object v0,out Smali 代碼:sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; Java 代碼:System.out

1569652513568

指令 2:1A 01 00 00 const-string v1,string@0000

1569652525288

偽代碼:const-string v1,string[0] Smali 代碼:const-string v1,“Hello World!” 指令 3:6E 20 01 00 10 00 invoke-virtual {v0,v1} , method@0001

1569652538367

偽代碼:invoke-virtual {v0, v1}, method[1]

1569652547868

Smali 代碼:invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V 更詳細的需要查看 baksmali 的源代碼。

指令 4:0E 00 return-void

1569652567142

在線分析 Android

http://androidxref.com/

1569652621891

解決 修改 x dex 文件之后的錯誤

當我們修改 dex 文件之后,即使再簽名,再打包,最終還是無法安裝,因為 dex 文件對文件 有校驗,安裝時會讀取 dex 文件頭部的 hash 值和重新計算的值進行比對,完成校驗。

1569652662102

此時模擬器中有安裝殘留,需要在/data/data/目錄中刪除對應的安裝目錄 重新安裝,即可完成。

修復 dex文件的原理

將 dex 文件頭部的兩個 Hash 值重新計算,然后寫回去。 ① 先計算 SHA-1 值(第三個字段),修改值 ② 再計算 CheckSum 值(第二個字段),修改值

Android 架構

https://source.android.google.cn/devices/architecture


免責聲明!

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



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