diff options
| -rw-r--r-- | miasm2/arch/x86/sem.py | 51 | ||||
| -rw-r--r-- | miasm2/ir/translators/C.py | 8 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.c | 19 | ||||
| -rw-r--r-- | test/ir/ir2C.py | 2 | ||||
| -rw-r--r-- | test/samples/x86_32/bsr_bsf.S | 42 | ||||
| -rw-r--r-- | test/test_all.py | 8 |
6 files changed, 95 insertions, 35 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index bc98baf3..928554cb 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -2496,32 +2496,41 @@ def aas(ir, instr, ): return e, [] -def bsf(ir, instr, a, b): - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) - - e = [m2_expr.ExprAff(zf, m2_expr.ExprCond(b, m2_expr.ExprInt_from(zf, 0), - m2_expr.ExprInt_from(zf, 1)))] +def bsr_bsf(ir, instr, a, b, op_name): + """ + IF SRC == 0 + ZF = 1 + DEST is left unchanged + ELSE + 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) - e_do = [] - e_do.append(m2_expr.ExprAff(a, m2_expr.ExprOp('bsf', b))) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip)) - e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, lbl_do, lbl_skip))) - return e, [irbloc(lbl_do.name, [e_do])] + aff_dst = m2_expr.ExprAff(ir.IRDst, lbl_next) + e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, + lbl_src_not_null, + lbl_src_null))] + e_src_null = [] + e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 1))) + # XXX destination is undefined + e_src_null.append(aff_dst) + e_src_not_null = [] + e_src_not_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 0))) + e_src_not_null.append(m2_expr.ExprAff(a, m2_expr.ExprOp(op_name, b))) + e_src_not_null.append(aff_dst) -def bsr(ir, instr, a, b): - lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode) - lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode) + return e, [irbloc(lbl_src_null.name, [e_src_null]), + irbloc(lbl_src_not_null.name, [e_src_not_null])] - e = [m2_expr.ExprAff(zf, m2_expr.ExprCond(b, m2_expr.ExprInt_from(zf, 0), - m2_expr.ExprInt_from(zf, 1)))] +def bsf(ir, instr, a, b): + return bsr_bsf(ir, instr, a, b, "bsf") - e_do = [] - e_do.append(m2_expr.ExprAff(a, m2_expr.ExprOp('bsr', b))) - e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip)) - e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(b, lbl_do, lbl_skip))) - return e, [irbloc(lbl_do.name, [e_do])] +def bsr(ir, instr, a, b): + return bsr_bsf(ir, instr, a, b, "bsr") def arpl(ir, instr, a, b): diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index a730b1d8..007f8378 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -59,6 +59,10 @@ class TranslatorC(Translator): if expr.op == 'parity': return "parity(%s&0x%x)" % (cls.from_expr(expr.args[0]), size2mask(expr.args[0].size)) + elif expr.op in ['bsr', 'bsf']: + return "x86_%s(%s, 0x%x)" % (expr.op, + cls.from_expr(expr.args[0]), + expr.args[0].size) elif expr.op == '!': return "(~ %s)&0x%x" % (cls.from_expr(expr.args[0]), size2mask(expr.args[0].size)) @@ -102,10 +106,6 @@ class TranslatorC(Translator): cls.from_expr(expr.args[0]), cls.from_expr(expr.args[1]), size2mask(expr.args[0].size)) - elif expr.op in ['bsr', 'bsf']: - return 'my_%s(%s, %s)' % (expr.op, - cls.from_expr(expr.args[0]), - cls.from_expr(expr.args[1])) elif (expr.op.startswith('cpuid') or expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]): diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index 188f0372..057c10be 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -915,26 +915,29 @@ int rcr_cf_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf { return rcl_cf_op(size, a, size+1-b, cf); } -unsigned int my_bsr(unsigned int a, unsigned int b) + +unsigned int x86_bsr(uint64_t src, unsigned int size) { int i; - for (i=31; i>=0; i--){ - if (b & (1<<i)) + for (i=size-1; i>=0; i--){ + if (src & (1<<i)) return i; } - return a; + fprintf(stderr, "sanity check error bsr\n"); + exit(0); } -unsigned int my_bsf(unsigned int a, unsigned int b) +unsigned int x86_bsf(uint64_t src, unsigned int size) { int i; - for (i=0; i<32; i++){ - if (b & (1<<i)) + for (i=0; i<size; i++){ + if (src & (1<<i)) return i; } - return a; + fprintf(stderr, "sanity check error bsf\n"); + exit(0); } diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py index 1089bba4..11b9b10e 100644 --- a/test/ir/ir2C.py +++ b/test/ir/ir2C.py @@ -37,7 +37,7 @@ class TestIrIr2C(unittest.TestCase): self.translationTest( ExprOp('-', *args[:2]), r'(((0x0&0xffffffff) - (0x1&0xffffffff))&0xffffffff)') self.translationTest( - ExprOp('bsr', *args[:2]), r'my_bsr(0x0, 0x1)') + ExprOp('bsr', *args[:1]), r'x86_bsr(0x0, 0x20)') self.translationTest( ExprOp('cpuid0', *args[:2]), r'cpuid0(0x0, 0x1)') self.translationTest( diff --git a/test/samples/x86_32/bsr_bsf.S b/test/samples/x86_32/bsr_bsf.S new file mode 100644 index 00000000..0f915ed1 --- /dev/null +++ b/test/samples/x86_32/bsr_bsf.S @@ -0,0 +1,42 @@ +main: + ;; BSF + ;; standard case + MOV ECX, 0xF0000004 + MOV EAX, 0x0 + BSF EAX, ECX + JZ bad + CMP EAX, 2 + JNZ bad + + + ;; case undef + MOV ECX, 0x0 + MOV EAX, 0x1337beef + BSF EAX, ECX + JNZ bad + CMP EAX, 0x1337beef + JNZ bad + + ;; BSR + ;; standard case + MOV ECX, 0x4000000F + MOV EAX, 0x0 + BSR EAX, ECX + JZ bad + CMP EAX, 30 + JNZ bad + + + ;; case undef + MOV ECX, 0x0 + MOV EAX, 0x1337beef + BSR EAX, ECX + JNZ bad + CMP EAX, 0x1337beef + JNZ bad + + RET + +bad: + INT 0x3 + RET diff --git a/test/test_all.py b/test/test_all.py index a2fd6df3..1e5de442 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -68,7 +68,9 @@ class SemanticTestAsm(RegressionTest): class SemanticTestExec(RegressionTest): """Execute a binary file""" - launcher_dct = {("PE", "x86_64"): "sandbox_pe_x86_64.py"} + launcher_dct = {("PE", "x86_64"): "sandbox_pe_x86_64.py", + ("PE", "x86_32"): "sandbox_pe_x86_32.py", + } launcher_base = os.path.join("..", "example", "jitter") def __init__(self, arch, container, address, *args, **kwargs): @@ -86,9 +88,13 @@ class SemanticTestExec(RegressionTest): test_x86_64_mul_div = SemanticTestAsm("x86_64", "PE", ["mul_div"]) +test_x86_32_bsr_bsf = SemanticTestAsm("x86_32", "PE", ["bsr_bsf"]) testset += test_x86_64_mul_div +testset += test_x86_32_bsr_bsf testset += SemanticTestExec("x86_64", "PE", 0x401000, ["mul_div"], depends=[test_x86_64_mul_div]) +testset += SemanticTestExec("x86_32", "PE", 0x401000, ["bsr_bsf"], + depends=[test_x86_32_bsr_bsf]) ## Core for script in ["interval.py", |