metasm 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (276) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -0
  4. data/.gitignore +3 -0
  5. data/.hgtags +3 -0
  6. data/Gemfile +3 -0
  7. data/INSTALL +61 -0
  8. data/LICENCE +458 -0
  9. data/README +29 -21
  10. data/Rakefile +10 -0
  11. data/TODO +10 -12
  12. data/doc/code_organisation.txt +3 -1
  13. data/doc/core/DynLdr.txt +247 -0
  14. data/doc/core/ExeFormat.txt +43 -0
  15. data/doc/core/Expression.txt +220 -0
  16. data/doc/core/GNUExports.txt +27 -0
  17. data/doc/core/Ia32.txt +236 -0
  18. data/doc/core/SerialStruct.txt +108 -0
  19. data/doc/core/VirtualString.txt +145 -0
  20. data/doc/core/WindowsExports.txt +61 -0
  21. data/doc/core/index.txt +1 -0
  22. data/doc/style.css +6 -3
  23. data/doc/usage/debugger.txt +327 -0
  24. data/doc/usage/index.txt +1 -0
  25. data/doc/use_cases.txt +2 -2
  26. data/metasm.gemspec +23 -0
  27. data/{lib/metasm.rb → metasm.rb} +15 -3
  28. data/{lib/metasm → metasm}/compile_c.rb +15 -9
  29. data/metasm/cpu/arc.rb +8 -0
  30. data/metasm/cpu/arc/decode.rb +404 -0
  31. data/metasm/cpu/arc/main.rb +191 -0
  32. data/metasm/cpu/arc/opcodes.rb +588 -0
  33. data/metasm/cpu/arm.rb +14 -0
  34. data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
  35. data/{lib/metasm → metasm/cpu}/arm/decode.rb +15 -18
  36. data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
  37. data/{lib/metasm → metasm/cpu}/arm/main.rb +3 -6
  38. data/metasm/cpu/arm/opcodes.rb +324 -0
  39. data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
  40. data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
  41. data/metasm/cpu/arm64.rb +15 -0
  42. data/metasm/cpu/arm64/debug.rb +38 -0
  43. data/metasm/cpu/arm64/decode.rb +285 -0
  44. data/metasm/cpu/arm64/encode.rb +41 -0
  45. data/metasm/cpu/arm64/main.rb +105 -0
  46. data/metasm/cpu/arm64/opcodes.rb +232 -0
  47. data/metasm/cpu/arm64/parse.rb +20 -0
  48. data/metasm/cpu/arm64/render.rb +95 -0
  49. data/{lib/metasm/mips/compile_c.rb → metasm/cpu/bpf.rb} +4 -2
  50. data/metasm/cpu/bpf/decode.rb +110 -0
  51. data/metasm/cpu/bpf/main.rb +60 -0
  52. data/metasm/cpu/bpf/opcodes.rb +81 -0
  53. data/metasm/cpu/bpf/render.rb +30 -0
  54. data/{lib/metasm/ppc.rb → metasm/cpu/cy16.rb} +2 -4
  55. data/metasm/cpu/cy16/decode.rb +247 -0
  56. data/metasm/cpu/cy16/main.rb +63 -0
  57. data/metasm/cpu/cy16/opcodes.rb +78 -0
  58. data/metasm/cpu/cy16/render.rb +30 -0
  59. data/metasm/cpu/dalvik.rb +11 -0
  60. data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +34 -34
  61. data/{lib/metasm → metasm/cpu}/dalvik/main.rb +71 -4
  62. data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +21 -12
  63. data/{lib/metasm/mips.rb → metasm/cpu/ebpf.rb} +3 -4
  64. data/metasm/cpu/ebpf/debug.rb +61 -0
  65. data/metasm/cpu/ebpf/decode.rb +142 -0
  66. data/metasm/cpu/ebpf/main.rb +58 -0
  67. data/metasm/cpu/ebpf/opcodes.rb +97 -0
  68. data/metasm/cpu/ebpf/render.rb +36 -0
  69. data/metasm/cpu/ia32.rb +17 -0
  70. data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +23 -9
  71. data/{lib/metasm → metasm/cpu}/ia32/debug.rb +44 -6
  72. data/{lib/metasm → metasm/cpu}/ia32/decode.rb +342 -128
  73. data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +75 -53
  74. data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
  75. data/{lib/metasm → metasm/cpu}/ia32/main.rb +66 -8
  76. data/metasm/cpu/ia32/opcodes.rb +1424 -0
  77. data/{lib/metasm → metasm/cpu}/ia32/parse.rb +55 -17
  78. data/{lib/metasm → metasm/cpu}/ia32/render.rb +32 -5
  79. data/metasm/cpu/mcs51.rb +8 -0
  80. data/metasm/cpu/mcs51/decode.rb +99 -0
  81. data/metasm/cpu/mcs51/main.rb +87 -0
  82. data/metasm/cpu/mcs51/opcodes.rb +120 -0
  83. data/metasm/cpu/mips.rb +14 -0
  84. data/metasm/cpu/mips/debug.rb +42 -0
  85. data/{lib/metasm → metasm/cpu}/mips/decode.rb +59 -38
  86. data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
  87. data/{lib/metasm → metasm/cpu}/mips/main.rb +13 -6
  88. data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +87 -18
  89. data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
  90. data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
  91. data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
  92. data/metasm/cpu/msp430/decode.rb +243 -0
  93. data/metasm/cpu/msp430/main.rb +62 -0
  94. data/metasm/cpu/msp430/opcodes.rb +101 -0
  95. data/metasm/cpu/openrisc.rb +11 -0
  96. data/metasm/cpu/openrisc/debug.rb +106 -0
  97. data/metasm/cpu/openrisc/decode.rb +182 -0
  98. data/metasm/cpu/openrisc/decompile.rb +350 -0
  99. data/metasm/cpu/openrisc/main.rb +70 -0
  100. data/metasm/cpu/openrisc/opcodes.rb +109 -0
  101. data/metasm/cpu/openrisc/render.rb +37 -0
  102. data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
  103. data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
  104. data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
  105. data/metasm/cpu/ppc.rb +11 -0
  106. data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -37
  107. data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
  108. data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
  109. data/{lib/metasm → metasm/cpu}/ppc/main.rb +23 -18
  110. data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -6
  111. data/metasm/cpu/ppc/parse.rb +55 -0
  112. data/metasm/cpu/python.rb +8 -0
  113. data/metasm/cpu/python/decode.rb +116 -0
  114. data/metasm/cpu/python/main.rb +36 -0
  115. data/metasm/cpu/python/opcodes.rb +180 -0
  116. data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
  117. data/{lib/metasm → metasm/cpu}/sh4/decode.rb +50 -23
  118. data/{lib/metasm → metasm/cpu}/sh4/main.rb +38 -27
  119. data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
  120. data/metasm/cpu/st20.rb +9 -0
  121. data/metasm/cpu/st20/decode.rb +173 -0
  122. data/metasm/cpu/st20/decompile.rb +283 -0
  123. data/metasm/cpu/st20/main.rb +37 -0
  124. data/metasm/cpu/st20/opcodes.rb +140 -0
  125. data/{lib/metasm/arm.rb → metasm/cpu/webasm.rb} +4 -5
  126. data/metasm/cpu/webasm/debug.rb +31 -0
  127. data/metasm/cpu/webasm/decode.rb +321 -0
  128. data/metasm/cpu/webasm/decompile.rb +386 -0
  129. data/metasm/cpu/webasm/encode.rb +104 -0
  130. data/metasm/cpu/webasm/main.rb +81 -0
  131. data/metasm/cpu/webasm/opcodes.rb +214 -0
  132. data/metasm/cpu/x86_64.rb +15 -0
  133. data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +40 -25
  134. data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
  135. data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +58 -15
  136. data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +59 -28
  137. data/{lib/metasm → metasm/cpu}/x86_64/main.rb +18 -6
  138. data/metasm/cpu/x86_64/opcodes.rb +138 -0
  139. data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +12 -4
  140. data/metasm/cpu/x86_64/render.rb +35 -0
  141. data/metasm/cpu/z80.rb +9 -0
  142. data/metasm/cpu/z80/decode.rb +286 -0
  143. data/metasm/cpu/z80/main.rb +67 -0
  144. data/metasm/cpu/z80/opcodes.rb +224 -0
  145. data/metasm/cpu/z80/render.rb +48 -0
  146. data/{lib/metasm/os/main.rb → metasm/debug.rb} +201 -407
  147. data/{lib/metasm → metasm}/decode.rb +104 -24
  148. data/{lib/metasm → metasm}/decompile.rb +804 -478
  149. data/{lib/metasm → metasm}/disassemble.rb +385 -170
  150. data/{lib/metasm → metasm}/disassemble_api.rb +684 -105
  151. data/{lib/metasm → metasm}/dynldr.rb +231 -138
  152. data/{lib/metasm → metasm}/encode.rb +20 -5
  153. data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
  154. data/{lib/metasm → metasm}/exe_format/autoexe.rb +3 -0
  155. data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
  156. data/{lib/metasm → metasm}/exe_format/coff.rb +35 -7
  157. data/{lib/metasm → metasm}/exe_format/coff_decode.rb +70 -23
  158. data/{lib/metasm → metasm}/exe_format/coff_encode.rb +24 -22
  159. data/{lib/metasm → metasm}/exe_format/dex.rb +26 -8
  160. data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
  161. data/{lib/metasm → metasm}/exe_format/elf.rb +108 -58
  162. data/{lib/metasm → metasm}/exe_format/elf_decode.rb +202 -36
  163. data/{lib/metasm → metasm}/exe_format/elf_encode.rb +126 -32
  164. data/metasm/exe_format/gb.rb +65 -0
  165. data/metasm/exe_format/javaclass.rb +424 -0
  166. data/{lib/metasm → metasm}/exe_format/macho.rb +218 -16
  167. data/{lib/metasm → metasm}/exe_format/main.rb +28 -3
  168. data/{lib/metasm → metasm}/exe_format/mz.rb +2 -0
  169. data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
  170. data/{lib/metasm → metasm}/exe_format/pe.rb +96 -11
  171. data/metasm/exe_format/pyc.rb +167 -0
  172. data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
  173. data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
  174. data/metasm/exe_format/shellcode_rwx.rb +114 -0
  175. data/metasm/exe_format/swf.rb +205 -0
  176. data/metasm/exe_format/wasm.rb +402 -0
  177. data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
  178. data/metasm/exe_format/zip.rb +335 -0
  179. data/metasm/gui.rb +13 -0
  180. data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
  181. data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
  182. data/{lib/metasm → metasm}/gui/dasm_decomp.rb +177 -114
  183. data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
  184. data/metasm/gui/dasm_graph.rb +1754 -0
  185. data/{lib/metasm → metasm}/gui/dasm_hex.rb +16 -12
  186. data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
  187. data/{lib/metasm → metasm}/gui/dasm_main.rb +360 -77
  188. data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
  189. data/{lib/metasm → metasm}/gui/debug.rb +109 -34
  190. data/{lib/metasm → metasm}/gui/gtk.rb +174 -44
  191. data/{lib/metasm → metasm}/gui/qt.rb +14 -4
  192. data/{lib/metasm → metasm}/gui/win32.rb +180 -43
  193. data/{lib/metasm → metasm}/gui/x11.rb +59 -59
  194. data/{lib/metasm → metasm}/main.rb +421 -286
  195. data/metasm/os/emulator.rb +175 -0
  196. data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
  197. data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
  198. data/{lib/metasm → metasm}/os/linux.rb +628 -151
  199. data/metasm/os/main.rb +335 -0
  200. data/{lib/metasm → metasm}/os/windows.rb +151 -58
  201. data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
  202. data/{lib/metasm → metasm}/parse.rb +49 -36
  203. data/{lib/metasm → metasm}/parse_c.rb +405 -246
  204. data/{lib/metasm → metasm}/preprocessor.rb +71 -41
  205. data/{lib/metasm → metasm}/render.rb +14 -38
  206. data/misc/hexdump.rb +4 -3
  207. data/misc/lint.rb +58 -0
  208. data/misc/objdiff.rb +4 -1
  209. data/misc/objscan.rb +1 -1
  210. data/misc/openrisc-parser.rb +79 -0
  211. data/misc/txt2html.rb +9 -7
  212. data/samples/bindiff.rb +3 -4
  213. data/samples/dasm-plugins/bindiff.rb +15 -0
  214. data/samples/dasm-plugins/bookmark.rb +133 -0
  215. data/samples/dasm-plugins/c_constants.rb +57 -0
  216. data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
  217. data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
  218. data/samples/dasm-plugins/dasm_all.rb +70 -0
  219. data/samples/dasm-plugins/demangle_cpp.rb +31 -0
  220. data/samples/dasm-plugins/deobfuscate.rb +251 -0
  221. data/samples/dasm-plugins/dump_text.rb +35 -0
  222. data/samples/dasm-plugins/export_graph_svg.rb +86 -0
  223. data/samples/dasm-plugins/findgadget.rb +75 -0
  224. data/samples/dasm-plugins/hl_opcode.rb +32 -0
  225. data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
  226. data/samples/dasm-plugins/imm2off.rb +34 -0
  227. data/samples/dasm-plugins/match_libsigs.rb +93 -0
  228. data/samples/dasm-plugins/patch_file.rb +95 -0
  229. data/samples/dasm-plugins/scanfuncstart.rb +36 -0
  230. data/samples/dasm-plugins/scanxrefs.rb +29 -0
  231. data/samples/dasm-plugins/selfmodify.rb +197 -0
  232. data/samples/dasm-plugins/stringsxrefs.rb +28 -0
  233. data/samples/dasmnavig.rb +1 -1
  234. data/samples/dbg-apihook.rb +24 -9
  235. data/samples/dbg-plugins/heapscan.rb +283 -0
  236. data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
  237. data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
  238. data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
  239. data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
  240. data/samples/dbg-plugins/heapscan/winheap.h +174 -0
  241. data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
  242. data/samples/dbg-plugins/trace_func.rb +214 -0
  243. data/samples/disassemble-gui.rb +48 -7
  244. data/samples/disassemble.rb +31 -6
  245. data/samples/dump_upx.rb +24 -12
  246. data/samples/dynamic_ruby.rb +35 -27
  247. data/samples/elfencode.rb +15 -0
  248. data/samples/emubios.rb +251 -0
  249. data/samples/emudbg.rb +127 -0
  250. data/samples/exeencode.rb +6 -5
  251. data/samples/factorize-headers-peimports.rb +1 -1
  252. data/samples/lindebug.rb +186 -391
  253. data/samples/metasm-shell.rb +68 -57
  254. data/samples/peldr.rb +2 -2
  255. data/tests/all.rb +1 -1
  256. data/tests/arc.rb +26 -0
  257. data/tests/dynldr.rb +22 -4
  258. data/tests/expression.rb +57 -0
  259. data/tests/graph_layout.rb +285 -0
  260. data/tests/ia32.rb +80 -26
  261. data/tests/mcs51.rb +27 -0
  262. data/tests/mips.rb +10 -3
  263. data/tests/preprocessor.rb +18 -0
  264. data/tests/x86_64.rb +66 -18
  265. metadata +465 -219
  266. metadata.gz.sig +2 -0
  267. data/lib/metasm/arm/opcodes.rb +0 -177
  268. data/lib/metasm/gui.rb +0 -23
  269. data/lib/metasm/gui/dasm_graph.rb +0 -1354
  270. data/lib/metasm/ia32.rb +0 -14
  271. data/lib/metasm/ia32/opcodes.rb +0 -872
  272. data/lib/metasm/ppc/parse.rb +0 -52
  273. data/lib/metasm/x86_64.rb +0 -12
  274. data/lib/metasm/x86_64/opcodes.rb +0 -118
  275. data/samples/gdbclient.rb +0 -583
  276. data/samples/rubstop.rb +0 -399
@@ -0,0 +1,65 @@
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
+ # GameBoy ROM file format
14
+ class GameBoyRom < ExeFormat
15
+ class Header < SerialStruct
16
+ # starts at 0x104 in the file
17
+ mem :logo, 0x30
18
+ str :title, 0x10
19
+ byte :sgb_flag
20
+ byte :cartridge_type
21
+ byte :rom_size # n => (n+1) * 32k bytes
22
+ byte :ram_size
23
+ byte :destination_code
24
+ byte :old_licensee_code
25
+ byte :mask_rom_version
26
+ byte :header_checksum
27
+ byte :checksum_hi
28
+ byte :checksum_lo
29
+ end
30
+
31
+ def encode_byte(val) Expression[val].encode(:u8, @endianness) end
32
+ def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
33
+ def sizeof_byte ; 1 ; end
34
+
35
+
36
+ attr_accessor :header
37
+
38
+ def initialize(cpu=nil)
39
+ @endianness = (cpu ? cpu.endianness : :little)
40
+ super(cpu)
41
+ end
42
+
43
+ def decode_header
44
+ @encoded.ptr = 0x104
45
+ @header = Header.decode(self)
46
+ end
47
+
48
+ def decode
49
+ decode_header
50
+ @encoded.add_export('entrypoint', 0x100)
51
+ end
52
+
53
+ def cpu_from_headers
54
+ Z80.new('gb')
55
+ end
56
+
57
+ def each_section
58
+ yield @encoded, 0
59
+ end
60
+
61
+ def get_default_entrypoints
62
+ ['entrypoint']
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,424 @@
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
+ require 'metasm/exe_format/main'
7
+ require 'metasm/encode'
8
+ require 'metasm/decode'
9
+
10
+ module Metasm
11
+
12
+ class JavaClass < ExeFormat
13
+ MAGIC = "\xCA\xFE\xBA\xBE"
14
+
15
+ CONSTANT_TAG = {0x1 => 'Utf8', 0x3 => 'Integer',
16
+ 0x4 => 'Float', 0x5 => 'Long',
17
+ 0x6 => 'Double', 0x7 => 'Class',
18
+ 0x8 => 'String', 0x9 => 'Fieldref',
19
+ 0xa => 'Methodref', 0xb => 'InterfaceMethodref',
20
+ 0xc => 'NameAndType' }
21
+
22
+ class SerialStruct < Metasm::SerialStruct
23
+ new_int_field :u1, :u2, :u4
24
+ end
25
+
26
+ class Header < SerialStruct
27
+ mem :magic, 4, MAGIC
28
+ u2 :minor_version
29
+ u2 :major_version
30
+ end
31
+
32
+ class ConstantPool < SerialStruct
33
+ u2 :constant_pool_count
34
+ attr_accessor :constant_pool
35
+
36
+ def decode(c)
37
+ super(c)
38
+
39
+ @constant_pool = [nil]
40
+
41
+ i = 1
42
+ while i < @constant_pool_count
43
+ entry = ConstantPoolInfo.decode(c)
44
+ entry.idx = i
45
+ @constant_pool << entry
46
+ i += 1
47
+
48
+ if entry.tag =~ /Long|Double/
49
+ # we must insert a phantom cell
50
+ # for long and double constants
51
+ @constant_pool << nil
52
+ i += 1
53
+ end
54
+ end
55
+ end
56
+
57
+ def encode(c)
58
+ cp = super(c)
59
+
60
+ @constant_pool.each { |entry|
61
+ next if entry.nil?
62
+ cp << entry.encode(c)
63
+ }
64
+ cp
65
+ end
66
+
67
+ def [](idx)
68
+ @constant_pool[idx]
69
+ end
70
+
71
+ def []=(idx, val)
72
+ raise 'cannot be used to add a cp entry' if @constant_pool[idx].nil?
73
+ @constant_pool[idx] = val
74
+ end
75
+ end
76
+
77
+ class ConstantPoolInfo < SerialStruct
78
+ u1 :tag
79
+ fld_enum :tag, CONSTANT_TAG
80
+ attr_accessor :info, :idx
81
+
82
+ def decode(c)
83
+ super(c)
84
+
85
+ case @tag
86
+ when 'Utf8'
87
+ @info = ConstantUtf8.decode(c)
88
+ when /Integer|Float/
89
+ @info = ConstantIntFloat.decode(c)
90
+ when /Long|Double/
91
+ @info = ConstantLongDouble.decode(c)
92
+ when /Class|String/
93
+ @info = ConstantIndex.decode(c)
94
+ when /ref$/
95
+ @info = ConstantRef.decode(c)
96
+ when 'NameAndType'
97
+ @info = ConstantNameAndType.decode(c)
98
+ else
99
+ raise 'unkown constant tag'
100
+ return
101
+ end
102
+ end
103
+
104
+ def encode(c)
105
+ super(c) << @info.encode(c)
106
+ end
107
+ end
108
+
109
+ class ConstantUtf8 < SerialStruct
110
+ u2 :length
111
+ attr_accessor :bytes
112
+
113
+ def decode(c)
114
+ super(c)
115
+ @bytes = c.encoded.read(@length)
116
+ end
117
+
118
+ def encode(c)
119
+ super(c) << @bytes
120
+ end
121
+ end
122
+
123
+ class ConstantIntFloat < SerialStruct
124
+ u4 :bytes
125
+ end
126
+
127
+ class ConstantLongDouble < SerialStruct
128
+ u4 :high_bytes
129
+ u4 :low_bytes
130
+ end
131
+
132
+ class ConstantIndex < SerialStruct
133
+ u2 :index
134
+ end
135
+
136
+ class ConstantRef < SerialStruct
137
+ u2 :class_index
138
+ u2 :name_and_type_index
139
+ end
140
+
141
+ class ConstantNameAndType < SerialStruct
142
+ u2 :name_index
143
+ u2 :descriptor_index
144
+ end
145
+
146
+ class ClassInfo < SerialStruct
147
+ u2 :access_flags
148
+ u2 :this_class
149
+ u2 :super_class
150
+ end
151
+
152
+ class Interfaces < SerialStruct
153
+ u2 :interfaces_count
154
+ attr_accessor :interfaces
155
+
156
+ def decode(c)
157
+ super(c)
158
+
159
+ @interfaces = []
160
+ @interfaces_count.times {
161
+ @interfaces << ConstantIndex.decode(c)
162
+ }
163
+ end
164
+
165
+ def encode(c)
166
+ ret = super(c)
167
+
168
+ @interfaces.each { |e|
169
+ ret << e.encode(c)
170
+ }
171
+ ret
172
+ end
173
+
174
+ def [](idx)
175
+ @interfaces[idx]
176
+ end
177
+ end
178
+
179
+ class Fields < SerialStruct
180
+ u2 :fields_count
181
+ attr_accessor :fields
182
+
183
+ def decode(c)
184
+ super(c)
185
+ @fields = []
186
+ @fields_count.times {
187
+ @fields << FieldMethodInfo.decode(c)
188
+ }
189
+ end
190
+
191
+ def encode(c)
192
+ ret = super(c)
193
+
194
+ @fields.each { |e|
195
+ ret << e.encode(c)
196
+ }
197
+ ret
198
+ end
199
+
200
+ def [](idx)
201
+ @fields[idx]
202
+ end
203
+ end
204
+
205
+ class Methods < SerialStruct
206
+ u2 :methods_count
207
+ attr_accessor :methods
208
+
209
+ def decode(c)
210
+ super(c)
211
+ @methods = []
212
+ @methods_count.times {
213
+ @methods << FieldMethodInfo.decode(c)
214
+ }
215
+ end
216
+
217
+ def encode(c)
218
+ ret = super(c)
219
+
220
+ @methods.each { |e|
221
+ ret << e.encode(c)
222
+ }
223
+ ret
224
+ end
225
+
226
+ def [](idx)
227
+ @methods[idx]
228
+ end
229
+ end
230
+
231
+ class FieldMethodInfo < SerialStruct
232
+ u2 :access_flags
233
+ u2 :name_index
234
+ u2 :descriptor_index
235
+ attr_accessor :attributes
236
+
237
+ def decode(c)
238
+ super(c)
239
+ @attributes = Attributes.decode(c)
240
+ end
241
+
242
+ def encode(c)
243
+ super(c) << @attributes.encode(c)
244
+ end
245
+ end
246
+
247
+ class Attributes < SerialStruct
248
+ u2 :attributes_count
249
+ attr_accessor :attributes
250
+
251
+ def decode(c)
252
+ super(c)
253
+
254
+ @attributes = []
255
+ @attributes_count.times { |i|
256
+ @attributes << AttributeInfo.decode(c)
257
+ }
258
+ end
259
+
260
+ def encode(c)
261
+ ret = super(c)
262
+
263
+ @attributes.each { |e|
264
+ ret << e.encode(c)
265
+ }
266
+ ret
267
+ end
268
+
269
+ def [](idx)
270
+ @attributes[idx]
271
+ end
272
+ end
273
+
274
+ class AttributeInfo < SerialStruct
275
+ u2 :attribute_name_index
276
+ u4 :attribute_length
277
+ attr_accessor :data
278
+
279
+ def decode(c)
280
+ super(c)
281
+ @data = c.encoded.read(@attribute_length)
282
+ end
283
+
284
+ def encode(c)
285
+ super(c) << @data
286
+ end
287
+ end
288
+
289
+ def encode_u1(val) Expression[val].encode(:u8, @endianness) end
290
+ def encode_u2(val) Expression[val].encode(:u16, @endianness) end
291
+ def encode_u4(val) Expression[val].encode(:u32, @endianness) end
292
+ def decode_u1(edata = @encoded) edata.decode_imm(:u8, @endianness) end
293
+ def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
294
+ def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
295
+ def sizeof_u1 ; 1 ; end
296
+ def sizeof_u2 ; 2 ; end
297
+ def sizeof_u4 ; 4 ; end
298
+
299
+ attr_accessor :header, :constant_pool, :class_info, :interfaces, :fields, :methods, :attributes
300
+
301
+ def initialize(endianness=:big)
302
+ @endianness = endianness
303
+ @encoded = EncodedData.new
304
+ super()
305
+ end
306
+
307
+ def decode
308
+ @header = Header.decode(self)
309
+ @constant_pool = ConstantPool.decode(self)
310
+ @class_info = ClassInfo.decode(self)
311
+ @interfaces = Interfaces.decode(self)
312
+ @fields = Fields.decode(self)
313
+ @methods = Methods.decode(self)
314
+ @attributes = Attributes.decode(self)
315
+ end
316
+
317
+ def encode
318
+ @encoded = EncodedData.new
319
+ @encoded << @header.encode(self)
320
+ @encoded << @constant_pool.encode(self)
321
+ @encoded << @class_info.encode(self)
322
+ @encoded << @interfaces.encode(self)
323
+ @encoded << @fields.encode(self)
324
+ @encoded << @methods.encode(self)
325
+ @encoded << @attributes.encode(self)
326
+ @encoded.data
327
+ end
328
+
329
+ def cpu_from_headers
330
+ raise 'JVM'
331
+ end
332
+
333
+ def each_section
334
+ raise 'n/a'
335
+ end
336
+
337
+ def get_default_entrypoints
338
+ []
339
+ end
340
+
341
+ def string_at(idx)
342
+ loop do
343
+ tmp = @constant_pool[idx].info
344
+ return tmp.bytes if tmp.kind_of? ConstantUtf8
345
+ idx = tmp.index
346
+ end
347
+ end
348
+
349
+ def decode_methodref(mref)
350
+ class_idx = mref.info.class_index
351
+ nt_idx = mref.info.name_and_type_index
352
+ name_idx = @constant_pool[nt_idx].info.name_index
353
+ desc_idx = @constant_pool[nt_idx].info.descriptor_index
354
+
355
+ string_at(class_idx) + '/' + string_at(name_idx) + string_at(desc_idx)
356
+ end
357
+
358
+ def cp_add(cpi, tag)
359
+ cpe = ConstantPoolInfo.new
360
+ cpe.tag = tag
361
+ cpe.info = cpi
362
+ cpe.idx = @constant_pool.constant_pool_count
363
+
364
+ @constant_pool.constant_pool << cpe
365
+ @constant_pool.constant_pool_count += 1
366
+ @constant_pool.constant_pool_count += 1 if tag =~ /Long|Double/
367
+
368
+ cpe.idx
369
+ end
370
+
371
+ def cp_find(tag)
372
+ constant_pool.constant_pool.each { |e|
373
+ next if !e or e.tag != tag
374
+ if yield(e.info)
375
+ return e.idx
376
+ end
377
+ }
378
+ nil
379
+ end
380
+
381
+
382
+ def cp_auto_utf8(string)
383
+ if idx = cp_find('Utf8') { |i| i.bytes == string }
384
+ return idx
385
+ end
386
+
387
+ cpi = ConstantUtf8.new
388
+ cpi.bytes = string
389
+ cpi.length = string.length
390
+ cp_add(cpi, 'Utf8')
391
+ end
392
+
393
+ def cp_auto_class(classname)
394
+ if idx = cp_find('Class') { |i| string_at(i.index) == classname }
395
+ return idx
396
+ end
397
+
398
+ cpi = ConstantIndex.new
399
+ cpi.index = cp_auto_utf8(classname)
400
+ cp_add(cpi, 'Class')
401
+ end
402
+
403
+ def cp_add_methodref(classname, name, descriptor)
404
+ nat = ConstantNameAndType.new
405
+ nat.name_index = cp_auto_utf8(name)
406
+ nat.descriptor_index = cp_auto_utf8(descriptor)
407
+ natidx = cp_add(nat, 'NameAndType')
408
+
409
+ cpi = ConstantRef.new
410
+ cpi.class_index = cp_auto_class(classname)
411
+ cpi.name_and_type_index = natidx
412
+
413
+ cp_add(cpi, 'Methodref')
414
+ end
415
+
416
+ def attribute_create(name, data)
417
+ a = AttributeInfo.new
418
+ a.attribute_name_index = cp_auto_utf8(name)
419
+ a.attribute_length = data.size
420
+ a.data = data
421
+ a
422
+ end
423
+ end
424
+ end