metasm 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +1 -0
  4. data/doc/code_organisation.txt +1 -1
  5. data/metasm.gemspec +1 -1
  6. data/metasm.rb +2 -1
  7. data/metasm/cpu/arc/decode.rb +3 -3
  8. data/metasm/cpu/arm/decode.rb +2 -2
  9. data/metasm/cpu/ia32/compile_c.rb +18 -2
  10. data/metasm/cpu/ia32/decode.rb +9 -4
  11. data/metasm/cpu/ia32/decompile.rb +22 -8
  12. data/metasm/cpu/ia32/opcodes.rb +5 -5
  13. data/metasm/cpu/mcs51.rb +8 -0
  14. data/metasm/cpu/mcs51/decode.rb +99 -0
  15. data/metasm/cpu/mcs51/main.rb +76 -0
  16. data/metasm/cpu/mcs51/opcodes.rb +120 -0
  17. data/metasm/cpu/mips/decode.rb +5 -4
  18. data/metasm/cpu/st20.rb +9 -0
  19. data/metasm/cpu/st20/decode.rb +180 -0
  20. data/metasm/cpu/st20/decompile.rb +283 -0
  21. data/metasm/cpu/st20/main.rb +37 -0
  22. data/metasm/cpu/st20/opcodes.rb +140 -0
  23. data/metasm/cpu/x86_64/encode.rb +4 -2
  24. data/metasm/cpu/x86_64/opcodes.rb +4 -2
  25. data/metasm/decode.rb +16 -15
  26. data/metasm/decompile.rb +1 -1
  27. data/metasm/disassemble.rb +3 -1
  28. data/metasm/disassemble_api.rb +3 -1
  29. data/metasm/dynldr.rb +9 -3
  30. data/metasm/encode.rb +2 -2
  31. data/metasm/exe_format/coff.rb +3 -1
  32. data/metasm/exe_format/coff_decode.rb +5 -3
  33. data/metasm/exe_format/elf.rb +4 -0
  34. data/metasm/exe_format/elf_decode.rb +1 -2
  35. data/metasm/exe_format/elf_encode.rb +4 -1
  36. data/metasm/exe_format/macho.rb +20 -6
  37. data/metasm/exe_format/pe.rb +1 -1
  38. data/metasm/exe_format/serialstruct.rb +1 -1
  39. data/metasm/gui.rb +1 -1
  40. data/metasm/gui/dasm_hex.rb +2 -2
  41. data/metasm/gui/dasm_main.rb +8 -8
  42. data/metasm/gui/debug.rb +4 -4
  43. data/metasm/gui/gtk.rb +1 -1
  44. data/metasm/gui/qt.rb +2 -2
  45. data/metasm/gui/win32.rb +1 -1
  46. data/metasm/main.rb +11 -6
  47. data/metasm/os/windows.rb +26 -23
  48. data/misc/hexdump.rb +2 -2
  49. data/misc/objdiff.rb +4 -1
  50. data/misc/objscan.rb +1 -1
  51. data/samples/dasm-plugins/bindiff.rb +1 -1
  52. data/samples/dasm-plugins/scanxrefs.rb +2 -1
  53. data/samples/dynamic_ruby.rb +24 -25
  54. data/samples/elfencode.rb +15 -0
  55. data/samples/exeencode.rb +2 -2
  56. data/samples/metasm-shell.rb +67 -55
  57. data/tests/mcs51.rb +27 -0
  58. metadata +13 -2
@@ -0,0 +1,37 @@
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/main'
8
+
9
+ module Metasm
10
+ class ST20 < CPU
11
+ def initialize(size=32)
12
+ super()
13
+ @endianness = :little
14
+ @size = size
15
+ init_opcodes
16
+ end
17
+
18
+ def register_symbols
19
+ [:a, :b, :c]
20
+ end
21
+
22
+ def render_instruction(i)
23
+ r = []
24
+ r << i.opname
25
+ if not i.args.empty?
26
+ r << ' '
27
+ i.args.each { |a_| r << a_ << ', ' }
28
+ r.pop
29
+ end
30
+ r
31
+ end
32
+ end
33
+
34
+ class TransPuter < ST20
35
+ end
36
+ end
37
+
@@ -0,0 +1,140 @@
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/cpu/st20/main'
7
+
8
+ module Metasm
9
+
10
+ class ST20
11
+ def init_opcodes
12
+ @op_function = op_get_function
13
+ @op_operate = op_get_operate
14
+ @opcode_list = @op_function.sort.map { |b, n|
15
+ op = Opcode.new(n, b)
16
+ op.props[:setip] = true if n == 'cj'
17
+ op.props[:setip] = op.props[:stopexec] = true if n == 'j'
18
+ op.props[:setip] = op.props[:stopexec] = op.props[:saveip] = true if n == 'fcall'
19
+ op
20
+ }
21
+ @opc_operate = {}
22
+ op = Opcode.new('ret', 0)
23
+ op.props[:setip] = op.props[:stopexec] = true
24
+ @opc_operate['ret'] = op
25
+ end
26
+
27
+ def op_get_function
28
+ {
29
+ 0x00 => 'j', 0x10 => 'ldlp', 0x20 => 'pfix', 0x30 => 'ldnl',
30
+ 0x40 => 'ldc', 0x50 => 'ldnlp', 0x60 => 'nfix', 0x70 => 'ldl',
31
+ 0x80 => 'adc', 0x90 => 'fcall', 0xa0 => 'cj', 0xb0 => 'ajw',
32
+ 0xc0 => 'eqc', 0xd0 => 'stl', 0xe0 => 'stnl', 0xf0 => 'opr'
33
+ }
34
+ end
35
+
36
+ def op_get_operate
37
+ {
38
+ 0x00 => 'rev', 0x01 => 'dup', 0x02 => 'rot', 0x03 => 'arot',
39
+ 0x04 => 'add', 0x05 => 'sub', 0x06 => 'mul', 0x07 => 'wsub',
40
+ 0x08 => 'not', 0x09 => 'and', 0x0A => 'or', 0x0B => 'shl',
41
+ 0x0C => 'shr', 0x0D => 'jab', 0x0E => 'timeslice', 0x0F => 'breakpoint',
42
+ 0x10 => 'addc', 0x11 => 'subc', 0x12 => 'mac', 0x13 => 'umac',
43
+ 0x14 => 'smul', 0x15 => 'smacinit', 0x16 => 'smacloop', 0x17 => 'biquad',
44
+ 0x18 => 'divstep', 0x19 => 'unsign', 0x1A => 'saturate', 0x1B => 'gt',
45
+ 0x1C => 'gtu', 0x1D => 'order', 0x1E => 'orderu', 0x1F => 'ashr',
46
+ 0x20 => 'xor', 0x21 => 'xbword', 0x22 => 'xsword', 0x23 => 'bitld',
47
+ 0x24 => 'bitst', 0x25 => 'bitmask', 0x26 => 'statusset', 0x27 => 'statusclr',
48
+ 0x28 => 'statustst', 0x29 => 'rmw', 0x2A => 'lbinc', 0x2B => 'sbinc',
49
+ 0x2C => 'lsinc', 0x2D => 'lsxinc', 0x2E => 'ssinc', 0x2F => 'lwinc',
50
+ 0x30 => 'swinc', 0x31 => 'ecall', 0x32 => 'eret', 0x33 => 'run',
51
+ 0x34 => 'stop', 0x35 => 'signal', 0x36 => 'wait', 0x37 => 'enqueue',
52
+ 0x38 => 'dequeue', 0x39 => 'ldtdesc', 0x3A => 'ldpi', 0x3B => 'gajw',
53
+ 0x3C => 'ldprodid', 0x3D => 'io', 0x3E => 'swap32', 0x3F => 'nop',
54
+ }
55
+ end
56
+ end
57
+
58
+ class TransPuter
59
+ def op_get_operate
60
+ {
61
+ 0x00 => 'rev', 0x01 => 'lb', 0x02 => 'bsub', 0x03 => 'endp',
62
+ 0x04 => 'diff', 0x05 => 'add', 0x06 => 'gcall', 0x07 => 'in',
63
+ 0x08 => 'prod', 0x09 => 'gt', 0x0a => 'wsub', 0x0b => 'out',
64
+ 0x0c => 'sub', 0x0d => 'startp', 0x0e => 'outbyte', 0x0f => 'outword',
65
+ 0x10 => 'seterr', 0x11 => 'mreleasep', 0x12 => 'resetch', 0x13 => 'csub0',
66
+ 0x14 => 'extvrfy', 0x15 => 'stopp', 0x16 => 'ladd', 0x17 => 'stlb',
67
+ 0x18 => 'sthf', 0x19 => 'norm', 0x1a => 'ldiv', 0x1b => 'ldpi',
68
+ 0x1c => 'stlf', 0x1d => 'xdble', 0x1e => 'ldpri', 0x1f => 'rem',
69
+ 0x20 => 'ret', 0x21 => 'lend', 0x22 => 'ldtimer', 0x23 => 'testlds',
70
+ 0x24 => 'testlde', 0x25 => 'testldd', 0x26 => 'teststs', 0x27 => 'testste',
71
+ 0x28 => 'teststd', 0x29 => 'testerr', 0x2a => 'testpranal', 0x2b => 'tin',
72
+ 0x2c => 'div', 0x2d => 'testhardchan', 0x2e => 'dist', 0x2f => 'disc',
73
+ 0x30 => 'diss', 0x31 => 'lmul', 0x32 => 'not', 0x33 => 'xor',
74
+ 0x34 => 'bcnt', 0x35 => 'lshr', 0x36 => 'lshl', 0x37 => 'lsum',
75
+ 0x38 => 'lsub', 0x39 => 'runp', 0x3a => 'xword', 0x3b => 'sb',
76
+ 0x3c => 'gajw', 0x3d => 'savel', 0x3e => 'saveh', 0x3f => 'wcnt',
77
+ 0x40 => 'shr', 0x41 => 'shl', 0x42 => 'mint', 0x43 => 'alt',
78
+ 0x44 => 'altwt', 0x45 => 'altend', 0x46 => 'and', 0x47 => 'enbt',
79
+ 0x48 => 'enbc', 0x49 => 'enbs', 0x4a => 'move', 0x4b => 'or',
80
+ 0x4c => 'csngl', 0x4d => 'ccnt1', 0x4e => 'talt', 0x4f => 'ldiff',
81
+ 0x50 => 'sthb', 0x51 => 'taltwt', 0x52 => 'sum', 0x53 => 'mul',
82
+ 0x54 => 'sttimer', 0x55 => 'stoperr', 0x56 => 'cword', 0x57 => 'clrhalterr',
83
+ 0x58 => 'sethalterr', 0x59 => 'testhalterr', 0x5a => 'dup', 0x5b => 'move2dinit',
84
+ 0x5c => 'move2dall', 0x5d => 'move2dnonzero', 0x5e => 'move2dzero', 0x5f => 'gtu',
85
+ 0x60 => 'extin', 0x61 => 'extout', 0x62 => 'minn', 0x63 => 'unpacksn',
86
+ 0x64 => 'moutn', 0x65 => 'xminn', 0x66 => 'extenbc', 0x67 => 'extndisc',
87
+ 0x68 => 'extmin', 0x69 => 'extmout', 0x6a => 'extmin64', 0x6b => 'extmout64',
88
+ 0x6c => 'postnormsn', 0x6d => 'roundsn', 0x6e => 'extminn', 0x6f => 'extmoutn',
89
+ 0x70 => 'enbc3', 0x71 => 'ldinf', 0x72 => 'fmul', 0x73 => 'cflerr',
90
+ 0x74 => 'crcword', 0x75 => 'crcbyte', 0x76 => 'bitcnt', 0x77 => 'bitrevword',
91
+ 0x78 => 'bitrevnbits', 0x79 => 'pop', 0x7a => 'timerdisableh', 0x7b => 'timerdisablel',
92
+ 0x7c => 'timerenableh', 0x7d => 'timerenablel', 0x7e => 'ldmemstartval',
93
+ 0x80 => 'fpsttest', 0x81 => 'wsubdb', 0x82 => 'fpldnldbi', 0x83 => 'fpchkerr',
94
+ 0x84 => 'fpstnldb', 0x85 => 'fpldtest', 0x86 => 'fpldnlsni', 0x87 => 'fpadd',
95
+ 0x88 => 'fpstnlsn', 0x89 => 'fpsub', 0x8a => 'fpldnldb', 0x8b => 'fpmul',
96
+ 0x8c => 'fpdiv', 0x8d => 'fprange', 0x8e => 'fpldnlsn', 0x8f => 'fpremfirst',
97
+ 0x90 => 'fpremstep', 0x91 => 'fpnan', 0x92 => 'fpordered', 0x93 => 'fpnotfinite',
98
+ 0x94 => 'fpgt', 0x95 => 'fpeq', 0x96 => 'fpi32tor32', 0x97 => 'fpge',
99
+ 0x98 => 'fpi32tor64', 0x99 => 'enbt3', 0x9a => 'fpb32tor64', 0x9b => 'fplg',
100
+ 0x9c => 'fptesterr', 0x9d => 'fprtoi32', 0x9e => 'fpstnli32', 0x9f => 'fpldzerosn',
101
+ 0xa0 => 'fpldzerodb', 0xa1 => 'fpint', 0xa2 => 'getpri', 0xa3 => 'fpdup',
102
+ 0xa4 => 'fprev', 0xa5 => 'setpri', 0xa6 => 'fpldnladddb', 0xa7 => 'fpentry3',
103
+ 0xa8 => 'fpldnlmuldb', 0xa9 => 'fpentry2', 0xaa => 'fpldnladdsn', 0xab => 'fpentry',
104
+ 0xac => 'fpldnlmulsn', 0xad => 'enbs3',
105
+ 0xb0 => 'settimeslice', 0xb1 => 'break', 0xb2 => 'clrj0break', 0xb3 => 'setj0break',
106
+ 0xb4 => 'testj0break', 0xb6 => 'ldflags', 0xb7 => 'stflags',
107
+ 0xb8 => 'xbword', 0xb9 => 'lbx', 0xba => 'cb', 0xbb => 'cbu',
108
+ 0xbc => 'insphdr', 0xbd => 'readbfr', 0xbe => 'ldconf', 0xbf => 'stconf',
109
+ 0xc0 => 'ldcnt', 0xc1 => 'ssub', 0xc2 => 'ldth', 0xc3 => 'ldchstatus',
110
+ 0xc4 => 'intdis', 0xc5 => 'intenb', 0xc6 => 'ldtrapped', 0xc7 => 'cir',
111
+ 0xc8 => 'ss', 0xc9 => 'chantype', 0xca => 'ls', 0xcb => 'sttrapped',
112
+ 0xcc => 'ciru', 0xcd => 'gintdis', 0xce => 'gintenb', 0xcf => 'fprem',
113
+ 0xd0 => 'fprn', 0xd1 => 'fpdivby2', 0xd2 => 'fpmulby2', 0xd3 => 'fpsqrt',
114
+ 0xd4 => 'fprp', 0xd5 => 'fprm', 0xd6 => 'fprz', 0xd7 => 'fpr32tor64',
115
+ 0xd8 => 'fpr64tor32', 0xd9 => 'fpexpdec32', 0xda => 'fpexpinc32', 0xdb => 'fpabs',
116
+ 0xdd => 'fpadddbsn', 0xde => 'fpchki32', 0xdf => 'fpchki64',
117
+ 0xe0 => 'mnew', 0xe1 => 'mfree', 0xe2 => 'malloc', 0xe3 => 'mrelease',
118
+ 0xe4 => 'min', 0xe5 => 'mout', 0xe6 => 'min64', 0xe7 => 'mout64',
119
+ 0xe8 => 'xable', 0xe9 => 'xin', 0xea => 'xmin', 0xeb => 'xmin64',
120
+ 0xec => 'xend', 0xed => 'ndisc', 0xee => 'ndist', 0xef => 'ndiss',
121
+ 0xf0 => 'devlb', 0xf1 => 'devsb', 0xf2 => 'devls', 0xf3 => 'devss',
122
+ 0xf4 => 'devlw', 0xf5 => 'devsw', 0xf8 => 'xsword', 0xf9 => 'lsx',
123
+ 0xfa => 'cs', 0xfb => 'csu', 0xfc => 'trap', 0xfd => 'null',
124
+ 0x1ff => 'start',
125
+ 0x17c => 'lddevid',
126
+ 0x200 => 'in8', 0x201 => 'in32', 0x202 => 'out8', 0x203 => 'out32',
127
+ 0x204 => 'xstl',
128
+ 0x22f => 'proc_alloc',
129
+ 0x230 => 'proc_param', 0x231 => 'proc_mt_copy', 0x232 => 'proc_mt_move', 0x233 => 'proc_start',
130
+ 0x234 => 'proc_end', 0x235 => 'getaff', 0x236 => 'setaff', 0x237 => 'getpas',
131
+ 0x238 => 'mt_alloc', 0x239 => 'mt_release', 0x23a => 'mt_clone', 0x23b => 'mt_in',
132
+ 0x23c => 'mt_out', 0x23d => 'mt_xchg', 0x23e => 'mt_lock', 0x23f => 'mt_unlock',
133
+ 0x240 => 'mt_enroll', 0x241 => 'mt_resign', 0x242 => 'mt_sync', 0x243 => 'mt_xin',
134
+ 0x244 => 'mt_xout', 0x245 => 'mt_xxchg', 0x246 => 'mt_dclone', 0x247 => 'mt_bind',
135
+ 0x248 => 'mb', 0x249 => 'rmb', 0x24a => 'wmb', 0x24b => 'ext_mt_in',
136
+ 0x24c => 'ext_mt_out', 0x24d => 'mt_resize',
137
+ }
138
+ end
139
+ end
140
+ end
@@ -76,20 +76,22 @@ class X86_64
76
76
 
77
77
  imm ||= 0 if @b.val_enc == 5
78
78
  if imm
79
+ i32 = :i32
80
+ i32 = :a32 if (self.b and self.b.sz == 32) or (self.i and self.i.sz == 32)
79
81
  case Expression.in_range?(imm, :i8)
80
82
  when true
81
83
  or_bits[1<<6]
82
84
  [ret << Expression.encode_imm(imm, :i8, endianness)]
83
85
  when false
84
86
  or_bits[2<<6]
85
- [ret << Expression.encode_imm(imm, :a32, endianness)]
87
+ [ret << Expression.encode_imm(imm, i32, endianness)]
86
88
  when nil
87
89
  rets = ret.dup
88
90
  or_bits[1<<6]
89
91
  ret << @imm.encode(:i8, endianness)
90
92
  rets, ret = ret, rets # or_bits[] modifies ret directly
91
93
  or_bits[2<<6]
92
- ret << @imm.encode(:a32, endianness)
94
+ ret << @imm.encode(i32, endianness)
93
95
  [ret, rets]
94
96
  end
95
97
  else
@@ -46,8 +46,8 @@ class X86_64
46
46
  o.args.include?(:seg2A) or
47
47
  o.args.include?(:farptr) or
48
48
  %w[aaa aad aam aas bound daa das into jcxz jecxz
49
- lds les loadall arpl pusha pushad popa
50
- popad].include?(o.name.split('.')[0])
49
+ lds les loadall arpl pusha pushad popa popad pushfd popfd
50
+ ].include?(o.name.split('.')[0])
51
51
  # split needed for lds.a32
52
52
  }
53
53
 
@@ -57,6 +57,8 @@ class X86_64
57
57
 
58
58
  addop('cmpxchg16b', [0x0F, 0xC7], 1) { |o| o.props[:opsz] = 64 ; o.props[:argsz] = 128 }
59
59
  addop('iretq', [0xCF], nil, :stopexec, :setip) { |o| o.props[:opsz] = 64 } ; opcode_list.unshift opcode_list.pop
60
+ addop('pushfq', [0x9C]) { |o| o.props[:auto64] = true }
61
+ addop('popfq', [0x9D]) { |o| o.props[:auto64] = true }
60
62
  addop 'swapgs', [0x0F, 0x01, 0xF8]
61
63
 
62
64
  addop('movq', [0x0F, 0x6E], :mrmmmx, {:d => [1, 4]}) { |o| o.args = [:regmmx, :modrm] ; o.props[:opsz] = o.props[:argsz] = 64 }
@@ -63,24 +63,25 @@ class Indirection < ExpressionType
63
63
  @target.externals
64
64
  end
65
65
 
66
- def match_rec(target, vars)
67
- return false if not target.kind_of? Indirection
68
- t = target.target
69
- if vars[t]
70
- return false if @target != vars[t]
71
- elsif vars.has_key? t
72
- vars[t] = @target
73
- elsif t.kind_of? ExpressionType
74
- return false if not @target.match_rec(t, vars)
66
+ def match_rec(pattern, vars)
67
+ return false if not pattern.kind_of? Indirection
68
+ pt = pattern.target
69
+ if vars[pt]
70
+ return false if @target != vars[pt]
71
+ elsif vars.has_key? pt
72
+ vars[pt] = @target
73
+ elsif pt.kind_of? ExpressionType
74
+ return false if not @target.match_rec(pt, vars)
75
75
  else
76
- return false if targ != @target
76
+ return false if pt != @target
77
77
  end
78
- if vars[target.len]
79
- return false if @len != vars[target.len]
80
- elsif vars.has_key? target.len
81
- vars[target.len] = @len
78
+ pl = pattern.len
79
+ if vars[pl]
80
+ return false if @len != vars[pl]
81
+ elsif vars.has_key? pl
82
+ vars[pl] = @len
82
83
  else
83
- return false if target.len != @len
84
+ return false if pl != @len
84
85
  end
85
86
  vars
86
87
  end
@@ -181,7 +181,7 @@ class Decompiler
181
181
  addr = @dasm.normalize(addr)
182
182
 
183
183
  # (almost) NULL ptr
184
- return if addr.kind_of? Fixnum and addr >= 0 and addr < 32
184
+ return if addr.kind_of? Integer and addr >= 0 and addr < 32
185
185
 
186
186
  # check preceding structure we're hitting
187
187
  # TODO check what we step over when defining a new static struct
@@ -26,6 +26,8 @@ class DecodedInstruction
26
26
  attr_accessor :backtrace_binding
27
27
  # used during fixed-size instruction decoding to hold the decoded raw opcode
28
28
  attr_accessor :raw_data
29
+ # arbitrary data used during decoding, architecture-specific
30
+ attr_accessor :misc
29
31
 
30
32
  # create a new DecodedInstruction with an Instruction whose cpu is the argument
31
33
  # can take an existing Instruction as argument
@@ -544,7 +546,6 @@ class Disassembler
544
546
  def normalize(addr)
545
547
  return addr if not addr or addr == :default
546
548
  addr = Expression[addr].bind(@old_prog_binding).reduce if not addr.kind_of? Integer
547
- addr %= 1 << [@cpu.size, 32].max if @cpu and addr.kind_of? Integer
548
549
  addr
549
550
  end
550
551
 
@@ -1571,6 +1572,7 @@ puts " backtrace end #{ev} #{expr}" if debug_backtrace
1571
1572
  oldexpr = t[0][0]
1572
1573
  next false if expr == oldexpr # unmodifying loop
1573
1574
  puts " bt loop at #{Expression[t[0][1]]}: #{oldexpr} => #{expr} (#{t.map { |z| Expression[z[1]] }.join(' <- ')})" if debug_backtrace
1575
+ bt_log << [:loop, expr, oldexpr, t.map { |z| z[1] }] if bt_log
1574
1576
  false
1575
1577
  when :up
1576
1578
  next false if only_upto and h[:to] != only_upto
@@ -665,6 +665,8 @@ class Disassembler
665
665
  b1.to_indirect.to_a == [] and b2.from_indirect.to_a == []
666
666
  b2.list.each { |di| b1.add_di di }
667
667
  b1.to_normal = b2.to_normal
668
+ b1.to_subfuncret = b2.to_subfuncret
669
+ b1.to_indirect = b2.to_indirect
668
670
  b2.list.clear
669
671
  @addrs_done.delete_if { |ad| normalize(ad[0]) == b2.address }
670
672
  true
@@ -1042,7 +1044,7 @@ class Disassembler
1042
1044
  fd.puts "decoded #{t.length}", t
1043
1045
 
1044
1046
  t = @comment.map { |a, c|
1045
- c.map { |l| l.chomp }.join("\n").split("\n").map { |lc| "#{Expression[a]} #{lc.chomp}" }
1047
+ c.to_a.map { |l| l.chomp }.join("\n").split("\n").map { |lc| "#{Expression[a]} #{lc.chomp}" }
1046
1048
  }.join("\n")
1047
1049
  fd.puts "comment #{t.length}", t
1048
1050
 
@@ -85,7 +85,13 @@ extern VALUE *rb_eArgError __attribute__((import));
85
85
  #define ARY_LEN(o) (RArray(o)->len)
86
86
  #endif
87
87
 
88
- #define TYPE(x) (((VALUE)(x) & 1) ? T_FIXNUM : (((VALUE)(x) & 3) || ((VALUE)(x) < 7)) ? 0x40 : RString(x)->flags & T_MASK)
88
+ #if #{nil.object_id == 4 ? 1 : 0}
89
+ // ruby1.8
90
+ #define TYPE(x) (((VALUE)(x) & 1) ? T_FIXNUM : (((VALUE)(x) < 0x07) || (((VALUE)(x) & 0xf) == 0xe)) ? 0x40 : RString(x)->flags & T_MASK)
91
+ #else
92
+ // ruby2.0+, USE_FLONUM, world is hell
93
+ #define TYPE(x) (((VALUE)(x) & 1) ? T_FIXNUM : (((VALUE)(x) < 0x3f) || (((VALUE)(x) & 0xf) == 0xc) || (((VALUE)(x) & 3) == 2)) ? 0x40 : RString(x)->flags & T_MASK)
94
+ #endif
89
95
 
90
96
  VALUE rb_uint2inum(VALUE);
91
97
  VALUE rb_ull2inum(unsigned long long);
@@ -604,7 +610,7 @@ EOS
604
610
 
605
611
  binmodule = find_bin_path
606
612
 
607
- if not File.exists?(binmodule) or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
613
+ if not File.exist?(binmodule) or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
608
614
  compile_binary_module(host_exe, host_cpu, binmodule)
609
615
  end
610
616
 
@@ -727,7 +733,7 @@ EOS
727
733
  fname = ['dynldr', host_arch, host_cpu.shortname, RUBY_VERSION.gsub('.', '')].join('-') + '.so'
728
734
  dir = File.dirname(__FILE__)
729
735
  binmodule = File.join(dir, fname)
730
- if not File.exists? binmodule or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
736
+ if not File.exist? binmodule or File.stat(binmodule).mtime < File.stat(__FILE__).mtime
731
737
  if not dir = find_write_dir
732
738
  raise LoadError, "no writable dir to put the DynLdr ruby module, try to run as root"
733
739
  end
@@ -42,7 +42,7 @@ class ExeFormat
42
42
  edata
43
43
  end
44
44
 
45
- # chose among multiple possible sub-EncodedData
45
+ # choose among multiple possible sub-EncodedData
46
46
  # assumes all ambiguous edata have the equivallent relocations in the same order
47
47
  def assemble_resolve(ary)
48
48
  startlabel = new_label('section_start')
@@ -167,7 +167,7 @@ class ExeFormat
167
167
  # for linear expressions of internal variables (ie differences of labels from the ary):
168
168
  # - calc target numeric bounds, and reject relocs not accepting worst case value
169
169
  # - else reject all but largest place available
170
- # then chose the shortest overall EData left
170
+ # then choose the shortest overall EData left
171
171
  ary.map! { |elem|
172
172
  case elem
173
173
  when Array
@@ -46,9 +46,11 @@ class COFF < ExeFormat
46
46
  }
47
47
 
48
48
  DLL_CHARACTERISTIC_BITS = {
49
+ 0x20 => 'HIGH_ENTROPY_VA',
49
50
  0x40 => 'DYNAMIC_BASE', 0x80 => 'FORCE_INTEGRITY', 0x100 => 'NX_COMPAT',
50
51
  0x200 => 'NO_ISOLATION', 0x400 => 'NO_SEH', 0x800 => 'NO_BIND',
51
- 0x2000 => 'WDM_DRIVER', 0x8000 => 'TERMINAL_SERVER_AWARE'
52
+ 0x1000 => 'APPCONTAINER', 0x2000 => 'WDM_DRIVER',
53
+ 0x4000 => 'GUARD_CF', 0x8000 => 'TERMINAL_SERVER_AWARE'
52
54
  }
53
55
 
54
56
  BASE_RELOCATION_TYPE = { 0 => 'ABSOLUTE', 1 => 'HIGH', 2 => 'LOW', 3 => 'HIGHLOW',
@@ -66,7 +66,7 @@ class COFF
66
66
  class RelocObj
67
67
  def decode(coff)
68
68
  super(coff)
69
- @sym = coff.symbols[@symidx]
69
+ @sym = coff.symbols[@symidx] if coff.symbols
70
70
  end
71
71
  end
72
72
 
@@ -89,7 +89,7 @@ class COFF
89
89
  addr = addrs[i]
90
90
  if addr >= coff.directory['export_table'][0] and addr < coff.directory['export_table'][0] + coff.directory['export_table'][1] and coff.sect_at_rva(addr)
91
91
  name = coff.decode_strz
92
- e.forwarder_lib, name = name.split('.', 2)
92
+ e.forwarder_lib, name = name.split('.', 2) if name.index('.')
93
93
  if name[0] == ?#
94
94
  e.forwarder_ordinal = name[1..-1].to_i
95
95
  else
@@ -111,6 +111,7 @@ class COFF
111
111
  end
112
112
  if namep and ords
113
113
  namep.zip(ords).each { |np, oi|
114
+ next if not @exports[oi]
114
115
  @exports[oi].name_p = np
115
116
  if coff.sect_at_rva(np)
116
117
  @exports[oi].name = coff.decode_strz
@@ -429,7 +430,7 @@ class COFF
429
430
  # may return self when rva points to the coff header
430
431
  # returns nil if none match, 0 never matches
431
432
  def sect_at_rva(rva)
432
- return if not rva or rva <= 0
433
+ return if not rva or not rva.kind_of?(::Integer) or rva <= 0
433
434
  if sections and not @sections.empty?
434
435
  if s = @sections.find { |s_| s_.virtaddr <= rva and s_.virtaddr + EncodedData.align_size((s_.virtsize == 0 ? s_.rawsize : s_.virtsize), @optheader.sect_align) > rva }
435
436
  s.encoded.ptr = rva - s.virtaddr
@@ -551,6 +552,7 @@ class COFF
551
552
  s.relocnr.times { s.relocs << RelocObj.decode(self) }
552
553
  new_label 'pcrel'
553
554
  s.relocs.each { |r|
555
+ next if not r.sym
554
556
  case r.type
555
557
  when 'DIR32'
556
558
  s.encoded.reloc[r.va] = Metasm::Relocation.new(Expression[r.sym.name], :u32, @endianness)
@@ -9,6 +9,7 @@ require 'metasm/exe_format/main'
9
9
  module Metasm
10
10
  class ELF < ExeFormat
11
11
  MAGIC = "\x7fELF" # 0x7f454c46
12
+ MAGIC.force_encoding('BINARY') if MAGIC.respond_to?(:force_encoding)
12
13
  CLASS = { 0 => 'NONE', 1 => '32', 2 => '64', 200 => '64_icc' }
13
14
  DATA = { 0 => 'NONE', 1 => 'LSB', 2 => 'MSB' }
14
15
  VERSION = { 0 => 'INVALID', 1 => 'CURRENT' }
@@ -395,6 +396,8 @@ class ELF < ExeFormat
395
396
 
396
397
  DEFAULT_INTERP = '/lib/ld-linux.so.2'
397
398
  DEFAULT_INTERP64 = '/lib64/ld-linux-x86-64.so.2'
399
+ DEFAULT_INTERP.force_encoding('BINARY') if DEFAULT_INTERP.respond_to?(:force_encoding)
400
+ DEFAULT_INTERP64.force_encoding('BINARY') if DEFAULT_INTERP64.respond_to?(:force_encoding)
398
401
 
399
402
  class SerialStruct < Metasm::SerialStruct
400
403
  new_int_field :addr, :off, :xword, :sword, :sxword
@@ -682,6 +685,7 @@ end
682
685
 
683
686
  class FatELF < ExeFormat
684
687
  MAGIC = "\xfa\x70\x0e\x1f" # 0xfat..elf
688
+ MAGIC.force_encoding('BINARY') if MAGIC.respond_to?(:force_encoding)
685
689
 
686
690
  class SerialStruct < Metasm::SerialStruct
687
691
  new_int_field :qword