# 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 require 'metasm/cpu/ia32/opcodes' require 'metasm/render' # XXX move context in another file ? module Metasm class Ia32 class Argument include Renderable end [SegReg, DbgReg, TstReg, CtrlReg, FpReg].each { |c| c.class_eval { def render ; [self.class.i_to_s[@val]] end } } [Reg, SimdReg].each { |c| c.class_eval { def render ; [self.class.i_to_s[@sz][@val]] end def context ; {'set sz' => lambda { |s| @sz = s }} end } } class Farptr def render [@seg, ':', @addr] end end class ModRM def qualifier(sz) { 8 => 'byte', 16 => 'word', 32 => 'dword', 64 => 'qword', 128 => 'oword' }.fetch(sz) { |k| "_#{sz}bits" } end attr_accessor :instruction def render r = [] r << ( qualifier(@sz) << ' ptr ' ) if @sz and (not instruction or not @instruction.args.find { |a| a.kind_of? Reg and a.sz == @sz }) r << @seg << ':' if seg e = nil e = Expression[e, :+, @b] if b e = Expression[e, :+, @imm] if imm e = Expression[e, :+, (@s == 1 ? @i : [@s, :*, @i])] if s r << '[' << e << ']' end def context {'set targetsz' => lambda { |s| @sz = s }, 'set seg' => lambda { |s| @seg = Seg.new s }} end end def render_instruction(i) r = [] if pfx = i.prefix r << 'lock ' if pfx[:lock] r << pfx[:rep] << ' ' if pfx[:rep] r << pfx[:jmphint] << ' ' if pfx[:jmphint] r << 'seg_' << pfx[:seg] << ' ' if pfx[:seg] end r << i.opname sep = ' ' i.args.each { |a| a.instruction = i if a.kind_of? ModRM r << sep << a sep = ', ' } r end def instruction_context(i) # XXX h = {} op = opcode_list_byname[i.opname].first if i.prefix and i.prefix[:rep] h['toogle repz'] = lambda { i.prefix[:rep] = {'repnz' => 'repz', 'repz' => 'repnz'}[i.prefix[:rep]] } if op.props[:stropz] h['rm rep'] = lambda { i.prefix.delete :rep } else h['set rep'] = lambda { (i.prefix ||= {})[:rep] = 'rep' } if op.props[:strop] h['set rep'] = lambda { (i.prefix ||= {})[:rep] = 'repz' } if op.props[:stropz] end if i.args.find { |a| a.kind_of? ModRM and a.seg } h['rm seg'] = lambda { i.args.find { |a| a.kind_of? ModRM and a.seg }.seg = nil } end h['toggle lock'] = lambda { (i.prefix ||= {})[:lock] = !i.prefix[:lock] } h end def gui_hilight_word_regexp_init ret = {} %w[a b c d].each { |r| ret["#{r}l"] = "e?#{r}x|#{r}l" ret["#{r}h"] = "e?#{r}x|#{r}h" ret["#{r}x"] = ret["e#{r}x"] = "e?#{r}x|#{r}[hl]" } %w[sp bp si di].each { |r| ret[r] = ret["e#{r}"] = "e?#{r}" } ret end def gui_hilight_word_regexp(word) @gui_hilight_word_hash ||= gui_hilight_word_regexp_init @gui_hilight_word_hash[word] or super(word) end end end