metasm 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/doc/code_organisation.txt +1 -1
- data/metasm.gemspec +1 -1
- data/metasm.rb +2 -1
- data/metasm/cpu/arc/decode.rb +3 -3
- data/metasm/cpu/arm/decode.rb +2 -2
- data/metasm/cpu/ia32/compile_c.rb +18 -2
- data/metasm/cpu/ia32/decode.rb +9 -4
- data/metasm/cpu/ia32/decompile.rb +22 -8
- data/metasm/cpu/ia32/opcodes.rb +5 -5
- data/metasm/cpu/mcs51.rb +8 -0
- data/metasm/cpu/mcs51/decode.rb +99 -0
- data/metasm/cpu/mcs51/main.rb +76 -0
- data/metasm/cpu/mcs51/opcodes.rb +120 -0
- data/metasm/cpu/mips/decode.rb +5 -4
- data/metasm/cpu/st20.rb +9 -0
- data/metasm/cpu/st20/decode.rb +180 -0
- data/metasm/cpu/st20/decompile.rb +283 -0
- data/metasm/cpu/st20/main.rb +37 -0
- data/metasm/cpu/st20/opcodes.rb +140 -0
- data/metasm/cpu/x86_64/encode.rb +4 -2
- data/metasm/cpu/x86_64/opcodes.rb +4 -2
- data/metasm/decode.rb +16 -15
- data/metasm/decompile.rb +1 -1
- data/metasm/disassemble.rb +3 -1
- data/metasm/disassemble_api.rb +3 -1
- data/metasm/dynldr.rb +9 -3
- data/metasm/encode.rb +2 -2
- data/metasm/exe_format/coff.rb +3 -1
- data/metasm/exe_format/coff_decode.rb +5 -3
- data/metasm/exe_format/elf.rb +4 -0
- data/metasm/exe_format/elf_decode.rb +1 -2
- data/metasm/exe_format/elf_encode.rb +4 -1
- data/metasm/exe_format/macho.rb +20 -6
- data/metasm/exe_format/pe.rb +1 -1
- data/metasm/exe_format/serialstruct.rb +1 -1
- data/metasm/gui.rb +1 -1
- data/metasm/gui/dasm_hex.rb +2 -2
- data/metasm/gui/dasm_main.rb +8 -8
- data/metasm/gui/debug.rb +4 -4
- data/metasm/gui/gtk.rb +1 -1
- data/metasm/gui/qt.rb +2 -2
- data/metasm/gui/win32.rb +1 -1
- data/metasm/main.rb +11 -6
- data/metasm/os/windows.rb +26 -23
- data/misc/hexdump.rb +2 -2
- data/misc/objdiff.rb +4 -1
- data/misc/objscan.rb +1 -1
- data/samples/dasm-plugins/bindiff.rb +1 -1
- data/samples/dasm-plugins/scanxrefs.rb +2 -1
- data/samples/dynamic_ruby.rb +24 -25
- data/samples/elfencode.rb +15 -0
- data/samples/exeencode.rb +2 -2
- data/samples/metasm-shell.rb +67 -55
- data/tests/mcs51.rb +27 -0
- 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
|
data/metasm/cpu/x86_64/encode.rb
CHANGED
@@ -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,
|
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(
|
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
|
-
|
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 }
|
data/metasm/decode.rb
CHANGED
@@ -63,24 +63,25 @@ class Indirection < ExpressionType
|
|
63
63
|
@target.externals
|
64
64
|
end
|
65
65
|
|
66
|
-
def match_rec(
|
67
|
-
return false if not
|
68
|
-
|
69
|
-
if vars[
|
70
|
-
return false if @target != vars[
|
71
|
-
elsif vars.has_key?
|
72
|
-
vars[
|
73
|
-
elsif
|
74
|
-
return false if not @target.match_rec(
|
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
|
76
|
+
return false if pt != @target
|
77
77
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
84
|
+
return false if pl != @len
|
84
85
|
end
|
85
86
|
vars
|
86
87
|
end
|
data/metasm/decompile.rb
CHANGED
@@ -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?
|
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
|
data/metasm/disassemble.rb
CHANGED
@@ -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
|
data/metasm/disassemble_api.rb
CHANGED
@@ -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
|
|
data/metasm/dynldr.rb
CHANGED
@@ -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
|
-
#
|
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.
|
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.
|
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
|
data/metasm/encode.rb
CHANGED
@@ -42,7 +42,7 @@ class ExeFormat
|
|
42
42
|
edata
|
43
43
|
end
|
44
44
|
|
45
|
-
#
|
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
|
170
|
+
# then choose the shortest overall EData left
|
171
171
|
ary.map! { |elem|
|
172
172
|
case elem
|
173
173
|
when Array
|
data/metasm/exe_format/coff.rb
CHANGED
@@ -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
|
-
|
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)
|
data/metasm/exe_format/elf.rb
CHANGED
@@ -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
|