Post

Android Analyze for dex file

android dex file format
Android Analyze for dex file

Intro

I recently had an opportunity to analyze the dex file while I was analyzing the Android app. I’m going to write to record what I checked at this time.

block-beta
  columns 3
  block:dex_file:3
    %% columns auto (default)
    dex["classes.dex"] classes1.dex classes2.dex classes3.dex classes4.dex classes5.dex classesN.dex
  end
  block:lib:2
    columns 2
    armeabi armeabi_v7a arm64_v8a x86_64 x86 
  end  
  block:META_INF:1
    columns 1
    *.RSA *.SF *.MF 
  end
  block:etc_file:3
    %% columns auto (default)
    AndroidManifest.xml
    assets
    res
    resource.arsc
  end
  style dex_file fill:#898
  style dex fill:#f3f

Android apk architecture is assets and dex and lib..etc

today, let it parse dex file.

so what can i do? we need dex architecture.

we check dex file format and some write dex parser PoC code.

Android dex file format, The header contains information indicating the offset and size for each part, and more detailed information is recorded in the map off based on the information.

mindmap
classes.dex
    header
    dex_string_idx
    dex_type_idx
    dex_proto_idx
    dex_field_idx
    dex_method_idx
    dex_class_defs
    dex_map_list

This is summary some section for dex file.

now check it for detail.

block-beta
  block:DexHeader:1
    columns 4
    magic signature checksum file_size header_size endian_tag link_size link_off map_off string_ids_size string_ids_off type_ids_size type_ids_off proto_ids_size proto_ids_off field_ids_size field_ids_off method_ids_size method_ids_off class_defs_size class_defs_off data_size data_off
  end

This is dex file header.

block-beta
  block:DexField:1
    columns 1
    class_idx type_idx name_idx
  end

dex field section.

block-beta
  block:DexProto:1
    columns 1
    shorty_idx ret_type_idx param_off
  end

proto section, use for method-proto type.

block-beta
  block:DexMethod:1
    columns 1
    class_idx proto_idx name_idx
  end

method section is class_idx, proto_idx and name_idx.

block-beta
  block:DexString:1
    columns 1
    string_data_offset
  end

This is offset for string section.

so if you find offset, it is string length and next hex pointer is string start and you can read string as much as length.

block-beta
  block:DexType:1
    columns 1
    desc_idx
  end

This is type idx.

block-beta
  block:DexClass:1
    columns 1
    class_idx access_flag superclass_idx interface_off source_file_idx annotation_off class_data_off static_value_off
  end

And here is class_def section.

class_idx, flag, and superclass_idx…etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
typedef struct {
    char dex[3];
    char newline;
    char ver[3];
    char zero;
} DexMagic;

typedef struct {
    DexMagic magic;
    uint32_t checksum;
    uint8_t signature[20];
    uint32_t file_size;
    uint32_t header_size;
    uint32_t endian_tag;
    uint32_t link_size;
    uint32_t link_off;
    uint32_t map_off;
    uint32_t string_ids_size;
    uint32_t string_ids_off;
    uint32_t type_ids_size;
    uint32_t type_ids_off;
    uint32_t proto_ids_size;
    uint32_t proto_ids_off;
    uint32_t field_ids_size;
    uint32_t field_ids_off;
    uint32_t method_ids_size;
    uint32_t method_ids_off;
    uint32_t class_defs_size;
    uint32_t class_defs_off;
    uint32_t data_size;
    uint32_t data_off;
} DexHeader;

// method_ids

typedef struct {
    uint16_t class_idx; // 2 Byte
    uint16_t proto_idx;
    uint32_t name_idx;
} DexMethod;

// class_def

typedef struct {
    uint32_t class_idx;
    uint32_t access_flag;
    uint32_t superclass_idx;
    uint32_t interface_off;
    uint32_t source_file_idx;
    uint32_t annotation_off;
    uint32_t class_data_off;
    uint32_t static_value_off;
} DexClass;

// type_ids

typedef struct {
    uint32_t desc_idx;
} DexType;

// proto_ids

typedef struct {
    uint32_t shorty_idx;
    uint32_t ret_type_idx;
    uint32_t param_off;
} DexProto;

// String

typedef struct {
    uint32_t string_data_offset;
} DexString;

// field

typedef struct {
    uint16_t class_idx;
    uint16_t type_idx;
    uint32_t name_idx;
} DexField;

The analysis can be performed by parsing the file according to the structure above according to the offset.

Reference

https://source.android.com/docs/core/runtime/dex-format

This post is licensed under CC BY 4.0 by the author.
If you find any errors, please let me know by comment or email. Thank you.

© Ruffalo. Some rights reserved.

I'm

Using the Chirpy theme for Jekyll.