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 ...
随机推荐
- .net 环境下get 获取页面出现乱码问题解决
不多说了,先上代码: /// <summary> /// 获取页面内容 /// </summary> /// <param name="Url"> ...
- jQuery MiniUI开发系列之:创建组件对象
jQuery MiniUI可以使用Javascript和Html两种方式来创建对象. 1)Javascript创建对象 使用JavaScript创建对象,是最基本的方式,有如下几个要点: 1)使用ne ...
- Windows Update 时出现8024402C的错误
8024402C通常网络设置引起的问题. 你可以以管理员身份运行命令提示符,然后尝试以下操作: NETSH INT IP RESET NETSH WINHTTP RESET PROXY IPCONFI ...
- 转WCF Proxy Authentication Required
WCF Proxy Authentication Required The Problem When I’m in the office, I have to use an authenticated ...
- flex acionscript png图片去除多余空白,生成合适大小图片
//最小矩形(非透明最小区域) public static function getMinRect(target:BitmapData):Rectangle{ return target.getC ...
- 统计在从1到n的正整数中1出现的次数
问题: 给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有“1”的个数. 例如:N= 2,写下1,2.这样只出现了1个“1”. N= 12,我们会写下1, 2, 3, 4, ...
- Python体验(07)-图形界面之菜单
顺序安装以下程序: python解释器:https://www.python.org/downloads/ wxPython图形界面框架包:http://www.wxpython.org/ pycha ...
- xampp下创建多个虚拟网站目录
大家知道,伟大的IIS下面增加多个网站就1分钟搞定.现在换XAMPP下运行多个PHP目录,那我们需要有点探索精神.那么进入正题 首先,下载安装官方最新版本的xampp,地址:点击.记得如果电脑安装有I ...
- webApi上传下载文件
上传文件通过webApi html端调用时包含(form提交包含 enctype="multipart/form-data",才可以启作用获取到文件) public class U ...
- avalon源码分析(转)
avalon源码分析目录 第一篇 : 关于前端的MVVM架构 第二篇 : 初步接触 第三篇 : 执行流程1 第四篇 : 执行流程2 第五篇 : 整体架构 第六篇 : ViewModel 第七篇 : ...