Android逆向 Dex文件

Android 逆向学习指南
Android 可执行文件-dex 文件
uleb128 数据类型
SourceInsight 源码分析工具
解决修改 dex 文件之后的错误
修复 dex 文件的原理

  1. Android SDK 知识 1(环境搭建,SDK 工具(adb 和 monitor))
  2. Android UI 界面编程(基本控件)
  3. Android 四大组件(activity,service,broadcastreceiver,contentprovider)
  4. Andriod 消息机制和网络多线程(Thread,Runnable,Handler)
  5. Android 逆向(基本逆向工具,Smali 语言)
  6. Android 逆向(集成逆向工具,捕鱼游戏的破解,Smali 代码修改,Smali 代码注入,动态调
    试 smali)
  7. Android 逆向(病毒分析,Android 病毒的常见行为,锁机病毒的分析)
  8. Android 逆向(Hook 框架,Cydia 和 Xposed,Xposed 插件应用)
  9. Android 逆向(可执行文件格式, dex 文件, source insight 源码分析,010Editor 文件分析)

Android 逆向学习指南
Android SDK 学习《第一行代码第 2 版》
Android NDK 学习《Android C++ NDK 高级编程》前 3 章,Linux 相关的 API(动态加载、文
件操作)
Android Java 层逆向 工具+资料+文档+baksmali 源码,不断的练习和破解
Android 逆向应用 游戏破解、病毒分析
Android Hook 框架 Cydia,Xposed,frida, 学习 Java 反射相关的编程
Android 文件格式 ELF 文件格式(C++代码编译成.so 文件),DEX 文件格式(Java 编译)
Android ARM 汇编 ARM 指令集(算数指令、逻辑运算指令、跳转指令等等)
Android 动态调试 smali 动态调试、so 文件动态调试
Android 加固脱壳 先学习开源代码(加固流程),再学习 android 源码(dex 文件加载、so 文
件加载)
Android 源码学习 《Android 系统源码情景分析》罗升阳,csdn 博客(虚拟机加载、app
加载、系统加载)
Android 协议分析 抓包 http 协议的数据(Charles、Fiddler),分析其中的加密参数

Android 可执行文件-dex 文件
最简单的一个 dex 文件-HelloWorld
① 编译 smali 为 dex
java -jar smali-2.1.3.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 文件头
② 各种数据的数组,包括字符串、类型、方法原型、字段、方法
③ 类数据
④ 其他

image.png
  1. Dex 文件头


    image.png

字段 1:dex_magic,表示 dex 文件的文件标识,特征字符串
字段 2:checksum, 表示校验和,对文件求了 32 位的 hash 值(从字段 3 开始到文件末尾)
字段 3:signature[], 表示 SHA1(沙 one),对文件求 hash 值(从字段 4 开始到文件末尾)
字段 4:file_size, 表示文件大小

image.png

字段 5:dex 文件头大小
字段 6:数据排列方式-小端方式


image.png

各种表的大小以及偏移
① 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. 各种数据的数组,包括字符串、类型、方法原型、字段、方法
    ① 字符串表


    image.png

字符串表项,是一个字符串数据的偏移,偏移指向的是一个 string_data 结构。
String_data 结构中有两个字段:
字段 1: 代表长度,数据类型是 uleb128,变长的数据类型(1-5 字节)
字段 2: 存储数据,字符串以 0 结尾。
② 类型表


image.png

类型表表项,是一个索引值,类型描述符字符串在字符串表中的索引,图中的索引是 1,表
示在字符串表中的数组索引 1 中的元素。

image.png

类型描述符包括基本数据类型的描述符和类类型的描述符。
LHelloWorld; 是 HelloWorld 类的类描述符。

③ 原型表


image.png

原型表项中存储的是函数原型的各部分描述信息。包括短类型(shorty_idx)、返回类型
(return_type_idx)、参数的类型(parameters_off,最终还是一个指向字符串表的数组下标)
注意:字段为返回类型(return_type_idx)的值,是类型表中的索引。

④ 字段表


image.png

字段表项中内容存储的是字段的信息。包括字段所在类(class_idx)、字段的类型(type_idx)、
字段的名称(name_idx), class_idx 是类型表中的索引,type_idx 是类型表中的索引,字段名称
的索引是字符串表的数组下标。

⑤ 方法表


image.png

方法表项中存储的是方法的信息,包括方法所在的类(class_idx)、方法的原型(proto_idx)、方
法的名称(name_idx),其中 class_idx 是类型表中的索引,proto_idx 是在原型表中的索引,方
法名称的索引是字符串表的数组下标。

  1. 类数据
    类数据也是一个数组,每一个元素就是一个类的相关信息。


    image.png

在表项中的 class_data 中存储的是类数据,包括类名索引、访问属性、父类索引、接口偏移、
源码索引、注解偏移、类数据偏移。


image.png

在类数据中有存储类中的字段和方法信息,在每一个方法中的 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
第一字节:


image.png

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

image.png

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

image.png

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

image.png

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

image.png

伪代码:invoke-virtual {v0, v1}, method[1]

image.png

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

指令 4:0E 00 return-void


image.png

uleb128 数据类型
特点:变长,(1-5 字节),每一个字节最高位表示标志位,可以理解为是是否下一字节有数
据。
范围:整型,最大表示一个 32 位的无符号数据
举例:
整型数据:16 进制:0x180 二进制:0000 0001 1000 0000
小端方式二进制:1000 0000 0000 0001
Uleb128 : 1000 0000 0000 0011
查看源码读取信息

DEX_INLINE int readUnsignedLeb128(const u1** pStream) {
const u1* ptr = *pStream;
int result = *(ptr++); // 取出一个字节
if (result > 0x7f) { // 判断第一个字节的最高位是否有值
int cur = *(ptr++); // 取出第二个字节
result = (result & 0x7f) | ((cur & 0x7f) << 7); // 第一个字节留 7 位,第二字节留 7 位
// 字节 2 会左右 7 位,与第一字节 做 或操作
// 举例: uleb128: 1000 0000 0000 0011
// &0x7F 0000 0000 0000 0011
// A | B<<7 0000 0000 | (0000 0011<<7)
// 0000 0000 | 110000000
// = 1 1000 0000=0x180
if (cur > 0x7f) {
cur = *(ptr++);
result |= (cur & 0x7f) << 14;
if (cur > 0x7f) {
cur = (ptr++);
result |= (cur & 0x7f) << 21;
if (cur > 0x7f) {
/

  • Note: We don't check to see if cur is out of
  • range here, meaning we tolerate garbage in the
  • high four-order bits.
    */
    cur = *(ptr++);
    result |= cur << 28;
    }
    }
    }
    }
    *pStream = ptr;
    return result;
    }

SourceInsight 源码分析工具
新建工程,导入源码


image.png
image.png

使用指南

image.png

如果需要查找,使用菜单中的搜索功能即可。
解决修改 dex 文件之后的错误
当我们修改 dex 文件之后,即使再签名,再打包,最终还是无法安装,因为 dex 文件对文件
有校验,安装时会读取 dex 文件头部的 hash 值和重新计算的值进行比对,完成校验。


image.png

使用修复工具,修复之后,再次安装


image.png

此时模拟器中有安装残留,需要在/data/data/目录中删除对应的安装目录
重新安装,即可完成。

修复 dex 文件的原理 DexRepairTools
将 dex 文件头部的两个 Hash 值重新计算,然后写回去。
① 先计算 SHA-1 值,修改值
② 再计算 CheckSum 值,修改值

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,028评论 25 707
  • 文件头(File Header) Dex文件头主要包括校验和以及其他结构的偏移地址和长度信息。 字段名称偏移值长度...
    朱立志阅读 941评论 0 0
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,711评论 2 59
  • 四、幼儿认知的发展 1、记忆的发展 2、思维的发展 3、心理理论 四、幼儿认知的发展 1、记忆的发展 (1)记忆容...
    赵淇竹阅读 1,360评论 0 1
  • 习惯了每天有你陪伴在身边,可忽然有一天你转身便要离开,我难过地抱着你哭。 你转过身捧着我的脸深情地说道:“傻瓜,我...
    年槿悠阅读 836评论 0 1