Mercurial > paraspace
annotate paraspace/dexfile.py @ 3:a78db169b0c8
parse AnnotationSetItems
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 23 May 2011 21:44:58 +0800 |
parents | add64d56b0e2 |
children | b0766f1984bb |
rev | line source |
---|---|
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 | |
2 | 26 header_fields = \ |
27 'magic checksum signature fileSize headerSize endianTag ' \ | |
28 'linkSize linkOff mapOff stringIdsSize stringIdsOff typeIdsSize ' \ | |
29 'typeIdsOff protoIdsSize protoIdsOff fieldIdsSize fieldIdsOff ' \ | |
30 'methodIdsSize methodIdsOff classDefsSize classDefsOff ' \ | |
31 'dataSize dataOff'.split() | |
32 | |
0 | 33 def parse(self, data): |
34 self.magic = data[:8] | |
35 self.checksum = data[8: 0x0c] | |
36 self.signature = data[0x0c: 0x20] | |
37 | |
38 idx = 0x20 | |
39 fields = 'fileSize headerSize endianTag linkSize linkOff mapOff ' \ | |
40 'stringIdsSize stringIdsOff typeIdsSize typeIdsOff ' \ | |
41 'protoIdsSize protoIdsOff fieldIdsSize fieldIdsOff ' \ | |
42 'methodIdsSize methodIdsOff classDefsSize classDefsOff ' \ | |
43 'dataSize dataOff'.split() | |
44 for field in fields: | |
45 d = data[idx: idx + 4] | |
46 value = _to_uint(d) | |
47 setattr(self, field, value) | |
48 idx = idx + 4 | |
49 pass | |
50 pass | |
51 pass | |
52 | |
53 | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
54 class man_off(object): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
55 off = None |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
56 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
57 def __init__(self, off): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
58 self.off = off |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
59 pass |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
60 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
61 def __call__(self, sz): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
62 off = self.off |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
63 self.off = off + sz |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
64 return off |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
65 pass |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
66 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
67 |
0 | 68 def _to_uint(data): |
69 v = 0 | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
70 sh = 0 |
0 | 71 for c in data: |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
72 v = v + (ord(c) << sh) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
73 sh = sh + 8 |
0 | 74 pass |
75 return v | |
76 | |
77 | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
78 def _uleb128(data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
79 sh = 0 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
80 v = 0 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
81 for c in data: |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
82 cv = ord(c) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
83 v = v + ((cv & 0x7f) << sh) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
84 sh = sh + 7 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
85 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
86 if cv <= 0x7f: |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
87 break |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
88 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
89 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
90 nbytes = sh / 7 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
91 return v, nbytes |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
92 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
93 |
2 | 94 def _leb128(data): |
95 v, sh = _uleb128(data) | |
96 if v & (1 << (sh * 7 - 1)): | |
97 v = -((1 << (sh * 7)) - v) | |
98 pass | |
99 return v, sh | |
100 | |
101 | |
0 | 102 class _DEX_MapItem(object): |
103 type = None # 2 bytes | |
104 unused = None # 2 bytes | |
105 size = None # 4 bytes | |
106 offset = None # 4 bytes | |
107 | |
108 data_size = 12 | |
2 | 109 types = { |
110 0x0000: 'kDexTypeHeaderItem', | |
111 0x0001: 'kDexTypeStringIdItem', | |
112 0x0002: 'kDexTypeTypeIdItem', | |
113 0x0003: 'kDexTypeProtoIdItem', | |
114 0x0004: 'kDexTypeFieldIdItem', | |
115 0x0005: 'kDexTypeMethodIdItem', | |
116 0x0006: 'kDexTypeClassDefItem', | |
117 0x1000: 'kDexTypeMapList', | |
118 0x1001: 'kDexTypeTypeList', | |
119 0x1002: 'kDexTypeAnnotationSetRefList', | |
120 0x1003: 'kDexTypeAnnotationSetItem', | |
121 0x2000: 'kDexTypeClassDataItem', | |
122 0x2001: 'kDexTypeCodeItem', | |
123 0x2002: 'kDexTypeStringDataItem', | |
124 0x2003: 'kDexTypeDebugInfoItem', | |
125 0x2004: 'kDexTypeAnnotationItem', | |
126 0x2005: 'kDexTypeEncodedArrayItem', | |
127 0x2006: 'kDexTypeAnnotationsDirectoryItem' | |
128 } | |
0 | 129 |
130 def parse(self, data): | |
131 self.type = _to_uint(data[:2]) | |
132 self.size = _to_uint(data[4:8]) | |
133 self.offset = _to_uint(data[8:12]) | |
134 pass | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
135 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
136 @classmethod |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
137 def find_type_name(self, type_name): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
138 type_value = [v |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
139 for v, name in _DEX_MapItem.types.items() |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
140 if name == type_name][0] |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
141 return type_value |
0 | 142 pass |
143 | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
144 |
0 | 145 class _DEX_TypeId(object): |
146 descriptorIdx = None # 4 bytes | |
147 | |
148 data_size = 4 | |
149 | |
150 def parse(self, data): | |
151 self.descriptorIdx = _to_uint(data[:4]) | |
152 pass | |
153 pass | |
154 | |
155 | |
156 class _DEX_ProtoId(object): | |
157 shortyIdx = None # 4 bytes | |
158 returnTypeIdx = None # 4 bytes | |
159 parametersOff = None # 4 bytes | |
160 | |
161 data_size = 12 | |
162 | |
163 def parse(self, data): | |
164 self.shortyIdx = _to_uint(data[:4]) | |
165 self.returnTypeIdx = _to_uint(data[4:8]) | |
166 self.parametersOff = _to_uint(data[8:12]) | |
167 pass | |
168 pass | |
169 | |
170 | |
171 class _DEX_FieldId(object): | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
172 classIdx = None # 2 bytes |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
173 typeIdx = None # 2 bytes |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
174 nameIdx = None # 4 bytes |
0 | 175 |
176 data_size = 8 | |
177 | |
178 def parse(self, data): | |
179 self.classIdx = _to_uint(data[:2]) | |
180 self.typeIdx = _to_uint(data[2:4]) | |
181 self.nameIdx = _to_uint(data[4:8]) | |
182 pass | |
183 pass | |
184 | |
185 | |
186 class _DEX_MethodId(object): | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
187 classIdx = None # 2 bytes |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
188 protoIdx = None # 2 bytes |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
189 nameIdx = None # 4 bytes |
0 | 190 |
191 data_size = 8 | |
192 | |
193 def parse(self, data): | |
194 self.classIdx = _to_uint(data[:2]) | |
195 self.protoIdx = _to_uint(data[2:4]) | |
196 self.nameIdx = _to_uint(data[4:8]) | |
197 pass | |
198 pass | |
199 | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
200 |
0 | 201 class _DEX_ClassDef(object): |
202 classIdx = None # 0x00 | |
203 accessFlags = None # 0x04 | |
204 superclassIdx = None # 0x08 | |
205 interfacesOff = None # 0x0c | |
206 sourceFileIdx = None # 0x10 | |
207 annotationsOff = None # 0x14 | |
208 classDataOff = None # 0x18 | |
209 staticValuesOff = None # 0x1c | |
210 | |
211 data_size = 0x20 | |
212 | |
213 def parse(self, data): | |
214 self.classIdx = _to_uint(data[:4]) | |
215 self.accessFlags = _to_uint(data[4:8]) | |
216 self.superclassIdx = _to_uint(data[8:0xc]) | |
217 self.interfacesOff = _to_uint(data[0xc:0x10]) | |
218 self.sourceFileIdx = _to_uint(data[0x10:0x14]) | |
219 self.annotationsOff = _to_uint(data[0x14:0x18]) | |
220 self.classDataOff = _to_uint(data[0x18:0x1c]) | |
221 self.staticValuesOff = _to_uint(data[0x1c:0x20]) | |
222 pass | |
223 pass | |
224 | |
225 | |
2 | 226 class _DEX_ClassDataHeader(object): |
227 staticFieldsSize = None | |
228 instanceFieldsSize = None | |
229 directMethodsSize = None | |
230 virtualMethodsSize = None | |
231 | |
232 data_size = None | |
233 | |
234 def parse(self, data, off): | |
235 self.staticFieldsSize, sh = _uleb128(data[off:off + 10]) | |
236 sz = sh | |
237 off = off + sh | |
238 self.instanceFieldsSize, sh = _uleb128(data[off:off + 10]) | |
239 sz = sz + sh | |
240 off = off + sh | |
241 self.directMethodsSize, sh = _uleb128(data[off:off + 10]) | |
242 sz = sz + sh | |
243 off = off + sh | |
244 self.virtualMethodsSize, sh = _uleb128(data[off:off + 10]) | |
245 sz = sz + sh | |
246 | |
247 self.data_size = sz | |
248 pass | |
249 pass | |
250 | |
251 | |
252 class _DEX_Field(object): | |
253 fieldIdx = None | |
254 accessFlags = None | |
255 | |
256 data_size = None | |
257 | |
258 def parse(self, data, off): | |
259 self.fieldIdx, sh = _uleb128(data[off:off + 10]) | |
260 sz = sh | |
261 off = off + sh | |
262 self.accessFlags, sh = _uleb128(data[off:off + 10]) | |
263 sz = sz + sh | |
264 | |
265 self.data_size = sz | |
266 pass | |
267 pass | |
268 | |
269 | |
270 class _DEX_Method(object): | |
271 methodIdx = None | |
272 accessFlags = None | |
273 codeOff = None | |
274 | |
275 data_size = None | |
276 | |
277 def parse(self, data, off): | |
278 self.methodIdx, sh = _uleb128(data[off:off + 10]) | |
279 sz = sh | |
280 off = off + sh | |
281 | |
282 self.accessFlags, sh = _uleb128(data[off:off + 10]) | |
283 sz = sz + sh | |
284 off = off + sh | |
285 | |
286 self.codeOff, sh = _uleb128(data[off:off + 10]) | |
287 sz = sz + sh | |
288 | |
289 self.data_size = sz | |
290 pass | |
291 pass | |
292 | |
293 class _DEX_ClassData(object): | |
294 header = None # DexClassDataHeader | |
295 staticFields = None # DexField* | |
296 instanceFields = None # DexField* | |
297 directMethods = None # DexMethod* | |
298 virtualMethods = None # DexMethod* | |
299 | |
300 data_size = None | |
301 | |
302 def parse(self, data, off): | |
303 header = _DEX_ClassDataHeader() | |
304 header.parse(data, off) | |
305 self.header = header | |
306 | |
307 cur_off = [off + header.data_size] | |
308 | |
309 def parse_field(): | |
310 field = _DEX_Field() | |
311 off = cur_off[0] | |
312 field.parse(data, off) | |
313 cur_off[0] = cur_off[0] + field.data_size | |
314 | |
315 # | |
316 # field index depends previous one to reduce size | |
317 # | |
318 field.fieldIdx = field.fieldIdx + idx[0] | |
319 idx[0] = field.fieldIdx | |
320 | |
321 return field | |
322 | |
323 def parse_method(): | |
324 method = _DEX_Method() | |
325 off = cur_off[0] | |
326 method.parse(data, off) | |
327 cur_off[0] = cur_off[0] + method.data_size | |
328 | |
329 # | |
330 # method index depends previous one to reduce size | |
331 # | |
332 method.methodIdx = method.methodIdx + idx[0] | |
333 idx[0] = method.methodIdx | |
334 | |
335 return method | |
336 | |
337 idx = [0] | |
338 self.staticFields = [parse_field() | |
339 for i in range(header.staticFieldsSize)] | |
340 idx = [0] | |
341 self.instanceFields = [parse_field() | |
342 for i in range(header.instanceFieldsSize)] | |
343 idx = [0] | |
344 self.directMethods = [parse_method() | |
345 for i in range(header.directMethodsSize)] | |
346 idx = [0] | |
347 self.virtualMethods = [parse_method() | |
348 for i in range(header.virtualMethodsSize)] | |
349 | |
350 self.data_size = cur_off[0] - off | |
351 pass | |
352 pass | |
353 | |
354 | |
355 class _DEX_TypeList(object): | |
356 typeItems = None | |
357 | |
358 data_size = None | |
359 | |
360 def parse(self, data, off): | |
361 size = _to_uint(data[off:off + 4]) | |
362 | |
363 item_off = off + 4 | |
364 typeItems = [_to_uint(data[cur_off:cur_off + 2]) | |
365 for cur_off in range(item_off, item_off + size * 2, 2)] | |
366 data_size = 4 + size * 2 | |
367 | |
368 self.typeItems = typeItems | |
369 self.data_size = data_size | |
370 pass | |
371 pass | |
372 | |
373 | |
374 class _DEX_TypeLists(object): | |
375 typeLists = None | |
376 | |
377 data_size = None | |
378 | |
379 def parse(self, num, data, off): | |
380 def parse(): | |
381 off = (cur_off[0] + 3) & ~0x3 | |
382 typeList = _DEX_TypeList() | |
383 typeList.parse(data, off) | |
384 cur_off[0] = off + typeList.data_size | |
385 | |
386 return typeList | |
387 | |
388 cur_off = [off] | |
389 typeLists = [parse() for i in range(num)] | |
390 | |
391 self.typeLists = typeLists | |
392 self.data_size = cur_off[0] - off | |
393 pass | |
394 pass | |
395 | |
396 | |
397 class _DEX_Try(object): | |
398 startAddr = None # 4 bytes | |
399 insnCount = None # 2 bytes | |
400 handlerOff = None # 2 bytes | |
401 | |
402 data_size = 8 | |
403 | |
404 def parse(self, data, off): | |
405 cur_off = off | |
406 self.startAddr = _to_uint(data[cur_off:cur_off + 4]) | |
407 cur_off = cur_off + 4 | |
408 self.insnCount = _to_uint(data[cur_off:cur_off + 2]) | |
409 cur_off = cur_off + 2 | |
410 self.handlerOff = _to_uint(data[cur_off:cur_off + 2]) | |
411 pass | |
412 pass | |
413 | |
414 | |
415 class _DEX_CatchHandler(object): | |
416 typeIdx = None | |
417 address = None | |
418 | |
419 data_size = None | |
420 | |
421 def parse(self, data, off): | |
422 cur_off = off | |
423 self.typeIdx, sh = _uleb128(data[cur_off:cur_off + 5]) | |
424 cur_off = cur_off + sh | |
425 self.address, sh = _uleb128(data[cur_off:cur_off + 5]) | |
426 cur_off = cur_off + sh | |
427 | |
428 self.data_size = cur_off - off | |
429 pass | |
430 | |
431 def parse1(self, data, off): | |
432 self.address, sh = _uleb128(data[off:off + 5]) | |
433 | |
434 self.data_size = sh | |
435 pass | |
436 pass | |
437 | |
438 | |
439 class _DEX_Catch(object): | |
440 catchesAll = None | |
441 handlers = None | |
442 | |
443 data_size = None | |
444 | |
445 def parse(self, data, off): | |
446 def move_off(sz): | |
447 off = move_off.off | |
448 move_off.off = off + sz | |
449 return off | |
450 move_off.off = off | |
451 moff = move_off | |
452 | |
453 count, sh = _leb128(data[moff.off:moff.off + 5]) | |
454 moff(sh) | |
455 | |
456 if count > 0: | |
457 self.catchesAll = False | |
458 else: | |
459 self.catchesAll = True | |
460 count = -count | |
461 pass | |
462 | |
463 def parse_handler(): | |
464 handler = _DEX_CatchHandler() | |
465 handler.parse(data, moff.off) | |
466 moff(handler.data_size) | |
467 return handler | |
468 | |
469 self.handlers = [parse_handler() for i in range(count)] | |
470 | |
471 if self.catchesAll: | |
472 # | |
473 # Additional handler for catching all | |
474 # | |
475 handler = _DEX_CatchHandler() | |
476 handler.parse1(data, moff.off) | |
477 moff(handler.data_size) | |
478 self.handlers.append(handler) | |
479 pass | |
480 | |
481 self.data_size = moff.off - off | |
482 pass | |
483 pass | |
484 | |
485 | |
486 class _DEX_Code(object): | |
487 registersSize = None # 2 bytes | |
488 insSize = None # 2 bytes | |
489 outsSize = None # 2 bytes | |
490 triesSize = None # 2 bytes | |
491 debugInfoOff = None # 4 bytes | |
492 insnsSize = None # 4 bytes | |
493 insns = None | |
494 try_items = None | |
495 catch_handler_items = None | |
496 | |
497 data_size = None | |
498 | |
499 def parse(self, data, off): | |
500 def move_off(sz): | |
501 off = move_off.off | |
502 move_off.off = off + sz | |
503 return off | |
504 move_off.off = off | |
505 moff = move_off | |
506 | |
507 self.registersSize = _to_uint(data[moff.off:moff.off + 2]) | |
508 moff(2) | |
509 self.insSize = _to_uint(data[moff.off:moff.off + 2]) | |
510 moff(2) | |
511 self.outsSize = _to_uint(data[moff.off:moff.off + 2]) | |
512 moff(2) | |
513 self.triesSize = _to_uint(data[moff.off:moff.off + 2]) | |
514 moff(2) | |
515 self.debugInfoOff = _to_uint(data[moff.off:moff.off + 4]) | |
516 moff(4) | |
517 self.insnsSize = _to_uint(data[moff.off:moff.off + 4]) | |
518 moff(4) | |
519 | |
520 moff(self.insnsSize * 2) # skip insns | |
521 | |
522 if self.triesSize > 0: | |
523 def parse_try_item(): | |
524 try_item = _DEX_Try() | |
525 try_item.parse(data, moff.off) | |
526 moff(try_item.data_size) | |
527 return try_item | |
528 | |
529 moff.off = (moff.off + 3) & ~0x3 | |
530 self.try_items = [parse_try_item() for i in range(self.triesSize)] | |
531 | |
532 def parse_catch_handler(): | |
533 catch = _DEX_Catch() | |
534 catch.parse(data, moff.off) | |
535 moff(catch.data_size) | |
536 return catch | |
537 | |
538 # | |
539 # No tries, no catch handlers | |
540 # | |
541 handlersSize, sh = _uleb128(data[moff.off:moff.off + 5]) | |
542 moff(sh) | |
543 self.catch_handler_items = [parse_catch_handler() | |
544 for i in range(handlersSize)] | |
545 pass | |
546 | |
547 moff.off = (moff.off + 3) & ~0x3 | |
548 self.data_size = moff.off - off | |
549 pass | |
550 pass | |
551 | |
552 | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
553 class _DEX_AnnotationSetItem(object): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
554 size = None # 4 bytes |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
555 annotations = None # 4 * size bytes |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
556 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
557 data_size = None |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
558 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
559 def parse(self, data, off): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
560 moff = man_off(off) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
561 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
562 self.size = _to_uint(data[moff(4):moff(0)]) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
563 self.annotations = [_to_uint(data[moff(4):moff(0)]) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
564 for i in range(self.size)] |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
565 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
566 self.data_size = moff(0) - off |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
567 pass |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
568 pass |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
569 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
570 |
0 | 571 class DEXFile(object): |
572 _data = None | |
573 _header = None | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
574 _maps = None |
0 | 575 _strings = None |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
576 _typeIds = None |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
577 _protoIds = None |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
578 _fieldIds = None |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
579 _methodIds = None |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
580 _classDefs = None |
2 | 581 _classDatas = None |
582 _typeLists = None | |
583 _codeItems = None | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
584 _annotationSetItems = None |
0 | 585 |
586 def __init__(self): | |
587 pass | |
588 | |
589 def open(self, filename): | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
590 fo = file(filename, 'r') |
0 | 591 data = fo.read() |
592 | |
593 self.parse(data) | |
594 pass | |
595 | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
596 def _parse_maps(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
597 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
598 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
599 off = header.mapOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
600 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
601 num = _to_uint(data[off:off + 4]) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
602 off = off + 4 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
603 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
604 maps = [] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
605 for i in range(num): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
606 item_data = data[off:off + _DEX_MapItem.data_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
607 item = _DEX_MapItem() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
608 item.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
609 maps.append(item) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
610 off = off + _DEX_MapItem.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
611 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
612 |
2 | 613 self._maps = maps |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
614 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
615 |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
616 def find_map_item(self, type_value): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
617 maps = self._maps |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
618 codeItem_map = [map for map in maps if map.type == type_value][0] |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
619 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
620 return codeItem_map |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
621 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
622 def find_map_item_name(self, type_name): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
623 type_value = _DEX_MapItem.find_type_name(type_name) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
624 map = self.find_map_item(type_value) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
625 return map |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
626 |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
627 def _parse_strings(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
628 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
629 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
630 strings = [] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
631 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
632 num = header.stringIdsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
633 off = header.stringIdsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
634 for i in range(num): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
635 str_start_off = _to_uint(data[off:off + 4]) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
636 str_stop_off = data.index('\x00', str_start_off) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
637 string = data[str_start_off:str_stop_off] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
638 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
639 sz, sh = _uleb128(string) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
640 string = string[sh:] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
641 strings.append(string) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
642 off = off + 4 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
643 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
644 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
645 self._strings = strings |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
646 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
647 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
648 def _parse_typeIds(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
649 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
650 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
651 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
652 num = header.typeIdsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
653 off = header.typeIdsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
654 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
655 def parse(item_data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
656 type_id = _DEX_TypeId() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
657 type_id.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
658 return type_id |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
659 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
660 item_size = _DEX_TypeId.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
661 item_offs = range(off, off + item_size * num, item_size) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
662 item_datas = [data[item_off:item_off + item_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
663 for item_off in item_offs] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
664 typeIds = [parse(item_data) for item_data in item_datas] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
665 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
666 self._typeIds = typeIds |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
667 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
668 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
669 def _parse_protoIds(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
670 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
671 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
672 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
673 num = header.protoIdsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
674 off = header.protoIdsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
675 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
676 def parse(item_data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
677 proto_id = _DEX_ProtoId() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
678 proto_id.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
679 return proto_id |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
680 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
681 item_size = _DEX_ProtoId.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
682 item_offs = range(off, off + item_size * num, item_size) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
683 item_datas = [data[item_off:item_off + item_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
684 for item_off in item_offs] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
685 protoIds = [parse(item_data) for item_data in item_datas] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
686 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
687 self._protoIds = protoIds |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
688 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
689 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
690 def _parse_fieldIds(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
691 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
692 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
693 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
694 num = header.fieldIdsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
695 off = header.fieldIdsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
696 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
697 def parse(item_data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
698 field_id = _DEX_FieldId() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
699 field_id.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
700 return field_id |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
701 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
702 item_size = _DEX_FieldId.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
703 item_offs = range(off, off + item_size * num, item_size) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
704 item_datas = [data[item_off:item_off + item_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
705 for item_off in item_offs] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
706 fieldIds = [parse(item_data) for item_data in item_datas] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
707 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
708 self._fieldIds = fieldIds |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
709 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
710 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
711 def _parse_methodIds(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
712 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
713 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
714 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
715 num = header.methodIdsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
716 off = header.methodIdsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
717 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
718 def parse(item_data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
719 method_id = _DEX_MethodId() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
720 method_id.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
721 return method_id |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
722 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
723 item_size = _DEX_MethodId.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
724 item_offs = range(off, off + item_size * num, item_size) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
725 item_datas = [data[item_off:item_off + item_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
726 for item_off in item_offs] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
727 methodIds = [parse(item_data) for item_data in item_datas] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
728 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
729 self._methodIds = methodIds |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
730 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
731 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
732 def _parse_classDefs(self): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
733 data = self._data |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
734 header = self._header |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
735 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
736 num = header.classDefsSize |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
737 off = header.classDefsOff |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
738 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
739 def parse(item_data): |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
740 class_def = _DEX_ClassDef() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
741 class_def.parse(item_data) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
742 return class_def |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
743 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
744 item_size = _DEX_ClassDef.data_size |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
745 item_offs = range(off, off + item_size * num, item_size) |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
746 item_datas = [data[item_off:item_off + item_size] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
747 for item_off in item_offs] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
748 classDefs = [parse(item_data) for item_data in item_datas] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
749 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
750 self._classDefs = classDefs |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
751 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
752 |
2 | 753 def _parse_classDatas(self): |
754 header = self._header | |
755 data = self._data | |
756 maps = self._maps | |
757 | |
758 kDexTypeClassDataItem = [type | |
759 for type, name in _DEX_MapItem.types.items() | |
760 if name == 'kDexTypeClassDataItem'][0] | |
761 class_data_map = [map | |
762 for map in maps | |
763 if map.type == kDexTypeClassDataItem][0] | |
764 | |
765 off = [class_data_map.offset] | |
766 def parse_class_data(): | |
767 class_data = _DEX_ClassData() | |
768 class_data.parse(data, off[0]) | |
769 off[0] = off[0] + class_data.data_size | |
770 return class_data | |
771 class_datas = [parse_class_data() for i in range(class_data_map.size)] | |
772 | |
773 self._classDatas = class_datas | |
774 pass | |
775 | |
776 def _parse_typeLists(self): | |
777 maps = self._maps | |
778 data = self._data | |
779 | |
780 kDexTypeTypeList = [type | |
781 for type, name in _DEX_MapItem.types.items() | |
782 if name == 'kDexTypeTypeList'][0] | |
783 typeList_map = [map for map in maps if map.type == kDexTypeTypeList][0] | |
784 num_typeLists = typeList_map.size | |
785 | |
786 typeLists = _DEX_TypeLists() | |
787 typeLists.parse(num_typeLists, data, typeList_map.offset) | |
788 | |
789 self._typeLists = typeLists | |
790 pass | |
791 | |
792 def _parse_codeItems(self): | |
793 maps = self._maps | |
794 data = self._data | |
795 | |
796 kDexTypeCodeItem = [type | |
797 for type, name in _DEX_MapItem.types.items() | |
798 if name == 'kDexTypeCodeItem'][0] | |
799 codeItem_map = [map for map in maps if map.type == kDexTypeCodeItem][0] | |
800 num_codeItems = codeItem_map.size | |
801 | |
802 cur_off = [codeItem_map.offset] | |
803 def parse_code(): | |
804 off = cur_off[0] | |
805 code = _DEX_Code() | |
806 code.parse(data, off) | |
807 cur_off[0] = off + code.data_size | |
808 return code | |
809 | |
810 codeItems = [parse_code() for i in range(num_codeItems)] | |
811 | |
812 self._codeItems = codeItems | |
813 pass | |
814 | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
815 def _parse_annotationSetItems(self): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
816 data = self._data |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
817 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
818 annoset_map = self.find_map_item_name('kDexTypeAnnotationSetItem') |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
819 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
820 moff = man_off(annoset_map.offset) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
821 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
822 def parse_annotationSetItem(): |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
823 item = _DEX_AnnotationSetItem() |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
824 item.parse(data, moff(0)) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
825 moff(item.data_size) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
826 return item |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
827 |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
828 self._annotationSetItems = [parse_annotationSetItem() |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
829 for i in range(annoset_map.size)] |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
830 pass |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
831 |
0 | 832 def parse(self, data): |
833 self._data = data | |
834 header = _DEX_header() | |
835 header.parse(data) | |
836 self._header = header | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
837 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
838 self._parse_maps() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
839 self._parse_strings() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
840 self._parse_typeIds() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
841 self._parse_protoIds() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
842 self._parse_fieldIds() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
843 self._parse_methodIds() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
844 self._parse_classDefs() |
2 | 845 self._parse_classDatas() |
846 self._parse_typeLists() | |
847 self._parse_codeItems() | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
848 self._parse_annotationSetItems() |
0 | 849 pass |
850 pass | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
851 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
852 if __name__ == '__main__': |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
853 dex = DEXFile() |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
854 dex.open('test.dex') |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
855 |
2 | 856 print 'Header' |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
857 h = dex._header |
2 | 858 for attr in h.header_fields: |
859 print '\t%s: %s' % (attr, repr(getattr(h, attr))) | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
860 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
861 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
862 print |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
863 print 'Define Classes' |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
864 strings = dex._strings |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
865 classDefs = dex._classDefs |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
866 typeIds = dex._typeIds |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
867 for classDef in classDefs: |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
868 typeId = typeIds[classDef.classIdx] |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
869 descriptor = strings[typeId.descriptorIdx] |
2 | 870 data_off = classDef.classDataOff |
871 print '\t%s @0x%x' % (descriptor, data_off) | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
872 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
873 |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
874 print |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
875 print 'Reference Classes' |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
876 for typeId in typeIds: |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
877 descriptor = strings[typeId.descriptorIdx] |
2 | 878 print '\t%s' % (descriptor) |
879 pass | |
880 | |
881 print | |
882 print 'Class data' | |
883 methodIds = dex._methodIds | |
884 classDatas = dex._classDatas | |
885 for classData in classDatas: | |
886 print '\tclass' | |
887 for method in classData.directMethods: | |
888 code_off = method.codeOff | |
889 methodId = methodIds[method.methodIdx] | |
890 name = strings[methodId.nameIdx] | |
891 print '\t\t%s@0x%x' % (name, code_off) | |
892 pass | |
893 for method in classData.virtualMethods: | |
894 code_off = method.codeOff | |
895 methodId = methodIds[method.methodIdx] | |
896 name = strings[methodId.nameIdx] | |
897 print '\t\t%s@0x%x' % (name, code_off) | |
898 pass | |
899 pass | |
900 | |
901 print | |
902 print 'TypeLists size is %d bytes' % (dex._typeLists.data_size) | |
903 | |
904 bytes = sum([code.data_size for code in dex._codeItems]) | |
905 print | |
906 print 'CodeItems size is %d bytes' % (bytes) | |
907 | |
3
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
908 bytes = sum([annoset.data_size for annoset in dex._annotationSetItems]) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
909 print |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
910 print 'AnnotationSetItems size is %d bytes' % (bytes) |
a78db169b0c8
parse AnnotationSetItems
Thinker K.F. Li <thinker@codemud.net>
parents:
2
diff
changeset
|
911 |
2 | 912 print |
913 print 'Data maps' | |
914 maps = dex._maps | |
915 for map in maps: | |
916 print '\t0x%04x(%s) size=%d offset=0x%08x' % (map.type, | |
917 map.types[map.type], | |
918 map.size, | |
919 map.offset) | |
1
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
920 pass |
05346b632adb
Parse records mentioned in file header
Thinker K.F. Li <thinker@codemud.net>
parents:
0
diff
changeset
|
921 pass |