metasploit-framework/lib/metasm/samples/dasm-plugins/c_constants.rb

58 lines
1.5 KiB
Ruby

# This file is part of Metasm, the Ruby assembly manipulation suite
# Copyright (C) 2006-2009 Yoann GUILLOT
#
# Licence is LGPL, see LICENCE in the top-level directory
# metasm dasm plugin
# decompose immediate values from C constants, adds a comment with the decomposition
# find immediate exprs in the instruction at addr, yield them
def imm_to_const(addr)
return if not di = di_at(addr)
# TODO enter into memrefs ?
di.instruction.args.grep(Expression).each { |a|
i = a.reduce
next if not i.kind_of? Integer
next if not cstbase = yield(i)
if c = imm_to_const_decompose(i, cstbase)
di.add_comment c
end
}
end
# find the bitwise decomposition of imm into constants whose name include cstbase
def imm_to_const_decompose(imm, cstbase)
cstbase = /#{cstbase}/i if not cstbase.kind_of? Regexp
dict = {}
c_parser.lexer.definition.keys.grep(cstbase).each { |cst|
if i = c_parser.macro_numeric(cst)
dict[cst] = i
end
}
c_parser.toplevel.symbol.each { |k, v|
dict[k] = v if v.kind_of? Integer and k =~ cstbase
}
dict.delete_if { |k, v| imm & v != v }
if cst = dict.index(imm)
cst
else
# a => 1, b => 2, c => 4, all => 7: discard abc, keep 'all'
dict.delete_if { |k, v| dict.find { |kk, vv| vv > v and vv & v == v } }
dict.keys.join(' | ') if not dict.empty?
end
end
if gui
gui.keyboard_callback[?K] = lambda { |*a|
addr = gui.curaddr
imm_to_const(addr) { |i|
gui.inputbox("const name for #{Expression[i]}") { |name|
imm_to_const(addr) { |ii| name if ii == i }
gui.gui_update
}
nil
}
}
end