metasm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. data/BUGS +11 -0
  2. data/CREDITS +17 -0
  3. data/README +270 -0
  4. data/TODO +114 -0
  5. data/doc/code_organisation.txt +146 -0
  6. data/doc/const_missing.txt +16 -0
  7. data/doc/core_classes.txt +75 -0
  8. data/doc/feature_list.txt +53 -0
  9. data/doc/index.txt +59 -0
  10. data/doc/install_notes.txt +170 -0
  11. data/doc/style.css +3 -0
  12. data/doc/use_cases.txt +18 -0
  13. data/lib/metasm.rb +80 -0
  14. data/lib/metasm/arm.rb +12 -0
  15. data/lib/metasm/arm/debug.rb +39 -0
  16. data/lib/metasm/arm/decode.rb +167 -0
  17. data/lib/metasm/arm/encode.rb +77 -0
  18. data/lib/metasm/arm/main.rb +75 -0
  19. data/lib/metasm/arm/opcodes.rb +177 -0
  20. data/lib/metasm/arm/parse.rb +130 -0
  21. data/lib/metasm/arm/render.rb +55 -0
  22. data/lib/metasm/compile_c.rb +1457 -0
  23. data/lib/metasm/dalvik.rb +8 -0
  24. data/lib/metasm/dalvik/decode.rb +196 -0
  25. data/lib/metasm/dalvik/main.rb +60 -0
  26. data/lib/metasm/dalvik/opcodes.rb +366 -0
  27. data/lib/metasm/decode.rb +213 -0
  28. data/lib/metasm/decompile.rb +2659 -0
  29. data/lib/metasm/disassemble.rb +2068 -0
  30. data/lib/metasm/disassemble_api.rb +1280 -0
  31. data/lib/metasm/dynldr.rb +1329 -0
  32. data/lib/metasm/encode.rb +333 -0
  33. data/lib/metasm/exe_format/a_out.rb +194 -0
  34. data/lib/metasm/exe_format/autoexe.rb +82 -0
  35. data/lib/metasm/exe_format/bflt.rb +189 -0
  36. data/lib/metasm/exe_format/coff.rb +455 -0
  37. data/lib/metasm/exe_format/coff_decode.rb +901 -0
  38. data/lib/metasm/exe_format/coff_encode.rb +1078 -0
  39. data/lib/metasm/exe_format/dex.rb +457 -0
  40. data/lib/metasm/exe_format/dol.rb +145 -0
  41. data/lib/metasm/exe_format/elf.rb +923 -0
  42. data/lib/metasm/exe_format/elf_decode.rb +979 -0
  43. data/lib/metasm/exe_format/elf_encode.rb +1375 -0
  44. data/lib/metasm/exe_format/macho.rb +827 -0
  45. data/lib/metasm/exe_format/main.rb +228 -0
  46. data/lib/metasm/exe_format/mz.rb +164 -0
  47. data/lib/metasm/exe_format/nds.rb +172 -0
  48. data/lib/metasm/exe_format/pe.rb +437 -0
  49. data/lib/metasm/exe_format/serialstruct.rb +246 -0
  50. data/lib/metasm/exe_format/shellcode.rb +114 -0
  51. data/lib/metasm/exe_format/xcoff.rb +167 -0
  52. data/lib/metasm/gui.rb +23 -0
  53. data/lib/metasm/gui/cstruct.rb +373 -0
  54. data/lib/metasm/gui/dasm_coverage.rb +199 -0
  55. data/lib/metasm/gui/dasm_decomp.rb +369 -0
  56. data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
  57. data/lib/metasm/gui/dasm_graph.rb +1354 -0
  58. data/lib/metasm/gui/dasm_hex.rb +543 -0
  59. data/lib/metasm/gui/dasm_listing.rb +599 -0
  60. data/lib/metasm/gui/dasm_main.rb +906 -0
  61. data/lib/metasm/gui/dasm_opcodes.rb +291 -0
  62. data/lib/metasm/gui/debug.rb +1228 -0
  63. data/lib/metasm/gui/gtk.rb +884 -0
  64. data/lib/metasm/gui/qt.rb +495 -0
  65. data/lib/metasm/gui/win32.rb +3004 -0
  66. data/lib/metasm/gui/x11.rb +621 -0
  67. data/lib/metasm/ia32.rb +14 -0
  68. data/lib/metasm/ia32/compile_c.rb +1523 -0
  69. data/lib/metasm/ia32/debug.rb +193 -0
  70. data/lib/metasm/ia32/decode.rb +1167 -0
  71. data/lib/metasm/ia32/decompile.rb +564 -0
  72. data/lib/metasm/ia32/encode.rb +314 -0
  73. data/lib/metasm/ia32/main.rb +233 -0
  74. data/lib/metasm/ia32/opcodes.rb +872 -0
  75. data/lib/metasm/ia32/parse.rb +327 -0
  76. data/lib/metasm/ia32/render.rb +91 -0
  77. data/lib/metasm/main.rb +1193 -0
  78. data/lib/metasm/mips.rb +11 -0
  79. data/lib/metasm/mips/compile_c.rb +7 -0
  80. data/lib/metasm/mips/decode.rb +253 -0
  81. data/lib/metasm/mips/encode.rb +51 -0
  82. data/lib/metasm/mips/main.rb +72 -0
  83. data/lib/metasm/mips/opcodes.rb +443 -0
  84. data/lib/metasm/mips/parse.rb +51 -0
  85. data/lib/metasm/mips/render.rb +43 -0
  86. data/lib/metasm/os/gnu_exports.rb +270 -0
  87. data/lib/metasm/os/linux.rb +1112 -0
  88. data/lib/metasm/os/main.rb +1686 -0
  89. data/lib/metasm/os/remote.rb +527 -0
  90. data/lib/metasm/os/windows.rb +2027 -0
  91. data/lib/metasm/os/windows_exports.rb +745 -0
  92. data/lib/metasm/parse.rb +876 -0
  93. data/lib/metasm/parse_c.rb +3938 -0
  94. data/lib/metasm/pic16c/decode.rb +42 -0
  95. data/lib/metasm/pic16c/main.rb +17 -0
  96. data/lib/metasm/pic16c/opcodes.rb +68 -0
  97. data/lib/metasm/ppc.rb +11 -0
  98. data/lib/metasm/ppc/decode.rb +264 -0
  99. data/lib/metasm/ppc/decompile.rb +251 -0
  100. data/lib/metasm/ppc/encode.rb +51 -0
  101. data/lib/metasm/ppc/main.rb +129 -0
  102. data/lib/metasm/ppc/opcodes.rb +410 -0
  103. data/lib/metasm/ppc/parse.rb +52 -0
  104. data/lib/metasm/preprocessor.rb +1277 -0
  105. data/lib/metasm/render.rb +130 -0
  106. data/lib/metasm/sh4.rb +8 -0
  107. data/lib/metasm/sh4/decode.rb +336 -0
  108. data/lib/metasm/sh4/main.rb +292 -0
  109. data/lib/metasm/sh4/opcodes.rb +381 -0
  110. data/lib/metasm/x86_64.rb +12 -0
  111. data/lib/metasm/x86_64/compile_c.rb +1025 -0
  112. data/lib/metasm/x86_64/debug.rb +59 -0
  113. data/lib/metasm/x86_64/decode.rb +268 -0
  114. data/lib/metasm/x86_64/encode.rb +264 -0
  115. data/lib/metasm/x86_64/main.rb +135 -0
  116. data/lib/metasm/x86_64/opcodes.rb +118 -0
  117. data/lib/metasm/x86_64/parse.rb +68 -0
  118. data/misc/bottleneck.rb +61 -0
  119. data/misc/cheader-findpppath.rb +58 -0
  120. data/misc/hexdiff.rb +74 -0
  121. data/misc/hexdump.rb +55 -0
  122. data/misc/metasm-all.rb +13 -0
  123. data/misc/objdiff.rb +47 -0
  124. data/misc/objscan.rb +40 -0
  125. data/misc/pdfparse.rb +661 -0
  126. data/misc/ppc_pdf2oplist.rb +192 -0
  127. data/misc/tcp_proxy_hex.rb +84 -0
  128. data/misc/txt2html.rb +440 -0
  129. data/samples/a.out.rb +31 -0
  130. data/samples/asmsyntax.rb +77 -0
  131. data/samples/bindiff.rb +555 -0
  132. data/samples/compilation-steps.rb +49 -0
  133. data/samples/cparser_makestackoffset.rb +55 -0
  134. data/samples/dasm-backtrack.rb +38 -0
  135. data/samples/dasmnavig.rb +318 -0
  136. data/samples/dbg-apihook.rb +228 -0
  137. data/samples/dbghelp.rb +143 -0
  138. data/samples/disassemble-gui.rb +102 -0
  139. data/samples/disassemble.rb +133 -0
  140. data/samples/dump_upx.rb +95 -0
  141. data/samples/dynamic_ruby.rb +1929 -0
  142. data/samples/elf_list_needed.rb +46 -0
  143. data/samples/elf_listexports.rb +33 -0
  144. data/samples/elfencode.rb +25 -0
  145. data/samples/exeencode.rb +128 -0
  146. data/samples/factorize-headers-elfimports.rb +77 -0
  147. data/samples/factorize-headers-peimports.rb +109 -0
  148. data/samples/factorize-headers.rb +43 -0
  149. data/samples/gdbclient.rb +583 -0
  150. data/samples/generate_libsigs.rb +102 -0
  151. data/samples/hotfix_gtk_dbg.rb +59 -0
  152. data/samples/install_win_env.rb +78 -0
  153. data/samples/lindebug.rb +924 -0
  154. data/samples/linux_injectsyscall.rb +95 -0
  155. data/samples/machoencode.rb +31 -0
  156. data/samples/metasm-shell.rb +91 -0
  157. data/samples/pe-hook.rb +69 -0
  158. data/samples/pe-ia32-cpuid.rb +203 -0
  159. data/samples/pe-mips.rb +35 -0
  160. data/samples/pe-shutdown.rb +78 -0
  161. data/samples/pe-testrelocs.rb +51 -0
  162. data/samples/pe-testrsrc.rb +24 -0
  163. data/samples/pe_listexports.rb +31 -0
  164. data/samples/peencode.rb +19 -0
  165. data/samples/peldr.rb +494 -0
  166. data/samples/preprocess-flatten.rb +19 -0
  167. data/samples/r0trace.rb +308 -0
  168. data/samples/rubstop.rb +399 -0
  169. data/samples/scan_pt_gnu_stack.rb +54 -0
  170. data/samples/scanpeexports.rb +62 -0
  171. data/samples/shellcode-c.rb +40 -0
  172. data/samples/shellcode-dynlink.rb +146 -0
  173. data/samples/source.asm +34 -0
  174. data/samples/struct_offset.rb +47 -0
  175. data/samples/testpe.rb +32 -0
  176. data/samples/testraw.rb +45 -0
  177. data/samples/win32genloader.rb +132 -0
  178. data/samples/win32hooker-advanced.rb +169 -0
  179. data/samples/win32hooker.rb +96 -0
  180. data/samples/win32livedasm.rb +33 -0
  181. data/samples/win32remotescan.rb +133 -0
  182. data/samples/wintrace.rb +92 -0
  183. data/tests/all.rb +8 -0
  184. data/tests/dasm.rb +39 -0
  185. data/tests/dynldr.rb +35 -0
  186. data/tests/encodeddata.rb +132 -0
  187. data/tests/ia32.rb +82 -0
  188. data/tests/mips.rb +116 -0
  189. data/tests/parse_c.rb +239 -0
  190. data/tests/preprocessor.rb +269 -0
  191. data/tests/x86_64.rb +62 -0
  192. metadata +255 -0
@@ -0,0 +1,457 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2009 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+
7
+ require 'metasm/exe_format/main'
8
+ require 'metasm/encode'
9
+ require 'metasm/decode'
10
+
11
+
12
+ module Metasm
13
+ # Android Dalvik executable file format (similar to java .class)
14
+ class DEX < ExeFormat
15
+ MAGIC = "dex\n"
16
+ OPTMAGIC = "dey\n"
17
+ DEPSMAGIC = "deps"
18
+
19
+ TYPE = { 0x0000 => 'Header', 0x0001 => 'StringId',
20
+ 0x0002 => 'TypeId', 0x0003 => 'ProtoId',
21
+ 0x0004 => 'FieldId', 0x0005 => 'MethodId',
22
+ 0x0006 => 'ClassDef',
23
+ 0x1000 => 'MapList', 0x1001 => 'TypeList',
24
+ 0x1002 => 'AnnotationSetRefList', 0x1003 => 'AnnotationSetItem',
25
+ 0x2000 => 'ClassData', 0x2001 => 'CodeItem',
26
+ 0x2002 => 'StringData', 0x2003 => 'DebugInfoItem',
27
+ 0x2004 => 'AnnotationItem', 0x2005 => 'EncodedArrayItem',
28
+ 0x2006 => 'AnnotationsDirectoryItem' }
29
+
30
+ OPT_FLAGS = { 1 => 'VERIFIED', 2 => 'BIG', 4 => 'FIELDS', 8 => 'INVOCATIONS' }
31
+
32
+ ACCESSIBILITY_CLASS = { 1 => 'PUBLIC', 0x10 => 'FINAL', 0x20 => 'SUPER',
33
+ 0x200 => 'INTERFACE', 0x400 => 'ABSTRACT', 0x2000 => 'ANNOTATION',
34
+ 0x4000 => 'ENUM' }
35
+
36
+ VISIBILITY = { 0 => 'BUILD', 1 => 'RUNTIME', 2 => 'SYSTEM' }
37
+
38
+ OBJ_TYPE = { 0 => 'Byte', 2 => 'Short', 3 => 'Char', 4 => 'Int',
39
+ 6 => 'Long', 0x10 => 'Float', 0x11 => 'Double', 0x17 => 'String',
40
+ 0x18 => 'Type', 0x19 => 'Field', 0x1a => 'Method', 0x1b => 'Enum',
41
+ 0x1c => 'Array', 0x1d => 'Annotation', 0x1e => 'Null',
42
+ 0x1f => 'Boolean' }
43
+
44
+
45
+ class SerialStruct < Metasm::SerialStruct
46
+ new_int_field :u2, :u4, :uleb, :sleb
47
+ end
48
+
49
+ class Header < SerialStruct
50
+ mem :sig, 4
51
+ str :ver, 4
52
+ decode_hook { |exe, hdr| raise InvalidExeFormat, "E: invalid DEX signature #{hdr.sig.inspect}" if hdr.sig != MAGIC }
53
+ u4 :checksum
54
+ mem :sha1sum, 20
55
+ u4 :filesz
56
+ u4 :headersz
57
+ u4 :endiantag, 0x12345678
58
+ u4 :linksz
59
+ u4 :linkoff
60
+ u4 :mapoff
61
+ u4 :stringidssz
62
+ u4 :stringidsoff
63
+ u4 :typeidssz
64
+ u4 :typeidsoff
65
+ u4 :protoidssz
66
+ u4 :protoidsoff
67
+ u4 :fieldidssz
68
+ u4 :fieldidsoff
69
+ u4 :methodidssz
70
+ u4 :methodidsoff
71
+ u4 :classdefssz
72
+ u4 :classdefsoff
73
+ u4 :datasz
74
+ u4 :dataoff
75
+ end
76
+
77
+ # header added by optimisation pass ?
78
+ class OptHeader < SerialStruct
79
+ mem :sig, 4
80
+ str :ver, 4
81
+ decode_hook { |exe, hdr| raise InvalidExeFormat, "E: invalid DEY signature #{hdr.sig.inspect}" if hdr.sig != OPTMAGIC }
82
+ u4 :dexoff
83
+ u4 :dexsz
84
+ u4 :depsoff
85
+ u4 :depssz
86
+ u4 :auxoff
87
+ u4 :auxsz
88
+ u4 :flags
89
+ u4 :pad
90
+
91
+ fld_bits :flags, OPT_FLAGS
92
+ end
93
+
94
+ class MapList < SerialStruct
95
+ u4 :sz
96
+ attr_accessor :list
97
+
98
+ def decode(exe)
99
+ super(exe)
100
+ @list = (1..@sz).map { MapItem.decode(exe) }
101
+ end
102
+ end
103
+
104
+ class MapItem < SerialStruct
105
+ u2 :type
106
+ fld_enum :type, TYPE
107
+ u2 :unused
108
+ u4 :sz
109
+ u4 :off
110
+ end
111
+
112
+ class StringId < SerialStruct
113
+ u4 :off
114
+ end
115
+
116
+ class StringData < SerialStruct
117
+ uleb :sz
118
+ attr_accessor :str # array of sz utf8 chars
119
+
120
+ def decode(exe)
121
+ super(exe)
122
+ @str = exe.decode_strz
123
+ end
124
+ end
125
+
126
+ class TypeId < SerialStruct
127
+ u4 :descridx
128
+ end
129
+
130
+ class FieldId < SerialStruct
131
+ u2 :classidx
132
+ u2 :typeidx
133
+ u4 :nameidx
134
+ end
135
+
136
+ class MethodId < SerialStruct
137
+ u2 :classidx
138
+ u2 :typeidx
139
+ u4 :nameidx
140
+ end
141
+
142
+ class ProtoId < SerialStruct
143
+ u4 :shortyidx
144
+ u4 :returntypeidx
145
+ u4 :parametersoff
146
+ end
147
+
148
+ class ClassDef < SerialStruct
149
+ u4 :classidx
150
+ u4 :accessflags
151
+ fld_bits :accessflags, ACCESSIBILITY_CLASS
152
+ u4 :superclassidx
153
+ u4 :interfaceoff
154
+ u4 :sourcefileidx
155
+ u4 :annotationsoff
156
+ u4 :classdataoff
157
+ u4 :staticvaluesoff
158
+
159
+ attr_accessor :data
160
+ end
161
+
162
+ class ClassData < SerialStruct
163
+ uleb :staticfsz
164
+ uleb :instancefsz
165
+ uleb :directmsz
166
+ uleb :virtualmsz
167
+
168
+ attr_accessor :static_fields, :instance_fields,
169
+ :direct_methods, :virtual_methods
170
+
171
+ def decode(exe)
172
+ super(exe)
173
+
174
+ @static_fields = (1..@staticfsz).map { EncodedField.decode(exe) }
175
+ @instance_fields = (1..@instancefsz).map { EncodedField.decode(exe) }
176
+ @direct_methods = (1..@directmsz).map { EncodedMethod.decode(exe) }
177
+ @virtual_methods = (1..@virtualmsz).map { EncodedMethod.decode(exe) }
178
+ end
179
+ end
180
+
181
+ class EncodedField < SerialStruct
182
+ uleb :fieldid_diff # this field id - array.previous field id
183
+ uleb :access
184
+
185
+ attr_accessor :field
186
+ end
187
+
188
+ class EncodedMethod < SerialStruct
189
+ uleb :methodid_diff # this method id - array.previous method id
190
+ uleb :access
191
+ uleb :codeoff # offset to CodeItem
192
+
193
+ attr_accessor :method, :code, :name
194
+ end
195
+
196
+ class TypeItem < SerialStruct
197
+ u2 :typeidx
198
+ end
199
+
200
+ class TypeList < SerialStruct
201
+ u4 :sz
202
+ attr_accessor :list
203
+
204
+ def decode(exe)
205
+ super(exe)
206
+ @list = (1..@sz).map { TypeItem.decode(exe) }
207
+ exe.decode_u2 if @sz & 1 == 1 # align
208
+ end
209
+ end
210
+
211
+ class CodeItem < SerialStruct
212
+ u2 :registerssz
213
+ u2 :inssz
214
+ u2 :outssz
215
+ u2 :triessz
216
+ u4 :debugoff
217
+ u4 :insnssz
218
+
219
+ attr_accessor :insns_off, :try_items, :catch_items
220
+
221
+ def decode(exe)
222
+ p0 = exe.encoded.ptr
223
+ super(exe)
224
+ @insns_off = exe.encoded.ptr - p0
225
+ exe.encoded.ptr += 2*@insnssz
226
+ return if @triessz <= 0
227
+ exe.decode_u2 if @insnssz & 1 == 1 # align
228
+ @try_items = (1..@triessz).map { Try.decode(exe) }
229
+ stptr = exe.encoded.ptr
230
+ hnr = exe.decode_uleb
231
+ @catch_items = (1..hnr).map { CatchHandler.decode(exe, exe.encoded.ptr - stptr) }
232
+ end
233
+ end
234
+
235
+ class Try < SerialStruct
236
+ u4 :startaddr
237
+ u2 :insncount
238
+ u2 :handleroff # byte offset into the @catch_items structure
239
+ end
240
+
241
+ class CatchHandler < SerialStruct
242
+ sleb :size
243
+ attr_accessor :byteoff
244
+ attr_accessor :type_pairs, :catchalloff
245
+
246
+ def decode(exe, boff = nil)
247
+ super(exe)
248
+
249
+ @byteoff = boff
250
+ @type_pairs = (1..@size.abs).map { CatchTypePair.decode(exe) }
251
+ @catchalloff = exe.decode_uleb if @size <= 0
252
+ end
253
+ end
254
+
255
+ class CatchTypePair < SerialStruct
256
+ uleb :typeidx
257
+ uleb :handleroff
258
+ end
259
+
260
+ class Link < SerialStruct
261
+ # undefined
262
+ end
263
+
264
+ class AnnotationDirectoryItem < SerialStruct
265
+ u4 :classannotationsoff
266
+ u4 :fieldssz
267
+ u4 :methodssz
268
+ u4 :parameterssz
269
+
270
+ attr_accessor :field, :method, :parameter
271
+ def decode(exe)
272
+ super(exe)
273
+ @field = (1..@fieldssz).map { FieldAnnotationItem.decode(exe) }
274
+ @method = (1..@methodssz).map { MethodAnnotationItem.decode(exe) }
275
+ @parameter = (1..@parameterssz).map { ParameterAnnotationItem.decode(exe) }
276
+ end
277
+ end
278
+
279
+ class FieldAnnotationItem < SerialStruct
280
+ u4 :fieldidx
281
+ u4 :annotationsoff
282
+ end
283
+
284
+ class MethodAnnotationItem < SerialStruct
285
+ u4 :methodidx
286
+ u4 :annotationsoff
287
+ end
288
+
289
+ class ParameterAnnotationItem < SerialStruct
290
+ u4 :methodidx
291
+ u4 :annotationsoff # off to AnnSetRefList
292
+ end
293
+
294
+ class AnnotationSetRefList < SerialStruct
295
+ u4 :sz
296
+ attr_accessor :list
297
+
298
+ def decode(exe)
299
+ super(exe)
300
+ @list = (1..@sz).map { AnnotationSetRefItem.decode(exe) }
301
+ end
302
+ end
303
+
304
+ class AnnotationSetRefItem < SerialStruct
305
+ u4 :annotationsoff
306
+ end
307
+
308
+ class AnnotationSetItem < SerialStruct
309
+ u4 :sz
310
+ attr_accessor :list
311
+
312
+ def decode(exe)
313
+ super(exe)
314
+ @list = (1..@sz).map { AnnotationItem.decode(exe) }
315
+ end
316
+ end
317
+
318
+ class AnnotationItem < SerialStruct
319
+ byte :visibility
320
+ fld_enum :visibility, VISIBILITY
321
+ attr_accessor :annotation
322
+ end
323
+
324
+
325
+ attr_accessor :endianness
326
+
327
+ def encode_u2(val) Expression[val].encode(:u16, @endianness) end
328
+ def encode_u4(val) Expression[val].encode(:u32, @endianness) end
329
+ def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
330
+ def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
331
+ def decode_uleb(ed = @encoded, signed=false)
332
+ v = s = 0
333
+ while s < 5*7
334
+ b = ed.read(1).unpack('C').first.to_i
335
+ v |= (b & 0x7f) << s
336
+ break if (b&0x80) == 0
337
+ s += 7
338
+ end
339
+ v = Expression.make_signed(v, s) if signed
340
+ v
341
+ end
342
+ def decode_sleb(ed = @encoded) decode_uleb(ed, true) end
343
+ attr_accessor :header, :strings, :types, :protos, :fields, :methods, :classes
344
+
345
+ def initialize(endianness=:little)
346
+ @endianness = endianness
347
+ @encoded = EncodedData.new
348
+ super()
349
+ end
350
+
351
+ def decode_header
352
+ @header = Header.decode(self)
353
+ end
354
+
355
+ def decode_strings
356
+ @encoded.ptr = @header.stringidsoff
357
+ so = (1..@header.stringidssz).map { StringId.decode(self) }
358
+ @strings = so.map { |s| @encoded.ptr = s.off ; StringData.decode(self).str }
359
+ end
360
+
361
+ def decode_types
362
+ @encoded.ptr = @header.typeidsoff
363
+ tl = (1..@header.typeidssz).map { TypeId.decode(self) }
364
+ @types = tl.map { |t| @strings[t.descridx] } # TODO demangle or something
365
+ end
366
+
367
+ def decode_protos
368
+ @encoded.ptr = @header.protoidsoff
369
+ @protos = (1..@header.protoidssz).map { ProtoId.decode(self) }
370
+ end
371
+
372
+ def decode_fields
373
+ @encoded.ptr = @header.fieldidsoff
374
+ @fields = (1..@header.fieldidssz).map { FieldId.decode(self) }
375
+ end
376
+
377
+ def decode_methods
378
+ @encoded.ptr = @header.methodidsoff
379
+ @methods = (1..@header.methodidssz).map { MethodId.decode(self) }
380
+ end
381
+
382
+ def decode_classes
383
+ @encoded.ptr = @header.classdefsoff
384
+ @classes = (1..@header.classdefssz).map { ClassDef.decode(self) }
385
+ @classes.each { |c|
386
+ next if c.classdataoff == 0
387
+ @encoded.ptr = c.classdataoff
388
+ c.data = ClassData.decode(self)
389
+ id = 0
390
+ (c.data.direct_methods + [0] + c.data.virtual_methods).each { |m|
391
+ next id=0 if m == 0
392
+ id += m.methodid_diff
393
+ m.method = @methods[id]
394
+ m.name = @strings[m.method.nameidx]
395
+ @encoded.ptr = m.codeoff
396
+ m.code = CodeItem.decode(self)
397
+ next if @encoded.ptr > @encoded.length
398
+ l = new_label(m.name + '@' + @types[c.classidx])
399
+ @encoded.add_export l, m.codeoff + m.code.insns_off
400
+ }
401
+ }
402
+ end
403
+
404
+ def decode
405
+ decode_header
406
+ decode_strings
407
+ decode_types
408
+ decode_protos
409
+ decode_fields
410
+ decode_methods
411
+ decode_classes
412
+ end
413
+
414
+ def cpu_from_headers
415
+ Dalvik.new(self)
416
+ end
417
+
418
+ def init_disassembler
419
+ dasm = super()
420
+ @classes.each { |c|
421
+ next if not c.data
422
+ (c.data.direct_methods + c.data.virtual_methods).each { |m|
423
+ n = @types[c.classidx] + '->' + m.name
424
+ dasm.comment[m.codeoff+m.code.insns_off] = [n]
425
+ }
426
+ }
427
+ dasm.function[:default] = @cpu.disassembler_default_func
428
+ dasm
429
+ end
430
+
431
+ def each_section
432
+ yield @encoded, 0
433
+ # @classes.each { |c|
434
+ # next if not c.data
435
+ # (c.data.direct_methods + c.data.virtual_methods).each { |m|
436
+ # next if not m.code
437
+ # next if not ed = @encoded[m.codeoff+m.code.insns_off, 2*m.code.insnssz]
438
+ # yield ed, ed.export.index(0)
439
+ # }
440
+ # }
441
+ end
442
+
443
+ def get_default_entrypoints
444
+ []
445
+ end
446
+ end
447
+
448
+ class DEY < DEX
449
+ attr_accessor :optheader, :fullencoded
450
+ def decode_header
451
+ @optheader = OptHeader.decode(self)
452
+ @fullencoded = @encoded
453
+ @encoded = @fullencoded[@optheader.dexoff, @optheader.dexsz]
454
+ super
455
+ end
456
+ end
457
+ end