metasm 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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