DEX文件解析---1、dex文件头解析

一、dex文件

dex文件是Android平台上可执行文件的一种文件类型。它的文件格式可以下面这张图概括:

dex文件头一般固定为0x70个字节大小,包含标志、版本号、校验码、sha-1签名以及其他一些方法、类的数量和偏移地址等信息。如下图所示:

二、dex文件头各字段解析

dex文件头包含以下各个字段:

magic:包含了dex文件标识符以及版本,从0x00开始,长度为8个字节

checksum:dex文件校验码,偏移量为:0x08,长度为4个字节。

signature:dex sha-1签名,偏移量为0x0c,长度为20个字节

file_szie:dex文件大小,偏移量为0x20,长度为4个字节

header_size:dex文件头大小,偏移量为0x24,长度为4个字节,一般为0x70

endian_tag:dex文件判断字节序是否交换,偏移量为0x28,长度为4个字节,一般情况下为0x78563412

link_size:dex文件链接段大小,为0则表示为静态链接,偏移量为0x2c,长度为4个字节

link_off:dex文件链接段偏移位置,偏移量为0x30,长度为4个字节

map_off:dex文件中map数据段偏移位置,偏移位置为0x34,长度为4个字节

string_ids_size:dex文件包含的字符串数量,偏移量为0x38,长度为4个字节

string_ids_off:dex文件字符串开始偏移位置,偏移量为0x3c,长度为4个字节

type_ids_size:dex文件类数量,偏移量为0x40,长度为4个字节

type_ids_off:dex文件类偏移位置,偏移量为0x44,长度为4个字节

photo_ids_size:dex文件中方法原型数量,偏移量为0x48,长度为4个字节

photo_ids_off:dex文件中方法原型偏移位置,偏移量为0x4c,长度为4个字节

field_ids_size:dex文件中字段数量,偏移量为0x50,长度为4个字节

field_ids_off:dex文件中字段偏移位置,偏移量为0x54,长度为4个字节

method_ids_size:dex文件中方法数量,偏移量为0x58,长度为4个字节

method_ids_off:dex文件中方法偏移位置,偏移量为0x5c,长度为4个字节

class_defs_size:dex文件中类定义数量,偏移量为0x60,长度为4个字节

class_defs_off:dex文件中类定义偏移位置,偏移量为0x64,长度为4个字节

data_size:dex数据段大小,偏移量为0x68,长度为4个字节

data_off:dex数据段偏移位置,偏移量为0x6c,长度为4个字节

三、dex文件头代码解析示例(python)

dex使用open函数以二进制打开文件,然后使用seek函数移动文件指针,例如magic就是f.seek(0x00),然后读取相应信息的字节数即可,例如读取版本号f.seek(0x04) f.read(4),然后做相应打印操作就行,dex文件头较简单,不涉及编码等,所以解析起来感觉脑子都不用带。。。。。具体代码可以看下面或者github,下面附上代码运行图:

四、dex文件头解析实现代码(python实现)

import binascii

def parserHeader(f):

f.seek(0x00)

magic_mask = f.read(4)

magic_mask = binascii.b2a_hex(magic_mask)

magic_mask = str(magic_mask,encoding='utf-8')

print('文件标识符: ',end='')

print(magic_mask)

f.seek(0x04)

magic_version = f.read(4)

magic_version = binascii.b2a_hex(magic_version)

magic_version = str(magic_version,encoding='utf-8')

print('文件版本: ',end='')

print(magic_version)

f.seek(0x08)

checksum = f.read(4)

checksum = binascii.b2a_hex(checksum)

checksum = str(checksum,encoding='utf-8')

print('校验码: ',end='')

print(checksum)

f.seek(0x0c)

signature = f.read(20)

signature = binascii.b2a_hex(signature)

signature = str(signature,encoding='utf-8')

print('SHA-1签名: ',end='')

print(signature)

f.seek(0x20)

file_size = f.read(4)

a = bytearray(file_size)

a.reverse()

file_size = bytes(a)

file_size = binascii.b2a_hex(file_size)

file_size = str(file_size,encoding='utf-8')

print('文件大小: ',end='')

print(int(file_size,16),end='')

print(' byte')

f.seek(0x24)

header_size = f.read(4)

a = bytearray(header_size)

a.reverse()

header_size = bytes(a)

header_size = binascii.b2a_hex(header_size)

header_size = str(header_size,encoding='utf-8')

print('文件头大小: ',end='')

print(int(header_size,16),end='')

print(' byte')

f.seek(0x28)

endian_tag = f.read(4)

endian_tag = binascii.b2a_hex(endian_tag)

endian_tag = str(endian_tag,encoding='utf-8')

print('字节序交换标志: ',end='')

print(endian_tag)

f.seek(0x2c)

link_size = f.read(4)

a = bytearray(link_size)

a.reverse()

link_size = bytes(a)

link_size = binascii.b2a_hex(link_size)

link_size = str(link_size,encoding='utf-8')

print('链接段大小: ',end='')

print(int(link_size,16),end='')

print(' byte')

f.seek(0x30)

link_off = f.read(4)

a = bytearray(link_off)

a.reverse()

link_off = bytes(a)

link_off = binascii.b2a_hex(link_off)

link_off = str(link_off,encoding='utf-8')

print('链接段偏移位置: ',end='')

print(hex(int(link_off,16)))

f.seek(0x34)

map_off = f.read(4)

a = bytearray(map_off)

a.reverse()

map_off = bytes(a)

map_off = binascii.b2a_hex(map_off)

map_off = str(map_off,encoding='utf-8')

print('map数据偏移位置: ',end='')

print(hex(int(map_off,16)))

f.seek(0x38)

stringidsSize = f.read(4)

a = bytearray(stringidsSize)

a.reverse()

stringidsSize = bytes(a)

stringidsSize = binascii.b2a_hex(stringidsSize)

stringidsSize = str(stringidsSize,encoding='utf-8')

print('字符串数量: ',end='')

print(int(stringidsSize,16),end='')

print('(',end='')

print(hex(int(stringidsSize,16)),end='')

print(')')

f.seek(0x3c)

string_ids_off = f.read(4)

a = bytearray(string_ids_off)

a.reverse()

string_ids_off = bytes(a)

string_ids_off = binascii.b2a_hex(string_ids_off)

string_ids_off = str(string_ids_off,encoding='utf-8')

print('字符串偏移位置: ',end='')

print(hex(int(string_ids_off,16)))

f.seek(0x40)

type_ids_size = f.read(4)

a = bytearray(type_ids_size)

a.reverse()

type_ids_size = bytes(a)

type_ids_size = binascii.b2a_hex(type_ids_size)

type_ids_size = str(type_ids_size,encoding='utf-8')

print('类数量: ',end='')

print(int(type_ids_size,16),end='')

print('(',end='')

print(hex(int(type_ids_size,16)),end='')

print(')')

f.seek(0x44)

type_ids_off = f.read(4)

a = bytearray(type_ids_off)

a.reverse()

type_ids_off = bytes(a)

type_ids_off = binascii.b2a_hex(type_ids_off)

type_ids_off = str(type_ids_off,encoding='utf-8')

print('类偏移位置: ',end='')

print(hex(int(type_ids_off,16)))

f.seek(0x48)

photo_ids_size = f.read(4)

a = bytearray(photo_ids_size)

a.reverse()

photo_ids_size = bytes(a)

photo_ids_size = binascii.b2a_hex(photo_ids_size)

photo_ids_size = str(photo_ids_size,encoding='utf-8')

print('方法原型数量: ',end='')

print(int(photo_ids_size,16),end='')

print('(',end='')

print(hex(int(photo_ids_size,16)),end='')

print(')')

f.seek(0x4c)

photo_ids_off = f.read(4)

a = bytearray(photo_ids_off)

a.reverse()

photo_ids_off = bytes(a)

photo_ids_off = binascii.b2a_hex(photo_ids_off)

photo_ids_off = str(photo_ids_off,encoding='utf-8')

print('方法原型偏移位置: ',end='')

print(hex(int(photo_ids_off,16)))

f.seek(0x50)

field_ids_size = f.read(4)

a = bytearray(field_ids_size)

a.reverse()

field_ids_size = bytes(a)

field_ids_size = binascii.b2a_hex(field_ids_size)

field_ids_size = str(field_ids_size,encoding='utf-8')

print('字段数量: ',end='')

print(int(field_ids_size,16),end='')

print('(',end='')

print(hex(int(field_ids_size,16)),end='')

print(')')

f.seek(0x54)

field_ids_off = f.read(4)

a = bytearray(field_ids_off)

a.reverse()

field_ids_off = bytes(a)

field_ids_off = binascii.b2a_hex(field_ids_off)

field_ids_off = str(field_ids_off,encoding='utf-8')

print('字段偏移位置: ',end='')

print(hex(int(field_ids_off,16)))

f.seek(0x58)

method_ids_size = f.read(4)

a = bytearray(method_ids_size)

a.reverse()

method_ids_size = bytes(a)

method_ids_size = binascii.b2a_hex(method_ids_size)

method_ids_size = str(method_ids_size,encoding='utf-8')

print('方法数量: ',end='')

print(int(method_ids_size,16),end='')

print('(',end='')

print(hex(int(method_ids_size,16)),end='')

print(')')

f.seek(0x5c)

method_ids_off = f.read(4)

a = bytearray(method_ids_off)

a.reverse()

method_ids_off = bytes(a)

method_ids_off = binascii.b2a_hex(method_ids_off)

method_ids_off = str(method_ids_off,encoding='utf-8')

print('方法偏移位置: ',end='')

print(hex(int(method_ids_off,16)))

f.seek(0x60)

class_defs_size = f.read(4)

a = bytearray(class_defs_size)

a.reverse()

class_defs_size = bytes(a)

class_defs_size = binascii.b2a_hex(class_defs_size)

class_defs_size = str(class_defs_size,encoding='utf-8')

print('类定义数量: ',end='')

print(int(class_defs_size,16),end='')

print('(',end='')

print(hex(int(class_defs_size,16)),end='')

print(')')

f.seek(0x64)

class_defs_off = f.read(4)

a = bytearray(class_defs_off)

a.reverse()

class_defs_off = bytes(a)

class_defs_off = binascii.b2a_hex(class_defs_off)

class_defs_off = str(class_defs_off,encoding='utf-8')

print('类定义偏移位置: ',end='')

print(hex(int(class_defs_off,16)))

f.seek(0x68)

data_size = f.read(4)

a = bytearray(data_size)

a.reverse()

data_size = bytes(a)

data_size = binascii.b2a_hex(data_size)

data_size = str(data_size,encoding='utf-8')

print('数据段大小: ',end='')

print(int(data_size,16),end='')

print('(',end='')

print(hex(int(data_size,16)),end='')

print(')')

f.seek(0x6c)

data_off = f.read(4)

a = bytearray(data_off)

a.reverse()

data_off = bytes(a)

data_off = binascii.b2a_hex(data_off)

data_off = str(data_off,encoding='utf-8')

print('数据段偏移位置: ',end='')

print(hex(int(data_off,16)))

if __name__ == '__main__':

f = open("C:\\Users\\admin\\Desktop\\android_nx\\classes.dex", 'rb', True)

parserHeader(f)

f.close()

五、相关链接

参考链接

android内部dex解析,DEX文件解析---1、dex文件头解析相关推荐

  1. 解析Markdown文件生成React组件文档

    前言 最近做的项目使用了微前端框架single-spa. 对于这类微前端框架而言,通常有个utility应用,也就是公共应用,里面是各个子应用之间可以共用的一些公共组件或者方法. 对于一个团队而言,项 ...

  2. 记:ELF文件解析初定义——文件头解析

    0x00 概论 因为TI的DSP输出文件与传统的ELF文件不符,所以本人就顺道研究了一下现在的ELF的文件格式. 会将其陆续完成在文章中. 阅读本文之前,您需要掌握的技能有: 技能名称 技能熟练度 技 ...

  3. VC++ MSXML创建XML文件以及对XML文档解析

    VC++ MSXML创建XML文件以及对XML文档解析 转自http://www.newxing.com/Tech/Program/Cpp/703.html // XmlCreationDemo.cp ...

  4. java解析xml文件的几种方式(DOM解析)

    好久不用的东西,今天居然被面试官问到了.那既然这样,我们就一起回顾下java解析xml文件的几种方式吧. DOM解析 dom解析所需依赖是我们jdk自带的,所以只需要使用jdk为我们提供的接口即可上手 ...

  5. 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | 文件头 Header 分析 | 标签 Tag 分析 | 视频标签 Tag 数据分析 )

    文章目录 安卓直播推流专栏博客总结 一. RTMP 格式解析 二. 文件头 Header 分析 三. 标签 Tag 分析 四. 视频标签 Tag 数据分析 安卓直播推流专栏博客总结 Android R ...

  6. ART世界探险(12) - OAT文件分析(2) - ELF文件头分析(中)

    ART世界探险(12) - OAT文件分析(2) - ELF文件头分析(中) 段(section)的概念 一块内存分配给应用程序之后,从代码的组织上,我们就有将它们分段的需求. 比如,可以分为代码段, ...

  7. 使用Android内部的DownloadProvider下载文件,并获取cache权限 .

    Android内部提供了一个DownloadProvider,是一个非常完整的下载工具,提供了很好的外部接口可以被其他 应用程序调用,来完成下载工作.同时也提供和很好的下载.通知.存储等机制. 在An ...

  8. python解析sql文件_如何从Python中解析sql文件?

    是否有任何方法可以从Python中执行.SQL文件中的某些SQL命令,而不是文件中的所有SQL命令?假设我有以下.sql文件:DROP TABLE IF EXISTS `tableA`; CREATE ...

  9. java 解析 svg文件_java – 如何加载和解析SVG文档

    概观 使用Apache Batik加载和解析SVG文件.该解决方案在将SVG文件转换为MetaPost的初步阶段显示Java代码.这应该提供有关如何使用Java从SVG文件加载,解析和提取内容的一般概 ...

  10. 视频文件头解析--mkv

    MKV 的文件格式的目标是,成为多媒休包容格式的标准.它基于EBML(扩展二进制多媒体语言).与XML标记语言有点相似. EBML是类似于XML那样的层次化结构,每一个元素都有它的ID(就是元素名)和 ...

最新文章

  1. 题目1460:Oil Deposit
  2. R语言aggregate函数数据聚合实战
  3. JUC系列(五)| Synchonized关键字进一步理解
  4. redis的学习使用,第四章
  5. 第18章 Linux集群架构
  6. python小练习—名片管理系统(增、删、改、查、数据本地保存)
  7. php json字符串转json对象一直出错,显示空
  8. Java第二节课总结
  9. 【转】一个小妙招能让你在服装上省下好多rmb
  10. cognos oracle sql,Cognos联接Oracle数据库
  11. 5304—K3 Cloud 自定义webAPI
  12. html表格里面嵌入按钮,bootstarp-table表格中嵌套多个BUTON按钮实现
  13. 解决电脑输入法无法切换的问题
  14. python怎么让图片旋转45度_python – 有没有办法将matplotlib图旋转45度?
  15. java fillrect_Java graphics2D fillRect无法使用半透明颜色正常...
  16. 腾达路由器登录远端服务器无响应,腾达路由器 192.168.0.1(tendawifi.com)打不开,怎么办?...
  17. word 2016 无法输入中文 输入法失效 只能输入英文
  18. 李章最帅!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  19. 2018版 主流SDR设备横向比较
  20. vmware时间不同步的问题

热门文章

  1. 苹果手机怎么投影到墙上_手机怎么投屏到投影仪上?这篇图文教程教你轻松搞定...
  2. dB,dBm W之换算关系
  3. dbfs和dbm的换算_dB 、dBm、dBuv的概念及换算
  4. 行为树 --- [3] BehaviorTree.CPP在Windows下的使用(基于VSCode)
  5. pdf打印机如何加密pdf文件?
  6. Mugeda(木疙瘩)H5案例课—世界名画抖抖抖起来了-岑远科-专题视频课程
  7. 公司年会抽奖的一个java实现
  8. python xlwt_Python xlwt导出excel完整版
  9. 阿铭Linux_网站维护学习笔记201903019
  10. h5算命php源码,H5付费算命PHP源码那么火_付费算命源码如何下载