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


一、dex文件

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



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


二、dex文件头各字段解析

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

  1. magic:包含了dex文件标识符以及版本,从0x00开始,长度为8个字节
  2. checksum:dex文件校验码,偏移量为:0x08,长度为4个字节。
  3. signature:dex sha-1签名,偏移量为0x0c,长度为20个字节
  4. file_szie:dex文件大小,偏移量为0x20,长度为4个字节
  5. header_size:dex文件头大小,偏移量为0x24,长度为4个字节,一般为0x70
  6. endian_tag:dex文件判断字节序是否交换,偏移量为0x28,长度为4个字节,一般情况下为0x78563412
  7. link_size:dex文件链接段大小,为0则表示为静态链接,偏移量为0x2c,长度为4个字节
  8. link_off:dex文件链接段偏移位置,偏移量为0x30,长度为4个字节
  9. map_off:dex文件中map数据段偏移位置,偏移位置为0x34,长度为4个字节
  10. string_ids_size:dex文件包含的字符串数量,偏移量为0x38,长度为4个字节
  11. string_ids_off:dex文件字符串开始偏移位置,偏移量为0x3c,长度为4个字节
  12. type_ids_size:dex文件类数量,偏移量为0x40,长度为4个字节
  13. type_ids_off:dex文件类偏移位置,偏移量为0x44,长度为4个字节
  14. photo_ids_size:dex文件中方法原型数量,偏移量为0x48,长度为4个字节
  15. photo_ids_off:dex文件中方法原型偏移位置,偏移量为0x4c,长度为4个字节
  16. field_ids_size:dex文件中字段数量,偏移量为0x50,长度为4个字节
  17. field_ids_off:dex文件中字段偏移位置,偏移量为0x54,长度为4个字节
  18. method_ids_size:dex文件中方法数量,偏移量为0x58,长度为4个字节
  19. method_ids_off:dex文件中方法偏移位置,偏移量为0x5c,长度为4个字节
  20. class_defs_size:dex文件中类定义数量,偏移量为0x60,长度为4个字节
  21. class_defs_off:dex文件中类定义偏移位置,偏移量为0x64,长度为4个字节
  22. data_size:dex数据段大小,偏移量为0x68,长度为4个字节
  23. 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()

五、相关链接

  参考链接

  某作者github链接(相关附件下载):https://github.com/windy-purple/parserDex

  PS:部分图片来自于网络,侵删

DEX文件解析---1、dex文件头解析的更多相关文章

  1. JPEG解码——(3)文件头解析

    与具体的编码数据空间相比,jpeg文件头占据非常小乃至可以忽略不计的大小. 仍然拿JPEG解码--(1)JPEG文件格式概览中的<animal park>这张图片来举例,从跳过SOS(FF ...

  2. Activiti-5.3工作流引擎-源码解析(流程文档解析)

    前面我们通过BPMN20.xsd和Activiti自定义的XML Schema文件初步了解了业务流程模型的定义,那么现在我们来了解一下流程文档的解析过程,这个过程主要是通过代码解析来完成. 代码解析过 ...

  3. wav音频文件头解析

    wav概述 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(ResourceInterchange File Format)文件规范,用于保存Windows平台的音频信息 ...

  4. 设置Pycharm在创建py文件时自动添加文件头注释(类似于钩子特性)

    在每次新建一个py文件的时候 1 如何自动添加 #!/usr/bin/env python2 自动添加       #-*- coding: utf-8 -*- 操作方法: File -> se ...

  5. 读写UTF-8、Unicode文件(加上了文件头,貌似挺好用)

    conf配置文件一些为UTF-8和Unicode格式,这样便可良好的支持多语言,从网上查阅资料后,将读写UTF-8.Unicode文件写了几个最精简的函数,更新后加了是否写文件头的功能,以适应更多需要 ...

  6. Pycharm在创建py文件时,自动添加文件头注释

    依次File -> Settings -> Editor -> File and Code Templates -> Python Script   添加以下代码: # -*- ...

  7. DEX文件解析--7、类及其类数据解析(完结篇)

    一.前言    前置技能链接:       DEX文件解析---1.dex文件头解析       DEX文件解析---2.Dex文件checksum(校验和)解析       DEX文件解析--3.d ...

  8. DEX文件解析--3、dex文件字符串解析

    一.前言    前两篇文章链接:     1.DEX文件头解析     2.DEX文件校验和解析    PS:前几天检查文件夹的时候发现DEX文件解析还只写了开头,正好找点事情来做,就去接着解析DEX ...

  9. DEX文件解析--4、dex类的类型解析

    一.前言   前几篇系列文章链接:     DEX文件解析---1.dex文件头解析     DEX文件解析---2.Dex文件checksum(校验和)解析     DEX文件解析--3.dex文件 ...

随机推荐

  1. [HDU2294] Pendant - 矩阵加速递推

    Pendant Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  2. openssl之aes对称加密

    AES:密码学中的高级加密标准(Advanced Encryption Standard,AES),又称 Rijndael加密法. 对称加密:用同一个密码  加密/解密  文件. 使用openssl中 ...

  3. Libevent::evhttp服务器

    #include <cstdio> #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  4. 【OUC2019写作】学术论文写作第九小组第一次博客作业

    个人简介 潘旻琦:我是潘旻琦:我的爱好是游泳:羊肉泡馍是海大食堂中我最喜欢的一道菜(清真食堂):一句想说的话是:“追随本心,坚持不懈”. 郭念帆:我是郭念帆:我的爱好是足球:海大食堂中最喜欢的一道菜偏 ...

  5. 【阿里云IoT+YF3300】6.物联网设备报警配置

    纵然5G时代已经在时代的浪潮中展现出了它的身影,但是就目前的物联网环境中,网络问题仍旧是一个比较突出的硬伤.众所周知,在当前的物联网规划中,与其说是实现万物互联,倒不如说是行业指标数据监控.对于一些特 ...

  6. if-elif-else分支判断语句(附加continue和break)---举例说明

    一.分支循环语句: a=input("请输入一个五位数字") if(len(a)!=5): print("输入的数字不合格"); elif(a[0::]==a[ ...

  7. 再不努力提高效率,小姐姐都被人追走了:K8S一键部署了解一下?

    随着互联网时代的不断发展,开发者可能会面临这样的困境:为了解决问题.提升开发效率而竭力研发出来的"创新",似乎削弱了他们在公司的重要程度,甚至取代了他们原先的地位.比如,在云原生时 ...

  8. 是可忍孰不可忍!!nodepad++作者台独分子,恶毒言论!!!

    本来用了两年这个软件吧,不带任何情感的,单纯辅助工具.直到今天,在GitHub上,发现了这个作者以及一些同党都是一群尼玛生在中国骂中国的狗币. https://github.com/notepad-p ...

  9. 编程语言分类 + python解释器的安装 + jupyter的使用(day 02整理)

    目录 一.昨日内容回顾 一 计算机基础之编程 (一) 什么是编程语言 (二) 什么是编程 (三) 为什么编程 二 计算机组成 (一) CPU (二) 存储器 (三) I/O设备 (四) 多核CPU ( ...

  10. Shell进阶精品课程

    课程链接 Shell精品进阶教程:理解Shell的方方面面 课程目标 系统性的掌握shell相关知识,进阶shell脚本能力,对shell各方面了然于心 适用人群 具备shell基础但想深入.系统性掌 ...