日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

2020-10-27(dex文件解析)

發(fā)布時(shí)間:2025/3/21 编程问答 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020-10-27(dex文件解析) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一張圖搞懂dex
大圖這里

當(dāng)然也可以通過(guò)下面的圖12 DexFile的文件格式,了解更清楚。

DEX文件詳解
什么是dex文件?
如何生成一個(gè)dex文件
dex文件的作用
dex文件格式詳解
什么是dex文件?
dex文件是Android系統(tǒng)中的一種文件,是一種特殊的數(shù)據(jù)格式,和APK、jar 等格式文件類似。
能夠被DVM識(shí)別,加載并執(zhí)行的文件格式。
簡(jiǎn)單說(shuō)就是優(yōu)化后的android版.exe。每個(gè)apk安裝包里都有。包含應(yīng)用程序的全部操作指令以及運(yùn)行時(shí)數(shù)據(jù)。
相對(duì)于PC上的java虛擬機(jī)能運(yùn)行.class;android上的Davlik虛擬機(jī)能運(yùn)行.dex。

當(dāng)java程序編譯成class后,還需要使用dx工具將所有的class文件整合到一個(gè)dex文件,目的是其中各個(gè)類能夠共享數(shù)據(jù),在一定程度上降低了冗余,同時(shí)也是文件結(jié)構(gòu)更加經(jīng)湊,實(shí)驗(yàn)表明,dex文件是傳統(tǒng)jar文件大小的50%左右

圖2 apk中的dex文件

為何要研究dex格式?因?yàn)閐ex里面包含了所有app代碼,利用反編譯工具可以獲取java源碼。理解并修改dex文件,就能更好的apk破解和防破解。

使用dex文件的最大目的是實(shí)現(xiàn)安全管理,但在追求安全的前提下,一定要注意對(duì)dex文件實(shí)現(xiàn)優(yōu)化處理。

注意:并不是只有Java才可以生成dex文件,C和C++也可以生成dex文件

如何生成一個(gè)dex文件?
通過(guò)IDE自動(dòng)幫我們build生成
手動(dòng)通過(guò)dx命令去生成dex文件
在待測(cè)試的class文件目錄下(我將TestMain.class放到了F盤根目錄下),執(zhí)行命令dx --dex --output TestMain.dex TestMain.class,就會(huì)生成TestMain.dex文件。
手動(dòng)運(yùn)行dex文件在手機(jī)
在待測(cè)試的dex文件目錄下(我將TestMain.class放到了F盤根目錄下),通過(guò)adb push TestMain.dex /storage/emulated/0命令,然后通過(guò)adb shell命令進(jìn)入手機(jī),后執(zhí)行dalvikvm -cp /sdcard/TestMain.dex TestMain,就會(huì)打印出
Hello World!
如下圖3所示(使用AS的終端,沒有用Windows的cmd命令)

圖3 手動(dòng)運(yùn)行dex文件

注意:

環(huán)境變量的配置,dex在SDK目錄下的build-tools目錄下有很多版本,這里可以選擇最新版本目錄下dx.bat配置到環(huán)境變量path路徑下;同樣,adb命令也同樣配置。
運(yùn)行完dex文件,可以通過(guò)exit退出手機(jī),電腦本地盤符
查看dex文件
大圖這里

圖4 dex文件概貌

通過(guò)010Editor工具(圖片來(lái)自網(wǎng)絡(luò))
大圖這里

圖5 注:圖片來(lái)自網(wǎng)絡(luò)

下圖6是TestMain.dex通過(guò)010Editor工具得到的
大圖這里

圖6 010Editor 檢測(cè)TestMain.dex結(jié)果

圖7是通過(guò)010Editor工具檢測(cè)TestMain.dex得到的 Template Result結(jié)果
大圖這里

圖7 010Editor檢測(cè)TemplateResult結(jié)果

通過(guò)dexdump 命令查看(注意)
利用build-tools 下的dexdump 命令查看,dexdump -d -l plain TestMain.dex,得到下面的結(jié)果

F:\>dexdump -d -l plain TestMain.dex Processing 'TestMain.dex'... Opened 'TestMain.dex', DEX version '035' Class #0 -Class descriptor : 'LTestMain;'Access flags : 0x0001 (PUBLIC)Superclass : 'Ljava/lang/Object;'Interfaces -Static fields -Instance fields -#0 : (in LTestMain;)name : 'mX'type : 'I'access : 0x0001 (PUBLIC)Direct methods -#0 : (in LTestMain;)name : '<init>'type : '()V'access : 0x10001 (PUBLIC CONSTRUCTOR)code -registers : 2ins : 1outs : 1insns size : 7 16-bit code units 00015c: |[00015c] TestMain.<init>:()V 00016c: 7010 0400 0100 |0000: invoke-direct {v1}, Ljava/lang/Object;.<init>:()V // method@0004 000172: 1200 |0003: const/4 v0, #int 0 // #0 000174: 5910 0000 |0004: iput v0, v1, LTestMain;.mX:I // field@0000 000178: 0e00 |0006: return-voidcatches : (none)positions :0x0000 line=110x0003 line=30x0006 line=12locals :0x0000 - 0x0007 reg=1 this LTestMain;#1 : (in LTestMain;)name : 'main'type : '([Ljava/lang/String;)V'access : 0x0009 (PUBLIC STATIC)code -registers : 4ins : 1outs : 2insns size : 16 16-bit code units 00017c: |[00017c] TestMain.main:([Ljava/lang/String;)V 00018c: 2200 0100 |0000: new-instance v0, LTestMain; // type@0001 000190: 7010 0000 0000 |0002: invoke-direct {v0}, LTestMain;.<init>:()V // method@0000 000196: 6e10 0200 0000 |0005: invoke-virtual {v0}, LTestMain;.test:()V // method@0002 00019c: 6201 0100 |0008: sget-object v1, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0001 0001a0: 1a02 0100 |000a: const-string v2, "Hello World!" // string@0001 0001a4: 6e20 0300 2100 |000c: invoke-virtual {v1, v2}, Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // method@0003 0001aa: 0e00 |000f: return-voidcatches : (none)positions :0x0000 line=60x0005 line=70x0008 line=80x000f line=9locals :0x0005 - 0x0010 reg=0 testMainObject LTestMain;0x0000 - 0x0010 reg=3 args [Ljava/lang/String;Virtual methods -#0 : (in LTestMain;)name : 'test'type : '()V'access : 0x0001 (PUBLIC)code -registers : 1ins : 1outs : 0insns size : 1 16-bit code units 0001ac: |[0001ac] TestMain.test:()V 0001bc: 0e00 |0000: return-voidcatches : (none)positions :0x0000 line=15locals :0x0000 - 0x0001 reg=0 this LTestMain;source_file_idx : 8 (TestMain.java)

registers:Dalvik 最初目標(biāo)是運(yùn)行在以ARM 做CPU 的機(jī)器上的,ARM 芯片的一個(gè)主要特點(diǎn)是寄存器多。寄存器多的話有好處,就是可以把操作數(shù)放在寄存器里,而不是像傳統(tǒng)VM 一樣放在棧中。自然,操作寄存器是比操作內(nèi)存(棧嘛,其實(shí)就是一塊內(nèi)存區(qū)域)快。registers 變量表示該方法運(yùn)行過(guò)程中會(huì)使用多少個(gè)寄存器。
ins:輸入?yún)?shù)對(duì)應(yīng)的個(gè)數(shù)
outs:此函數(shù)內(nèi)部調(diào)用其他函數(shù),需要的參數(shù)個(gè)數(shù)。
insns size:以4 字節(jié)為單位,代表該函數(shù)字節(jié)碼的長(zhǎng)度(類似Class 文件的code[]數(shù)組)
更多內(nèi)容參考:官網(wǎng)介紹----->Dalvik 可執(zhí)行文件格式

dex文件的作用
記錄整個(gè)工程中所有類的信息,記住的整個(gè)工程所有類的信息

dex文件格式詳解
一種8位字節(jié)的二進(jìn)制流文件
各個(gè)數(shù)據(jù)按順序緊密的排列,無(wú)間隙
整個(gè)應(yīng)用中所有的Java源文件都放在一個(gè)dex中
大圖這里

圖8 dex文件結(jié)構(gòu)

上圖中的文件頭部分,記錄了dex文件的信息,所有字段大致的一個(gè)分部;索引區(qū)部分,主要包含字符串、類型、方法原型、域、方法的索引;索引區(qū)最終又被存儲(chǔ)在數(shù)據(jù)區(qū),其中鏈接數(shù)據(jù)區(qū),主要存儲(chǔ)動(dòng)態(tài)鏈接庫(kù),so庫(kù)的信息。

源碼:/dalvik/libdex/DexFile.h:DexFile

struct DexFile {/* directly-mapped "opt" header */const DexOptHeader* pOptHeader;/* pointers to directly-mapped structs and arrays in base DEX */const DexHeader* pHeader;const DexStringId* pStringIds;const DexTypeId* pTypeIds;const DexFieldId* pFieldIds;const DexMethodId* pMethodIds;const DexProtoId* pProtoIds;const DexClassDef* pClassDefs;const DexLink* pLinkData; };

具體可查看Android源碼官網(wǎng)的關(guān)于dex文件結(jié)構(gòu)的詳解,如下圖9(大圖這里)

圖9 dex文件結(jié)構(gòu)詳解

總結(jié):

數(shù)據(jù)名稱 解釋
header dex 文件頭部,記錄整個(gè)dex文件的相關(guān)屬性
string_ids 字符串?dāng)?shù)據(jù)索引,記錄了每個(gè)字符串在數(shù)據(jù)區(qū)的偏移量
type_ids

數(shù)據(jù)名稱解釋
header dex文件頭部,記錄整個(gè)dex文件的相關(guān)屬性
string_ids字符串?dāng)?shù)據(jù)索引,記錄了每個(gè)字符串在數(shù)據(jù)區(qū)的偏移量
type_ids類似數(shù)據(jù)索引,記錄了每個(gè)類型的字符串索引
proto_ids原型數(shù)據(jù)索引,記錄了方法聲明的字符串,返回類型字符串,參數(shù)列表
field_ids字段數(shù)據(jù)索引,記錄了所屬類,類型以及方法名
method_ids類方法索引,記錄方法所屬類名,方法聲明以及方法名等信息
class_defs類定義數(shù)據(jù)索引,記錄指定類各類信息,包括接口,超類,類數(shù)據(jù)偏移量
data數(shù)據(jù)區(qū),保存了各個(gè)類的真是數(shù)據(jù)
link_data連接數(shù)據(jù)區(qū)

DEX 文件中會(huì)出現(xiàn)的數(shù)據(jù)類型

類型 含義
u1 等同于uint8_t,表示 1 字節(jié)的無(wú)符號(hào) 數(shù)
u2 等同于 uint16_t,表示 2 字節(jié)的無(wú)符號(hào)數(shù)
u4 等同于 uint32_t,表示 4 字節(jié)的無(wú)符號(hào)數(shù)
u8 等同于 uint64_t,表示 8 字節(jié)的無(wú)符號(hào)數(shù)
sleb128 有符號(hào) LEB128,可變長(zhǎng)度 1~5 字節(jié)
uleb128 無(wú)符號(hào) LEB128,可變長(zhǎng)度 1~5 字節(jié)
uleb128p1 無(wú)符號(hào) LEB128 值加1,可變長(zhǎng) 1~5 字節(jié)

/dalvik/libdex/DexFile.h中定義如下

typedef uint8_t u1;
typedef uint16_t u2;
typedef uint32_t u4;
typedef uint64_t u8;
typedef int8_t s1;
typedef int16_t s2;
typedef int32_t s4;
typedef int64_t s8;
LEB128
LEB128(“Little-Endian Base 128”)表示任意有符號(hào)或無(wú)符號(hào)整數(shù)的可變長(zhǎng)度編碼。該格式借鑒了 DWARF3 規(guī)范。在 .dex 文件中,LEB128 僅用于對(duì) 32 位數(shù)字進(jìn)行編碼。

每個(gè) LEB128 編碼值均由 1-5 個(gè)字節(jié)組成,共同表示一個(gè) 32 位的值。每個(gè)字節(jié)均已設(shè)置其最高有效位(序列中的最后一個(gè)字節(jié)除外,其最高有效位已清除)。每個(gè)字節(jié)的剩余 7 位均為有效負(fù)荷,即第一個(gè)字節(jié)中有 7 個(gè)最低有效位,第二個(gè)字節(jié)中也是 7 個(gè),依此類推。對(duì)于有符號(hào) LEB128 (sleb128),序列中最后一個(gè)字節(jié)的最高有效負(fù)荷位會(huì)進(jìn)行符號(hào)擴(kuò)展,以生成最終值。在無(wú)符號(hào)情況 (uleb128) 下,任何未明確表示的位都會(huì)被解譯為 0。
大圖這里

圖10 雙字節(jié) LEB128 值的按位圖

變量 uleb128p1 用于表示一個(gè)有符號(hào)值,其表示法是編碼為 uleb128 的值加 1。這使得編碼 -1(或被視為無(wú)符號(hào)值 0xffffffff)成為一個(gè)單字節(jié)(但沒有任何其他負(fù)數(shù)),并且該編碼在下面這些明確說(shuō)明的情況下非常實(shí)用:所表示的數(shù)值必須為非負(fù)數(shù)或 -1(或 0xffffffff);不允許任何其他負(fù)值(或不太可能需要使用較大的無(wú)符號(hào)值)。
以下是這類格式的一些示例:

編碼序列 As sleb128 As uleb128 As uleb128p1
00 0 0 -1
01 1 1 0
7f -1 127 126
80 7f -128 16256
dex文件頭
Dex文件頭主要包括校驗(yàn)和以及其他結(jié)構(gòu)的偏移地址和長(zhǎng)度信息。
源碼位于 /dalvik/libdex/DexFile.h:DexHeader

struct DexHeader {u1 magic[8]; /* includes version number */u4 checksum; /* adler32 checksum */u1 signature[kSHA1DigestLen]; /* SHA-1 hash */u4 fileSize; /* length of entire file */u4 headerSize; /* offset to start of next section */u4 endianTag;u4 linkSize;u4 linkOff;u4 mapOff;u4 stringIdsSize;u4 stringIdsOff;u4 typeIdsSize;u4 typeIdsOff;u4 protoIdsSize;u4 protoIdsOff;u4 fieldIdsSize;u4 fieldIdsOff;u4 methodIdsSize;u4 methodIdsOff;u4 classDefsSize;u4 classDefsOff;u4 dataSize;u4 dataOff; };

具體詳解如下圖5所示
大圖這里

圖11 dex文件頭信息

各個(gè)字段詳解摘要
mapOff 字段
指定 DexMapList 結(jié)構(gòu)距離 Dex 頭的偏移
DexMapList 結(jié)構(gòu)體:

struct DexMapList
{
u4 size; // DexMapItem 的個(gè)數(shù)
DexMapItem list[1]; // DexMapItem 結(jié)構(gòu)
};
size:表示接下來(lái)有多少個(gè) DexMapItem
list:是一個(gè) DexMapItem 結(jié)構(gòu)體數(shù)組
DexMapItem 結(jié)構(gòu)體:
struct DexMapItem
{
u2 type; // kDexType 開頭的類型
u2 unused; // 未使用,用于對(duì)齊
u4 size; // 指定類型的個(gè)數(shù)
u4 offset; // 指定類型數(shù)據(jù)的文件偏移
};
type:一個(gè)枚舉常量

enum
{
kDexTypeHeaderItem = 0x0000, // 對(duì)應(yīng) DexHeader
kDexTypeStringIdItem = 0x0001, // 對(duì)應(yīng) stringIdsSize 與 stringIdsOff 字段
kDexTypeTypeIdItem = 0x0002, // 對(duì)應(yīng) typeIdsSize 與 typeIdsOff 字段
kDexTypeProtoIdItem = 0x0003, // 對(duì)應(yīng) protoIdsSize 與 protoIdsOff 字段
kDexTypeFieldIdItem = 0x0004, // 對(duì)應(yīng) fieldIdsSize 與 fieldIdsOff 字段
kDexTypeMethodIdItem = 0x0005, // 對(duì)應(yīng) methodIdsSize 與 methodIdsOff 字段
kDexTypeClassDefItem = 0x0006, // 對(duì)應(yīng) classDefsSize 與 classDefsOff 字段
kDexTypeMapList = 0x1000,
kDexTypeTypeList = 0x1001,
kDexTypeAnnotationSetRefList = 0x1002,
kDexTypeAnnotationSetItem = 0x1003,
kDexTypeClassDataItem = 0x2000,
kDexTypeCodeItem = 0x2001,
kDexTypeStringDataItem = 0x2002,
kDexTypeDebugInfoItem = 0x2003,
kDexTypeAnnotationItem = 0x2004,
kDexTypeEncodeArrayItem = 0x2005,
kDexTypeAnnotationsDirectoryItem = 0x2006
};
size:指定類型的個(gè)數(shù)
offset:指定類型數(shù)據(jù)的偏移
DexStringId 結(jié)構(gòu)體(stringIdsSize 與 stringIdsOff 字段)

typedef struct _DexStringId
{
u4 stringDataOff; // 指向 MUTF-8 字符串的偏移
}DexStringId, *PDexStringId;
MUTF-8 編碼:

使用 1~3 字節(jié)編碼長(zhǎng)度
大于 16 位的 Unicode 編碼 U+10000~U+10FFFF 使用 3 字節(jié)來(lái)編碼
U+0000 采用 2 字節(jié)編碼
采用空字符 null 作為結(jié)尾
第一個(gè)字節(jié)存放字節(jié)個(gè)數(shù)(不包含自已)
DexTypeId 結(jié)構(gòu)體(typeIdsSize 與 typeIdsOff 字段)
是一個(gè)類型結(jié)構(gòu)體

typedef struct _DexTypeId
{
u4 descriptorIdx; // 指向 DexStringId 列表的索引
}DexTypeId, *PDexTypeId;
descriptorIdx:指向 DexStringId 列表的索引,它對(duì)應(yīng)的字符串代表了具體類的類型
DexProtoId 結(jié)構(gòu)體(protoIdsSize 與 protoIdsOff 字段)
是一個(gè)方法聲明結(jié)構(gòu)體,方法聲明 = 返回類型 + 參數(shù)列表

typedef struct _DexProtoId
{
u4 shortyIdx; // 方法聲明字符串,指向 DexStringId 列表的索引
u4 returnTypeIdx; // 方法返回類型字符串,指向 DexStringId 列表的索引
u4 parametersOff; // 方法的參數(shù)列表,指向 DexTypeList 結(jié)構(gòu)體的偏移
}DexProtoId, *PDexProtoId;
shortyIdx:方法聲明字符串,方法聲明 = 返回類型 + 參數(shù)列表
returnTypeIdx:方法返回類型字符串
parametersOff:指向一個(gè) DexTypeList 結(jié)構(gòu)體,存放了方法的參數(shù)列表
DexTypeList 結(jié)構(gòu)體:

typedef struct _DexTypeList
{
u4 size; // 接下來(lái) DexTypeItem 的個(gè)數(shù)
DexTypeItem* list; // DexTypeItem 結(jié)構(gòu)
}DexTypeList, *PDexTypeList;
size:接下來(lái) DexTypeItem 的個(gè)數(shù)
list:是一個(gè) DexTypeItem 結(jié)構(gòu)體數(shù)組
DexTypeItem 結(jié)構(gòu)體:

typedef struct _DexTypeItem
{
u2 typeIdx; // 指向 DexTypeId 列表的索引
}DexTypeItem, *PDexTypeItem;
typeIdx:DexTypeId 列表的索引

DexFieldId 結(jié)構(gòu)體(fieldIdsSize 與 fieldIdsOff 字段)
指明了字段所有的類、字段的類型以及字段名

typedef struct _DexFieldId
{
u2 classIdx; // 類的類型,指向 DexTypeId 列表的索引
u2 typeIdx; // 字段的類型,指向 DexTypeId 列表的索引
u4 nameIdx; // 字段名,指向 DexStringId 列表的索引
}DexFieldId, *PDexFieldId;
classIdx:類的類型
typeIdx:字段的類型
nameIdx:字段名
DexMethodId 結(jié)構(gòu)體(methodIdsSize 與 methodIdsOff 字段)
方法結(jié)構(gòu)體

typedef struct _DexMethodId
{
u2 classIdx; // 類的類型,指向 DexTypeId 列表的索引
u2 protoIdx; // 聲明的類型,指向 DexProtoId 列表的索引
u4 nameIdx; // 方法名,指向 DexStringId 列表的索引
}DexMethodId, *PDexMethodId;
classIdx:類的類型
protoIdx:聲明的類型
nameIdx:方法名
DexClassDef 結(jié)構(gòu)體(classDefsSize 和 classDefsOff 字段)
類結(jié)構(gòu)體

typedef struct _DexClassDef
{
u4 classIdx; // 類的類型,指向 DexTypeId 列表的索引
u4 accessFlags; // 訪問(wèn)標(biāo)志
u4 superclassIdx; // 父類類型,指向 DexTypeId 列表的索引
u4 interfacesOff; // 接口,指向 DexTypeList 的偏移,否則為0
u4 sourceFileIdx; // 源文件名,指向 DexStringId 列表的索引
u4 annotationsOff; // 注解,指向 DexAnnotationsDirectoryItem 結(jié)構(gòu),或者為 0
u4 classDataOff; // 指向 DexClassData 結(jié)構(gòu)的偏移,類的數(shù)據(jù)部分
u4 staticValuesOff; // 指向 DexEncodedArray 結(jié)構(gòu)的偏移,記錄了類中的靜態(tài)數(shù)據(jù),主要是靜態(tài)方法
}DexClassDef, *PDexClassDef;
classIdx:類的類型,指向 DexTypeId 列表的索引
accessFlags:訪問(wèn)標(biāo)志,它是以ACC_開頭的枚舉值
superclassIdx:父類類型,指向 DexTypeId 列表的索引
interfacesOff:接口,指向 DexTypeList 的偏移,如果沒有,則為 0
sourceFileIdx:源文件名,指向 DexStringId 列表的索引
annotationsOff:注解,指向 DexAnnotationsDirectoryItem 結(jié)構(gòu),或者為 0
classDataOff:指向 DexClassData 結(jié)構(gòu)的偏移,類的數(shù)據(jù)部分
staticValuesOff:指向 DexEncodeArray 結(jié)構(gòu)的偏移,記錄了類中的靜態(tài)數(shù)據(jù),沒有則為 0
DexClassData 結(jié)構(gòu)體:

typedef struct _DexClassData
{
DexClassDataHeader header; // 指定字段與方法的個(gè)數(shù)
DexField* staticFields; // 靜態(tài)字段,DexField 結(jié)構(gòu)
DexField* instanceFields; // 實(shí)例字段,DexField 結(jié)構(gòu)
DexMethod* directMethods; // 直接方法,DexMethod 結(jié)構(gòu)
DexMethod* virtualMethods; // 虛方法,DexMethod 結(jié)構(gòu)
}DexClassData, *PDexClassData;
header:DexClassDataHeader 結(jié)構(gòu)體,指定字段與方法的個(gè)數(shù)
staticFields:靜態(tài)字段,DexField 結(jié)構(gòu)體數(shù)組
instanceFields:實(shí)例字段,DexField 結(jié)構(gòu)體數(shù)組
directMethods:直接方法,DexMthod 結(jié)構(gòu)體數(shù)組
virtualMethods:虛方法,DexMethod 結(jié)構(gòu)體數(shù)組
DexClassDataHeader 結(jié)構(gòu)體:

typedef struct _DexClassDataHeader
{
uleb128 staticFieldsSize; // 靜態(tài)字段個(gè)數(shù)
uleb128 instanceFieldsSize; // 實(shí)例字段個(gè)數(shù)
uleb128 directMethodsSize; // 直接方法個(gè)數(shù)
uleb128 virtualMethodsSize; // 虛方法個(gè)數(shù)
}DexClassDataHeader, *PDexClassDataHeader;
staticFieldsSize:靜態(tài)字段個(gè)數(shù)
instanceFieldsSize:實(shí)例字段個(gè)數(shù)
directMethodsSize:直接方法個(gè)數(shù)
virtualMethodsSize:虛方法個(gè)數(shù)
DexField 結(jié)構(gòu)體:

typedef struct _DexField
{
uleb128 fieldIdx; // 指向 DexFieldId 的索引
uleb128 accessFlags; // 訪問(wèn)標(biāo)志
}DexField, *PDexField;
fieldIdx:字段描述,指向 DexFieldId 的索引
accessFlags:訪問(wèn)標(biāo)志
DexMethod 結(jié)構(gòu)體:

typedef struct _DexMethod
{
uleb128 methodIdx; // 指向 DexMethodId 的索引
uleb128 accessFlags; // 訪問(wèn)標(biāo)志
uleb128 codeOff; // 指向 DexCode 結(jié)構(gòu)的偏移
}DexMethod, *PDexMethod;
methodIdx:方法描述,指向 DexMethodId 的索引
accessFlags:訪問(wèn)標(biāo)志
codeOff:指向 DexCode 結(jié)構(gòu)的偏移
DexCode 結(jié)構(gòu)體:

typedef struct _DexCode
{
u2 registersSize; // 使用的寄存器個(gè)數(shù)
u2 insSize; // 參數(shù)個(gè)數(shù)
u2 outsSize; // 調(diào)用其他方法時(shí)使用的寄存器個(gè)數(shù)
u2 triesSize; // Try/Catch 個(gè)數(shù)
u4 debbugInfoOff; // 指向調(diào)試信息的偏移
u4 insnsSize; // 指令集個(gè)數(shù),以 2 字節(jié)為單位
u2* insns; // 指令集
}DexCode, *PDexCode;
還有一些不太常見的結(jié)構(gòu)體,要用的時(shí)候再去看看就行了。Dex 文件的整體結(jié)構(gòu)就這樣,就是一個(gè)多層索引的結(jié)構(gòu)。

string_ids(字符串索引)
這一區(qū)域存儲(chǔ)的是Dex文件字符串資源的索引信息,該索引信息是目標(biāo)字符串在Dex文件數(shù)據(jù)區(qū)所在的真實(shí)物理偏移量。

源碼位于 /dalvik/libdex/DexFile.h:DexStringId

struct DexStringId {
u4 stringDataOff; /* file offset to string_data_item */
};
stringDataOff記錄了目標(biāo)字符串在Dex文件中的實(shí)際偏移量,虛擬機(jī)想讀取該字符串時(shí),只需將Dex文件在內(nèi)存中的起始地址加上stringDataOff所指的偏移量,就是該字符串在內(nèi)存中的實(shí)際物理地址。
在Dex文件中,每個(gè)每個(gè)字符串對(duì)應(yīng)一個(gè)DexStringId,大小4B。另外虛擬機(jī)通過(guò)DexHeader中的String_ids_size獲得當(dāng)前Dex文件中的字符串的總數(shù),通過(guò)乘法就可對(duì)該索引資源進(jìn)行訪問(wèn)。

DexLink

struct DexLink {
u1 bleargh;
};
DexFile 在內(nèi)存中的映射
在Android系統(tǒng)中, java 源文件會(huì)被編譯為“ .jar ” 格式的dex類型文件, 在代碼中稱為dexfile 。在加載Class 之前, 必先讀取相應(yīng)的jar文件。通常我們使用read()函數(shù)來(lái)讀取文件中的內(nèi)容。但在Dalvik中使用mmap() 函數(shù)。和read()不同, mmap()函數(shù)會(huì)將dex文件映射到內(nèi)存中,這樣通過(guò)普通的內(nèi)存讀取操作即可訪問(wèn)dexfile中的內(nèi)容。

Dexfile的文件格式如圖12 所示, 主要有三部分組成:頭部,索引,數(shù)據(jù)。通過(guò)頭部可知索引的位置和數(shù)同,可知數(shù)據(jù)區(qū)的起始位置。其中classDefsOff 指定了ClassDef 在文件的起始位置, dataOff 指定了數(shù)據(jù)在文件的起始位置, ClassDef 即可理解為Class 的索引。通過(guò)讀取ClassDef 可獲知Class 的基本信息,其中classDataOff 指定了Class 數(shù)據(jù)在數(shù)據(jù)區(qū)的位置。
大圖這里

圖12 DexFile的文件格式

在將dexfile文件映射到內(nèi)存后,會(huì)調(diào)用dexFileParse()函數(shù)對(duì)其分析,分析的結(jié)果存放于名為DexFile的數(shù)據(jù)結(jié)構(gòu)中。DexFile 中的baseAddr指向映射區(qū)的起始位置, pClassDefs 指向ClassDefs(即class索引)的起始位置。由于在查找class 時(shí),都是使用class的名字進(jìn)行查找的,所以為了加快查找速度, 創(chuàng)建了一個(gè)hash表。在hash表中對(duì)class 名字進(jìn)行hash,并生成index。這些操作都是在對(duì)文件解析時(shí)所完成的,這樣雖然在加載過(guò)程中比較耗時(shí),但是在運(yùn)行過(guò)程中可節(jié)省大量查找時(shí)間。

解析完后, 接下來(lái)開始加載class文件。在此需要將加載類用ClassObject來(lái)保存,所以在此需要先分析和ClassObject 相關(guān)的幾個(gè)數(shù)據(jù)結(jié)構(gòu)。

首先在文件Object.h 中可以看到如下對(duì)結(jié)構(gòu)體Object 的定義。(android2.3.7源碼)

typedef struct Object {
/* ptr to class object /
ClassObject clazz;

/** A word containing either a "thin" lock or a "fat" monitor. See* the comments in Sync.c for a description of its layout.*/ u4 lock;

} Object;
通過(guò)結(jié)構(gòu)體Object定義了基本類的實(shí)現(xiàn),這里有如下兩個(gè)變量。

lock : 對(duì)應(yīng)Obejct 對(duì)象中的鎖實(shí)現(xiàn),即notify wait 的處理。
clazz : 是結(jié)構(gòu)體指針,姑且不看結(jié)構(gòu)體內(nèi)容,這里用了指針的定義。
下面會(huì)有更多的結(jié)構(gòu)體定義:

struct DataObject {
Object obj; /* MUST be first item /
/ variable #of u4 slots; u8 uses 2 slots /
u4 instanceData[1];
};
struct StringObject {
Object obj; / MUST be first item /
/ variable #of u4 slots; u8 uses 2 slots */
u4 instanceData[1];
};
我們看到最熟悉的一個(gè)詞StringObject ,把這個(gè)結(jié)構(gòu)體展開后是下面的樣子。

struct StringObject {
/* ptr t o class object /
ClassObject clazz ;
/* variable #of u4 slots; u8 uses 2 slots */
u4 lock;
u4 instanceData[1];
};
由此不難發(fā)現(xiàn), 任何對(duì)象的內(nèi)存結(jié)構(gòu)體中第一行都是Object結(jié)構(gòu)體,而這個(gè)結(jié)構(gòu)體第一個(gè)總是一個(gè)ClassObejct,第二個(gè)總是lock 。按照C++中的技巧,這些結(jié)構(gòu)體可以當(dāng)成Object結(jié)構(gòu)體使用,因此所有的類在內(nèi)存中都具有“對(duì)象”的功能,即可以找到一個(gè)類(ClassObject),可以有一個(gè)鎖(lock) 。

StringObject是對(duì)String類進(jìn)行管理的數(shù)據(jù)對(duì)象,ArrayObejct是數(shù)據(jù)相關(guān)的管理。

ClassObject-Class 在加載后的表現(xiàn)形式
在解析完文件后, 接下來(lái)需要加載Class 的具體內(nèi)容。在Dalvik中, 由數(shù)據(jù)結(jié)構(gòu)ClassObject負(fù)責(zé)存放加載的信息。如圖13所示,加載過(guò)程會(huì)在內(nèi)存中alloc幾個(gè)區(qū)域,分別存放directMethods 、virtualMethods 、sfields 、ifields 。這些信息是從dex 文件的數(shù)據(jù)區(qū)中讀取的,首先會(huì)讀取Class 的詳細(xì)信息,從中獲得directMethod 、virtua!Method 、sfield 、ifield 等的信息,然后再讀取。在此需要注意, 在C lassObj ect 結(jié)構(gòu)中有個(gè)名為super 的成員,通過(guò)super成員可以指向它的超類。
大圖這里

圖13 加載過(guò)程

Android dex 文件優(yōu)化
對(duì)Android dex 文件進(jìn)行優(yōu)化來(lái)說(shuō), 需要注意的一點(diǎn)是dex文件的結(jié)構(gòu)是緊湊的,但是我們還是要想方設(shè)法地進(jìn)行提高程序的運(yùn)行速度,我們就仍然需要對(duì)dex文件進(jìn)行進(jìn)一步優(yōu)化。

調(diào)整所有字段的字節(jié)序( LITTLE_ENDIAN),和對(duì)齊結(jié)構(gòu)中的每一個(gè)域來(lái)驗(yàn)證dex文件中的所有類,并對(duì)一些特定的類進(jìn)行優(yōu)化或?qū)Ψ椒ɡ锏牟僮鞔a進(jìn)行優(yōu)化。優(yōu)化后的文件大小會(huì)有所增加, 大約是原Android dex文件的1~4 倍。

優(yōu)化時(shí)機(jī)
優(yōu)化發(fā)生的時(shí)機(jī)有兩個(gè):

對(duì)于預(yù)置應(yīng)用來(lái)說(shuō),可以在系統(tǒng)編譯后,生成優(yōu)化文件,以O(shè)DEX 結(jié)尾。這樣在發(fā)布時(shí)除APK文件(不包含dex)以外,還有一個(gè)相應(yīng)的Android dex 文件。
對(duì)于非預(yù)置應(yīng)用, 包含在APK文件里的dex 文件會(huì)在運(yùn)行時(shí)被優(yōu)化,優(yōu)化后的文件將被保存在緩存中。
如下圖14所示代碼調(diào)用流程

圖14 代碼調(diào)用流程

每一個(gè)Android應(yīng)用都運(yùn)行在一個(gè)Dalvik虛擬機(jī)實(shí)例里,而每一個(gè)虛擬機(jī)實(shí)例都是一個(gè)獨(dú)立的進(jìn)程空間。虛擬機(jī)的線程機(jī)制,內(nèi)存分配和管理, Mutex等都是依賴底層操作系統(tǒng)而實(shí)現(xiàn)的。

所有Android應(yīng)用的線程都對(duì)應(yīng)一個(gè)Linux線程(可參考----理解Android線程創(chuàng)建流程),虛擬機(jī)因而可以更多地依賴操作系統(tǒng)的線程調(diào)度和管理機(jī)制。不同的應(yīng)用在不同的進(jìn)程空間里運(yùn)行,加之對(duì)不同來(lái)源的應(yīng)用都使用不同的Linux用戶來(lái)運(yùn)行,可以最大限度地保護(hù)應(yīng)用的安全和獨(dú)立運(yùn)行。

Zygote是一個(gè)虛擬機(jī)進(jìn)程,同時(shí)也是一個(gè)虛擬機(jī)實(shí)例的孵化器,每當(dāng)系統(tǒng)要求執(zhí)行一個(gè)Android應(yīng)用程序,Zygote就會(huì)孵化出一個(gè)子進(jìn)程來(lái)執(zhí)行該應(yīng)用程序。這樣做的好處顯而易見:Zygote進(jìn)程是在系統(tǒng)啟動(dòng)時(shí)產(chǎn)生的,它會(huì)完成虛擬機(jī)的初始化,庫(kù)的載,預(yù)置類庫(kù)的加載和初始化等操作,而在系統(tǒng)需要一個(gè)新的虛擬機(jī)實(shí)例時(shí),Zygote通過(guò)復(fù)制自身,最快速地提供一個(gè)虛擬機(jī)實(shí)例。另外,對(duì)于一些只讀的系統(tǒng)庫(kù),所有虛擬機(jī)實(shí)例都和Zygote 共享一塊內(nèi)存區(qū)域,大大節(jié)省了內(nèi)存開銷。

Android 應(yīng)用所使用的編程語(yǔ)言是Java語(yǔ)言,和Java SE 一樣,編譯時(shí)使用Oracle JDK 將Java源程序編程成標(biāo)準(zhǔn)的Java 字節(jié)碼文件(. class 文件)。而后通過(guò)工具軟件DX 把所有的字節(jié)碼文件轉(zhuǎn)成Android dex 文件(classes . dex) 。最后使用Android 打包工具(aapt)將dex 文件、資源文件以及AndroidManifest.xml 文件(二進(jìn)制格式)組合成一個(gè)應(yīng)用程序包(APK) 。應(yīng)用程序包可以被發(fā)布到手機(jī)上運(yùn)行。

圖15 Android應(yīng)用編譯及運(yùn)行流程

odex 介紹
odex 是Optimized dex 的簡(jiǎn)寫,也就是優(yōu)化后的dex 文件。為什么要優(yōu)化呢?主要還是為了提高Dalvik 虛擬機(jī)的運(yùn)行速度。但是odex 不是簡(jiǎn)單的、通用的優(yōu)化,而是在其優(yōu)化過(guò)程中,依賴系統(tǒng)已經(jīng)編譯好的其他模塊,簡(jiǎn)單點(diǎn)說(shuō):

從Class 文件到dex 文件是針對(duì)Android 平臺(tái)的一種優(yōu)化,是一種通用的優(yōu)化。優(yōu)化過(guò)程中,唯一的輸入是Class 文件。
odex 文件就是dex 文件具體在某個(gè)系統(tǒng)(不同手機(jī),不同手機(jī)的OS,不同版本的OS 等)上的優(yōu)化。odex 文件的優(yōu)化依賴系統(tǒng)上的幾個(gè)核心模塊( 由BOOTCLASSPATH 環(huán)境變量給出, 一般是/system/framework/下的jar 包,尤其是core.jar)。odex 的優(yōu)化就好像是把中那些本來(lái)需要在執(zhí)行過(guò)程中做的類校驗(yàn)、調(diào)用其他類函數(shù)時(shí)的解析等工作給提前處理了。
通過(guò)利用dexopt得到test.odex,接著利用dexdump得到其內(nèi)容,最后可以利用Beyond Compare比較這兩個(gè)文件的差異。
如下圖所示

圖16 test.dex 和test.odex 差異

圖16中,綠色框中是test.dex的內(nèi)容,紅色框中是test.odex的內(nèi)容,這也是兩個(gè)文件的差異內(nèi)容:

test.dex中,TestMain類僅僅是PUBLIC的,但test.odex則增加了VERIFIED和OPTIMIZED兩項(xiàng)。VERIFIED是表示該類被校驗(yàn)過(guò)了,至于校驗(yàn)什么東西,以后再說(shuō)。
然后就是一些方法的不同了。優(yōu)化后的odex文件,一些字節(jié)碼指令變成了xxx-quick。比如圖中最后一句代碼對(duì)于的字節(jié)碼中,未優(yōu)化前invoke-virtual指令表示從method table指定項(xiàng)(圖中是0002)里找到目標(biāo)函數(shù),而優(yōu)化后的odex使用了invoke-virtual-quick表示從vtable中找到目標(biāo)函數(shù)(圖中是000b)。
vtable是虛表的意思,一般在OOP實(shí)現(xiàn)中用得很多。vtable一定比methodtable快么?那倒是有可能。我個(gè)人猜測(cè):

method表應(yīng)該是每個(gè)dex文件獨(dú)有的,即它是基于dex文件的。
根據(jù)odex文件的生成方法(后面會(huì)講),我覺得vtable恐怕是把dex文件及依賴的類(比如Java基礎(chǔ)類,如Object類等)放一起進(jìn)行了處理,最終得到一張大的vtable。這個(gè)odex文件依賴的一些函數(shù)都放在vtable中。運(yùn)行時(shí)直接調(diào)用指定位置的函數(shù)就好,不需要再解析了。以上僅是我的猜測(cè)。
注意:
odex文件由dexopt生成,這個(gè)工具在SDK里沒有,只能由源碼生成。odex文件的生成有三種方式:

preopt:即OEM廠商(比如手機(jī)廠商),在制作鏡像的時(shí)候,就把那些需要放到鏡像文件里的jar包,APK等預(yù)先生成對(duì)應(yīng)的odex文件,然后再把classes.dex文件從jar包和APK中去掉以節(jié)省文件體積。
installd:當(dāng)一個(gè)apk安裝的時(shí)候,PackageManagerService會(huì)調(diào)用installd的服務(wù),將apk中的class.dex進(jìn)行處理。當(dāng)然,這種情況下,APK中的class.dex不會(huì)被剔除。
dalvik VM:preopt是廠商的行為,可做可不做。如果沒有做的話,dalvik VM在加載一個(gè)dex文件的時(shí)候,會(huì)先生成odex。所以,dalvik VM實(shí)際上用得是odex文件。以后我們研究dalvik VM的時(shí)候會(huì)看到這部分內(nèi)容。
實(shí)際上dex轉(zhuǎn)odex是利用了dalvik vm,里邊也會(huì)運(yùn)行dalvik vm的相關(guān)方法。

總結(jié):

以標(biāo)準(zhǔn)角度來(lái)看,Class文件是由Java VM規(guī)范定義的,所以通用性更廣。dex或者是odex只不過(guò)是規(guī)范在Android平臺(tái)上的一種具體實(shí)現(xiàn)罷了,而且dex/odex在很多地方也需要遵守規(guī)范。因?yàn)閐ex文件的來(lái)源其實(shí)還是Class文件。
對(duì)于初學(xué)者而言,我建議了解Class文件的結(jié)構(gòu)為主。另外,關(guān)于dex/odex的文件結(jié)構(gòu),除非有明確需求(比如要自己修改字節(jié)碼等),否則以了解原理就可以。而且,將來(lái)我們看到dalvik vm的實(shí)際代碼后,你會(huì)發(fā)現(xiàn)dex的文件內(nèi)容還是會(huì)轉(zhuǎn)換成代碼里的那些你很熟悉的類型,數(shù)據(jù)結(jié)構(gòu)。比如dex存儲(chǔ)字符串是一種優(yōu)化后的方法,但是到vm代碼中,還不是只能用字符串來(lái)表示嗎?
另外,你還會(huì)發(fā)現(xiàn),Class、dex還是odex文件都存儲(chǔ)了很多源碼中的信息,比如類名、函數(shù)名、參數(shù)信息、成員變量信息等,而且直接用得是字符串。這和Native的二進(jìn)制比起來(lái),就容易看懂多了。
參考鏈接
深入理解Android之Java虛擬機(jī)Dalvik
Androidsource之Dalvik 字節(jié)碼
Androidsource之Dalvik 可執(zhí)行文件格式(dex文件)
Android安全–Dex文件格式詳解
詳細(xì)描述了dex/odex指令的格式----->Dalvik opcodes
解釋器中對(duì) 標(biāo)號(hào) 的使用
A deep dive into DEX file format
Dex文件格式詳解
android中Dex文件結(jié)構(gòu)詳解
Dex文件及Dalvik字節(jié)碼格式解析
Dex 文件格式詳解
Dex文件格式詳解
Android關(guān)于Dex拆分(MultiDex)技術(shù)詳解

總結(jié)

以上是生活随笔為你收集整理的2020-10-27(dex文件解析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

欧美高清成人 | 夜夜爽www| 九热精品 | 婷婷伊人综合亚洲综合网 | 亚洲精品美女久久久久网站 | 日韩福利在线观看 | 91理论片午午伦夜理片久久 | 国产色视频网站 | 欧美视频在线观看免费网址 | 成年人黄色免费网站 | 欧美久久久久久 | 综合网伊人 | avav片| 日韩高清片| 婷婷亚洲五月色综合 | 91入口在线观看 | 干 操 插 | 国产精品久久久久999 | 欧美在线视频二区 | 国产日韩精品欧美 | 国产成人精品999 | 国产视频观看 | 一区二区三区在线免费观看视频 | 久久中文网 | 国产精品久久久久久婷婷天堂 | 99精品一级欧美片免费播放 | 在线黄频| 狠狠色丁香婷综合久久 | 欧美午夜性生活 | 亚洲精品一区二区三区新线路 | 国产精品久久久久久吹潮天美传媒 | 五月天综合网 | 9999精品视频| 久久96国产精品久久99软件 | 久久国产精品一二三区 | 午夜精品一区二区三区在线播放 | 免费手机黄色网址 | 久久99精品久久久久久清纯直播 | 国产精品 国内视频 | 久久久国产影视 | 色婷婷激情电影 | .精品久久久麻豆国产精品 亚洲va欧美 | 日日夜夜综合 | 国产婷婷在线观看 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 国产精品成人在线 | 最近的中文字幕大全免费版 | 欧美成人按摩 | 成年人毛片在线观看 | 人人爱人人添 | 欧美久久久久久久久中文字幕 | 精品亚洲在线 | 91九色porny蝌蚪主页 | 国产在线91精品 | 久久久久亚洲精品 | 四虎永久精品在线 | 欧美视频在线二区 | 国产无区一区二区三麻豆 | 国产999精品久久久久久绿帽 | 91在线视频在线 | 中国一级片在线 | 欧美久久久一区二区三区 | 中文资源在线官网 | 国产精品理论片在线观看 | 亚洲欧美怡红院 | 天天爽人人爽夜夜爽 | 色网站视频 | 久久91久久久久麻豆精品 | 亚洲欧洲av | 日日干av | 亚洲精品三级 | 久久精品电影网 | 波多野结衣网址 | 久久精品久久国产 | 色综合久久88色综合天天人守婷 | 中文字幕视频一区二区 | 五月婷网 | 成人在线视频一区 | 天天射网 | 久久99久久99免费视频 | 精品视频专区 | 日韩高清在线一区二区 | 五月婷婷六月丁香激情 | 97在线观看免费观看高清 | 精品国产一区二区三区久久 | 91热爆视频 | 婷婷激情五月 | 中文一区二区三区在线观看 | 国产亚洲精品久久久网站好莱 | 久久香蕉电影网 | 亚洲1区在线 | 久草在线视频首页 | 婷婷免费视频 | av观看免费在线 | 久久久午夜精品理论片中文字幕 | 久久手机在线视频 | 伊人影院得得 | 亚洲第一区在线观看 | 996久久国产精品线观看 | 91在线播 | 日韩一二三区不卡 | 天天综合久久综合 | 中文字幕123区 | 福利一区二区在线 | 亚洲精品国产综合久久 | 99视频+国产日韩欧美 | 免费观看的黄色片 | 国产免费午夜 | 成人午夜影院在线观看 | av成人免费网站 | 色久av | 中文字幕色在线 | 五月天六月婷婷 | www亚洲视频| 久久看免费视频 | 亚洲经典视频在线观看 | 国产精品男女 | 一级免费看视频 | 国产美腿白丝袜足在线av | 日韩精品久久久久久 | 欧美成人精品三级在线观看播放 | 精品久久久久一区二区国产 | 欧美一级片免费 | 久草免费福利在线观看 | 久久国产精品一区二区 | 91精品久久香蕉国产线看观看 | 91免费看片黄 | 欧洲精品视频一区 | 色免费在线 | 夜夜操夜夜干 | 中文字幕91视频 | 96精品高清视频在线观看软件特色 | 99久久精品国产观看 | 日韩av免费在线电影 | 亚洲综合干 | 在线亚洲激情 | 波多野结衣资源 | 特级aaa毛片 | 久久国产精品99久久久久久老狼 | 国产精品毛片一区 | 成人av高清 | 一区二区三区在线观看免费视频 | www色网站 | 国产美女免费观看 | 天天拍天天干 | 一区在线观看视频 | 日本91在线 | 欧美日韩午夜 | 91大神在线看 | 人人爽人人插 | 欧美精品v国产精品v日韩精品 | 日韩免费看的电影 | 日韩黄色一区 | 亚洲日本va中文字幕 | 91亚洲狠狠婷婷综合久久久 | 4p变态网欧美系列 | 美女免费黄视频网站 | 91福利区一区二区三区 | 免费看污片 | 精品国精品自拍自在线 | 国产乱码精品一区二区三区介绍 | 三级视频片 | 国产精品99蜜臀久久不卡二区 | 亚洲成人高清在线 | 国产免费人成xvideos视频 | 久二影院 | 欧美九九视频 | 久草在线视频网站 | 中国一级特黄毛片大片久久 | 在线观看视频亚洲 | 日韩羞羞 | 日韩精品视频免费在线观看 | 综合网久久| 日韩精品久久久久久中文字幕8 | 色婷婷啪啪免费在线电影观看 | 久久99国产精品久久 | 69久久夜色精品国产69 | 最近中文字幕大全中文字幕免费 | 精品久久电影 | 黄色毛片大全 | 久久久综合香蕉尹人综合网 | 欧美成人理伦片 | 亚洲视频在线观看免费 | 日韩理论视频 | 色婷婷国产精品一区在线观看 | 91看片一区二区三区 | 亚洲专区在线 | 久久国产精品二国产精品中国洋人 | 成人一级黄色片 | 国内精品视频在线 | 69国产精品视频 | www178ccom视频在线 | 成人小视频在线免费观看 | 91香蕉视频黄 | 国产伦理一区二区 | 毛片99| 免费亚洲视频 | 欧美一区二区三区在线播放 | 国产一区二区视频在线 | 国产经典三级 | 九九九热精品免费视频观看网站 | 西西人体4444www高清视频 | 亚洲极色 | 欧美激情精品 | 亚洲国产视频在线 | 日韩欧美网址 | 九九一级片 | 亚洲视频1 | 国产精品欧美精品 | 久久99久国产精品黄毛片入口 | 国产精品一区二区av麻豆 | 91在线中文| 波多野结依在线观看 | www在线免费观看 | 福利视频一区二区 | 欧美日韩国产色综合一二三四 | 亚洲精品国产综合99久久夜夜嗨 | 日韩中文字幕在线观看 | 在线免费看黄网站 | 永久免费av在线播放 | 亚洲首页 | 91资源在线视频 | 性色在线视频 | 成人免费视频观看 | 国产免费高清视频 | 97在线观看免费高清完整版在线观看 | 91亚州 | 精品视频不卡 | 97日日碰人人模人人澡分享吧 | 久久免费视频网站 | 欧美精品二| 国产免费又粗又猛又爽 | 国产一级电影在线 | 少妇搡bbbb搡bbb搡忠贞 | 久久五月婷婷丁香 | 欧美日韩一区二区在线观看 | 久久久穴| 亚洲视频,欧洲视频 | av再线观看| 在线观看中文字幕av | 国内精品久久久久影院一蜜桃 | 中文字幕在线播放视频 | 国产福利91精品张津瑜 | 国产在线观看污片 | 久草91视频| 日本中文字幕免费观看 | 福利视频入口 | 亚洲精品视频在线观看免费 | 色吧av色av| 99色婷婷| 亚洲综合成人av | 美女精品在线观看 | 在线观看国产永久免费视频 | 国产精品毛片一区二区 | 欧美一区成人 | 精品色综合 | 精品视频在线免费观看 | 丁香婷婷网 | 午夜视频在线观看欧美 | 成年人免费av| 中文字幕国产一区二区 | 婷婷色5月| 欧美激情精品久久久久久 | 99免费在线观看视频 | 欧美性久久久 | a√国产免费a | 色久综合 | 午夜电影一区 | 久草免费新视频 | 国产精品黄色 | 激情婷婷在线观看 | 伊人春色电影网 | 国产精品久久久久久久久久免费 | 免费毛片aaaaaa | 九九九九九精品 | www欧美xxxx | 亚洲1区在线 | 久草在线手机观看 | 91视频a| 日本久久久久久久久久久 | 精品久久久久久久久中文字幕 | 国产精品a久久 | 日日夜夜噜 | 欧美一区二区免费在线观看 | 国产999精品久久久久久 | 久久久久国产成人精品亚洲午夜 | 久久久国产高清 | 日本三级在线观看中文字 | 超碰公开在线 | 久久精彩免费视频 | 国产综合精品久久 | 国产精品美女在线观看 | 国产视频中文字幕 | 在线观看免费国产小视频 | 中文av字幕在线观看 | 国产精品免费久久久 | 亚洲精品视频免费在线 | 免费高清无人区完整版 | 欧美激情精品久久久久久免费 | 嫩草伊人久久精品少妇av | 亚洲精品视 | 欧美色888 | 91麻豆免费版 | 亚色视频在线观看 | 色综合天天色 | 亚洲欧美国内爽妇网 | 亚洲干 | 免费欧美高清视频 | 欧美精品乱码久久久久 | 国产成人久久久77777 | 日本黄色免费电影网站 | 丁香婷婷基地 | 精品视频9999 | 女人久久久久 | 99精品一区二区 | 色香com. | 成人免费视频视频在线观看 免费 | 国产亚洲无 | 色婷婷av一区二 | 日日干av | 夜夜高潮夜夜爽国产伦精品 | 91黄色在线观看 | 99久久精品免费一区 | 亚洲天堂自拍视频 | 天天色欧美| 91在线影院| 久久久久久久久久毛片 | 伊人国产女| av一区在线 | 特级西西444www大胆高清无视频 | 精品人妖videos欧美人妖 | 欧美少妇bbwhd | 91视频中文字幕 | 免费一区在线 | 在线成人观看 | 日韩成人邪恶影片 | 中文一区二区三区在线观看 | 免费无遮挡动漫网站 | 国产成人精品一区二区三区福利 | 久久久国产精品电影 | 天天拍夜夜拍 | a黄色一级片| 欧美性春潮 | 一区二区三区中文字幕在线 | 九九在线视频免费观看 | 黄色一及电影 | 久久精彩视频 | 色网站中文字幕 | 免费观看特级毛片 | 久久美女电影 | 国产永久免费高清在线观看视频 | 成人av免费网站 | 在线免费高清一区二区三区 | 99久久日韩精品视频免费在线观看 | 97超视频免费观看 | 高清不卡毛片 | 99精品国产兔费观看久久99 | 日韩a在线观看 | 很黄很黄的网站免费的 | 二区三区中文字幕 | 亚洲精品黄色片 | 国产精品9999 | 天天躁日日躁狠狠躁av麻豆 | 久久综合中文字幕 | 免费在线黄色av | www.99av| 97看片 | 麻豆系列在线观看 | 国产精品久久久久影院 | 99中文字幕视频 | 91丨九色丨蝌蚪丨对白 | 天天爽夜夜爽人人爽曰av | 午夜视频99| 成人97视频一区二区 | 91av99| 国产精品自产拍在线观看 | 亚洲成a人片77777潘金莲 | 精品久操| 亚洲午夜精品一区二区三区电影院 | 狠狠干成人| 亚洲精品视频免费在线观看 | 久久五月天婷婷 | 久久久精品国产免费观看同学 | 五月天六月婷 | 亚洲视频免费在线看 | 一区二区电影在线观看 | 最新超碰在线 | 久久伊99综合婷婷久久伊 | 免费av的网站 | 天天操夜夜操 | 色资源在线 | 四虎影视成人 | 国产精品va | 成人久久精品视频 | 国产一二三区av | 国产色区 | 久久黄色小说 | 免费福利在线视频 | 久久久久久亚洲精品 | 国产一级不卡视频 | 欧美人体xx | 欧美日在线 | 国产亚洲在线视频 | 超碰在线免费福利 | 一区二区三区在线电影 | 91在线视频| 亚洲视频精品 | 91视频 - v11av| 日本精品久久久久影院 | 免费精品视频在线观看 | 999久久国产精品免费观看网站 | 成人动漫视频在线 | 精品成人国产 | 91污污视频在线观看 | 免费在线观看污 | 国产尤物在线 | 91香蕉国产| 精品成人网| 免费国产视频 | 黄色免费观看网址 | www.激情五月.com| 日日操夜 | 中文字幕在线专区 | 久久综合色影院 | 亚洲精品高清视频在线观看 | 在线观看视频一区二区三区 | 免费三级在线 | 免费观看成人网 | 色婷婷中文| 色综合天 | 国产香蕉久久 | 999在线视频 | 婷婷色网视频在线播放 | av三区在线| 久久久久免费精品国产 | 欧美另类69 | 欧美十八 | 日韩免费高清在线观看 | 午夜av剧场 | 911在线| 69久久夜色精品国产69 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 区一区二区三在线观看 | 成人久久 | 国产精品久久久999 国产91九色视频 | 日韩精品大片 | 天堂在线视频免费观看 | 国产一区在线视频 | 欧美在线一二区 | 免费看高清毛片 | 狠狠色丁香婷婷综合欧美 | www.天天操.com | 天天艹日日干 | 欧美日韩一区二区三区在线免费观看 | 久久五月激情 | 91在线看片 | 天天综合亚洲 | 91人人爽久久涩噜噜噜 | 国产精品国产三级在线专区 | 久久精品国产一区二区三区 | 精品亚洲欧美无人区乱码 | 欧美精品在线视频 | 亚洲人成影院在线 | 日日摸日日 | 日本黄色免费看 | 久久久久成人精品免费播放动漫 | 亚洲欧美综合精品久久成人 | 色天天久久| 亚洲视频1区2区 | 激情久久五月天 | 亚洲日本中文字幕在线观看 | 欧美日韩一区二区三区免费视频 | 国产精品美女久久久久久 | 色婷婷激情 | 国产精品欧美日韩在线观看 | 日韩在线首页 | 狠狠色丁香婷婷综合久小说久 | 日日夜夜草 | 国产精品毛片一区二区三区 | 日韩不卡高清 | 久草在线高清视频 | 91久色蝌蚪 | 国产精品一区二区久久久 | 手机成人在线 | 狠狠插天天干 | 国产成人精品三级 | 欧美日韩视频免费看 | 久久综合操 | 国产成人久久av977小说 | 狠狠狠狠狠狠狠 | 中文字幕 国产精品 | 亚洲欧美视频在线 | 在线www色 | 国产免费又黄又爽 | 不卡视频国产 | 国产96视频 | 99精品视频在线观看视频 | 国产精品高清在线观看 | 色综合天天狠天天透天天伊人 | 国产99亚洲 | 天天草av | 激情五月播播久久久精品 | 亚洲精品综合一区二区 | 欧美亚洲国产精品久久高清浪潮 | 久久成人免费 | 青青草国产成人99久久 | 久久久国产高清 | 国产日产精品一区二区三区四区的观看方式 | 久久午夜精品 | 九九欧美 | 婷婷在线色 | 中文字幕乱码在线播放 | 亚洲国产精品一区二区久久,亚洲午夜 | 国产精品区一区 | 99久久婷婷国产综合精品 | 在线免费av网站 | 成年人国产在线观看 | 国产精品成人久久久久 | 久久精国产| 国产视频一 | 欧美激情视频免费看 | 香蕉视频在线视频 | 国产精品久久久久婷婷二区次 | 国产不卡一 | 欧美日韩中文国产 | 天堂成人在线 | 人人爽人人片 | 99在线国产 | av不卡中文 | 又大又硬又黄又爽视频在线观看 | 91看片成人 | 超碰大片 | 日本不卡123 | 天天超碰 | 欧美性视频网站 | 毛片网在线观看 | 操操综合网 | 99久久久久久久 | 激情综合国产 | 波多野结衣资源 | 久久精品国产亚洲精品 | 国产欧美精品一区二区三区 | 97超碰精品| 最近高清中文在线字幕在线观看 | 日韩免费大片 | 99国产精品久久久久老师 | 国产精品av免费 | 色综合久久五月天 | 一级a毛片高清视频 | 92av视频 | 日韩电影精品 | 国产美女免费观看 | 国产亚洲精品久久久久久网站 | 永久免费观看视频 | 一级黄色大片在线观看 | 久久国产经典视频 | 亚洲午夜久久久久久久久久久 | 精品96久久久久久中文字幕无 | 欧美精品在线免费 | 黄色片网站av | 欧美大香线蕉线伊人久久 | 狠狠的干 | 视频在线一区二区三区 | 九九欧美视频 | 久久精品久久久久电影 | 成人黄大片视频在线观看 | 日韩大片在线免费观看 | 99视频精品全部免费 在线 | 综合激情久久 | 亚洲激情久久 | 成片视频免费观看 | 黄色成人在线观看 | 一区二区三区www | 91日韩在线视频 | 91av在线免费看 | 国产精品毛片一区 | 最近2019中文免费高清视频观看www99 | 国产色综合天天综合网 | 精品美女在线视频 | 久久夜色精品国产欧美一区麻豆 | 国产一区二区日本 | 国产欧美久久久精品影院 | 99久久精 | 韩日精品视频 | av解说在线 | 成人综合婷婷国产精品久久免费 | 国产精品成人免费一区久久羞羞 | 国产成人一区二区三区 | 亚洲国产精品传媒在线观看 | 人人爽人人爽人人爽人人爽 | 8x8x在线观看视频 | 蜜臀av.com | 欧美精品在线一区 | 久久黄色a级片 | 久久久久观看 | 久久亚洲综合色 | 亚洲成av人片在线观看香蕉 | 人人狠狠综合久久亚洲婷 | 99精品在线视频播放 | 国产精品入口久久 | 青青草国产成人99久久 | av黄色免费在线观看 | av丝袜在线 | 免费看片网页 | 久久草草影视免费网 | 久久免费美女视频 | 亚洲,播放 | 超碰在线亚洲 | 一本—道久久a久久精品蜜桃 | 久久久久免费观看 | 最近中文字幕大全中文字幕免费 | 激情综合网色播五月 | 久久久久久国产精品999 | 国产精品s色 | 精品福利视频在线 | a v在线视频 | 久久精品99国产精品酒店日本 | 天天操月月操 | 欧美性性网 | 久久99国产精品视频 | av成人免费在线看 | 人人澡超碰碰97碰碰碰软件 | 欧美成人精品欧美一级乱 | 精品国产一区二区在线 | 国产色在线视频 | 久久精品国产美女 | 在线观看网站你懂的 | 欧美伦理一区二区三区 | 一本一道久久a久久综合蜜桃 | 中文字幕av一区二区三区四区 | 丁香六月中文字幕 | 97超碰在线视 | 国产做爰视频 | 中文字幕免费成人 | 97视频一区 | 在线观看国产高清视频 | 亚洲男人天堂a | 国产精品毛片久久蜜 | 欧美 日韩 成人 | 久久久三级视频 | 精品国产精品久久一区免费式 | 中文字幕亚洲综合久久五月天色无吗'' | 国产99精品 | 免费av大片 | 九九久久婷婷 | 久久久久久久久影院 | 黄网站免费大全入口 | 国产日产精品久久久久快鸭 | 久草视频免费在线观看 | 日韩欧美精品在线 | 国内少妇自拍视频一区 | 在线 国产一区 | 毛片一区二区 | 精品国产乱子伦一区二区 | 97精品国产97久久久久久免费 | 亚洲一区欧美激情 | 国产午夜精品一区二区三区嫩草 | 丁香国产视频 | 西西44人体做爰大胆视频 | 99久久精品午夜一区二区小说 | 激情丁香久久 | 中文字幕精品一区二区三区电影 | 欧美日韩中文字幕在线视频 | 四虎国产精| 日韩在线三区 | 很黄很黄的网站免费的 | 亚洲精品乱码久久久久久蜜桃不爽 | 成人av在线网址 | 婷婷色影院| 久久精品一二三区 | 深爱五月激情网 | 国产成人精品不卡 | 91porny九色91啦中文 | 久久av伊人| 亚洲精品国产自产拍在线观看 | 91麻豆网站 | 国内精品久久久久 | 2019中文字幕第一页 | 国产精品1区2区3区 久久免费视频7 | 中文字幕乱码电影 | 精品日韩在线 | 亚洲精品tv久久久久久久久久 | 波多野结衣电影一区二区三区 | 韩国视频一区二区三区 | 国产精品美女久久久久久久 | 国产一区在线视频观看 | 欧美日韩成人 | 国产精品一区二区免费看 | 免费av电影网站 | 欧美久久久久久久久久久久久 | 久久国产一区二区 | 色婷婷综合久久久中文字幕 | 日韩欧美一区二区三区在线观看 | 日韩一区二区三区不卡 | 久久亚洲免费 | 欧美成人黄色片 | 国产高清在线免费观看 | 在线免费观看国产黄色 | 日韩精品欧美视频 | 久久激情视频免费观看 | 国产一卡二卡四卡国 | 美女网站久久 | 在线黄网站 | 亚洲国产最新 | 亚洲精品免费在线播放 | 日韩免费一区二区三区 | 97精品久久 | 国产aa免费视频 | 国产成人久久av977小说 | 成人av免费在线观看 | 我要看黄色一级片 | 免费日韩视频 | 日韩精品免费在线观看视频 | 精品国产精品久久 | 日韩一区二区三区在线观看 | 中国美女一级看片 | 欧美高清成人 | 日韩欧美在线综合网 | 久久久99精品免费观看乱色 | 日韩美视频 | 欧美日韩国产一区二 | 在线观看岛国av | 国产精品国产三级国产aⅴ无密码 | 国产一区二区精品91 | 一级淫片a | 日日综合网 | 国产精品永久免费 | 日韩欧美在线免费 | 中文视频在线看 | 国产精品观看在线亚洲人成网 | 国产毛片久久 | 日韩av午夜| 精品国产久| 日韩国产欧美在线播放 | 99久久这里有精品 | 91日韩在线| 99热这里只有精品免费 | 在线视频91 | 成人在线播放av | 欧美午夜a | 综合色伊人 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 黄色h在线观看 | 很污的网站 | 丁香花五月 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 免费a网站 | 国产在线超碰 | 人人视频网站 | 国产成人免费高清 | 日韩中文字幕免费 | av中文字幕网址 | a在线一区 | 久久综合加勒比 | 久草视频2| 在线观看黄色的网站 | 亚洲国产精品500在线观看 | 在线观看 亚洲 | 九九热re | 久久成年人 | 丰满少妇高潮在线观看 | 9ⅰ精品久久久久久久久中文字幕 | 人人超碰在线 | 久久久久久国产精品免费 | av丝袜美腿 | 久久久久这里只有精品 | 久草视频一区 | 国产精品美女999 | 欧美日韩调教 | 91免费视频黄 | 97碰碰精品嫩模在线播放 | 色综合中文综合网 | 久久久免费少妇 | 天天做天天干 | 视频在线观看日韩 | 久久久久国产成人精品亚洲午夜 | 国产麻豆电影在线观看 | 91精品伦理 | 99热精品国产 | 韩国一区视频 | 免费手机黄色网址 | 91麻豆.com| 国产在线高清 | 久久怡红院| 黄色毛片视频 | 久久中文精品视频 | 五月婷在线视频 | 久久美女高清视频 | 97免费在线观看 | 国产片免费在线观看视频 | 国产在线观看免 | 在线观看中文字幕第一页 | 久久久99精品免费观看app | 久久精品99国产精品酒店日本 | 久草在线看片 | 国产精品久久久久高潮 | 亚洲性xxxx | 五月激情久久久 | 亚洲成人av在线播放 | 五月天色婷婷丁香 | 亚洲黄色片一级 | 国产午夜精品免费一区二区三区视频 | 日韩欧美专区 | 久久九九国产视频 | 国产高清无线码2021 | 日韩精品第1页 | 欧美精品首页 | 国产在线观看中文字幕 | 91日本在线播放 | 91看片黄色| 久久久久成人免费 | 玖玖999| 午夜.dj高清免费观看视频 | 六月婷操 | 亚洲国产成人精品在线观看 | 国产麻豆视频网站 | 久久艹在线 | 日韩乱码中文字幕 | 天天综合成人网 | 亚洲一区二区麻豆 | 久久av电影| 27xxoo无遮挡动态视频 | 亚洲一区日韩精品 | 99久久精品国产一区二区三区 | 天天干天天插伊人网 | a在线观看免费视频 | 日韩在线观看视频免费 | 亚洲精品视频二区 | 91久久精品一区二区二区 | 国产高清不卡一区二区三区 | 8x8x在线观看视频 | 最近最新最好看中文视频 | 久久影院精品 | 99精品免费久久久久久日本 | 日本高清免费中文字幕 | 黄色一级动作片 | 成人免费视频网址 | 国产精品毛片久久蜜 | 中文在线亚洲 | 亚洲精品伦理在线 | 国产成人一区二区在线观看 | 91粉色视频 | 丁香在线观看完整电影视频 | 亚洲精品国产精品国自 | 久久久国产毛片 | 亚洲精品国产精品国自 | 国产精品久久视频 | 中文字幕色婷婷在线视频 | 国产分类视频 | 国产精品一区二区av日韩在线 | 精品福利在线 | 久久久影片 | 精品久久久久一区二区国产 | 18国产精品白浆在线观看免费 | 国产成人精品亚洲日本在线观看 | 中文字幕在线观看网站 | 午夜电影 电影 | 久久久久电影 | 又黄又爽又无遮挡的视频 | 在线观看免费成人 | 夜夜看av| 亚洲综合激情小说 | 成 人 黄 色视频免费播放 | 国产91九色蝌蚪 | 91视频 - v11av| 精品久久国产一区 | 97精品视频在线播放 | 久久久久影视 | 午夜精品久久久 | 久久黄色网址 | 91精品久久久久 | 深夜免费福利网站 | 国产一级精品绿帽视频 | 黄色一级大片在线免费看国产一 | 国产高清一 | 久久婷婷一区二区三区 | 三级黄色大片在线观看 | 欧美国产高清 | 超碰97人人射妻 | 黄色片亚洲 | 人成电影网 | 九九九九九国产 | 在线观看免费一区 | 天天天综合网 | 九九热精品视频在线播放 | 蜜臀久久99精品久久久酒店新书 | 久久天天综合网 | 九九久久视频 | 激情综合网在线观看 | 9999在线视频 | 国产艹b视频 | 欧美激情一区不卡 | 国产成视频在线观看 | 婷婷久久一区二区三区 | 超碰97国产精品人人cao | 日女人免费视频 | 久草亚洲视频 | 亚洲人成网站精品片在线观看 | 美女视频国产 | 在线看的av网站 | 在线观看国产中文字幕 | 婷婷免费视频 | 日日麻批40分钟视频免费观看 | av成人免费网站 | 国产小视频网站 | 日韩三级.com | 激情婷婷 | 午夜av一区二区三区 | 成人午夜电影在线播放 | 人人插人人艹 | 色窝资源| 亚洲一区视频在线播放 | 碰碰影院| 91天堂素人约啪 | 久久99精品国产99久久6尤 | 四虎在线免费观看 | 中文字幕有码在线观看 | 日韩一级网站 | 欧美精品一区二区在线播放 | 亚洲精品视频网址 | 日韩免费在线观看视频 | 日韩精品欧美视频 | 国产一区久久久 | 亚洲精品中文在线观看 | 亚洲综合在线观看视频 | 精品国产一区二区三区在线 | 国偷自产视频一区二区久 | 91大神一区二区三区 | 97超碰人人模人人人爽人人爱 | 亚洲无人区小视频 | 黄色在线观看www | 69久久久久久久 | 日日天天干 | 亚洲丝袜一区二区 | 精品国产日本 | 特级西西www44高清大胆图片 | 色网站在线看 | 精品久久一级片 | 九九九热| 激情综合网五月激情 | 999成人| 欧美精品亚洲二区 | 国产小视频免费在线网址 | 精品久久久久久亚洲 | 欧美在线18 | 久久中文精品视频 | 日韩爱爱网站 | 92国产精品久久久久首页 | 国产视频一区精品 | 2020天天干夜夜爽 | 成人福利av| 国产无遮挡又黄又爽在线观看 | www.黄色 | 精品国产电影一区二区 | 欧美日韩免费在线视频 | 99综合视频 | 99热99| 久久久久久久久久久电影 | 五月天电影免费在线观看一区 | 国产女v资源在线观看 | 日本二区三区在线 | 中文字幕精品一区二区精品 | www久久99 | 日韩欧美在线免费观看 | 午夜视频黄| 久久99久久99精品免观看软件 | 久久99精品国产麻豆婷婷 | 香蕉久久久久久av成人 | 91av在线播放视频 | 免费在线观看成人 | 日本中文字幕在线视频 | 中文字幕永久免费 | 天天天插 | 精品在线99 | 国产亚洲永久域名 | 亚洲 成人 一区 | 国产亚洲情侣一区二区无 | 国产情侣一区 | 亚洲一区日韩在线 | 欧美日韩精品在线观看视频 | 天天爱天天操天天爽 | 亚洲专区视频在线观看 | 国产成人精品女人久久久 | 天天操狠狠操夜夜操 | 国产一级片久久 | 欧美精品久久人人躁人人爽 | 国产一区二区三区免费在线观看 | www久久九 | 亚洲电影在线看 | 久久久九九 | 日韩欧美网站 | 久草在线高清 | 成人播放器 | 久久伦理电影 | 国产免费大片 | 免费看久久 | 99免费精品 | 国产美女在线免费观看 |