24
発表者 : 僻地のプログラマ kmt-t

詳解Dexファイルフォーマット

  • Upload
    kmt-t

  • View
    3.898

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 詳解Dexファイルフォーマット

発表者 : 僻地のプログラマ kmt-t

Page 2: 詳解Dexファイルフォーマット

ハンドルネーム ◦ 正式にはkmt-t

◦ はてなID : kmt-t2

◦ Twitter ID : kmt_t

僻地(鳥取県)出身です ◦ 大阪まで出稼ぎに出ています

得意分野など ◦ プログラミング言語はC++/C#など

◦ 組み込みではミドルウェア開発を得意にしています

2D/3Dグラフィックスおよび画像処理

ファイルシステム

Page 3: 詳解Dexファイルフォーマット

今回の発表はDalvik仮想マシン3部作の最後です 1. Dalvik仮想マシンのアーキテクチャ

2. Dalvikバイトコードのリファレンスの読み方

3. 詳解DEXフォーマット ← 今回はこれ!

発表の目的 1. Dalvik仮想マシンのソースコードを誰でも読めるように!

2. Dalvik仮想マシンに関するみんなのリテラシを上げる!

3. より深い部分の発表をするための下地をつくる!

Page 4: 詳解Dexファイルフォーマット

Dalvik仮想マシンの実行ファイル ◦ Windowsで言えばPEファイルに相当します

◦ Javaで言えばクラスファイルに相当します

◦ Javaのクラスファイルとは形式が違います

◦ 配布する場合は生のDEXファイルではなくパッケージされたapkファイルにすることが殆どです

Dalvik仮想マシン同様シンプルで結構簡単です

◦ 理解するとバイトコードの動的生成、バイトコードエンジニアリングなどができるようになります

リファレンス ◦ $ANDROID_SOURCE/dalvik/docs/dex-format.html

Page 5: 詳解Dexファイルフォーマット

Linuxにおけるobjdump相当 ◦ Android SDKに含まれています

◦ このツールでDEXファイルのいろいろな情報が抜き出せます

◦ 実用的にはこのツールが不自由なく使えるレベルのDEXファイルフォーマットの知識があれば充分

代表的なオプション

オプション 説明

-f ヘッダ(クラスやメソッドの定義など)のサマリーの表示

-h ヘッダ(クラスやメソッドの定義など)の詳細の表示

-d コードの逆アセンブルの表示

Page 6: 詳解Dexファイルフォーマット
Page 7: 詳解Dexファイルフォーマット

ファイルは以下の領域に分割

data領域、link_data領域に可変長データを格納 ◦ link_data領域はアンドキュメンテッド

◦ それ以外の領域には固定長のデータしか格納されない

ヘッダ領域 string_ids領域

type_ids領域 proto_ids領域

field_ids領域 method_ids領域

class_defs領域 data領域

link_data領域

Page 8: 詳解Dexファイルフォーマット

アイテム名 内容

magic “dex¥n035¥0” (固定値)

checksum alder32によるチェックサム。signatureでも同様

の検出ができるが、ファイルの破損チェック用計算コストの問題から通常はこちらを使った方が良い

signature SHA-1によるハッシュ値。ファイルを一意に識別す

るために使用できる。配布元の正しいハッシュ値と比較すれば改ざんされていることは簡単に検出できる。計算コストが高いので毎起動時に検査するのは難しい

file_size ファイルサイズ

header_size ヘッダサイズ。固定長

endian_tag 固定データ(0x12345678)。ファイルのエンディアン識別用

Page 9: 詳解Dexファイルフォーマット

アイテム名 内容

link_size link_data領域のバイト数

link_off link_data領域へのオフセット

map_off data領域のレイアウトを示すmapへのオフセット。基本的にmapの情報は他の情報の冗長データになっている(ファイルかデータを読み出す際には必須ではない)

string_ids_size 文字列定数プールに格納されている文字列の数。

string_ids_off string_ids領域へのオフセット

type_ids_size type_ids領域のデータの数

type_ids_off type_ids領域へのオフセット

proto_ids_size proto_ids領域のデータの数

proto_ids_off proto_ids領域へのオフセット

Page 10: 詳解Dexファイルフォーマット

アイテム名 内容

field_ids_size field_ids領域のデータ数

field_ids_off field_ids領域へのオフセット

method_ids_size method_ids領域のデータ数

method_ids_off method_ids領域へのオフセット

class_defs_size class_defs領域のデータの数

class_defs_off class_defs領域へのオフセット

data_size data領域のバイト数

data_off data領域へのオフセット

Page 11: 詳解Dexファイルフォーマット

定数文字列プールを格納する領域

以下の情報の配列(データ数はヘッダに記述)

オフセットが指すdata領域には以下のデータが格納

データ名 型名 内容

string_data_off uint data領域の定数文字列データへのオフセット

データ名 型名 内容

utf16_size uleb128 MUFT-8文字列をUTF-16にデコードしたときの文字列長

data MUTF-8 文字列データ

Page 12: 詳解Dexファイルフォーマット

LEB128 ◦ DWORF3でも使われているデータ形式らしいです

◦ 可変長整数データ型です

Byteの最上位bitが立っている場合は次のByteはその上位7bitが格納されています。byteの最上位ビットが落ちている場合はデータ終了

◦ 値の小さな整数はデータ長が短くなります

◦ 可変長なのでdata領域のみに存在します

余談 ◦ 実際にはDEXはapk(ZIP)でパッケージされるのであんまり意味が無い(圧縮したらサイズは同じぐらいになる)のでは

Page 13: 詳解Dexファイルフォーマット

UTF-16の一文字を1~3byteにエンコードした形式 ◦ Javaバイトコードでも使われています

◦ Java、Dalvikともに内部の文字コードはUTF-16です

◦ MUTF-8の方がUTF-8より都合がいいです

◦ エンコード元がUTF-16なのでサロゲートペアは出現します

◦ Linuxでのワイド文字列はUTF-32なので取り扱いは注意

◦ 可変長なのでdata領域のみに存在します

余談 ◦ あんまり意味が無いと思うんですが(UTF-16そのままでもあまり差が出ないはず)、がんばりすぎですよね

Page 14: 詳解Dexファイルフォーマット

DEXファイルで参照されている型のテーブル

以下の情報の配列(データ数はヘッダに記述)

TypeDiscriptorは以下のフォーマットの文字列

データ名 型名 内容

descriptor_idx uint 型名を表すTypeDiscriptor文字列のID (string_ids領域ののインデックス)

文字列 型名

V, Z, B, S, C, I, J, F, D プリミティブ型

Lfully/qualified/Name; クラス型 (この場合”fully.qualified.Name”)

[TypeDescrioter 配列型 (“[I”ならintの配列)

Page 15: 詳解Dexファイルフォーマット

DEXファイルで参照されているメソッド型のテーブル

以下の情報の配列(データ数はヘッダに記述)

データ名 型名 内容

shorty_idx uint 型名を表すShortTypeDiscriptor文字列のID(string_ids領域のインデックス)

return_type_idx uint 戻り値型のID (type_ids領域のインデックス)

parameters_off uint パラメータ型のIDのリストへのオフセット。オフセットの指す先はdata領域

Page 16: 詳解Dexファイルフォーマット

クラスのフィールド情報を格納する領域

以下の情報の配列(データ数はヘッダに記述)

データ名 型名 内容

class_idx ushort フィールドを所有するクラス型のID (type_ids領域のインデックス)

type_idx ushort フィールド型のID (type_ids領域のインデックス)

name_idx uint フィールド名の文字列ID (string_ids領域のインデックス)

Page 17: 詳解Dexファイルフォーマット

クラスのメソッド情報を格納する領域

以下の情報の配列(データ数はヘッダに記述)

データ名 型名 内容

class_idx ushort メソッドを所有するクラス型のID (type_ids領域のインデックス)

proto_idx ushort メソッド型のID (proto_ids領域のインデックス)

name_idx uint メソッド名の文字列ID (string_ids領域のインデックス)

Page 18: 詳解Dexファイルフォーマット

クラス情報を格納する領域

以下の情報の配列(データ数はヘッダに記述)

データ名 型名 内容

class_idx uint クラス型のID (type_ids領域のインデックス)

access_flags uint アクセス属性フラグ

superclass_idx uint 親クラス型のID (type_ids領域のインデックス)

interfaces_off uint 継承インターフェイス型のリストへのオフセット

source_file_idx uint ソースファイル名の文字列ID

annotations_off uint アノテーション情報のオフセット

class_data_off uint class_dataへのオフセット

static_values_off uint 静的フィールドの初期値.

Page 19: 詳解Dexファイルフォーマット

data領域に含まれるデータ一覧 (1/2)

データ名 内容

MapList ファイルデータのレイアウト情報

StringData 文字列データ

TypeList 型IDのリスト

AnnotationDirectory クラスとそのフィールド、メソッドのすべてのアノテーション情報の集まり

AnnotationSetRef アノテーションのリストのリスト

AnnotationSet アノテーションのリスト

Annotation アノテーション

EncodedArray クラスの初期値、アノテーションの設定値を圧縮したデータ

Page 20: 詳解Dexファイルフォーマット

data領域に含まれるデータ一覧 (2/2)

データ名 内容

ClassData クラス情報

Code メソッドのバイトコードの情報

DebugInfo デバッグ情報

Page 21: 詳解Dexファイルフォーマット

データ名 型名 内容

static_fields_size uleb128 静的フィールドの数

instance_fields_size uleb128 インスタンスフィールドの数

direct_methods_size uleb128 コンストラクタ、静的メソッドの数

virtual_methods_size uleb128 仮想メソッドの数

static_fields

encoded_field

の配列 静的フィールドの数

instance_fields encoded_field

の配列 インスタンスフィールドの情報

direct_methods encoded_method

の配列 コンストラクタ、静的メソッドの 情報

virtual_methods

encoded_method

の配列 仮想メソッドの情報

Page 22: 詳解Dexファイルフォーマット

encoded_field構造体

encoded_method構造体

データ名 型名 内容

field_idx_diff Uleb128 フィールドID (field_ids領域のインデックス) 差分前のフィールドの値との差分

access_flags Uleb128 アクセスフラグ

データ名 型名 内容

method_idx_diff uleb128 メソッドID (method_ids領域のインデックス) 差分前のメソッドの値との差分

access_flags uleb128 アクセスフラグ

code_off uleb128 コード構造体のオフセット

Page 23: 詳解Dexファイルフォーマット

データ名 型名 内容

registers_size ushort メソッドで使用するレジスタ数

ins_size ushort 引数の数

outs_size ushort 出力引数の数

tries_size ushort tryスコープの数

debug_info_off uint デバッグ情報のオフセット

insns_size uint バイトコードの16bitユニット数

insns ushortの配列 バイトコード命令列

padding ushort(optional) アライメントのためのパディング

tries tryスコープの配列 tryスコープの情報

handlers ハンドラの配列 例外補足ハンドラのリスト

Page 24: 詳解Dexファイルフォーマット