Android Dex文件格式(二)
//Direct-mapped "class_def_item".
struct DexClassDef {
u4 classIdx; //类的类型, DexTypeId中的索引下标
u4 accessFlags; //访问标志
u4 superclassIdx; //父类类型, DexTypeId中的索引下标
u4 interfacesOff; //接口偏移, 指向DexTypeList的结构
u4 sourceFileIdx; //源文件名, DexStringId中的索引下标
u4 annotationsOff; //注解偏移, 指向DexAnnotationsDirectoryItem的结构
u4 classDataOff; //类数据偏移, 指向DexClassData的结构
u4 staticValuesOff; //类静态数据偏移, 指向DexEncodedArray的结构
};
struct DexClassData {
DexClassDataHeader header; //指定字段与方法的个数
DexField* staticFields; //静态字段
DexField* instanceFields; //实例字段
DexMethod* directMethods; //直接方法
DexMethod* virtualMethods; //虚方法
};
struct DexClassDataHeader {
uleb128 staticFieldsSize; //静态字段个数
uleb128 instanceFieldsSize; //实例字段个数
uleb128 directMethodsSize; //直接方法个数
uleb128 virtualMethodsSize; //虚方法个数
};
struct DexMethod {
uleb128 methodIdx; //指向DexMethodId的索引
uleb128 accessFlags; //访问标志
uleb128 codeOff; //指向DexCode结构的偏移
};
struct DexCode {
u2 registersSize; 使用的寄存器个数
u2 insSize; 参数个数
u2 outsSize; 调用其他方法时使用的寄存器个数
u2 triesSize; Try/Catch个数
u4 debugInfoOff; 指向调试信息的偏移
u4 insnsSize; 指令集个数, 以2字节为单位
u2 insns[1]; 指令集
//followed by optional u2 padding
//followed by try_item[triesSize]
//followed by uleb128 handlersSize
//followed by catch_handler_item[handlersSize]
};

| index | classIdx | accessFlags | superclassIdx | interfacesOff | sourceFileIdx | annotationsOff | classDataOff | staticValuesOff |
| 0 | 0x00 | 0x01 | 0x02 | 0x00 | 0x03 | 0x00 | 0x388 | 0x00 |
| 0_string | LHello; | public | Ljava/lang/Object; | no interfaces | Hello.java | no annotations |
DexClassData:

在程序中,一般使用32位比特位来表示一个整型的数值。不过,一般能够使用到的整数值都不会太大,使用32比特位来表示就有点太浪费了。对于普通计算机来说,这没什么问题,毕竟存储空间那么大。但是,对于移动设备来说,存储空间和内存空间都非常宝贵,不能浪费,能省就省。
DEX_INLINE int readUnsignedLeb128(const u1** pStream) {
const u1* ptr = *pStream;
int result = *(ptr++);
if (result > 0x7f) {
int cur = *(ptr++);
result = (result & );
if (cur > 0x7f) {
cur = *(ptr++);
result |= (cur & ;
if (cur > 0x7f) {
cur = *(ptr++);
result |= (cur & ;
if (cur > 0x7f) {
cur = *(ptr++);
result |= cur << ;
}
}
}
}
*pStream = ptr;
return result;
}
| index | staticFieldsSize | instanceFieldsSize | directMethodsSize | virtualMethodsSize |
| 0 | 0 | 0 | 3 | 0 |
通过对DexClassDataHeader的解析, 得到有3个直接方法, 后面紧跟的就是DexMethod结构,该结构中的u4也是uleb128编码的

| index | methodIdx | accessFlags | codeOff |
| 0 | 0x0 | 0x10001 | 0x1B0 |
| 0_string | void LHello;-><init>() | public|constructor | |
| 1 | 0x01 | 0x09 | 0x1C8 |
| 1_string | void LHello;->MyPrint(Ljava/lang/String;) | public|static | |
| 2 | 0x01(看010Editor解析此处也是0x01) | 0x09 | 0x210 |
| 2_string | 但是字符串描述也是下表为0x02的信息 | public|static |
DexMethod表中下标0中成员methonIdx所指向的Method信息:

| DexMethod_index | registersSize | insSize | outsSize | triesSize | debugInfoOff | insnsSize | insns |
| 0 | 0x01 | 0x01 | 0x01 | 0x00 | 0x372 | 0x04 | 0x70, 0x10, 0x05, 0x00, 0x00, 0x00, 0x0E, 0x00 |
| 1 | 0x04 | 0x01 | 0x03 | 0x00 | 0x377 | 0x1C | 0x62, 0x00, 0x00, 0x00, 0x22, 0x01, 0x04, 0x00, 0x70, 0x10, 0x06, 0x00, 0x01, 0x00, 0x6E, 0x20, 0x07, 0x00, 0x31, 0x00, 0x0C, 0x01, 0x1A, 0x02, 0x00, 0x00, 0x6E, 0x20, 0x07, 0x00, 0x21, 0x00, 0x0C, 0x01, 0x6E, 0x10, 0x08, 0x00, 0x01, 0x00, 0x0C, 0x01, 0x12, 0x02, 0x23, 0x22, 0x07, 0x00, 0x6E, 0x30, 0x03, 0x00, 0x10, 0x02, 0x0E, 0x00 |
| 2 | 0x03 | 0x01 | 0x02 | 0x00 | 0x380 | 0x0D | 0x1A, 0x00, 0x14, 0x00, 0x71, 0x10, 0x01, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x1A, 0x01, 0x02, 0x00, 0x6E, 0x20, 0x04, 0x00, 0x10, 0x00, 0x0E, 0x00 |
下面就开始解析这3个方法中每个方法的指令格式:


单独使用位标识还无法确定一条指令,必须通过指令格式标识来指定指令的格式编码。 它的约定如下:指令格式标识大多由三个字符组成,前两个是数字,最后一个是字母第一个数字是表示指令有多少个16位的字组成第二个数字是表示指令最多使用寄存器的个数。特殊标记“r”标识使用一定范围内的寄存器第三个字母为类型码,表示指令用到的额外数据的类型

















解析完dex之后我们有很多事都可以做了1、我们可以检测一个apk中是否包含了指定系统的api(当然这些api没有被混淆),同样也可以检测这个apk是否包含了广告,以前我们可以通过解析AndroidManifest.xml文件中的service,activity,receiver,meta等信息来判断,因为现在的广告sdk都需要添加这些东西,如果我们可以解析dex的话,那么我们可以得到他的所有字符串内容,就是string_ids池,这样就可以判断调用了哪些api。那么就可以判断这个apk的一些行为了,当然这里还有一个问题,假如dex加密了我们就蛋疼了。好吧,那就牵涉出第二件事了。2、我们在之前说过如何对apk进行加固,其实就是加密apk/dex文件内容,那么这时候我们必须要了解dex的文件结构信息,因为我们先加密dex,然后在动态加载dex进行解密即可3、我们可以更好的逆向工作,其实说到这里,我们看看apktool源码也知道,他内部的反编译原理就是这些,只是他会将指令翻译成smail代码,这个网上是有相对应的jar包api的,所以我们知道了dex的数据结构,那么原理肯定就知道了,同样还有一个dex2jar工具原理也是类似的4、 .....等等等等
Android Dex文件格式学习笔记pdf版下载:
链接: http://pan.baidu.com/s/1eR745Rs
密码: qqqk
Android Dex文件格式(二)的更多相关文章
- Android Dex文件格式(一)
dex是Android平台上(Dalvik虚拟机)的可执行文件, 相当于Windows平台中的exe文件, 每个Apk安装包中都有dex文件, 里面包含了该app的所有源码, 通过反编译工具可以获取到 ...
- dex文件格式二
一. dex文件头 (1) magic value 在DexFile.c dexFileParse函数中 会先检查magic opt 啥是magic opt呢? 我们刚刚从cache目录拷贝出来的 ...
- Android Dex文件格式解析
Dex文件是Android虚拟机下的可执行文件,包含了应用程序所用到所有操作指令和运行时数据.在程序编译过程中,java源文件先被编译成class文件,然后通过dx工具将多个class文件整合为一个d ...
- dex文件格式一
一.生成dex文件 我们可以通过java文件来生成一个简单的dex文件 编译过程: 首先编写java代码如下: (1) 编译成 java class 文件 执行命令 : javac Hello.jav ...
- dex文件格式学习
一.dex文件的生成 我们可以通过java文件来生成一个简单的dex文件 编译过程: 首先编写java代码如下: (1) 编译成 java class 文件 执行命令 : javac Hello.ja ...
- Android逆向之旅---解析编译之后的Dex文件格式
一.前言 新的一年又开始了,大家是否还记得去年年末的时候,我们还有一件事没有做,那就是解析Android中编译之后的classes.dex文件格式,我们在去年的时候已经介绍了: 如何解析编译之后的xm ...
- [Android Security] DEX文件格式分析
copy from : https://segmentfault.com/a/1190000007652937 0x00 前言 分析 dex 文件格式最好的方式是找个介绍文档,自己再写一个简单的 de ...
- Android反编译(二)之反编译XML资源文件
Android反编译(二) 之反编译XML资源文件 [目录] 1.工具 2.反编译步骤 3.重新编译APK 4.实例 5.装X技巧 6.学习总结 1.工具 1).反编译工具 apktool http ...
- Android Bug:Error:com.android.dex.DexException: Multiple dex files define Landroid/support/design/widget/CoordinatorLayout$LayoutParams;
项目编译通过,运行时出现异常: Error:com.android.dex.DexException: Multiple dex files define Landroid/support/desig ...
随机推荐
- Logstash5.0.X离线安装插件报错,仍然提示无法联网
本人最初将此解决方案发布在 ELK中文社区 http://elasticsearch.cn/question/1046 由于生产环境无法连接互联网,所有再一台联网机器上将所有插件做了 pack 拖到生 ...
- iptables删除规则
查看nat规则: iptables -t nat -nL --line-number 添加规则是-A和-I,-A是添加到末尾,-I是添加到指定位置,默认添加到最前面.删除使用-D,也就是原来“ipta ...
- Github-素材篇
my github: http://github.com/yaochao
- 现代工程仿真CAE技术介绍
随着现代科学技术的发展,人们正在不断建造更为快速的交通工具.更大规模的建筑物.更大跨度的桥梁.更大功率的发电机组和更为精密的机械设备.这一切都要求工程师在设计阶段就能精确地预测出产品和工程的技术性能, ...
- 【小错误】ORA-00265: instance recovery required, cannot set ARCHIVELOG mode
1.错误描述:今天在起归档的时候报一下错误: SQL> alter database archivelog; alter database archivelog * ERROR at line ...
- JAVA新手笔记 Intent对象和Bundle对象
Intent对象和Bundle对象 功能主要是在 MainActivity中定义了2个EditText,当用户输入内容,把他传入到第二个活动, 自己新创的活动中,MyActivity中 放在MainA ...
- 用jquery解析JSON数据的方法以及字符串转换成json的3种方法
用jquery解析JSON数据的方法,作为jquery异步请求的传输对象,jquery请求后返回的结果是 json对象,这里考虑的都是服务器返回JSON形式的字符串的形式,对于利用JSONObject ...
- 基于springmvc和restClient的rest服务的测试
在开发中,不熟悉驱动驱动测试开发的coder往往喜欢将服务应用启动以后测试,对于GET请求可以直接在浏览器中输入URL就可以,参数非中文可以直接追加到URL后.但是,对于其他请求方式的测试必须借助相应 ...
- 这是个简单的UTF8转码的小Demo
NSString *name = @"你好啊"; NSString *string = [NSString stringWithFormat:@"%@",nam ...
- html尖角提示框的实现
<style type="text/css"> .box { background-color: #bebf22; ...