More Related Content
Similar to 詳解Dexファイルフォーマット
Similar to 詳解Dexファイルフォーマット (20)
More from Takuya Matsunaga
More from Takuya Matsunaga (6)
詳解Dexファイルフォーマット
- 2. ハンドルネーム
◦ 正式にはkmt-t
◦ はてなID : kmt-t2
◦ Twitter ID : kmt_t
僻地(鳥取県)出身です
◦ 大阪まで出稼ぎに出ています
得意分野など
◦ プログラミング言語はC++/C#など
◦ 組み込みではミドルウェア開発を得意にしています
2D/3Dグラフィックスおよび画像処理
ファイルシステム
- 3. 今回の発表はDalvik仮想マシン3部作の最後です
1. Dalvik仮想マシンのアーキテクチャ
2. Dalvikバイトコードのリファレンスの読み方
3. 詳解DEXフォーマット ← 今回はこれ!
発表の目的
1. Dalvik仮想マシンのソースコードを誰でも読めるように!
2. Dalvik仮想マシンに関するみんなのリテラシを上げる!
3. より深い部分の発表をするための下地をつくる!
- 4. Dalvik仮想マシンの実行ファイル
◦ Windowsで言えばPEファイルに相当します
◦ Javaで言えばクラスファイルに相当します
◦ Javaのクラスファイルとは形式が違います
◦ 配布する場合は生のDEXファイルではなくパッケージされた
apkファイルにすることが殆どです
Dalvik仮想マシン同様シンプルで結構簡単です
◦ 理解するとバイトコードの動的生成、バイトコードエンジニアリ
ングなどができるようになります
リファレンス
◦ $ANDROID_SOURCE/dalvik/docs/dex-format.html
- 5. Linuxにおけるobjdump相当
◦ Android SDKに含まれています
◦ このツールでDEXファイルのいろいろな情報が抜き出せます
◦ 実用的にはこのツールが不自由なく使えるレベルのDEXファ
イルフォーマットの知識があれば充分
代表的なオプション
オプション 説明
-f ヘッダ(クラスやメソッドの定義など)のサマリーの表示
-h ヘッダ(クラスやメソッドの定義など)の詳細の表示
-d コードの逆アセンブルの表示
- 7. ファイルは以下の領域に分割
ヘッダ領域 string_ids領域
type_ids領域 proto_ids領域
field_ids領域 method_ids領域
class_defs領域 data領域
link_data領域
data領域、link_data領域に可変長データを格納
◦ link_data領域はアンドキュメンテッド
◦ それ以外の領域には固定長のデータしか格納されない
- 8. アイテム名 内容
magic “dex¥n035¥0” (固定値)
checksum alder32によるチェックサム。signatureでも同様
の検出ができるが、ファイルの破損チェック用計算
コストの問題から通常はこちらを使った方が良い
signature SHA-1によるハッシュ値。ファイルを一意に識別す
るために使用できる。配布元の正しいハッシュ値と
比較すれば改ざんされていることは簡単に検出で
きる。計算コストが高いので毎起動時に検査する
のは難しい
file_size ファイルサイズ
header_size ヘッダサイズ。固定長
endian_tag 固定データ(0x12345678)。ファイルのエンディア
ン識別用
- 9. アイテム名 内容
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領域へのオフセット
- 10. アイテム名 内容
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領域へのオフセット
- 11. 定数文字列プールを格納する領域
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
string_data_off uint data領域の定数文字列データへのオフセット
オフセットが指すdata領域には以下のデータが格納
データ名 型名 内容
utf16_size uleb128 MUFT-8文字列をUTF-16にデコードしたとき
の文字列長
data MUTF-8 文字列データ
- 12. LEB128
◦ DWORF3でも使われているデータ形式らしいです
◦ 可変長整数データ型です
Byteの最上位bitが立っている場合は次のByteはその上位7bit
が格納されています。byteの最上位ビットが落ちている場合は
データ終了
◦ 値の小さな整数はデータ長が短くなります
◦ 可変長なのでdata領域のみに存在します
余談
◦ 実際にはDEXはapk(ZIP)でパッケージされるのであんまり意
味が無い(圧縮したらサイズは同じぐらいになる)のでは
- 13. UTF-16の一文字を1~3byteにエンコードした形式
◦ Javaバイトコードでも使われています
◦ Java、Dalvikともに内部の文字コードはUTF-16です
◦ MUTF-8の方がUTF-8より都合がいいです
◦ エンコード元がUTF-16なのでサロゲートペアは出現します
◦ Linuxでのワイド文字列はUTF-32なので取り扱いは注意
◦ 可変長なのでdata領域のみに存在します
余談
◦ あんまり意味が無いと思うんですが(UTF-16そのままでもあ
まり差が出ないはず)、がんばりすぎですよね
- 14. DEXファイルで参照されている型のテーブル
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
descriptor_idx uint 型名を表すTypeDiscriptor文字列のID
(string_ids領域ののインデックス)
TypeDiscriptorは以下のフォーマットの文字列
文字列 型名
V, Z, B, S, C, I, J, F, D プリミティブ型
Lfully/qualified/Name; クラス型 (この場合”fully.qualified.Name”)
[TypeDescrioter 配列型 (“[I”ならintの配列)
- 15. DEXファイルで参照されているメソッド型のテーブル
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
shorty_idx uint 型名を表すShortTypeDiscriptor文字列の
ID(string_ids領域のインデックス)
return_type_idx uint 戻り値型のID
(type_ids領域のインデックス)
parameters_off uint パラメータ型のIDのリストへのオフセット。オフ
セットの指す先はdata領域
- 16. クラスのフィールド情報を格納する領域
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
class_idx ushort フィールドを所有するクラス型のID
(type_ids領域のインデックス)
type_idx ushort フィールド型のID
(type_ids領域のインデックス)
name_idx uint フィールド名の文字列ID
(string_ids領域のインデックス)
- 17. クラスのメソッド情報を格納する領域
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
class_idx ushort メソッドを所有するクラス型のID
(type_ids領域のインデックス)
proto_idx ushort メソッド型のID
(proto_ids領域のインデックス)
name_idx uint メソッド名の文字列ID
(string_ids領域のインデックス)
- 18. クラス情報を格納する領域
以下の情報の配列(データ数はヘッダに記述)
データ名 型名 内容
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 静的フィールドの初期値.
- 19. data領域に含まれるデータ一覧 (1/2)
データ名 内容
MapList ファイルデータのレイアウト情報
StringData 文字列データ
TypeList 型IDのリスト
AnnotationDirectory クラスとそのフィールド、メソッドのすべてのアノテーショ
ン情報の集まり
AnnotationSetRef アノテーションのリストのリスト
AnnotationSet アノテーションのリスト
Annotation アノテーション
EncodedArray クラスの初期値、アノテーションの設定値を圧縮した
データ
- 20. data領域に含まれるデータ一覧 (2/2)
データ名 内容
ClassData クラス情報
Code メソッドのバイトコードの情報
DebugInfo デバッグ情報
- 21. データ名 型名 内容
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 仮想メソッドの情報
の配列
- 22. encoded_field構造体
データ名 型名 内容
field_idx_diff Uleb128 フィールドID (field_ids領域のインデックス)
差分前のフィールドの値との差分
access_flags Uleb128 アクセスフラグ
encoded_method構造体
データ名 型名 内容
method_idx_diff uleb128 メソッドID (method_ids領域のインデックス)
差分前のメソッドの値との差分
access_flags uleb128 アクセスフラグ
code_off uleb128 コード構造体のオフセット
- 23. データ名 型名 内容
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 ハンドラの配列 例外補足ハンドラのリスト