diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/arch/x86/arch.py | 4 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 173 | ||||
| -rw-r--r-- | miasm2/core/sembuilder.py | 122 | ||||
| -rw-r--r-- | miasm2/ir/symbexec.py | 11 | ||||
| -rw-r--r-- | miasm2/jitter/jitcore_python.py | 11 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 8 | ||||
| -rw-r--r-- | test/arch/x86/qemu/testqemu.py | 6 | ||||
| -rw-r--r-- | test/core/sembuilder.py | 11 | ||||
| -rw-r--r-- | test/test_all.py | 3 |
9 files changed, 213 insertions, 136 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 2b9b3cb1..74ac0939 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -3252,6 +3252,10 @@ addop("cmpsq", [bs8(0xa7), bs_opmode64]) addop("cmpxchg", [bs8(0x0f), bs('1011000'), w8] + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg]) +addop("cmpxchg8b", [bs8(0x0f), bs8(0xc7), bs_opmode16] + rmmod(d1, rm_arg_m64)) +addop("cmpxchg8b", [bs8(0x0f), bs8(0xc7), bs_opmode32] + rmmod(d1, rm_arg_m64)) +addop("cmpxchg16b", [bs8(0x0f), bs8(0xc7), bs_opmode64] + rmmod(d1, rm_arg_m64)) + # XXX TODO CMPXCHG8/16 addop("comiss", [bs8(0x0f), bs8(0x2f), no_xmm_pref] + diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index f1784692..c39d2583 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -22,9 +22,20 @@ from miasm2.arch.x86.regs import * from miasm2.arch.x86.arch import mn_x86, repeat_mn, replace_regs from miasm2.expression.expression_helper import expr_cmps, expr_cmpu from miasm2.ir.ir import ir, irbloc +from miasm2.core.sembuilder import SemBuilder import math import struct + +# SemBuilder context +ctx = {'mRAX': mRAX, + 'mRBX': mRBX, + 'mRCX': mRCX, + 'mRDX': mRDX, + 'zf': zf, + } +sbuild = SemBuilder(ctx) + # interrupt with eip update after instr EXCEPT_SOFT_BP = (1 << 1) EXCEPT_INT_XX = (1 << 2) @@ -195,15 +206,15 @@ def gen_jcc(ir, instr, cond, dst, jmp_if): """ e = [] - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] next_lbl = m2_expr.ExprId(ir.get_next_label(instr), dst.size) if jmp_if: dstA, dstB = dst, next_lbl else: dstA, dstB = next_lbl, dst mn_dst = m2_expr.ExprCond(cond, - dstA.zeroExtend(instr.mode), - dstB.zeroExtend(instr.mode)) + dstA.zeroExtend(ir.IRDst.size), + dstB.zeroExtend(ir.IRDst.size)) e.append(m2_expr.ExprAff(meip, mn_dst)) e.append(m2_expr.ExprAff(ir.IRDst, mn_dst)) return e, [] @@ -216,8 +227,8 @@ def gen_fcmov(ir, instr, cond, arg1, arg2, mov_if): @cond: condition @mov_if: invert condition if False""" - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) if mov_if: dstA, dstB = lbl_do, lbl_skip else: @@ -236,8 +247,8 @@ def gen_cmov(ir, instr, cond, arg1, arg2, mov_if): @cond: condition @mov_if: invert condition if False""" - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) if mov_if: dstA, dstB = lbl_do, lbl_skip else: @@ -258,11 +269,10 @@ def mov(ir, instr, a, b): return e, [] -def xchg(ir, instr, a, b): - e = [] - e.append(m2_expr.ExprAff(a, b)) - e.append(m2_expr.ExprAff(b, a)) - return e, [] +@sbuild.parse +def xchg(arg1, arg2): + arg1 = arg2 + arg2 = arg1 def movzx(ir, instr, a, b): @@ -452,8 +462,8 @@ def _rotate_tpl(ir, instr, a, b, op, left=False, include_cf=False): return [], [] e = [] - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip)) e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, lbl_do, lbl_skip))) @@ -548,8 +558,8 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False, return [], [] e = [] - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip)) e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, lbl_do, lbl_skip))) @@ -914,10 +924,10 @@ def bswap(ir, instr, a): def cmps(ir, instr, size): - lbl_cmp = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_0 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_1 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_cmp = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) s = instr.v_admode() a = m2_expr.ExprMem(mRDI[instr.mode][:s], size) @@ -947,10 +957,10 @@ def cmps(ir, instr, size): def scas(ir, instr, size): - lbl_cmp = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_0 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_1 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_cmp = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) s = instr.v_admode() a = m2_expr.ExprMem(mRDI[instr.mode][:s], size) @@ -1107,10 +1117,10 @@ def call(ir, instr, dst): e = [] # opmode, admode = instr.opmode, instr.admode s = dst.size - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] opmode, admode = s, instr.v_admode() myesp = mRSP[instr.mode][:opmode] - n = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) if (isinstance(dst, m2_expr.ExprOp) and dst.op == "segm"): @@ -1144,8 +1154,8 @@ def call(ir, instr, dst): if ir.do_stk_segm: c = m2_expr.ExprOp('segm', SS, c) e.append(m2_expr.ExprAff(m2_expr.ExprMem(c, size=s), n)) - e.append(m2_expr.ExprAff(meip, dst.zeroExtend(instr.mode))) - e.append(m2_expr.ExprAff(ir.IRDst, dst.zeroExtend(instr.mode))) + e.append(m2_expr.ExprAff(meip, dst.zeroExtend(ir.IRDst.size))) + e.append(m2_expr.ExprAff(ir.IRDst, dst.zeroExtend(ir.IRDst.size))) #if not expr_is_int_or_label(dst): # dst = meip return e, [] @@ -1154,7 +1164,7 @@ def call(ir, instr, dst): def ret(ir, instr, a=None): e = [] s = instr.mode - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] opmode, admode = instr.v_opmode(), instr.v_admode() s = opmode myesp = mRSP[instr.mode][:s] @@ -1179,7 +1189,7 @@ def ret(ir, instr, a=None): def retf(ir, instr, a=None): e = [] s = instr.mode - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] opmode, admode = instr.v_opmode(), instr.v_admode() if a is None: a = m2_expr.ExprInt(0, s) @@ -1238,9 +1248,9 @@ def enter(ir, instr, a, b): def jmp(ir, instr, dst): e = [] - meip = mRIP[instr.mode] - e.append(m2_expr.ExprAff(meip, dst)) # dst.zeroExtend(instr.mode))) - e.append(m2_expr.ExprAff(ir.IRDst, dst)) # dst.zeroExtend(instr.mode))) + meip = mRIP[ir.IRDst.size] + e.append(m2_expr.ExprAff(meip, dst)) # dst.zeroExtend(ir.IRDst.size))) + e.append(m2_expr.ExprAff(ir.IRDst, dst)) # dst.zeroExtend(ir.IRDst.size))) if isinstance(dst, m2_expr.ExprMem): dst = meip @@ -1249,7 +1259,7 @@ def jmp(ir, instr, dst): def jmpf(ir, instr, a): e = [] - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] s = instr.mode if (isinstance(a, m2_expr.ExprOp) and a.op == "segm"): segm = a.args[0] @@ -1344,15 +1354,15 @@ def jno(ir, instr, dst): def loop(ir, instr, dst): e = [] - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) c = myecx - m2_expr.ExprInt_from(myecx, 1) dst_o = m2_expr.ExprCond(c, - dst.zeroExtend(instr.mode), - n.zeroExtend(instr.mode)) + dst.zeroExtend(ir.IRDst.size), + n.zeroExtend(ir.IRDst.size)) e.append(m2_expr.ExprAff(myecx, c)) e.append(m2_expr.ExprAff(meip, dst_o)) e.append(m2_expr.ExprAff(ir.IRDst, dst_o)) @@ -1361,11 +1371,11 @@ def loop(ir, instr, dst): def loopne(ir, instr, dst): e = [] - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size), m2_expr.ExprInt1(1), @@ -1374,8 +1384,8 @@ def loopne(ir, instr, dst): e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt_from(myecx, 1))) dst_o = m2_expr.ExprCond(c, - dst.zeroExtend(instr.mode), - n.zeroExtend(instr.mode)) + dst.zeroExtend(ir.IRDst.size), + n.zeroExtend(ir.IRDst.size)) e.append(m2_expr.ExprAff(meip, dst_o)) e.append(m2_expr.ExprAff(ir.IRDst, dst_o)) return e, [] @@ -1383,19 +1393,19 @@ def loopne(ir, instr, dst): def loope(ir, instr, dst): e = [] - meip = mRIP[instr.mode] + meip = mRIP[ir.IRDst.size] admode = instr.v_admode() myecx = mRCX[instr.mode][:admode] - n = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size), m2_expr.ExprInt1(1), m2_expr.ExprInt1(0)) c &= zf e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt_from(myecx, 1))) dst_o = m2_expr.ExprCond(c, - dst.zeroExtend(instr.mode), - n.zeroExtend(instr.mode)) + dst.zeroExtend(ir.IRDst.size), + n.zeroExtend(ir.IRDst.size)) e.append(m2_expr.ExprAff(meip, dst_o)) e.append(m2_expr.ExprAff(ir.IRDst, dst_o)) return e, [] @@ -1586,9 +1596,9 @@ def cqo(ir, instr): def stos(ir, instr, size): - lbl_df_0 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_1 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) s = instr.v_admode() @@ -1622,9 +1632,9 @@ def stos(ir, instr, size): def lods(ir, instr, size): - lbl_df_0 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_1 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) e = [] s = instr.v_admode() @@ -1659,9 +1669,9 @@ def lods(ir, instr, size): def movs(ir, instr, size): - lbl_df_0 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_df_1 = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) s = instr.v_admode() # a = m2_expr.ExprMem(mRDI[instr.mode][:s], size) @@ -2681,9 +2691,9 @@ def bsr_bsf(ir, instr, a, b, op_name): ZF = 0 DEST = @op_name(SRC) """ - lbl_src_null = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_src_not_null = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_next = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + lbl_src_null = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_src_not_null = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) aff_dst = m2_expr.ExprAff(ir.IRDst, lbl_next) e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, @@ -2948,25 +2958,27 @@ def l_in(ir, instr, a, b): return e, [] -def cmpxchg(ir, instr, a, b): - e = [] +@sbuild.parse +def cmpxchg(arg1, arg2): + accumulator = mRAX[instr.mode][:arg1.size] + if (accumulator - arg1): + zf = i1(0) + accumulator = arg1 + else: + zf = i1(1) + arg1 = arg2 - c = mRAX[instr.mode][:a.size] - cond = c - a - e.append( - m2_expr.ExprAff(zf, - m2_expr.ExprCond(cond, - m2_expr.ExprInt_from(zf, 0), - m2_expr.ExprInt_from(zf, 1)))) - e.append(m2_expr.ExprAff(a, m2_expr.ExprCond(cond, - b, - a) - )) - e.append(m2_expr.ExprAff(c, m2_expr.ExprCond(cond, - a, - c) - )) - return e, [] + +@sbuild.parse +def cmpxchg8b(arg1): + accumulator = {mRAX[instr.mode], mRDX[instr.mode]} + if accumulator - arg1: + zf = i1(0) + mRAX[instr.mode] = arg1[:instr.mode] + mRDX[instr.mode] = arg1[instr.mode:] + else: + zf = i1(1) + arg1 = {mRBX[instr.mode], mRCX[instr.mode]} def lds(ir, instr, a, b): @@ -3700,6 +3712,7 @@ mnemo_func = {'mov': mov, 'out': l_out, "sysenter": l_sysenter, "cmpxchg": cmpxchg, + "cmpxchg8b": cmpxchg8b, "lds": lds, "les": les, "lss": lss, @@ -3895,10 +3908,10 @@ class ir_x86_16(ir): c_cond = cond_dec | (zf ^ m2_expr.ExprInt1(1)) # gen while - lbl_do = m2_expr.ExprId(self.gen_label(), instr.mode) - lbl_end = m2_expr.ExprId(self.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(self.get_next_label(instr), instr.mode) - lbl_next = m2_expr.ExprId(self.get_next_label(instr), instr.mode) + lbl_do = m2_expr.ExprId(self.gen_label(), self.IRDst.size) + lbl_end = m2_expr.ExprId(self.gen_label(), self.IRDst.size) + lbl_skip = m2_expr.ExprId(self.get_next_label(instr), self.IRDst.size) + lbl_next = m2_expr.ExprId(self.get_next_label(instr), self.IRDst.size) for b in extra_ir: for ir in b.irs: diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py index 8be3fb12..83981919 100644 --- a/miasm2/core/sembuilder.py +++ b/miasm2/core/sembuilder.py @@ -16,6 +16,7 @@ class MiasmTransformer(ast.NodeTransformer): X if Y else Z -> ExprCond(Y, X, Z) 'X'(Y) -> ExprOp('X', Y) ('X' % Y)(Z) -> ExprOp('X' % Y, Z) + {a, b} -> ExprCompose([a, 0, a.size], [b, a.size, a.size + b.size]) """ # Parsers @@ -93,6 +94,32 @@ class MiasmTransformer(ast.NodeTransformer): keywords=[], starargs=None, kwargs=None) return call + def visit_Set(self, node): + "{a, b} -> ExprCompose([a, 0, a.size], [b, a.size, a.size + b.size])" + if len(node.elts) == 0: + return node + + # Recursive visit + node = self.generic_visit(node) + + new_elts = [] + index = ast.Num(n=0) + for elt in node.elts: + new_index = ast.BinOp(op=ast.Add(), left=index, + right=ast.Attribute(value=elt, + attr='size', + ctx=ast.Load())) + new_elts.append(ast.List(elts=[elt, index, new_index], + ctx=ast.Load())) + index = new_index + return ast.Call(func=ast.Name(id='ExprCompose', + ctx=ast.Load()), + args=[ast.List(elts=new_elts, + ctx=ast.Load())], + keywords=[], + starargs=None, + kwargs=None) + class SemBuilder(object): """Helper for building instruction's semantic side effects method @@ -121,10 +148,14 @@ class SemBuilder(object): return self._functions.copy() @staticmethod - def _create_labels(): - """Return the AST standing for label creations""" - out = ast.parse("lbl_end = ExprId(ir.get_next_instr(instr))").body - out += ast.parse("lbl_if = ExprId(ir.gen_label())").body + def _create_labels(lbl_else=False): + """Return the AST standing for label creations + @lbl_else (optional): if set, create a label 'lbl_else'""" + lbl_end = "lbl_end = ExprId(ir.get_next_label(instr), ir.IRDst.size)" + out = ast.parse(lbl_end).body + out += ast.parse("lbl_if = ExprId(ir.gen_label(), ir.IRDst.size)").body + if lbl_else: + out += ast.parse("lbl_else = ExprId(ir.gen_label(), ir.IRDst.size)").body return out def _parse_body(self, body, argument_names): @@ -147,11 +178,13 @@ class SemBuilder(object): if (isinstance(dst, ast.Name) and dst.id not in argument_names and - dst.id not in self._ctx): + dst.id not in self._ctx and + dst.id not in self._local_ctx): # Real variable declaration statement.value = src real_body.append(statement) + self._local_ctx[dst.id] = src continue dst.ctx = ast.Load() @@ -170,19 +203,21 @@ class SemBuilder(object): # String (docstring, comment, ...) -> keep it real_body.append(statement) - elif (isinstance(statement, ast.If) and - not statement.orelse): + elif isinstance(statement, ast.If): # Create jumps : ir.IRDst = lbl_if if cond else lbl_end + # if .. else .. are also handled cond = statement.test - real_body += self._create_labels() + real_body += self._create_labels(lbl_else=True) lbl_end = ast.Name(id='lbl_end', ctx=ast.Load()) lbl_if = ast.Name(id='lbl_if', ctx=ast.Load()) + lbl_else = ast.Name(id='lbl_else', ctx=ast.Load()) \ + if statement.orelse else lbl_end dst = ast.Call(func=ast.Name(id='ExprCond', ctx=ast.Load()), args=[cond, lbl_if, - lbl_end], + lbl_else], keywords=[], starargs=None, kwargs=None) @@ -204,38 +239,42 @@ class SemBuilder(object): kwargs=None)) # Create the new blocks - sub_blocks, sub_body = self._parse_body(statement.body, - argument_names) - if len(sub_blocks) > 1: - raise RuntimeError("Imbricated if unimplemented") - - ## Close the last block - jmp_end = ast.Call(func=ast.Name(id='ExprAff', - ctx=ast.Load()), - args=[IRDst, lbl_end], - keywords=[], - starargs=None, - kwargs=None) - sub_blocks[-1][-1].append(jmp_end) - sub_blocks[-1][-1] = ast.List(elts=sub_blocks[-1][-1], + elements = [(statement.body, 'lbl_if')] + if statement.orelse: + elements.append((statement.orelse, 'lbl_else')) + for content, lbl_name in elements: + sub_blocks, sub_body = self._parse_body(content, + argument_names) + if len(sub_blocks) > 1: + raise RuntimeError("Imbricated if unimplemented") + + ## Close the last block + jmp_end = ast.Call(func=ast.Name(id='ExprAff', + ctx=ast.Load()), + args=[IRDst, lbl_end], + keywords=[], + starargs=None, + kwargs=None) + sub_blocks[-1][-1].append(jmp_end) + sub_blocks[-1][-1] = ast.List(elts=sub_blocks[-1][-1], + ctx=ast.Load()) + sub_blocks[-1] = ast.List(elts=sub_blocks[-1], ctx=ast.Load()) - sub_blocks[-1] = ast.List(elts=sub_blocks[-1], - ctx=ast.Load()) - - ## Replace the block with a call to 'irbloc' - lbl_if_name = ast.Attribute(value=ast.Name(id='lbl_if', - ctx=ast.Load()), - attr='name', ctx=ast.Load()) - - sub_blocks[-1] = ast.Call(func=ast.Name(id='irbloc', - ctx=ast.Load()), - args=[lbl_if_name, - sub_blocks[-1]], - keywords=[], - starargs=None, - kwargs=None) - blocks += sub_blocks - real_body += sub_body + + ## Replace the block with a call to 'irbloc' + lbl_if_name = ast.Attribute(value=ast.Name(id=lbl_name, + ctx=ast.Load()), + attr='name', ctx=ast.Load()) + + sub_blocks[-1] = ast.Call(func=ast.Name(id='irbloc', + ctx=ast.Load()), + args=[lbl_if_name, + sub_blocks[-1]], + keywords=[], + starargs=None, + kwargs=None) + blocks += sub_blocks + real_body += sub_body # Prepare a new block for following statement blocks.append([[]]) @@ -255,6 +294,9 @@ class SemBuilder(object): fc_ast = parsed.body[0] argument_names = [name.id for name in fc_ast.args.args] + # Init local cache + self._local_ctx = {} + # Translate (blocks[0][0] is the current instr) blocks, body = self._parse_body(fc_ast.body, argument_names) diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py index f51baf9f..9ac79b1f 100644 --- a/miasm2/ir/symbexec.py +++ b/miasm2/ir/symbexec.py @@ -384,10 +384,7 @@ class symbexec(object): # test if mem lookup is known tmp = m2_expr.ExprMem(a, e.dst.size) dst = tmp - if self.func_write and isinstance(dst.arg, m2_expr.ExprInt): - self.func_write(self, dst, src, pool_out) - else: - pool_out[dst] = src + pool_out[dst] = src elif isinstance(e.dst, m2_expr.ExprId): pool_out[e.dst] = src @@ -398,7 +395,6 @@ class symbexec(object): def eval_ir(self, ir): mem_dst = [] - # src_dst = [(x.src, x.dst) for x in ir] src_dst = self.eval_ir_expr(ir) eval_cache = dict(self.symbols.items()) for dst, src in src_dst: @@ -411,10 +407,11 @@ class symbexec(object): new_val.is_term = True self.symbols[new_mem] = new_val src_o = self.expr_simp(src) - # print 'SRCo', src_o - # src_o.is_term = True self.symbols[dst] = src_o if isinstance(dst, m2_expr.ExprMem): + if self.func_write and isinstance(dst.arg, m2_expr.ExprInt): + self.func_write(self, dst, src_o) + del self.symbols[dst] mem_dst.append(dst) return mem_dst diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py index 96db3a2b..e29c81c0 100644 --- a/miasm2/jitter/jitcore_python.py +++ b/miasm2/jitter/jitcore_python.py @@ -57,10 +57,8 @@ class JitCore_Python(jitcore.JitCore): def load(self): "Preload symbols according to current architecture" - symbols_init = {} - for r in self.ir_arch.arch.regs.all_regs_ids_no_alias: - symbols_init[r] = self.ir_arch.arch.regs.regs_init[r] - + symbols_init = {r:m2_expr.ExprInt(0, size=r.size) + for r in self.ir_arch.arch.regs.all_regs_ids_no_alias} self.symbexec = symbexec(self.ir_arch, symbols_init, func_read = self.func_read, func_write = self.func_write) @@ -76,12 +74,11 @@ class JitCore_Python(jitcore.JitCore): return m2_expr.ExprInt(int(value[::-1].encode("hex"), 16), expr_mem.size) - def func_write(self, symb_exec, dest, data, mem_cache): + def func_write(self, symb_exec, dest, data): """Memory read wrapper for symbolic execution @symb_exec: symbexec instance @dest: ExprMem instance - @data: Expr instance - @mem_cache: dict""" + @data: Expr instance""" # Get the content to write data = expr_simp(data) diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 5721d72a..7d6260a2 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -832,6 +832,14 @@ reg_tests = [ "0fb000"), (m32, "00000000 CMPXCHG DWORD PTR [EAX], EAX", "0fb100"), + (m16, "00000000 CMPXCHG8B QWORD PTR [SI+0x24]", + "0fc74c24"), + (m32, "00000000 CMPXCHG8B QWORD PTR [ESP+0x8]", + "0fc74c2408"), + (m64, "00000000 CMPXCHG8B QWORD PTR [RSP+0x8]", + "0fc74c2408"), + (m64, "00000000 CMPXCHG16B QWORD PTR [RSP+0x8]", + "480fc74c2408"), (m32, "00000000 CDQ", "99"), diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py index 7cf2ab75..a7df4fe4 100644 --- a/test/arch/x86/qemu/testqemu.py +++ b/test/arch/x86/qemu/testqemu.py @@ -45,6 +45,7 @@ def xxx___printf_chk(jitter): fmt = get_str_ansi(jitter, args.format) # Manage llx fmt = fmt.replace("llx", "lx") + fmt = fmt.replace("%016lx", "%016z") fmt_a = parse_fmt(fmt) esp = jitter.cpu.ESP @@ -61,11 +62,16 @@ def xxx___printf_chk(jitter): a2 = upck32(jitter.vm.get_mem(esp + 8 + 4*(i+1), 4)) a = struct.unpack("d", struct.pack("Q", a2 << 32 | a))[0] i += 1 + elif x.lower() == 'z': + a2 = upck32(jitter.vm.get_mem(esp + 8 + 4*(i+1), 4)) + a = a2 << 32 | a + i += 1 else: raise RuntimeError("Not implemented format") args.append(a) i += 1 + fmt = fmt.replace("%016z", "%016lx") output = fmt%(tuple(args)) # NaN bad repr in Python output = output.replace("nan", "-nan") diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py index 468e3ef5..15fa67a4 100644 --- a/test/core/sembuilder.py +++ b/test/core/sembuilder.py @@ -13,9 +13,15 @@ class IR(object): def get_next_instr(self, _): return asm_label("NEXT") + def get_next_label(self, _): + return asm_label("NEXT") + def gen_label(self): return asm_label("GEN") +class Instr(object): + mode = 32 + # Test sb = SemBuilder(m2_expr.__dict__) @@ -28,15 +34,18 @@ def test(Arg1, Arg2, Arg3): Arg3 = Arg3 if Arg2 else i32(0) tmpvar = 'myop'(i32(2)) Arg2 = ('myopsize%d' % Arg1.size)(tmpvar, Arg1) + alias = Arg1[:24] if not Arg1: Arg2 = Arg3 + else: + alias = {i16(4), i8(5)} a = m2_expr.ExprId('A') b = m2_expr.ExprId('B') c = m2_expr.ExprId('C') ir = IR() -instr = None +instr = Instr() res = test(ir, instr, a, b, c) print "[+] Returned:" diff --git a/test/test_all.py b/test/test_all.py index fe9c6880..94f3d8ca 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -108,8 +108,9 @@ QEMU_TESTS = { "self_modifying_code": ("tcc", "python"), "conv": ("tcc", "python"), "bcd": ("tcc", "python"), + "xchg": ("tcc", "python"), # Unsupported - # "floats", "xchg", "string", "misc", "segs", "code16", "exceptions", + # "floats", "string", "misc", "segs", "code16", "exceptions", # "single_step" } |