DEXファイル解析--- 1、DEXヘッダ解析
、DEXファイル
DEXファイルは、Androidプラットフォームの実行可能ファイルのファイルタイプです。:それはファイル形式は下の写真にまとめることができ
、DEXヘッダが通常フラグを含む、サイズが0x70バイトに設定されているバージョン番号、チェックサム、SHA-1署名、他の方法、クラス番号及びオフセットアドレスを情報。下図のように:
二、フィールドを解析DEXヘッダ
各ファイルのヘッダには、次のフィールドが含まれていDEX:
- マジック:DEXの長さが0x00の8バイトからファイル識別子およびバージョン開始が含まれています
- チェックサム:DEXファイルのチェックサム、オフセット:0x08に、4バイトの長さ。
- 署名:DEX SHA-1署名、0x0Cのオフセット、20バイトの長さ
- file_szie:DEXファイルサイズは、0x20に、4バイトの長さをオフセット
- ヘッダサイズ:DEXヘッダサイズ、0x24をオフセット、4バイトの長さは、通常0x70
- endian_ タグ:エンディアンDEXファイル交換かどうかを決定する、の0x28オフセット、4バイトの長さは、一般的に0x78563412であります
- link_size:DEXファイル・リンク・セグメント・サイズ、0は静的にリンクを示し、0x2Cは、4バイトの長さをオフセット
- link_off:DEXファイル・リンク・セグメントは、0x30からのオフセット、4バイトの長さをオフセット
- map_off:DEXファイル地図データセグメントは、オフセット位置に0x34の、4バイトの長さであり、オフセット
- string_ids_size:DEXファイルは、文字列の数が含まれ、0x38、4バイトの長さをオフセット
- string_ids_off:DEX文字列ファイル、オフセット値を0x3c、4バイトの長さを開始オフセット
- type_ids_size:DEXファイルタイプの数、0x40のオフセット、4バイトの長さ
- type_ids_off:DEXクラスファイルオフセット位置は、4バイトの長さを0x44のオフセット
- photo_ids_size:DEXファイル番号プロトタイプ方法は、0x48、4バイトの長さをオフセット
- photo_ids_off:DEXメソッドプロトタイプファイルオフセット位置、オフセット0x4C、4バイトの長さ
- field_ids_size:ファイルのDEX数フィールドは、4バイトの長さを0x50をオフセット
- field_ids_off:オフセットDEXファイルフィールドオフセット位置が0x54、4バイトの長さであります
- method_ids_size:メソッドのDEXファイル番号は、0x58、4バイトの長さをオフセット
- method_ids_off:DEXファイルオフセット法、オフセットコードに5C、4バイトの長さ
- class_defs_size:ナンバーDEXクラス定義ファイルは、0x60、4バイトの長さをオフセット
- class_defs_off:DEXクラス定義ファイルオフセット位置は、0x64、4バイトの長さをオフセット
- DATA_SIZE:DEXセグメントサイズは、0x68、4バイトの長さをオフセット
- data_off:オフセットDEXデータセグメントは、0x6C、4バイトの長さをオフセット
三、DEXヘッダコード分析試料(パイソン)
DEX関数を求め、次に移動し、バイナリファイルのファイルポインタをオープンする機能を開く、例えばマジックでありf.seek(0x00)
、そのようなバージョン番号の読み取り、対応する情報バイトの数読み取るf.seek(0x04) f.read(4)
ラインに、それに応じて印刷動作を、よりDEXヘッダ我々はそれがベルトを感じて解決していないので、シンプルでは、など、コーディングは含まれません。。。。。特定のコードは、コードが、図は、以下に添付実行、下またはgithubの見ることができます。
四つの実装(Pythonは達成する)ことDEXヘッダ解析コード
import binascii
def parserHeader(f):
f.seek(0x00)
magic_mask = f.read(4)
magic_mask = binascii.b2a_hex(magic_mask)
magic_mask = str(magic_mask,encoding='utf-8')
print('文件标识符: ',end='')
print(magic_mask)
f.seek(0x04)
magic_version = f.read(4)
magic_version = binascii.b2a_hex(magic_version)
magic_version = str(magic_version,encoding='utf-8')
print('文件版本: ',end='')
print(magic_version)
f.seek(0x08)
checksum = f.read(4)
checksum = binascii.b2a_hex(checksum)
checksum = str(checksum,encoding='utf-8')
print('校验码: ',end='')
print(checksum)
f.seek(0x0c)
signature = f.read(20)
signature = binascii.b2a_hex(signature)
signature = str(signature,encoding='utf-8')
print('SHA-1签名: ',end='')
print(signature)
f.seek(0x20)
file_size = f.read(4)
a = bytearray(file_size)
a.reverse()
file_size = bytes(a)
file_size = binascii.b2a_hex(file_size)
file_size = str(file_size,encoding='utf-8')
print('文件大小: ',end='')
print(int(file_size,16),end='')
print(' byte')
f.seek(0x24)
header_size = f.read(4)
a = bytearray(header_size)
a.reverse()
header_size = bytes(a)
header_size = binascii.b2a_hex(header_size)
header_size = str(header_size,encoding='utf-8')
print('文件头大小: ',end='')
print(int(header_size,16),end='')
print(' byte')
f.seek(0x28)
endian_tag = f.read(4)
endian_tag = binascii.b2a_hex(endian_tag)
endian_tag = str(endian_tag,encoding='utf-8')
print('字节序交换标志: ',end='')
print(endian_tag)
f.seek(0x2c)
link_size = f.read(4)
a = bytearray(link_size)
a.reverse()
link_size = bytes(a)
link_size = binascii.b2a_hex(link_size)
link_size = str(link_size,encoding='utf-8')
print('链接段大小: ',end='')
print(int(link_size,16),end='')
print(' byte')
f.seek(0x30)
link_off = f.read(4)
a = bytearray(link_off)
a.reverse()
link_off = bytes(a)
link_off = binascii.b2a_hex(link_off)
link_off = str(link_off,encoding='utf-8')
print('链接段偏移位置: ',end='')
print(hex(int(link_off,16)))
f.seek(0x34)
map_off = f.read(4)
a = bytearray(map_off)
a.reverse()
map_off = bytes(a)
map_off = binascii.b2a_hex(map_off)
map_off = str(map_off,encoding='utf-8')
print('map数据偏移位置: ',end='')
print(hex(int(map_off,16)))
f.seek(0x38)
stringidsSize = f.read(4)
a = bytearray(stringidsSize)
a.reverse()
stringidsSize = bytes(a)
stringidsSize = binascii.b2a_hex(stringidsSize)
stringidsSize = str(stringidsSize,encoding='utf-8')
print('字符串数量: ',end='')
print(int(stringidsSize,16),end='')
print('(',end='')
print(hex(int(stringidsSize,16)),end='')
print(')')
f.seek(0x3c)
string_ids_off = f.read(4)
a = bytearray(string_ids_off)
a.reverse()
string_ids_off = bytes(a)
string_ids_off = binascii.b2a_hex(string_ids_off)
string_ids_off = str(string_ids_off,encoding='utf-8')
print('字符串偏移位置: ',end='')
print(hex(int(string_ids_off,16)))
f.seek(0x40)
type_ids_size = f.read(4)
a = bytearray(type_ids_size)
a.reverse()
type_ids_size = bytes(a)
type_ids_size = binascii.b2a_hex(type_ids_size)
type_ids_size = str(type_ids_size,encoding='utf-8')
print('类数量: ',end='')
print(int(type_ids_size,16),end='')
print('(',end='')
print(hex(int(type_ids_size,16)),end='')
print(')')
f.seek(0x44)
type_ids_off = f.read(4)
a = bytearray(type_ids_off)
a.reverse()
type_ids_off = bytes(a)
type_ids_off = binascii.b2a_hex(type_ids_off)
type_ids_off = str(type_ids_off,encoding='utf-8')
print('类偏移位置: ',end='')
print(hex(int(type_ids_off,16)))
f.seek(0x48)
photo_ids_size = f.read(4)
a = bytearray(photo_ids_size)
a.reverse()
photo_ids_size = bytes(a)
photo_ids_size = binascii.b2a_hex(photo_ids_size)
photo_ids_size = str(photo_ids_size,encoding='utf-8')
print('方法原型数量: ',end='')
print(int(photo_ids_size,16),end='')
print('(',end='')
print(hex(int(photo_ids_size,16)),end='')
print(')')
f.seek(0x4c)
photo_ids_off = f.read(4)
a = bytearray(photo_ids_off)
a.reverse()
photo_ids_off = bytes(a)
photo_ids_off = binascii.b2a_hex(photo_ids_off)
photo_ids_off = str(photo_ids_off,encoding='utf-8')
print('方法原型偏移位置: ',end='')
print(hex(int(photo_ids_off,16)))
f.seek(0x50)
field_ids_size = f.read(4)
a = bytearray(field_ids_size)
a.reverse()
field_ids_size = bytes(a)
field_ids_size = binascii.b2a_hex(field_ids_size)
field_ids_size = str(field_ids_size,encoding='utf-8')
print('字段数量: ',end='')
print(int(field_ids_size,16),end='')
print('(',end='')
print(hex(int(field_ids_size,16)),end='')
print(')')
f.seek(0x54)
field_ids_off = f.read(4)
a = bytearray(field_ids_off)
a.reverse()
field_ids_off = bytes(a)
field_ids_off = binascii.b2a_hex(field_ids_off)
field_ids_off = str(field_ids_off,encoding='utf-8')
print('字段偏移位置: ',end='')
print(hex(int(field_ids_off,16)))
f.seek(0x58)
method_ids_size = f.read(4)
a = bytearray(method_ids_size)
a.reverse()
method_ids_size = bytes(a)
method_ids_size = binascii.b2a_hex(method_ids_size)
method_ids_size = str(method_ids_size,encoding='utf-8')
print('方法数量: ',end='')
print(int(method_ids_size,16),end='')
print('(',end='')
print(hex(int(method_ids_size,16)),end='')
print(')')
f.seek(0x5c)
method_ids_off = f.read(4)
a = bytearray(method_ids_off)
a.reverse()
method_ids_off = bytes(a)
method_ids_off = binascii.b2a_hex(method_ids_off)
method_ids_off = str(method_ids_off,encoding='utf-8')
print('方法偏移位置: ',end='')
print(hex(int(method_ids_off,16)))
f.seek(0x60)
class_defs_size = f.read(4)
a = bytearray(class_defs_size)
a.reverse()
class_defs_size = bytes(a)
class_defs_size = binascii.b2a_hex(class_defs_size)
class_defs_size = str(class_defs_size,encoding='utf-8')
print('类定义数量: ',end='')
print(int(class_defs_size,16),end='')
print('(',end='')
print(hex(int(class_defs_size,16)),end='')
print(')')
f.seek(0x64)
class_defs_off = f.read(4)
a = bytearray(class_defs_off)
a.reverse()
class_defs_off = bytes(a)
class_defs_off = binascii.b2a_hex(class_defs_off)
class_defs_off = str(class_defs_off,encoding='utf-8')
print('类定义偏移位置: ',end='')
print(hex(int(class_defs_off,16)))
f.seek(0x68)
data_size = f.read(4)
a = bytearray(data_size)
a.reverse()
data_size = bytes(a)
data_size = binascii.b2a_hex(data_size)
data_size = str(data_size,encoding='utf-8')
print('数据段大小: ',end='')
print(int(data_size,16),end='')
print('(',end='')
print(hex(int(data_size,16)),end='')
print(')')
f.seek(0x6c)
data_off = f.read(4)
a = bytearray(data_off)
a.reverse()
data_off = bytes(a)
data_off = binascii.b2a_hex(data_off)
data_off = str(data_off,encoding='utf-8')
print('数据段偏移位置: ',end='')
print(hex(int(data_off,16)))
if __name__ == '__main__':
f = open("C:\\Users\\admin\\Desktop\\android_nx\\classes.dex", 'rb', True)
parserHeader(f)
f.close()
V.関連リンク
参考リンク
- https://blog.csdn.net/tabactivity/article/details/78950379
- https://blog.csdn.net/sinat_18268881/article/details/55832757
著者githubのリンク(関連アクセサリーのダウンロード):https://github.com/windy-purple/parserDex
PS:ネットワークからのいくつかの写真、侵入を削除します