• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android逆向之旅---解析编译之后的Dex文件格式

Android逆向之旅---解析编译之后的Dex文件格式

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android dex,android dex分包方案,android dex分包,android dex文件,android dex2jar等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android逆向之旅---解析编译之后的Dex文件格式


一、前言

新的一年又开始了,大家是否还记得去年年末的时候,我们还有一件事没有做,那就是解析Android中编译之后的classes.dex文件格式,我们在去年的时候已经介绍了:

如何解析编译之后的xml文件格式:

http://blog.csdn.net/jiangwei0910410003/article/details/50568487

如何解析编译之后的resource.arsc文件格式:

http://blog.csdn.net/jiangwei0910410003/article/details/50628894

那么我们还剩下一个文件格式就是classes.dex了,那么今天我们就来看看最后一个文件格式解析,关于Android中的dex文件的相关知识这里就不做太多的解释了,网上有很多资料可以参考,而且,我们在之前介绍的一篇加固apk的那篇文章中也介绍了一点dex的格式知识点:http://blog.csdn.net/jiangwei0910410003/article/details/48415225,我们按照之前的解析思路来,首先还是来一张神图:

\

有了这张神图,那么接下来我们就可以来介绍dex的文件结构了,首先还是来看一张大体的结构图:

\

 

二、准备工作

我们在讲解数据结构之前,我们需要先创建一个简单的例子来帮助我们来解析,我们需要得到一个简单的dex文件,这里我们不借助任何的IDE工具,就可以构造一个dex文件出来。借助的工具很简单:javac,dx命令即可。

创建 java 源文件 ,内容如下
代码:
public class Hello
{
public static void main(String[] argc)
{
System.out.println("Hello, Android!\n");
}
}

在当前工作路径下 , 编译方法如下 :
(1) 编译成 java class 文件
执行命令 : javac Hello.java
编译完成后 ,目录下生成 Hello.class 文件 。可以使用命令 java Hello 来测试下 ,会输出代码中的 “Hello, Android!” 的字符串 。
(2) 编译成 dex 文件
编译工具在 Android SDK 的路径如下 ,其中 19.0.1 是Android SDK build_tools 的版本 ,请按照在本地安装的 build_tools 版本来 。建议该路径加载到 PATH 路径下 ,否则引用 dx 工具时需要使用绝对路径 :./build-tools/19.0.1/dx
执行命令 :dx --dex --output=Hello.dex Hello.class
编译正常会生成 Hello.dex 文件 。
3. 使用 ADB 运行测试
测试命令和输出结果如下 :
$ adb root
$ adb push Hello.dex /sdcard/
$ adb shell
root@maguro:/ # dalvikvm -cp /sdcard/Hello.dex Hello
Hello, Android!

4. 重要说明
(1) 测试环境使用真机和 Android 虚拟机都可以的 。核心的命令是
dalvikvm -cp /sdcard/Hello.dex Hello
-cp 是 class path 的缩写 ,后面的 Hello 是要运行的 Class 的名称 。网上有描述说输入 dalvikvm --help
可以看到 dalvikvm 的帮助文档 ,但是在 Android4.4 的官方模拟器和自己的手机上测试都提示找不到
Class 路径 ,在Android 老的版本 ( 4.3 ) 上测试还是有输出的 。
(2) 因为命令在执行时 , dalvikvm 会在 /data/dalvik-cache/ 目录下创建 .dex 文件 ,因此要求 ADB 的
执行 Shell 对目录 /data/dalvik-cache/ 有读、写和执行的权限 ,否则无法达到预期效果 。

三、讲解数据结构

下面我们按照这张大体的思路图来一一讲解各个数据结构

第一、头部信息Header结构

dex文件里的header。除了描述.dex文件的文件信息外,还有文件里其它各个区域的索引。header对应成结构体类型,逻辑上的描述我用结构体header_item来理解它。先给出结构体里面用到的数据类型ubyte和uint的解释,然后再是结构体的描述,后面对各种结构描述的时候也是用的这种方法。

代码定义:

 

package com.wjdiankong.parsedex.struct;

import com.wjdiankong.parsedex.Utils;

public class HeaderType {
	
	/**
	 * struct header_item
		{
		ubyte[8] magic;
		unit checksum;
		ubyte[20] siganature;
		uint file_size;
		uint header_size;
		unit endian_tag;
		uint link_size;
		uint link_off;
		uint map_off;
		uint string_ids_size;
		uint string_ids_off;
		uint type_ids_size;
		uint type_ids_off;
		uint proto_ids_size;
		uint proto_ids_off;
		uint method_ids_size;
		uint method_ids_off;
		uint class_defs_size;
		uint class_defs_off;
		uint data_size;
		uint data_off;
		}
	 */
	public byte[] magic = new byte[8];
	public int checksum;
	public byte[] siganature = new byte[20];
	public int file_size;
	public int header_size;
	public int endian_tag;
	public int link_size;
	public int link_off;
	public int map_off;
	public int string_ids_size;
	public int string_ids_off;
	public int type_ids_size;
	public int type_ids_off;
	public int proto_ids_size;
	public int proto_ids_off;
	public int field_ids_size;
	public int field_ids_off;
	public int method_ids_size;
	public int method_ids_off;
	public int class_defs_size;
	public int class_defs_off;
	public int data_size;
	public int data_off;
	
	@Override
	public String toString(){
		return "magic:"+Utils.bytesToHexString(magic)+"\n"
				+ "checksum:"+checksum + "\n"
				+ "siganature:"+Utils.bytesToHexString(siganature) + "\n"
				+ "file_size:"+file_size + "\n"
				+ "header_size:"+header_size + "\n"
				+ "endian_tag:"+endian_tag + "\n"
				+ "link_size:"+link_size + "\n"
				+ "link_off:"+Utils.bytesToHexString(Utils.int2Byte(link_off)) + "\n"
				+ "map_off:"+Utils.bytesToHexString(Utils.int2Byte(map_off)) + "\n"
				+ "string_ids_size:"+string_ids_size + "\n"
				+ "string_ids_off:"+Utils.bytesToHexString(Utils.int2Byte(string_ids_off)) + "\n"
				+ "type_ids_size:"+type_ids_size + "\n"
				+ "type_ids_off:"+Utils.bytesToHexString(Utils.int2Byte(type_ids_off)) + "\n"
				+ "proto_ids_size:"+proto_ids_size + "\n"
				+ "proto_ids_off:"+Utils.bytesToHexString(Utils.int2Byte(proto_ids_off)) + "\n"
				+ "field_ids_size:"+field_ids_size + "\n"
				+ "field_ids_off:"+Utils.bytesToHexString(Utils.int2Byte(field_ids_off)) + "\n"
				+ "method_ids_size:"+method_ids_size + "\n"
				+ "method_ids_off:"+Utils.bytesToHexString(Utils.int2Byte(method_ids_off)) + "\n"
				+ "class_defs_size:"+class_defs_size + "\n"
				+ "class_defs_off:"+Utils.bytesToHexString(Utils.int2Byte(class_defs_off)) + "\n"
				+ "data_size:"+data_size + "\n"
				+ "data_off:"+Utils.bytesToHexString(Utils.int2Byte(data_off));
				
				
	}

}

 

查看Hex如下:

\

我们用一张图来描述各个字段的长度:

\
里面一对一对以_size和_off为后缀的描述:data_size是以Byte为单位描述data区的大小,其余的
_size都是描述该区里元素的个数;_off描述相对与文件起始位置的偏移量。其余的6个是描述.dex文件信
息的,各项说明如下:
(1) magic value
这 8 个 字节一般是常量 ,为了使 .dex 文件能够被识别出来 ,它必须出现在 .dex 文件的最开头的
位置 。数组的值可以转换为一个字符串如下 :
{ 0x64 0x65 0x78 0x0a 0x30 0x33 0x35 0x00 }= "dex\n035\0"
中间是一个 ‘\n' 符号 ,后面 035 是 Dex 文件格式的版本 。
(2) checksum 和 signature
文件校验码 ,使用alder32 算法校验文件除去 maigc ,checksum 外余下的所有文件区域 ,用于检
查文件错误 。
signature , 使用 SHA-1 算法 hash 除去 magic ,checksum 和 signature 外余下的所有文件区域 ,
用于唯一识别本文件 。
(3) file_size
Dex 文件的大小 。
(4) header_size
header 区域的大小 ,单位 Byte ,一般固定为 0x70 常量 。
(5) endian_tag
大小端标签 ,标准 .dex 文件格式为 小端 ,此项一般固定为 0x1234 5678 常量 。

(6) link_size和link_off

这个两个字段是表示链接数据的大小和偏移值

(7) map_off

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android DEX 基础,androiddex基础
  • Android动态加载Dex机制解析
  • Android热补丁技术—dexposed原理简析(手机淘宝采用方案)
  • Android逆向之旅---解析编译之后的Dex文件格式

相关文章

  • 2017-05-221.0 Android基础入门教程
  • 2017-05-26Android开发学习——Android项目的目录结构,android项目
  • 2017-05-26Android中使用java.util.Properties犯的错,utilproperties
  • 2017-05-26Android,androidstudio
  • 2017-05-26Android中Fragment与Activity之间的交互(两种实现方式),androidfragment
  • 2017-05-26《转》深入理解Activity启动流程(一)–Activity启动的概要流程,《转》activity
  • 2017-05-26Android 动画资源 详解
  • 2017-05-26android toolbar 假标题居中,androidtoolbar
  • 2017-05-26谷歌电子市场5--推荐,谷歌电子市场5--
  • 2017-05-26PendingIntent 显示通知,pendingintent通知

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 基于PGPool的1主2从PostgreSQL流复制HA的搭建
    • android6.0 adbd深入分析(二)adb驱动数据的处理、写数据到adb驱动节点
    • andriod arcgis加载影像TIF,andriodarcgis
    • Android必知必会-使用okhttp的PUT方式上传文件
    • 安卓6.0(棉花糖)新特性汇总,安卓6.0
    • Android基础部分再学习---activity的状态保存
    • Android 之 图片压缩
    • android插件开发-就是你了!启动吧!插件的activity(二)
    • Android MotionEvent详解
    • 谷歌电子市场5--推荐,谷歌电子市场5--

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有