请勿转载,谢谢!!!

连续半个月重感冒和咳嗽,这个时候才倍感身体的重要。

所以身体才是革命的本钱啊。。。

言归正传。

编码格式uleb128

先介绍下dex中用到的一种编码方式uleb128。

简单来说,它是对int(4字节)数据的一个可变长度编码,使得原先固定长度(4字节)的数据,可以通过更少的字节表示出来;而且这个可变长度不超过5。

假定有数据序列:a b c d e,我们把它们用二进制表示出来:

aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee

如果每字节的高位开头是1,那么继续往后;如果高位开头是0,那么终止在这里;然后把所有的高位都去除,反序拼出来的二进制,就是最后的结果。

比如这样的:

1aaaaaaa 1bbbbbbb 1ccccccc 0ddddddd eeeeeeee

一直到第4个,它是以0为高位开头的,那么这个有效数据就是前四个字节组成,并且反序如下:

ddddddd ccccccc bbbbbbb aaaaaaa

如上,第一是反序,第二是每个字节只有7位。

这个就是简单的uleb128的示范。

解码程序如下:

uleb128解码

数据结构

类信息

其中classDataOff是指向类数据信息区域的一个偏移数值。

类数据信息

从这里可以看到,类数据其实包含了四种信息,静态属性,实例属性,直接方法和虚方法。

字段和方法

对于DexMethod来说,它代表一个类的方法,方法中当然是包含代码的,那么代码(字节码)所在的位置,通过codeOff来表示。

另外加一个说明,这里的fieldIdx和methodIdx其实是一个diff,也就是说,在field列表和method列表中,第一个Idx是真实的Idx,后面的Idx都是在这个基础上做的diff。

字节码信息

数据追踪

按照上面的数据结构,我们走一遍真实的dex数据。

头部区域中的类区域信息

如上一篇所讲,在dex的头部区域中,有两个字段分别表示类信息的偏移值和类的个数;上图中,第一个四字节(07)表示类的总个数,第二个四字节(2ac)就表示类信息的偏移值。

我们找到2ac处: (按照类定义,每个类信息占据4*8=32个字节)

类信息数据区

我们把这7个类的信息,按着类的结构解析并且打印出来:

打印类信息

结果是这样的:

类信息

也就是说,我写的这个Demo程序中,在dex里包含了7个类的信息,如上所示;其中MainActivity就是主Activity。

我们现在只看这个MainActivity的数据:

MainActivity类信息

其中类数据的偏移数值,是第7个四字节,也就是5cc (cc05 0000)。

MainActivity类数据信息

这里使用到了前面锁说的uleb128格式:00 00 01 01(四个字节)

按上面的解释方法,每个字节都是以0开头的,所以就是最后的结果了,那么定义出来的:

static_field_size = 0

instance_field_size = 0

direct_method_size = 1

virtual_method_size = 1

也就是说,MainActivity中没有属性信息,但是有一个直接方法和一个虚方法。

接下来的10个字节,就是直接方法和虚方法的信息(属性为空忽略),它们也是用uleb128进行编码的。

解码信息

这两个方法分别是:

A: method_idx = 5, code_off = 4f0

B: method_idx = 6, code_off = 508

根据上一篇文章中介绍的,我们查找到方法信息如下:

method-idx = 5

method-idx = 6

其中第一个是构造函数,第二个就是我们很熟悉的android方法,onCreate。

继续,我们跟踪onCreate方法的信息,它的偏移是508(十六进制):

onCreate方法体数据

对照结构如下:

onCreate方法体信息

其中从6f20开始,连续的32个字节,就是该方法体的字节码信息。

接下来的任务,就是把这32个字节,翻译成可以识别的指令信息,就是反汇编过程了。

在这之前,我们总结下类信息的打印程序:

读取类信息

读取类数据(一)

读取类数据(二)

用到的一些方法:

读取属性信息

读取方法信息

读取注解信息

读取DexTypeList类型

读取指令信息

反汇编

前面提到,onCreate方法中的指令字节序列,就是下面的32个字节数据。

指令集数据

我们知道指令一般是指令符+指令数组成的,第一个字节一般标识一个特定的指令。

在dex格式中,这个指令既表示具体的操作(字节码格式),又对应一个数据解析格式(说明格式)。

字节码格式文档:

说明格式文档:

比如第一个字节是6f,对照文档如下:

字节码格式

字节码格式

6e..72是数字范围,下面的35c就代表着数据说明格式。

说明格式

对于上面的35c来说,3表示本次指令共计3个字(2个字节),5表示寄存器数目,而c是一个助记符标识常量:

助记符

这3个字是怎么排列呢?

字节排列

把6f开始的3个字,如上面格式依次排开:

206f 0001 0032

对照格式得出:

A = 2, G = 0, op = 6f, BBBB = 1, C = 2, D = 3, E = 0, F = 0

这里的A = 2,那么对应格式:

格式A = 2

也就是op {v2, v3}, kind@0001。

再对照字节码格式文档,其实就是:

invoke-super {v2, v3}, meth@0001

根据method的信息,查询出: meth@0001是

meth@0001

那么前3个字的反汇编代码就是:

invoke-super {v2, v3}, Landroid/app/Activity; --> V onCreate(Landroid/os/Bundle;)

这个不就是调用父类Activity的onCreate方法吗?

对照源代码:

源代码

同样的方式,可以把32个字节的数据,全部反汇编出来。

我们是为了学习Dex的结构,所以会这么大费周折;更加方便的方式,是直接用现有的反编译工具,将dex反编译成smali,可以更加直观的看到信息。

在面对一个未知的应用时,我们没有源码,如果去修改它的信息呢?(假定没有加固)

最简单的方式,还是反编译出smali,通过修改smali再重新打包。

如果是,我们直接在dex上修改呢? 后面继续研究和探讨。

【待续】

python怎么编译dex_用python一步步解剖dex文件(二)相关推荐

  1. python正则表达式编译_用Python编译正则表达式

    嗯,这很奇怪.到目前为止,我的知识(在其他来源中,from this question)表明了我最初的答案: 第一个答案 Python缓存您使用的最后100个regex,因此即使您不显式地编译它们,也 ...

  2. python反编译Pyinstaller打包的可执行文件

    背景:最近在帮朋友写一款类似抢票的脚本,朋友有好几个脚本了,但是效果不理想,想让我帮忙,由于这种需要对接口进行详细了解,有些事件没有条件去抓包,然后我就对朋友已有的几个脚本动了心思.首先像这种爬虫类小 ...

  3. python 反编译

    python 反编译工具名称: Easy Python Decompiler 工具下载地址:http://sourceforge.net/projects/easypythondecompiler/? ...

  4. 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )

    文章目录 前言 一.打包 Jar 文件和 Dex 文件 1.示例代码 2.打包 Jar 文件 3.打包 Dex 文件 二.反编译 Dex 文件 三.分析 Dex 文件 1.Student 类相关信息 ...

  5. Android APK+Dex文件反编译及回编译工具

    本帖最后由 zhu891108 于 2012-8-3 11:00 编辑 大家好! 相信很多人玩智能手机,无论是塞班,安卓等等,不只是看重各种软件的功能,而更多的是看重系统的可定制性,可以自己动手DIY ...

  6. Android APK+Dex文件反编译及回编译工具 比 APKtool GUI 好千倍

    Android APK+Dex文件反编译及回编译工具 v1.7.2 正式版                        Soyu Zom 出品 =========================== ...

  7. Python IDE之Pydev: 基于Eclipse搭建python的编译环境(Eclipse+pydev)简介、安装、使用的详细攻略

    Python IDE之Pydev: 基于Eclipse搭建python的编译环境(Eclipse+pydev)简介.安装.使用的详细攻略 目录 pydev简介 PyDev 安装和配置 1.安装MyEc ...

  8. Python反编译pyinstaller打包的exe文件 从0开始(未加密篇)

    因为pyinstaller方便.兼容性相对较好,所以我们会经常见到一些用pyinstaller打包的Python程序,在这里我们了解一下如何对这些打包好的exe文件进行反编译(即反编译出.py文件), ...

  9. python 动态编译代码_使用PyQt(Python+Qt)+动态编译36行代码实现的计算器

    PyQt是基于跨平台的图形界面C++开发工具Qt加Python包装的一个GPL软件(GPL是GNU General Public License的缩写,是GNU通用公共授权非正式的中文翻译),Qt基于 ...

最新文章

  1. 第二十二讲 延迟定理
  2. 下一代Android或官方支持“App2sd”
  3. NGUI中UILabel使用url标签的一个bug
  4. oracle查看数据库是否恢复成功_记一次解决docker下oracle数据库故障事例
  5. linux tcp header更改,Linux Netfilter中修改TCP/UDP Payload的方法
  6. 牛客 牛牛选物(01背包)
  7. 电线bat_电线之间的新功能
  8. 入职 6 个月,被裁员。。。
  9. 超实用的JavaScript技巧及最佳实践(下)
  10. 【踩坑】XML转JSON中如何把单个元素转成数组
  11. EditPlus--用法--快捷键/配置/背景色/字体大小
  12. scala reduce和Fold
  13. Spark 小文件合并优化实践
  14. Spring Cloud Gateway 使用 HystrixGatewayFilterFactory 熔断降级
  15. 1370. Increasing Decreasing String
  16. Java数据结构与算法(二)
  17. 【Mysql数据库】数据库添加索引方式
  18. 河南太康一高高考成绩查询2021,太康一高 2020年高考捷报:清华、北大录取人数有望突破两位数……...
  19. 电信联通魔百盒烽火HG680-J/V系列-卡刷固件包(可救砖)
  20. python实现角谷定理

热门文章

  1. 马蜂窝裁php换java,php又又又凉凉了吗
  2. LATEX关于表格的一些处理
  3. 蓝桥杯 算法训练 关联矩阵Python实现
  4. 【Python语言】Python编程基础
  5. 网络安全入门到精通(总结篇) 最终篇(上)
  6. sql注入bypass方法
  7. 华为云文档数据库服务更安全
  8. 信号完整性(SI)电源完整性(PI)学习笔记(三十四)100条估计信号完整性效应的经验法则
  9. 概率论——随机变量及其分布
  10. 多分区装linux系统,Linux安装之多系统分区