0
|
1 class _DEX_header(object):
|
|
2 magic = None # 0x00, 8 bytes
|
|
3 checksum = None # 0x08, 4 bytes
|
|
4 signature = None # 0x0c, 20 bytes
|
|
5 fileSize = None # 0x20, 4 bytes
|
|
6 headerSize = None # 0x24
|
|
7 endianTag = None # 0x28
|
|
8 linkSize = None # 0x2c
|
|
9 linkOff = None # 0x30
|
|
10 mapOff = None # 0x34
|
|
11 stringIdsSize = None # 0x38
|
|
12 stringIdsOff = None # 0x3c
|
|
13 typeIdsSize = None # 0x40
|
|
14 typeIdsOff = None # 0x44
|
|
15 protoIdsSize = None # 0x48
|
|
16 protoIdsOff = None # 0x4c
|
|
17 fieldIdsSize = None # 0x50
|
|
18 fieldIdsOff = None # 0x54
|
|
19 methodIdsSize = None # 0x58
|
|
20 methodIdsOff = None # 0x5c
|
|
21 classDefsSize = None # 0x60
|
|
22 classDefsOff = None # 0x64
|
|
23 dataSize = None # 0x68
|
|
24 dataOff = None # 0x6c
|
|
25
|
|
26 def parse(self, data):
|
|
27 self.magic = data[:8]
|
|
28 self.checksum = data[8: 0x0c]
|
|
29 self.signature = data[0x0c: 0x20]
|
|
30
|
|
31 idx = 0x20
|
|
32 fields = 'fileSize headerSize endianTag linkSize linkOff mapOff ' \
|
|
33 'stringIdsSize stringIdsOff typeIdsSize typeIdsOff ' \
|
|
34 'protoIdsSize protoIdsOff fieldIdsSize fieldIdsOff ' \
|
|
35 'methodIdsSize methodIdsOff classDefsSize classDefsOff ' \
|
|
36 'dataSize dataOff'.split()
|
|
37 for field in fields:
|
|
38 d = data[idx: idx + 4]
|
|
39 value = _to_uint(d)
|
|
40 setattr(self, field, value)
|
|
41 idx = idx + 4
|
|
42 pass
|
|
43 pass
|
|
44 pass
|
|
45
|
|
46
|
|
47 def _to_uint(data):
|
|
48 v = 0
|
|
49 for c in data:
|
|
50 v = (v << 8) + ord(c)
|
|
51 pass
|
|
52 return v
|
|
53
|
|
54
|
|
55 class _DEX_MapItem(object):
|
|
56 type = None # 2 bytes
|
|
57 unused = None # 2 bytes
|
|
58 size = None # 4 bytes
|
|
59 offset = None # 4 bytes
|
|
60
|
|
61 data_size = 12
|
|
62
|
|
63 def parse(self, data):
|
|
64 self.type = _to_uint(data[:2])
|
|
65 self.size = _to_uint(data[4:8])
|
|
66 self.offset = _to_uint(data[8:12])
|
|
67 pass
|
|
68 pass
|
|
69
|
|
70 class _DEX_TypeId(object):
|
|
71 descriptorIdx = None # 4 bytes
|
|
72
|
|
73 data_size = 4
|
|
74
|
|
75 def parse(self, data):
|
|
76 self.descriptorIdx = _to_uint(data[:4])
|
|
77 pass
|
|
78 pass
|
|
79
|
|
80
|
|
81 class _DEX_ProtoId(object):
|
|
82 shortyIdx = None # 4 bytes
|
|
83 returnTypeIdx = None # 4 bytes
|
|
84 parametersOff = None # 4 bytes
|
|
85
|
|
86 data_size = 12
|
|
87
|
|
88 def parse(self, data):
|
|
89 self.shortyIdx = _to_uint(data[:4])
|
|
90 self.returnTypeIdx = _to_uint(data[4:8])
|
|
91 self.parametersOff = _to_uint(data[8:12])
|
|
92 pass
|
|
93 pass
|
|
94
|
|
95
|
|
96 class _DEX_FieldId(object):
|
|
97 classIdx # 2 bytes
|
|
98 typeIdx # 2 bytes
|
|
99 nameIdx # 4 bytes
|
|
100
|
|
101 data_size = 8
|
|
102
|
|
103 def parse(self, data):
|
|
104 self.classIdx = _to_uint(data[:2])
|
|
105 self.typeIdx = _to_uint(data[2:4])
|
|
106 self.nameIdx = _to_uint(data[4:8])
|
|
107 pass
|
|
108 pass
|
|
109
|
|
110
|
|
111 class _DEX_MethodId(object):
|
|
112 classIdx # 2 bytes
|
|
113 protoIdx # 2 bytes
|
|
114 nameIdx # 4 bytes
|
|
115
|
|
116 data_size = 8
|
|
117
|
|
118 def parse(self, data):
|
|
119 self.classIdx = _to_uint(data[:2])
|
|
120 self.protoIdx = _to_uint(data[2:4])
|
|
121 self.nameIdx = _to_uint(data[4:8])
|
|
122 pass
|
|
123 pass
|
|
124
|
|
125 class _DEX_ClassDef(object):
|
|
126 classIdx = None # 0x00
|
|
127 accessFlags = None # 0x04
|
|
128 superclassIdx = None # 0x08
|
|
129 interfacesOff = None # 0x0c
|
|
130 sourceFileIdx = None # 0x10
|
|
131 annotationsOff = None # 0x14
|
|
132 classDataOff = None # 0x18
|
|
133 staticValuesOff = None # 0x1c
|
|
134
|
|
135 data_size = 0x20
|
|
136
|
|
137 def parse(self, data):
|
|
138 self.classIdx = _to_uint(data[:4])
|
|
139 self.accessFlags = _to_uint(data[4:8])
|
|
140 self.superclassIdx = _to_uint(data[8:0xc])
|
|
141 self.interfacesOff = _to_uint(data[0xc:0x10])
|
|
142 self.sourceFileIdx = _to_uint(data[0x10:0x14])
|
|
143 self.annotationsOff = _to_uint(data[0x14:0x18])
|
|
144 self.classDataOff = _to_uint(data[0x18:0x1c])
|
|
145 self.staticValuesOff = _to_uint(data[0x1c:0x20])
|
|
146 pass
|
|
147 pass
|
|
148
|
|
149
|
|
150 class DEXFile(object):
|
|
151 _data = None
|
|
152 _header = None
|
|
153 _strings = None
|
|
154
|
|
155 def __init__(self):
|
|
156 pass
|
|
157
|
|
158 def open(self, filename):
|
|
159 fo = file(filename)
|
|
160 data = fo.read()
|
|
161
|
|
162 self.parse(data)
|
|
163 pass
|
|
164
|
|
165 def parse(self, data):
|
|
166 self._data = data
|
|
167 header = _DEX_header()
|
|
168 header.parse(data)
|
|
169 self._header = header
|
|
170 pass
|
|
171 pass
|