metasm 1.0.1 → 1.0.2

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 (235) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.hgtags +3 -0
  4. data/Gemfile +1 -0
  5. data/INSTALL +61 -0
  6. data/LICENCE +458 -0
  7. data/README +29 -21
  8. data/Rakefile +10 -0
  9. data/TODO +10 -12
  10. data/doc/code_organisation.txt +2 -0
  11. data/doc/core/DynLdr.txt +247 -0
  12. data/doc/core/ExeFormat.txt +43 -0
  13. data/doc/core/Expression.txt +220 -0
  14. data/doc/core/GNUExports.txt +27 -0
  15. data/doc/core/Ia32.txt +236 -0
  16. data/doc/core/SerialStruct.txt +108 -0
  17. data/doc/core/VirtualString.txt +145 -0
  18. data/doc/core/WindowsExports.txt +61 -0
  19. data/doc/core/index.txt +1 -0
  20. data/doc/style.css +6 -3
  21. data/doc/usage/debugger.txt +327 -0
  22. data/doc/usage/index.txt +1 -0
  23. data/doc/use_cases.txt +2 -2
  24. data/metasm.gemspec +22 -0
  25. data/{lib/metasm.rb → metasm.rb} +11 -3
  26. data/{lib/metasm → metasm}/compile_c.rb +13 -7
  27. data/metasm/cpu/arc.rb +8 -0
  28. data/metasm/cpu/arc/decode.rb +425 -0
  29. data/metasm/cpu/arc/main.rb +191 -0
  30. data/metasm/cpu/arc/opcodes.rb +588 -0
  31. data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
  32. data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
  33. data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
  34. data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
  35. data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
  36. data/metasm/cpu/arm/opcodes.rb +324 -0
  37. data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
  38. data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
  39. data/metasm/cpu/arm64.rb +15 -0
  40. data/metasm/cpu/arm64/debug.rb +38 -0
  41. data/metasm/cpu/arm64/decode.rb +289 -0
  42. data/metasm/cpu/arm64/encode.rb +41 -0
  43. data/metasm/cpu/arm64/main.rb +105 -0
  44. data/metasm/cpu/arm64/opcodes.rb +232 -0
  45. data/metasm/cpu/arm64/parse.rb +20 -0
  46. data/metasm/cpu/arm64/render.rb +95 -0
  47. data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
  48. data/metasm/cpu/bpf/decode.rb +142 -0
  49. data/metasm/cpu/bpf/main.rb +60 -0
  50. data/metasm/cpu/bpf/opcodes.rb +81 -0
  51. data/metasm/cpu/bpf/render.rb +41 -0
  52. data/metasm/cpu/cy16.rb +9 -0
  53. data/metasm/cpu/cy16/decode.rb +253 -0
  54. data/metasm/cpu/cy16/main.rb +63 -0
  55. data/metasm/cpu/cy16/opcodes.rb +78 -0
  56. data/metasm/cpu/cy16/render.rb +41 -0
  57. data/metasm/cpu/dalvik.rb +11 -0
  58. data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
  59. data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
  60. data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
  61. data/metasm/cpu/ia32.rb +17 -0
  62. data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
  63. data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
  64. data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
  65. data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
  66. data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
  67. data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
  68. data/metasm/cpu/ia32/opcodes.rb +1424 -0
  69. data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
  70. data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
  71. data/metasm/cpu/mips.rb +14 -0
  72. data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
  73. data/metasm/cpu/mips/debug.rb +42 -0
  74. data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
  75. data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
  76. data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
  77. data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
  78. data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
  79. data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
  80. data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
  81. data/metasm/cpu/msp430/decode.rb +247 -0
  82. data/metasm/cpu/msp430/main.rb +62 -0
  83. data/metasm/cpu/msp430/opcodes.rb +101 -0
  84. data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
  85. data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
  86. data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
  87. data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
  88. data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
  89. data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
  90. data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
  91. data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
  92. data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
  93. data/metasm/cpu/ppc/parse.rb +55 -0
  94. data/metasm/cpu/python.rb +8 -0
  95. data/metasm/cpu/python/decode.rb +136 -0
  96. data/metasm/cpu/python/main.rb +36 -0
  97. data/metasm/cpu/python/opcodes.rb +180 -0
  98. data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
  99. data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
  100. data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
  101. data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
  102. data/metasm/cpu/x86_64.rb +15 -0
  103. data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
  104. data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
  105. data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
  106. data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
  107. data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
  108. data/metasm/cpu/x86_64/opcodes.rb +136 -0
  109. data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
  110. data/metasm/cpu/x86_64/render.rb +35 -0
  111. data/metasm/cpu/z80.rb +9 -0
  112. data/metasm/cpu/z80/decode.rb +313 -0
  113. data/metasm/cpu/z80/main.rb +67 -0
  114. data/metasm/cpu/z80/opcodes.rb +224 -0
  115. data/metasm/cpu/z80/render.rb +59 -0
  116. data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
  117. data/{lib/metasm → metasm}/decode.rb +35 -4
  118. data/{lib/metasm → metasm}/decompile.rb +15 -16
  119. data/{lib/metasm → metasm}/disassemble.rb +201 -45
  120. data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
  121. data/{lib/metasm → metasm}/dynldr.rb +220 -133
  122. data/{lib/metasm → metasm}/encode.rb +10 -1
  123. data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
  124. data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
  125. data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
  126. data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
  127. data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
  128. data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
  129. data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
  130. data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
  131. data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
  132. data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
  133. data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
  134. data/metasm/exe_format/gb.rb +65 -0
  135. data/metasm/exe_format/javaclass.rb +424 -0
  136. data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
  137. data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
  138. data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
  139. data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
  140. data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
  141. data/metasm/exe_format/pyc.rb +167 -0
  142. data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
  143. data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
  144. data/metasm/exe_format/shellcode_rwx.rb +114 -0
  145. data/metasm/exe_format/swf.rb +205 -0
  146. data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
  147. data/metasm/exe_format/zip.rb +335 -0
  148. data/metasm/gui.rb +13 -0
  149. data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
  150. data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
  151. data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
  152. data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
  153. data/metasm/gui/dasm_graph.rb +1695 -0
  154. data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
  155. data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
  156. data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
  157. data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
  158. data/{lib/metasm → metasm}/gui/debug.rb +93 -27
  159. data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
  160. data/{lib/metasm → metasm}/gui/qt.rb +12 -2
  161. data/{lib/metasm → metasm}/gui/win32.rb +179 -42
  162. data/{lib/metasm → metasm}/gui/x11.rb +59 -59
  163. data/{lib/metasm → metasm}/main.rb +389 -264
  164. data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
  165. data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
  166. data/{lib/metasm → metasm}/os/linux.rb +628 -151
  167. data/metasm/os/main.rb +330 -0
  168. data/{lib/metasm → metasm}/os/windows.rb +132 -42
  169. data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
  170. data/{lib/metasm → metasm}/parse.rb +26 -24
  171. data/{lib/metasm → metasm}/parse_c.rb +221 -116
  172. data/{lib/metasm → metasm}/preprocessor.rb +55 -40
  173. data/{lib/metasm → metasm}/render.rb +14 -38
  174. data/misc/hexdump.rb +2 -1
  175. data/misc/lint.rb +58 -0
  176. data/misc/txt2html.rb +9 -7
  177. data/samples/bindiff.rb +3 -4
  178. data/samples/dasm-plugins/bindiff.rb +15 -0
  179. data/samples/dasm-plugins/bookmark.rb +133 -0
  180. data/samples/dasm-plugins/c_constants.rb +57 -0
  181. data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
  182. data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
  183. data/samples/dasm-plugins/dasm_all.rb +70 -0
  184. data/samples/dasm-plugins/demangle_cpp.rb +31 -0
  185. data/samples/dasm-plugins/deobfuscate.rb +251 -0
  186. data/samples/dasm-plugins/dump_text.rb +35 -0
  187. data/samples/dasm-plugins/export_graph_svg.rb +86 -0
  188. data/samples/dasm-plugins/findgadget.rb +75 -0
  189. data/samples/dasm-plugins/hl_opcode.rb +32 -0
  190. data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
  191. data/samples/dasm-plugins/imm2off.rb +34 -0
  192. data/samples/dasm-plugins/match_libsigs.rb +93 -0
  193. data/samples/dasm-plugins/patch_file.rb +95 -0
  194. data/samples/dasm-plugins/scanfuncstart.rb +36 -0
  195. data/samples/dasm-plugins/scanxrefs.rb +26 -0
  196. data/samples/dasm-plugins/selfmodify.rb +197 -0
  197. data/samples/dasm-plugins/stringsxrefs.rb +28 -0
  198. data/samples/dasmnavig.rb +1 -1
  199. data/samples/dbg-apihook.rb +24 -9
  200. data/samples/dbg-plugins/heapscan.rb +283 -0
  201. data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
  202. data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
  203. data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
  204. data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
  205. data/samples/dbg-plugins/heapscan/winheap.h +174 -0
  206. data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
  207. data/samples/dbg-plugins/trace_func.rb +214 -0
  208. data/samples/disassemble-gui.rb +35 -5
  209. data/samples/disassemble.rb +31 -6
  210. data/samples/dump_upx.rb +24 -12
  211. data/samples/dynamic_ruby.rb +12 -3
  212. data/samples/exeencode.rb +6 -5
  213. data/samples/factorize-headers-peimports.rb +1 -1
  214. data/samples/lindebug.rb +175 -381
  215. data/samples/metasm-shell.rb +1 -2
  216. data/samples/peldr.rb +2 -2
  217. data/tests/all.rb +1 -1
  218. data/tests/arc.rb +26 -0
  219. data/tests/dynldr.rb +22 -4
  220. data/tests/expression.rb +55 -0
  221. data/tests/graph_layout.rb +285 -0
  222. data/tests/ia32.rb +79 -26
  223. data/tests/mips.rb +9 -2
  224. data/tests/x86_64.rb +66 -18
  225. metadata +330 -218
  226. data/lib/metasm/arm/opcodes.rb +0 -177
  227. data/lib/metasm/gui.rb +0 -23
  228. data/lib/metasm/gui/dasm_graph.rb +0 -1354
  229. data/lib/metasm/ia32.rb +0 -14
  230. data/lib/metasm/ia32/opcodes.rb +0 -873
  231. data/lib/metasm/ppc/parse.rb +0 -52
  232. data/lib/metasm/x86_64.rb +0 -12
  233. data/lib/metasm/x86_64/opcodes.rb +0 -118
  234. data/samples/gdbclient.rb +0 -583
  235. data/samples/rubstop.rb +0 -399
@@ -0,0 +1,15 @@
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
+ # metasm dasm plugin: asks to load a second program, and unleash the samples/bindiff fury
7
+ # usage: load the plugin, and a 2nd binary, disassemble functions in both, diff'em
8
+
9
+ require File.join(Metasm::Metasmdir, 'samples', 'bindiff.rb')
10
+
11
+ Gui::DasmWindow.new("bindiff target").promptopen("chose bindiff target") { |w|
12
+ w.title = "#{w.widget.dasm.program.filename} - metasm bindiff"
13
+ @bindiff_win = BinDiffWindow.new(self, w.widget.dasm)
14
+ }
15
+
@@ -0,0 +1,133 @@
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
+ # metasm dasm GUI plugin:
8
+ # pops a list of bookmarked functions
9
+ # also allows the custom coloration of blocks/functions
10
+
11
+ if gui
12
+ class ColorWindow < Metasm::Gui::ToolWindow
13
+ def initialize_window(&b)
14
+ self.title = 'pick a color'
15
+ self.widget = ColorWidget.new(&b)
16
+ end
17
+ end
18
+
19
+ class ColorWidget < Metasm::Gui::DrawableWidget
20
+ attr_accessor :ph, :pw
21
+ def initialize_widget(&b)
22
+ super()
23
+ @action = b
24
+ @pw = 3
25
+ @ph = 8
26
+ end
27
+
28
+ def initial_size
29
+ [@pw*256, @ph*16]
30
+ end
31
+
32
+ def paint
33
+ 0x100.times { |x|
34
+ cx = x
35
+ if x & 0x10 > 0
36
+ cx = (x&0xf0) + (15-(x&0xf))
37
+ end
38
+ 0x10.times { |y|
39
+ col = '%02x%x' % [cx, y]
40
+ draw_rectangle_color(col, x*@pw, y*@ph, @pw, @ph)
41
+ }
42
+ }
43
+ end
44
+
45
+ def xy_to_col(x, y)
46
+ x = x.to_i / @pw
47
+ y = y.to_i / @ph
48
+ if x >=0 and y >= 0 and x <= 0xff and y <= 0xf
49
+ if x & 0x10 > 0
50
+ x = (x&0xf0) + (15-(x&0xf))
51
+ end
52
+ col = '%02x%x' % [x, y]
53
+ toplevel.title = "color #{col}"
54
+ col
55
+ end
56
+ end
57
+
58
+ def mousemove(x, y)
59
+ xy_to_col(x, y)
60
+ end
61
+
62
+ def mouserelease(x, y)
63
+ if c = xy_to_col(x, y)
64
+ toplevel.destroy
65
+ @action.call(c)
66
+ end
67
+ end
68
+ end
69
+
70
+ # list of user-specified addrs
71
+ @bookmarklist = []
72
+ # every single addr => color
73
+ @bookmarkcolor = {}
74
+
75
+ obg = gui.bg_color_callback # chain old callback
76
+ gui.bg_color_callback = lambda { |a|
77
+ if obg and col = obg[a]
78
+ col
79
+ else
80
+ # least priority
81
+ @bookmarkcolor[a]
82
+ end
83
+ }
84
+
85
+ popbookmarks = lambda { |*a|
86
+ list = [['address', 'color']] + @bookmarklist.map { |bm| [Expression[bm].to_s, @bookmarkcolor[bm].to_s] }
87
+ listcolcb = lambda { |e| [nil, @bookmarkcolor[Expression.parse_string(e[0]).reduce]] }
88
+ gui.listwindow('bookmarks', list, :color_callback => listcolcb) { |e| gui.focus_addr(e[0]) }
89
+ }
90
+
91
+ # an api to bookmark a function
92
+ def bookmark_function(addr, color)
93
+ return if not fa = find_function_start(addr)
94
+ list = function_blocks(fa).map { |k, v| block_at(k).list.map { |di| di.address } }.flatten
95
+ bookmark_addrs list, color
96
+ end
97
+ def bookmark_addrs(list, color)
98
+ al = [list].flatten.uniq
99
+ gui.session_append("dasm.bookmark_addrs(#{list.inspect}, #{color.inspect})")
100
+ @bookmarklist |= [al.min]
101
+ al.each { |a| @bookmarkcolor[a] = color }
102
+ gui.gui_update
103
+ end
104
+ def bookmark_delete_function(addr)
105
+ return if not fa = find_function_start(addr)
106
+ list = function_blocks(fa).map { |k, v| block_at(k).list.map { |di| di.address } }.flatten
107
+ bookmark_delete list
108
+ end
109
+ def bookmark_delete(list)
110
+ @bookmarklist -= list
111
+ list.each { |a| @bookmarkcolor.delete a }
112
+ end
113
+ def bookmark_delete_color(col)
114
+ @bookmarkcolor.delete_if { |k, v| if v == col ; @bookmarklist.delete k ; true end }
115
+ end
116
+
117
+
118
+ w = gui.toplevel
119
+ w.addsubmenu(w.find_menu('Views'), '_Bookmarks', popbookmarks)
120
+ w.update_menu
121
+ gui.keyboard_callback[?B] = popbookmarks
122
+ gui.keyboard_callback[?C] = lambda { |a|
123
+ if s = gui.curview.instance_variable_get('@selected_boxes') and not s.empty?
124
+ al = s.map { |b| b[:line_address] }
125
+ elsif fa = find_function_start(gui.curaddr)
126
+ al = function_blocks(fa).map { |k, v| block_at(k).list.map { |di| di.address } }
127
+ else
128
+ next
129
+ end
130
+ # XXX also prompt for comment/bookmark name ?
131
+ ColorWindow.new(gui.toplevel) { |col| bookmark_addrs(al, col) }
132
+ }
133
+ end
@@ -0,0 +1,57 @@
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
+ # metasm dasm plugin
8
+ # decompose immediate values from C constants, adds a comment with the decomposition
9
+
10
+ # find immediate exprs in the instruction at addr, yield them
11
+ def imm_to_const(addr)
12
+ return if not di = di_at(addr)
13
+ # TODO enter into memrefs ?
14
+ di.instruction.args.grep(Expression).each { |a|
15
+ i = a.reduce
16
+ next if not i.kind_of? Integer
17
+ next if not cstbase = yield(i)
18
+ if c = imm_to_const_decompose(i, cstbase)
19
+ di.add_comment c
20
+ end
21
+ }
22
+ end
23
+
24
+ # find the bitwise decomposition of imm into constants whose name include cstbase
25
+ def imm_to_const_decompose(imm, cstbase)
26
+ cstbase = /#{cstbase}/i if not cstbase.kind_of? Regexp
27
+ dict = {}
28
+ c_parser.lexer.definition.keys.grep(cstbase).each { |cst|
29
+ if i = c_parser.macro_numeric(cst)
30
+ dict[cst] = i
31
+ end
32
+ }
33
+ c_parser.toplevel.symbol.each { |k, v|
34
+ dict[k] = v if v.kind_of? Integer and k =~ cstbase
35
+ }
36
+ dict.delete_if { |k, v| imm & v != v }
37
+ if cst = dict.index(imm)
38
+ cst
39
+ else
40
+ # a => 1, b => 2, c => 4, all => 7: discard abc, keep 'all'
41
+ dict.delete_if { |k, v| dict.find { |kk, vv| vv > v and vv & v == v } }
42
+ dict.keys.join(' | ') if not dict.empty?
43
+ end
44
+ end
45
+
46
+ if gui
47
+ gui.keyboard_callback[?K] = lambda { |*a|
48
+ addr = gui.curaddr
49
+ imm_to_const(addr) { |i|
50
+ gui.inputbox("const name for #{Expression[i]}") { |name|
51
+ imm_to_const(addr) { |ii| name if ii == i }
52
+ gui.gui_update
53
+ }
54
+ nil
55
+ }
56
+ }
57
+ end
@@ -0,0 +1,125 @@
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
+ # metasm gui plugin: change the colortheme used in the GUI
8
+ # based on solarized: http://ethanschoonover.com/solarized/
9
+
10
+ if gui
11
+ solarized = {
12
+ # name => hex RRGGBB
13
+ :base03 => '002b36',
14
+ :base02 => '073642',
15
+ :base01 => '586e75',
16
+ :base00 => '657b83',
17
+ :base0 => '839496',
18
+ :base1 => '93a1a1',
19
+ :base2 => 'eee8d5',
20
+ :base3 => 'fdf6e3',
21
+ :yellow => 'b58900',
22
+ :orange => 'cb4b16',
23
+ :red => 'dc322f',
24
+ :magenta => 'd33682',
25
+ :violet => '6c71c4',
26
+ :blue => '268bd2',
27
+ :cyan => '2aa198',
28
+ :green => '859900',
29
+
30
+ # personnal additions for more contrast
31
+ :base0C => '094048',
32
+ :base0D => '00151b',
33
+
34
+ :black => '002b36', # base03
35
+ :white => '93a1a1', # base1
36
+
37
+ :yellow_bg => '5a591b',# approx mean with black + manual tweak
38
+ :orange_bg => '553a16',
39
+ :red_bg => '461b1d',
40
+ :magenta_bg => '69305c',
41
+ :violet_bg => '364d7d',
42
+ :blue_bg => '135a84',
43
+ :cyan_bg => '156567',
44
+ :green_bg => '16510b',
45
+ }
46
+
47
+ # all widget's colorscheme inherits from this one
48
+ # this is the dark background theme. For light background, change
49
+ # all 'baseX' into 'base0X' and 'base0X' into 'baseX'.
50
+ default = {
51
+ :background => :black,
52
+ :text => :white,
53
+ :instruction => :white,
54
+ :cursorline_bg => :base02,
55
+ :comment => :base01,
56
+ :caret => :base0,
57
+ :label => :violet,
58
+ :address => :blue,
59
+ :hl_word_bg => :white,
60
+ :hl_word => :black,
61
+ }
62
+
63
+ specific = {
64
+ # widget name => colortheme
65
+ # unspecified colors are taken from 'default'
66
+ # still unspecified colors are left unchanged
67
+ :listing => {
68
+ :raw_data => :white,
69
+ :arrows_bg => :base02,
70
+ :arrow_up => :cyan,
71
+ :arrow_dn => :blue,
72
+ :arrow_hl => :orange,
73
+ },
74
+
75
+ :opcodes => {
76
+ :raw_data => :white,
77
+ },
78
+
79
+ :decompile => {
80
+ :keyword => :blue,
81
+ :localvar => :red,
82
+ :globalvar => :green,
83
+ :intrinsic => :yellow,
84
+ },
85
+
86
+ :coverage => {
87
+ :code => :red,
88
+ :data => :blue,
89
+ :caret => :yellow,
90
+ :caret_col => :green,
91
+ },
92
+
93
+ :graph => {
94
+ :background => :base0D,
95
+ :hlbox_bg => :base02,
96
+ :box_bg => :base03,
97
+ :cursorline_bg => :base03,
98
+ :arrow_cond => :green,
99
+ :arrow_uncond => :cyan,
100
+ :arrow_direct => :blue,
101
+ :arrow_hl => :orange,
102
+ :box_bg_shadow => '000000',
103
+ },
104
+
105
+ :hex => {
106
+ :ascii => :white,
107
+ :data => :base1,
108
+ :write_pending => :red,
109
+ :caret_mirror => :base0C,
110
+ },
111
+ }
112
+
113
+ gui.view_indexes.each { |v|
114
+ cs = specific[v] || {}
115
+ view = gui.view(v)
116
+ # keep original view ':foo => :text' colors
117
+ legacy = view.default_color_association.dup
118
+ # but discard actual color defs (still present as fallback anyway)
119
+ legacy.delete_if { |k, c| c.kind_of?(::String) }
120
+ nca = solarized.merge(legacy).merge(default).merge(cs)
121
+ view.set_color_association(nca)
122
+ }
123
+
124
+ true
125
+ end
@@ -0,0 +1,60 @@
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
+ # metasm dasm plugin
8
+ # finds instances of indirect calls a la call [ecx+40h], backtraces ecx, comments with the C++ object function pointer name
9
+ # if the backtracked object has no type, prompt for a C structure name.
10
+
11
+ # TODO simpler gui interface to set [base+off] => ; struct->member
12
+
13
+ @indirect_call_struct = {}
14
+ def solve_indirect_call_set_struct(ptr, struct)
15
+ struct = @c_parser.toplevel.struct[struct] if struct.kind_of? String
16
+ raise 'no such struct' if not struct
17
+ @indirect_call_struct[ptr] = struct
18
+ end
19
+
20
+ def solve_indirect_calls
21
+ @decoded.values.grep(DecodedInstruction).each { |di|
22
+ next if not di.opcode.props[:saveip] # only calls
23
+ fptr = get_xrefs_x(di)
24
+ next if fptr.to_a.length != 1
25
+ fptr = Expression[fptr.first].reduce_rec
26
+ next if not fptr.kind_of? Indirection
27
+ next if not fptr.pointer.lexpr.kind_of? Symbol
28
+ next if not fptr.pointer.rexpr.kind_of? Integer
29
+ obj = backtrace(fptr.pointer.lexpr, di.address)
30
+ obj.delete Expression::Unknown
31
+ next if obj.length != 1
32
+ obj = obj.first
33
+ obj = Expression[obj].reduce_rec
34
+ next if not obj.kind_of? Indirection
35
+ obj = obj.pointer # vtable ptr -> object ptr
36
+
37
+ if not struct = @indirect_call_struct[obj]
38
+ struct = yield obj if block_given?
39
+ solve_indirect_call_set_struct(obj, struct || :none)
40
+ end
41
+
42
+ if struct.kind_of? C::Struct and fld = struct.members.find { |m| struct.offsetof(c_parser, m) == fptr.pointer.rexpr } and fld.name
43
+ di.add_comment "#{struct.name || obj}->#{fld.name}"
44
+ di.comment.delete 'x:unknown'
45
+ end
46
+ }
47
+ end
48
+
49
+ if gui
50
+ solve_indirect_calls { |ptr|
51
+ gui.inputbox("struct name for object at #{ptr}") { |name|
52
+ solve_indirect_call_set_struct(ptr, name)
53
+ # re-solve everything, cause we're called only once but many indirect calls may use ptr
54
+ solve_indirect_calls
55
+ gui.gui_update
56
+ }
57
+ }
58
+ gui.gui_update
59
+ nil
60
+ end
@@ -0,0 +1,70 @@
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
+ # metasm dasm plugin: retrieve a section section, and disassemble everything it can, skipping existing code and nops
8
+ # usage: load the plugin, then call (ruby snipped): dasm.dasm_all_section '.text'
9
+ def dasm_all(addrstart, length, method=:disassemble_fast_deep)
10
+ s = get_section_at(addrstart)
11
+ return if not s
12
+ s = s[0]
13
+ boff = s.ptr
14
+ off = 0
15
+ while off < length
16
+ if di = di_at(addrstart + off)
17
+ off += di.bin_length
18
+ elsif @decoded[addrstart+off]
19
+ off += 1
20
+ else
21
+ s.ptr = boff+off
22
+ maydi = cpu.decode_instruction(s, 0)
23
+ if not maydi
24
+ off += 1
25
+ elsif maydi.instruction.to_s =~ /nop|lea (.*), \[\1(?:\+0)?\]|mov (.*), \2|int 3/
26
+ off += maydi.bin_length
27
+ else
28
+ puts "dasm_all: found #{Expression[addrstart+off]}" if $VERBOSE
29
+ send(method, addrstart+off)
30
+ end
31
+ end
32
+ Gui.main_iter if gui and off & 15 == 0
33
+ end
34
+
35
+ count = 0
36
+ off = 0
37
+ while off < length
38
+ addr = addrstart+off
39
+ if di = di_at(addr)
40
+ if di.block_head?
41
+ b = di.block
42
+ if not @function[addr] and b.from_subfuncret.to_a.empty? and b.from_normal.to_a.empty?
43
+ l = auto_label_at(addr, 'sub_orph')
44
+ puts "dasm_all: found orphan function #{l}"
45
+ @function[addrstart+off] = DecodedFunction.new
46
+ @function[addrstart+off].finalized = true
47
+ detect_function_thunk(addr)
48
+ count += 1
49
+ end
50
+ end
51
+ off += di.bin_length
52
+ else
53
+ off += 1
54
+ end
55
+ Gui.main_iter if gui and off & 15 == 0
56
+ end
57
+
58
+ puts "found #{count} orphan functions" if $VERBOSE
59
+
60
+ gui.gui_update if gui
61
+ end
62
+
63
+ def dasm_all_section(name, method=:disassemble_fast_deep)
64
+ section_info.each { |n, a, l, i|
65
+ if name == n
66
+ dasm_all(Expression[a].reduce, l, method)
67
+ end
68
+ }
69
+ true
70
+ end