diff options
Diffstat (limited to 'miasm2/arch')
| -rw-r--r-- | miasm2/arch/mep/sem.py | 7 | ||||
| -rw-r--r-- | miasm2/arch/mips32/ira.py | 106 | ||||
| -rw-r--r-- | miasm2/arch/mips32/regs.py | 1 | ||||
| -rw-r--r-- | miasm2/arch/mips32/sem.py | 53 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 111 |
5 files changed, 188 insertions, 90 deletions
diff --git a/miasm2/arch/mep/sem.py b/miasm2/arch/mep/sem.py index e1d4c5fa..e779b970 100644 --- a/miasm2/arch/mep/sem.py +++ b/miasm2/arch/mep/sem.py @@ -912,7 +912,12 @@ def div(rn, rm): # Check if both numbers are positive or negative are_both_neg = sign_rn & sign_rm - are_both_pos = "=="(are_both_neg, sign_mask) + are_both_pos = ExprCond( + are_both_neg - sign_mask, + ExprInt(0, are_both_neg.size), + ExprInt(1, are_both_neg.size) + ) + # Invert both numbers rn_inv = ~rn + i32(1) diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py index def75750..4c4a33d8 100644 --- a/miasm2/arch/mips32/ira.py +++ b/miasm2/arch/mips32/ira.py @@ -1,7 +1,7 @@ #-*- coding:utf-8 -*- -from miasm2.expression.expression import ExprAff, ExprInt, ExprId -from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock +from miasm2.expression.expression import ExprAff, ExprOp +from miasm2.ir.ir import IRBlock, AssignBlock from miasm2.ir.analysis import ira from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b @@ -10,41 +10,73 @@ class ir_a_mips32l(ir_mips32l, ira): ir_mips32l.__init__(self, loc_db) self.ret_reg = self.arch.regs.V0 - def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): - IntermediateRepresentation.post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks) - new_irblocks = [] - for irb in ir_blocks: - pc_val = None - lr_val = None - for assignblk in irb: - pc_val = assignblk.get(self.arch.regs.PC, pc_val) - lr_val = assignblk.get(self.arch.regs.RA, lr_val) - - if pc_val is None or lr_val is None: - new_irblocks.append(irb) - continue - if lr_val.is_loc(): - offset = self.loc_db.get_location_offset(lr_val.loc_key) - if offset is not None: - lr_val = ExprInt(offset, 32) - if not lr_val.is_int(): - continue - - instr = block.lines[-2] - if int(lr_val) != instr.offset + 8: - raise ValueError("Wrong arg") - - # CALL - lbl = block.get_next() - new_lbl = self.gen_label() - call_assignblks, extra_irblocks = self.call_effects(pc_val, instr) - ir_blocks += extra_irblocks - irs.append(AssignBlock([ExprAff(self.IRDst, - ExprId(lbl, size=self.pc.size))], - instr)) - new_irblocks.append(IRBlock(new_lbl, call_assignblks)) - new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size))) - return new_irblocks + def call_effects(self, ad, instr): + call_assignblk = AssignBlock( + [ + ExprAff( + self.ret_reg, + ExprOp( + 'call_func_ret', + ad, + self.arch.regs.A0, + self.arch.regs.A1, + self.arch.regs.A2, + self.arch.regs.A3, + ) + ), + ], + instr + ) + + return [call_assignblk], [] + + + def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): + """ + Add a native block to the current IR + @block: native assembly block + @ircfg: IRCFG instance + @gen_pc_updt: insert PC update effects between instructions + """ + loc_key = block.loc_key + ir_blocks_all = [] + + assignments = [] + for index, instr in enumerate(block.lines): + if loc_key is None: + assignments = [] + loc_key = self.get_loc_key_for_instr(instr) + if instr.is_subcall(): + assert index == len(block.lines) - 2 + + # Add last instruction first (before call) + split = self.add_instr_to_current_state( + block.lines[-1], block, assignments, + ir_blocks_all, gen_pc_updt + ) + assert not split + # Add call effects after the delay splot + split = self.add_instr_to_current_state( + instr, block, assignments, + ir_blocks_all, gen_pc_updt + ) + assert split + break + split = self.add_instr_to_current_state( + instr, block, assignments, + ir_blocks_all, gen_pc_updt + ) + if split: + ir_blocks_all.append(IRBlock(loc_key, assignments)) + loc_key = None + assignments = [] + if loc_key is not None: + ir_blocks_all.append(IRBlock(loc_key, assignments)) + + new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) + for irblock in new_ir_blocks_all: + ircfg.add_irblock(irblock) + return new_ir_blocks_all def get_out_regs(self, _): return set([self.ret_reg, self.sp]) diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py index 7ff949f2..ddaaff79 100644 --- a/miasm2/arch/mips32/regs.py +++ b/miasm2/arch/mips32/regs.py @@ -24,6 +24,7 @@ regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\ ['GP', 'SP', 'FP', 'RA'] regs32_expr = [ExprId(x, 32) for x in regs32_str] +ZERO = regs32_expr[0] regs_flt_str = ['F%d'%i for i in xrange(0x20)] diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py index acf7370f..92001280 100644 --- a/miasm2/arch/mips32/sem.py +++ b/miasm2/arch/mips32/sem.py @@ -1,16 +1,20 @@ import miasm2.expression.expression as m2_expr from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.arch.mips32.arch import mn_mips32 -from miasm2.arch.mips32.regs import R_LO, R_HI, PC, RA, exception_flags +from miasm2.arch.mips32.regs import R_LO, R_HI, PC, RA, ZERO, exception_flags from miasm2.core.sembuilder import SemBuilder from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO # SemBuilder context -ctx = {"R_LO": R_LO, - "R_HI": R_HI, - "PC": PC, - "RA": RA} +ctx = { + "R_LO": R_LO, + "R_HI": R_HI, + "PC": PC, + "RA": RA, + "m2_expr": m2_expr +} + sbuild = SemBuilder(ctx) @@ -76,7 +80,7 @@ def lb(arg1, arg2): @sbuild.parse def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" - dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 - arg2 else arg3 + dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst ir.IRDst = dst @@ -84,7 +88,7 @@ def beq(arg1, arg2, arg3): def bgez(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" - dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1.msb() else arg2 + dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else arg2 PC = dst ir.IRDst = dst @@ -92,7 +96,7 @@ def bgez(arg1, arg2): def bne(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" - dst = arg3 if arg1 - arg2 else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) + dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else arg3 PC = dst ir.IRDst = dst @@ -143,15 +147,24 @@ def mul(arg1, arg2, arg3): @sbuild.parse def sltu(arg1, arg2, arg3): - """If @arg3 is less than @arg2 (unsigned), @arg1 is set to one. It gets zero + """If @arg2 is less than @arg3 (unsigned), @arg1 is set to one. It gets zero otherwise.""" - arg1 = (((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))) ^ arg2 ^ arg3).msb().zeroExtend(32) + arg1 = ExprCond( + ExprOp(m2_expr.TOK_INF_UNSIGNED, arg2, arg3), + ExprInt(1, arg1.size), + ExprInt(0, arg1.size) + ) @sbuild.parse def slt(arg1, arg2, arg3): - """If @arg3 is less than @arg2 (signed), @arg1 is set to one. It gets zero + """If @arg2 is less than @arg3 (signed), @arg1 is set to one. It gets zero otherwise.""" - arg1 = ((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))).msb().zeroExtend(32) + arg1 = ExprCond( + ExprOp(m2_expr.TOK_INF_SIGNED, arg2, arg3), + ExprInt(1, arg1.size), + ExprInt(0, arg1.size) + ) + @sbuild.parse def l_sub(arg1, arg2, arg3): @@ -230,14 +243,14 @@ def seh(arg1, arg2): @sbuild.parse def bltz(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than zero""" - dst_o = arg2 if arg1.msb() else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) + dst_o = arg2 if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o @sbuild.parse def blez(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" - cond = (i1(1) if arg1 else i1(0)) | arg1.msb() + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) dst_o = arg2 if cond else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o @@ -245,7 +258,7 @@ def blez(arg1, arg2): @sbuild.parse def bgtz(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" - cond = (i1(1) if arg1 else i1(0)) | arg1.msb() + cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size)) dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if cond else arg2 PC = dst_o ir.IRDst = dst_o @@ -480,12 +493,15 @@ class ir_mips32l(IntermediateRepresentation): args = instr.args instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) - pc_fixed = {self.pc: m2_expr.ExprInt(instr.offset + 4, 32)} + fixed_regs = { + self.pc: m2_expr.ExprInt(instr.offset + 4, 32), + ZERO: m2_expr.ExprInt(0, 32) + } - instr_ir = [m2_expr.ExprAff(expr.dst, expr.src.replace_expr(pc_fixed)) + instr_ir = [m2_expr.ExprAff(expr.dst, expr.src.replace_expr(fixed_regs)) for expr in instr_ir] - new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(pc_fixed)) + new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fixed_regs)) for irblock in extra_ir] return instr_ir, new_extra_ir @@ -497,6 +513,7 @@ class ir_mips32l(IntermediateRepresentation): class ir_mips32b(ir_mips32l): def __init__(self, loc_db=None): + self.addrsize = 32 IntermediateRepresentation.__init__(self, mn_mips32, 'b', loc_db) self.pc = mn_mips32.getpc() self.sp = mn_mips32.getsp() diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index a00b6f7c..ec85ae32 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -321,7 +321,7 @@ def mem2double(instr, arg): if arg.size > 64: # TODO: move to 80 bits arg = m2_expr.ExprMem(expraddr(instr.mode, arg.arg), size=64) - return m2_expr.ExprOp('mem_%.2d_to_double' % arg.size, arg) + return m2_expr.ExprOp('sint_to_fp', arg.signExtend(64)) else: return arg @@ -2091,8 +2091,7 @@ def float_pop(avoid_flt=None, popcount=1): if avoid_flt != float_list[i]: e.append(m2_expr.ExprAff(float_list[i], float_list[i + popcount])) - fill_value = m2_expr.ExprOp("sint_to_fp64", - m2_expr.ExprInt(0, float_list[i].size)) + fill_value = m2_expr.ExprOp("sint_to_fp", m2_expr.ExprInt(0, 64)) for i in xrange(8 - popcount, 8): e.append(m2_expr.ExprAff(float_list[i], fill_value)) @@ -2127,7 +2126,7 @@ def ftst(_, instr): dst = float_st0 e = [] - src = m2_expr.ExprOp('sint_to_fp64', m2_expr.ExprInt(0, 32)) + src = m2_expr.ExprOp('sint_to_fp', m2_expr.ExprInt(0, 64)) e.append(m2_expr.ExprAff(float_c0, m2_expr.ExprOp('fcom_c0', dst, src))) e.append(m2_expr.ExprAff(float_c1, m2_expr.ExprOp('fcom_c1', dst, src))) e.append(m2_expr.ExprAff(float_c2, m2_expr.ExprOp('fcom_c2', dst, src))) @@ -2253,8 +2252,8 @@ def comiss(_, instr, dst, src): e = [] - dst = m2_expr.ExprOp('sint_to_fp32', dst[:32]) - src = m2_expr.ExprOp('sint_to_fp32', src[:32]) + dst = m2_expr.ExprOp('sint_to_fp', dst[:32]) + src = m2_expr.ExprOp('sint_to_fp', src[:32]) e.append(m2_expr.ExprAff(cf, m2_expr.ExprOp('fcom_c0', dst, src))) e.append(m2_expr.ExprAff(pf, m2_expr.ExprOp('fcom_c2', dst, src))) @@ -2273,8 +2272,8 @@ def comisd(_, instr, dst, src): e = [] - dst = m2_expr.ExprOp('sint_to_fp64', dst[:64]) - src = m2_expr.ExprOp('sint_to_fp64', src[:64]) + dst = m2_expr.ExprOp('sint_to_fp', dst[:64]) + src = m2_expr.ExprOp('sint_to_fp', src[:64]) e.append(m2_expr.ExprAff(cf, m2_expr.ExprOp('fcom_c0', dst, src))) e.append(m2_expr.ExprAff(pf, m2_expr.ExprOp('fcom_c2', dst, src))) @@ -2292,6 +2291,8 @@ def fld(_, instr, src): if src.size == 32: src = m2_expr.ExprOp("fpconvert_fp64", src) + if isinstance(src, m2_expr.ExprMem) and src.size > 64: + raise NotImplementedError('convert from 80bits') e = [] e.append(m2_expr.ExprAff(float_st7, float_st6)) @@ -2377,7 +2378,7 @@ def fisttp(_, instr, dst): def fild(ir, instr, src): # XXXXX - src = m2_expr.ExprOp('sint_to_fp64', src) + src = m2_expr.ExprOp('sint_to_fp', src.signExtend(64)) e = [] e += set_float_cs_eip(instr) e_fld, extra = fld(ir, instr, src) @@ -2386,27 +2387,29 @@ def fild(ir, instr, src): def fldz(ir, instr): - return fld(ir, instr, m2_expr.ExprOp('sint_to_fp64', - m2_expr.ExprInt(0, 32))) + return fld(ir, instr, m2_expr.ExprOp('sint_to_fp', m2_expr.ExprInt(0, 64))) def fld1(ir, instr): - return fld(ir, instr, m2_expr.ExprOp('sint_to_fp64', - m2_expr.ExprInt(1, 32))) + return fld(ir, instr, m2_expr.ExprOp('sint_to_fp', m2_expr.ExprInt(1, 64))) def fldl2t(ir, instr): value_f = math.log(10) / math.log(2) - value = struct.unpack('I', struct.pack('f', value_f))[0] - return fld(ir, instr, m2_expr.ExprOp('sint_to_fp64', - m2_expr.ExprInt(value, 32))) + value = struct.unpack('Q', struct.pack('d', value_f))[0] + return fld(ir, instr, m2_expr.ExprOp( + 'sint_to_fp', + m2_expr.ExprInt(value, 64) + )) def fldpi(ir, instr): value_f = math.pi - value = struct.unpack('I', struct.pack('f', value_f))[0] - return fld(ir, instr, m2_expr.ExprOp('sint_to_fp64', - m2_expr.ExprInt(value, 32))) + value = struct.unpack('Q', struct.pack('d', value_f))[0] + return fld(ir, instr, m2_expr.ExprOp( + 'sint_to_fp', + m2_expr.ExprInt(value, 64) + )) def fldln2(ir, instr): @@ -2745,9 +2748,15 @@ def fptan(_, instr): e.append(m2_expr.ExprAff(float_st3, float_st2)) e.append(m2_expr.ExprAff(float_st2, float_st1)) e.append(m2_expr.ExprAff(float_st1, m2_expr.ExprOp('ftan', float_st0))) - e.append(m2_expr.ExprAff(float_st0, - m2_expr.ExprOp('sint_to_fp64', - m2_expr.ExprInt(1, 32)))) + e.append( + m2_expr.ExprAff( + float_st0, + m2_expr.ExprOp( + 'sint_to_fp', + m2_expr.ExprInt(1, 64) + ) + ) + ) e.append( m2_expr.ExprAff(float_stack_ptr, float_stack_ptr + m2_expr.ExprInt(1, 3))) @@ -3958,22 +3967,36 @@ def por(_, instr, dst, src): def cvtdq2pd(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:64], m2_expr.ExprOp('sint_to_fp64', src[:32]))) + m2_expr.ExprAff( + dst[:64], + m2_expr.ExprOp( + 'sint_to_fp', + src[:32].signExtend(64) + ) + ) + ) e.append( - m2_expr.ExprAff(dst[64:128], m2_expr.ExprOp('sint_to_fp64', src[32:64]))) + m2_expr.ExprAff( + dst[64:128], + m2_expr.ExprOp( + 'sint_to_fp', + src[32:64].signExtend(64) + ) + ) + ) return e, [] def cvtdq2ps(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp32', src[:32]))) + m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp', src[:32]))) e.append( - m2_expr.ExprAff(dst[32:64], m2_expr.ExprOp('sint_to_fp32', src[32:64]))) + m2_expr.ExprAff(dst[32:64], m2_expr.ExprOp('sint_to_fp', src[32:64]))) e.append( - m2_expr.ExprAff(dst[64:96], m2_expr.ExprOp('sint_to_fp32', src[64:96]))) + m2_expr.ExprAff(dst[64:96], m2_expr.ExprOp('sint_to_fp', src[64:96]))) e.append( - m2_expr.ExprAff(dst[96:128], m2_expr.ExprOp('sint_to_fp32', src[96:128]))) + m2_expr.ExprAff(dst[96:128], m2_expr.ExprOp('sint_to_fp', src[96:128]))) return e, [] @@ -4009,18 +4032,31 @@ def cvtpd2ps(_, instr, dst, src): def cvtpi2pd(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:64], m2_expr.ExprOp('sint_to_fp64', src[:32]))) + m2_expr.ExprAff( + dst[:64], + m2_expr.ExprOp( + 'sint_to_fp', + src[:32].signExtend(64) + ) + ) + ) e.append( - m2_expr.ExprAff(dst[64:128], m2_expr.ExprOp('sint_to_fp64', src[32:64]))) + m2_expr.ExprAff( + dst[64:128], + m2_expr.ExprOp( + 'sint_to_fp', + src[32:64].signExtend(64)) + ) + ) return e, [] def cvtpi2ps(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp32', src[:32]))) + m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp', src[:32]))) e.append( - m2_expr.ExprAff(dst[32:64], m2_expr.ExprOp('sint_to_fp32', src[32:64]))) + m2_expr.ExprAff(dst[32:64], m2_expr.ExprOp('sint_to_fp', src[32:64]))) return e, [] @@ -4072,14 +4108,21 @@ def cvtsd2ss(_, instr, dst, src): def cvtsi2sd(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:64], m2_expr.ExprOp('sint_to_fp64', src[:32]))) + m2_expr.ExprAff( + dst[:64], + m2_expr.ExprOp( + 'sint_to_fp', + src[:32].signExtend(64) + ) + ) + ) return e, [] def cvtsi2ss(_, instr, dst, src): e = [] e.append( - m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp32', src[:32]))) + m2_expr.ExprAff(dst[:32], m2_expr.ExprOp('sint_to_fp', src[:32]))) return e, [] |