安卓逆向之 dex、so 可执行文件结构详解 (正在更新中。。。)

我们从一个最小dex文件讲起,所谓最小dex文件就是不包含任何类的文件。

我们可以将文件头看作是头部,map看作是尾巴 

我们先有一个大致的印象,至于上面串表是什么东西等等的后面详细讲解

我们看一个人人都会的hello world。

public class HW {    
    public static void main(String[] args) {
        System.out.println("Hello World"); 
    }
}

将helloworld编译成dex文件,深度刨析dex文件结构,小伙伴们请系好安全带。

这里我借用一下ANGE ALBERTINI大佬的图片,我这里做一个汉化和注解
一个标准的dex文件包含头、表、数据构成,数据包含 堆、码、尾、类定义
 
 

 

 至于操作码和指令格式见

https://source.android.google.cn/devices/tech/dalvik/dalvik-bytecode?hl=zh-tw#instructions

https://source.android.google.cn/devices/tech/dalvik/instruction-formats.html?hl=zh-tw#formats

我们再看一个真实的apk中的dex文件分析,此次不会想上次那么详细。我们只需要关注重点。

这些字段的记录在http://source.android.com/devices/tech/dalvik/dex-format.html。

ins_size | 这段代码所对应的方法的传入参数的字数

outs_size | 这段代码在调用方法时需要的传出参数空间的字数

ins_size主要是不言自明的--它是存储方法参数(包括隐含的 "this "参数,用于非静态方法)所需的32位字数。所有的参数都需要一个 "字",除了长数(J)和双数(D),它们需要两个字。

outs_size基本上是相反的。 outs_size必须被设置得足够大,以容纳方法内发生的任何方法调用的参数。

如果你想对dex文件进行编程而不必担心这样的细节,你可以考虑使用dexlib2(为smali/baksmali开发并用于读写dex文件的库)。该库在maven仓库中可用,所以如果你使用gradle/mvn的话,很容易链接到它。

 HEADER

stringpIDs  


TYPepIDs类型索引表是 字符串列表的索引,表示所有的数据结构
字符串偏移表的索引,我们可以从类型索引表中找到字符串偏移表的位置,从而找到该字符串,该字符串就是数据结构标识符

protopIDs 函数原型
描述=返回值类型加参数类型
返回类型 
参数偏移=参数个数,参数类型

FIELDpIDS 字段索引=所有字段

METHODpIDS 所有方法
prototype 参数

CLASSpDEFS 本类定义或者叫类申明,指向累数据


CODE 函数调用


TYPEpLIST 类型列表  参数列表 包含参数个数和类型

String
Data 数据类型,函数名称,可打印字符串


CLASSpDATA 类数据。定义类中包含的元素


map是之前段的索引,属于冗余信息

偏移是文件开始的相对位置,索引是数组的下标
#dex里面的字符串和数据类型是单独定义的



public class HelloWorld {    //类定义
    public static void main(String[] args) {//类数据,函数原型
        System.out.println("Hello World"); //代码
    }
}
两个方法 
 HEADER

stringpIDs  
字符串堆-偏移表(ascii码表排序)-偏移表的偏移和偏移表的个数

TYPepIDs类型索引表是 字符串列表的索引,表示所有的数据结构
字符串偏移表的索引,我们可以从类型索引表中找到字符串偏移表的位置,从而找到该字符串,该字符串就是数据结构标识符

protopIDs 函数原型
描述=返回值类型加参数类型
返回类型 
参数偏移=参数个数,参数类型

FIELDpIDS 字段索引=所有字段

METHODpIDS 所有方法
prototype 参数

CLASSpDEFS 本类定义或者叫类申明,指向累数据


CODE 函数调用


TYPEpLIST 类型列表  参数列表 包含参数个数和类型

String
Data 


CLASSpDATA 类数据。




偏移是文件开始的相对位置,索引是数组的下标
#dex里面的字符串和数据类型是单独定义的



public class HelloWorld {    //类定义
    public static void main(String[] args) {//类数据,函数原型
        System.out.println("Hello World"); //代码
    }
}

  

 
 
 
 
 
增加一个字符,dex文件会发生上面改变?
 
 

so文件等到有时间了再说

原文地址:https://www.cnblogs.com/GKLBB/p/15060537.html