diff options
| -rw-r--r-- | miasm2/analysis/dse.py | 3 | ||||
| -rw-r--r-- | miasm2/arch/x86/ctype.py | 12 | ||||
| -rw-r--r-- | miasm2/arch/x86/jit.py | 9 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 115 | ||||
| -rw-r--r-- | miasm2/core/objc.py | 54 | ||||
| -rw-r--r-- | miasm2/expression/simplifications_common.py | 11 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr_py.c | 2 | ||||
| -rwxr-xr-x | test/arch/x86/unit/mn_pushpop.py | 195 | ||||
| -rw-r--r-- | test/expression/simplifications.py | 5 |
9 files changed, 335 insertions, 71 deletions
diff --git a/miasm2/analysis/dse.py b/miasm2/analysis/dse.py index 7fdc5035..56ed3292 100644 --- a/miasm2/analysis/dse.py +++ b/miasm2/analysis/dse.py @@ -185,6 +185,9 @@ class DSEEngine(object): self.jitter.jit.set_options(max_exec_per_call=1, jit_maxline=1) self.jitter.exec_cb = self.callback + # Clean jit cache to avoid multi-line basic blocks already jitted + self.jitter.jit.lbl2jitbloc.clear() + def attach(self, emulator): """Attach the DSE to @emulator @emulator: jitload (or API equivalent) instance""" diff --git a/miasm2/arch/x86/ctype.py b/miasm2/arch/x86/ctype.py index 0d8cd924..5e16f945 100644 --- a/miasm2/arch/x86/ctype.py +++ b/miasm2/arch/x86/ctype.py @@ -1,10 +1,12 @@ -from miasm2.core.objc import CLeafTypes, ObjCDecl +from miasm2.core.objc import CLeafTypes, ObjCDecl, PADDING_TYPE_NAME from miasm2.core.ctypesmngr import CTypeId, CTypePtr class CTypeAMD64_unk(CLeafTypes): """Define C types sizes/alignement for x86_64 architecture""" + obj_pad = ObjCDecl(PADDING_TYPE_NAME, 1, 1) # __padding__ is size 1/align 1 + obj_char = ObjCDecl("char", 1, 1) obj_short = ObjCDecl("short", 2, 2) obj_int = ObjCDecl("int", 4, 4) @@ -25,6 +27,8 @@ class CTypeAMD64_unk(CLeafTypes): def __init__(self): self.types = { + CTypeId(PADDING_TYPE_NAME): self.obj_pad, + CTypeId('char'): self.obj_char, CTypeId('short'): self.obj_short, CTypeId('int'): self.obj_int, @@ -68,7 +72,9 @@ class CTypeAMD64_unk(CLeafTypes): class CTypeX86_unk(CLeafTypes): - """Define C types sizes/alignement for x86_64 architecture""" + """Define C types sizes/alignement for x86_32 architecture""" + + obj_pad = ObjCDecl(PADDING_TYPE_NAME, 1, 1) # __padding__ is size 1/align 1 obj_char = ObjCDecl("char", 1, 1) obj_short = ObjCDecl("short", 2, 2) @@ -90,6 +96,8 @@ class CTypeX86_unk(CLeafTypes): def __init__(self): self.types = { + CTypeId(PADDING_TYPE_NAME): self.obj_pad, + CTypeId('char'): self.obj_char, CTypeId('short'): self.obj_short, CTypeId('int'): self.obj_int, diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py index 9acab5ed..d39f1f38 100644 --- a/miasm2/arch/x86/jit.py +++ b/miasm2/arch/x86/jit.py @@ -80,6 +80,15 @@ class jitter_x86_32(jitter): def ir_archbloc_fix_regs_for_mode(self, irblock, attrib=64): return self.orig_irbloc_fix_regs_for_mode(irblock, 64) + def push_uint16_t(self, value): + self.cpu.ESP -= self.ir_arch.sp.size / 8 + self.vm.set_mem(self.cpu.ESP, pck16(value)) + + def pop_uint16_t(self): + value = upck16(self.vm.get_mem(self.cpu.ESP, self.ir_arch.sp.size / 8)) + self.cpu.ESP += self.ir_arch.sp.size / 8 + return value + def push_uint32_t(self, value): self.cpu.ESP -= self.ir_arch.sp.size / 8 self.vm.set_mem(self.cpu.ESP, pck32(value)) diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index ca5b3f8d..b3dfb3ef 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -693,17 +693,14 @@ def push_gen(ir, instr, src, size): raise ValueError('bad size stacker!') if src.size < size: src = src.zeroExtend(size) - elif src.size == size: - pass - else: - raise ValueError('strange arg size') + off_size = src.size sp = mRSP[instr.mode] - new_sp = sp - m2_expr.ExprInt(size / 8, sp.size) + new_sp = sp - m2_expr.ExprInt(off_size / 8, sp.size) e.append(m2_expr.ExprAff(sp, new_sp)) if ir.do_stk_segm: new_sp = m2_expr.ExprOp('segm', SS, new_sp) - e.append(m2_expr.ExprAff(ir.ExprMem(new_sp, size), + e.append(m2_expr.ExprAff(ir.ExprMem(new_sp, off_size), src)) return e, [] @@ -722,7 +719,7 @@ def pop_gen(ir, instr, src, size): raise ValueError('bad size stacker!') sp = mRSP[instr.mode] - new_sp = sp + m2_expr.ExprInt(size / 8, sp.size) + new_sp = sp + m2_expr.ExprInt(src.size / 8, sp.size) # don't generate ESP incrementation on POP ESP if src != ir.sp: e.append(m2_expr.ExprAff(sp, new_sp)) @@ -937,25 +934,34 @@ def cmps(ir, instr, 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 = ir.ExprMem(mRDI[instr.mode][:s], size) - b = ir.ExprMem(mRSI[instr.mode][:s], size) + src1 = mRSI[instr.mode][:instr.v_admode()] + src2 = mRDI[instr.mode][:instr.v_admode()] + + if ir.do_str_segm: + if instr.additional_info.g2.value: + raise NotImplementedError("add segm support") + src1_sgm = m2_expr.ExprOp('segm', DS, src1) + src2_sgm = m2_expr.ExprOp('segm', ES, src2) + else: + src1_sgm = src1 + src2_sgm = src2 + + offset = m2_expr.ExprInt(size / 8, src1.size) + + e, _ = l_cmp(ir, instr, + ir.ExprMem(src1_sgm, size), + ir.ExprMem(src2_sgm, size)) - e, _ = l_cmp(ir, instr, b, a) e0 = [] - e0.append(m2_expr.ExprAff(a.arg, - a.arg + m2_expr.ExprInt(size / 8, a.arg.size))) - e0.append(m2_expr.ExprAff(b.arg, - b.arg + m2_expr.ExprInt(size / 8, b.arg.size))) + e0.append(m2_expr.ExprAff(src1, src1 + offset)) + e0.append(m2_expr.ExprAff(src2, src2 + offset)) e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)]) e1 = [] - e1.append(m2_expr.ExprAff(a.arg, - a.arg - m2_expr.ExprInt(size / 8, a.arg.size))) - e1.append(m2_expr.ExprAff(b.arg, - b.arg - m2_expr.ExprInt(size / 8, b.arg.size))) + e1.append(m2_expr.ExprAff(src1, src1 - offset)) + e1.append(m2_expr.ExprAff(src2, src2 - offset)) e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)]) @@ -969,20 +975,28 @@ def scas(ir, instr, 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 = ir.ExprMem(mRDI[instr.mode][:s], size) + src = mRDI[instr.mode][:instr.v_admode()] - e, extra = l_cmp(ir, instr, mRAX[instr.mode][:size], a) + if ir.do_str_segm: + if instr.additional_info.g2.value: + raise NotImplementedError("add segm support") + src_sgm = m2_expr.ExprOp('segm', ES, src) + else: + src_sgm = src + + offset = m2_expr.ExprInt(size / 8, src.size) + e, extra = l_cmp(ir, instr, + mRAX[instr.mode][:size], + ir.ExprMem(src_sgm, size)) e0 = [] - e0.append(m2_expr.ExprAff(a.arg, - a.arg + m2_expr.ExprInt(size / 8, a.arg.size))) + e0.append(m2_expr.ExprAff(src, src + offset)) + e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)]) e1 = [] - e1.append(m2_expr.ExprAff(a.arg, - a.arg - m2_expr.ExprInt(size / 8, a.arg.size))) + e1.append(m2_expr.ExprAff(src, src - offset)) e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)]) @@ -1081,12 +1095,11 @@ pa_regs = [ def pusha_gen(ir, instr, size): e = [] + cur_sp = mRSP[instr.mode] for i, reg in enumerate(pa_regs): - stk_ptr = mRSP[instr.mode] + \ - m2_expr.ExprInt(-(reg[size].size / 8) * (i + 1), instr.mode) - e.append(m2_expr.ExprAff(ir.ExprMem( - stk_ptr, reg[size].size), reg[size])) - e.append(m2_expr.ExprAff(mRSP[instr.mode], stk_ptr)) + stk_ptr = cur_sp + m2_expr.ExprInt(-(size / 8) * (i + 1), instr.mode) + e.append(m2_expr.ExprAff(ir.ExprMem(stk_ptr, size), reg[size])) + e.append(m2_expr.ExprAff(cur_sp, stk_ptr)) return e, [] @@ -1100,16 +1113,15 @@ def pushad(ir, instr): def popa_gen(ir, instr, size): e = [] + cur_sp = mRSP[instr.mode] for i, reg in enumerate(reversed(pa_regs)): if reg == mRSP: continue - stk_ptr = mRSP[instr.mode] + \ - m2_expr.ExprInt((reg[size].size / 8) * i, instr.mode) - e.append(m2_expr.ExprAff(reg[size], ir.ExprMem(stk_ptr, instr.mode))) + stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * i, instr.mode) + e.append(m2_expr.ExprAff(reg[size], ir.ExprMem(stk_ptr, size))) - stk_ptr = mRSP[instr.mode] + \ - m2_expr.ExprInt((instr.mode / 8) * (i + 1), instr.mode) - e.append(m2_expr.ExprAff(mRSP[instr.mode], stk_ptr)) + stk_ptr = cur_sp + m2_expr.ExprInt((size / 8) * (i + 1), instr.mode) + e.append(m2_expr.ExprAff(cur_sp, stk_ptr)) return e, [] @@ -1726,29 +1738,34 @@ def movs(ir, instr, 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) - a = mRDI[instr.mode][:instr.v_admode()] - b = mRSI[instr.mode][:instr.v_admode()] + dst = mRDI[instr.mode][:instr.v_admode()] + src = mRSI[instr.mode][:instr.v_admode()] e = [] - src = b - dst = a if ir.do_str_segm: if instr.additional_info.g2.value: raise NotImplementedError("add segm support") - src = m2_expr.ExprOp('segm', DS, src) - dst = m2_expr.ExprOp('segm', ES, dst) - e.append(m2_expr.ExprAff(ir.ExprMem(dst, size), - ir.ExprMem(src, size))) + src_sgm = m2_expr.ExprOp('segm', DS, src) + dst_sgm = m2_expr.ExprOp('segm', ES, dst) + + else: + src_sgm = src + dst_sgm = dst + + offset = m2_expr.ExprInt(size / 8, src.size) + + e.append(m2_expr.ExprAff(ir.ExprMem(dst_sgm, size), + ir.ExprMem(src_sgm, size))) e0 = [] - e0.append(m2_expr.ExprAff(a, a + m2_expr.ExprInt(size / 8, a.size))) - e0.append(m2_expr.ExprAff(b, b + m2_expr.ExprInt(size / 8, b.size))) + e0.append(m2_expr.ExprAff(src, src + offset)) + e0.append(m2_expr.ExprAff(dst, dst + offset)) e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)]) e1 = [] - e1.append(m2_expr.ExprAff(a, a - m2_expr.ExprInt(size / 8, a.size))) - e1.append(m2_expr.ExprAff(b, b - m2_expr.ExprInt(size / 8, b.size))) + e1.append(m2_expr.ExprAff(src, src - offset)) + e1.append(m2_expr.ExprAff(dst, dst - offset)) e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next)) e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)]) diff --git a/miasm2/core/objc.py b/miasm2/core/objc.py index 9ae16291..917d0ea9 100644 --- a/miasm2/core/objc.py +++ b/miasm2/core/objc.py @@ -15,6 +15,8 @@ from miasm2.core.ctypesmngr import CTypeUnion, CTypeStruct, CTypeId, CTypePtr,\ CTypeArray, CTypeOp, CTypeSizeof, CTypeEnum, CTypeFunc, CTypeEllipsis +PADDING_TYPE_NAME = "___padding___" + class ObjC(object): """Generic ObjC""" @@ -618,14 +620,18 @@ class CTypeAnalyzer(ExprReducer): Return the C type(s) of a native Miasm expression """ - def __init__(self, expr_types, types_mngr): + def __init__(self, expr_types, types_mngr, enforce_strict_access=True): """Init TypeAnalyzer @expr_types: a dictionnary linking ID names to their types @types_mngr: types manager + @enforce_strict_access: If false, get type even on expression + pointing to a middle of an object. If true, raise exception if such a + pointer is encountered """ self.expr_types = expr_types self.types_mngr = types_mngr + self.enforce_strict_access = enforce_strict_access def updt_expr_types(self, expr_types): """Update expr_types @@ -676,12 +682,13 @@ class CTypeAnalyzer(ExprReducer): obj = self.get_typeof( base_type.objtype, sub_offset, deref, lvl + 1) new_type = obj + elif isinstance(base_type, ObjCDecl): - if offset != 0: + if self.enforce_strict_access and offset != 0: return [] obj = ObjCPtr(base_type, void_type.align, void_type.size) - new_type = [obj] + elif isinstance(base_type, ObjCUnion): out = [] if offset == 0 and not deref: @@ -697,6 +704,8 @@ class CTypeAnalyzer(ExprReducer): out += new_type new_type = out elif isinstance(base_type, ObjCPtr): + if self.enforce_strict_access: + assert offset % base_type.size == 0 obj = ObjCPtr(base_type, void_type.align, void_type.size) new_type = [obj] else: @@ -781,7 +790,8 @@ class CTypeAnalyzer(ExprReducer): r_target = ptr_target.objtype # ptr_target: ptr<elem> # r_target: elem - if r_target.size != node.expr.size / 8: + if (not(self.enforce_strict_access) or + r_target.size != node.expr.size / 8): continue found.append(r_target) if not found: @@ -960,21 +970,15 @@ class ExprToAccessC(ExprReducer): finalobj = sname out.append(finalobj) new_type = out + elif isinstance(base_type, ObjCPtr): elem_num = offset / base_type.size + if self.enforce_strict_access: + assert offset % base_type.size == 0 - if elem_num == 0: - if self.enforce_strict_access: - assert offset % base_type.size == 0 - nobj = CGenArray(cgenobj, elem_num, - void_type.align, void_type.size) - new_type = [(nobj)] - else: - if self.enforce_strict_access: - assert offset % base_type.size == 0 - nobj = CGenArray(cgenobj, elem_num, - void_type.align, void_type.size) - new_type = [(nobj)] + nobj = CGenArray(cgenobj, elem_num, + void_type.align, void_type.size) + new_type = [(nobj)] else: raise NotImplementedError("deref type %r" % base_type) @@ -1348,6 +1352,11 @@ class CTypesManager(object): """Retrieve a void* objc""" return self.leaf_types.types.get(CTypePtr(CTypeId('void'))) + @property + def padding(self): + """Retrieve a padding ctype""" + return CTypeId(PADDING_TYPE_NAME) + def _get_objc(self, type_id, resolved=None, to_fix=None, lvl=0): if resolved is None: resolved = {} @@ -1378,11 +1387,19 @@ class CTypesManager(object): align_max, size_max = 0, 0 offset, align_max = 0, 1 + pad_index = 0 for name, field in type_id.fields: objc = self._get_objc(field, resolved, to_fix, lvl + 1) resolved[field] = objc align_max = max(align_max, objc.align) - offset = self.struct_compute_field_offset(objc, offset) + new_offset = self.struct_compute_field_offset(objc, offset) + if new_offset - offset: + pad_name = "__PAD__%d__" % pad_index + pad_index += 1 + size = new_offset - offset + pad_objc = self._get_objc(CTypeArray(self.padding, size), resolved, to_fix, lvl + 1) + out.add_field(pad_name, pad_objc, offset, pad_objc.size) + offset = new_offset out.add_field(name, objc, offset, objc.size) offset += objc.size @@ -1573,7 +1590,8 @@ class CHandler(object): simplify_c=access_simplifier, enforce_strict_access=True): self.exprc2expr = self.exprCToExpr_cls(expr_types, types_mngr) - self.type_analyzer = self.cTypeAnalyzer_cls(expr_types, types_mngr) + self.type_analyzer = self.cTypeAnalyzer_cls(expr_types, types_mngr, + enforce_strict_access) self.access_c_gen = self.exprToAccessC_cls(expr_types, types_mngr, enforce_strict_access) diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 01db7597..eb9d0958 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -542,6 +542,17 @@ def simp_compose(e_s, e): new_e = args[0].arg >> ExprInt(args[0].start, args[0].arg.size) return new_e + # {@X[base + i] 0 X, @Y[base + i + X] X (X + Y)} => @(X+Y)[base + i] + for i, arg in enumerate(args[:-1]): + nxt = args[i + 1] + if arg.is_mem() and nxt.is_mem(): + gap = e_s(nxt.arg - arg.arg) + if gap.is_int() and int(gap) == arg.size / 8: + args = args[:i] + [ExprMem(arg.arg, + arg.size + nxt.size)] + args[i + 2:] + return ExprCompose(*args) + + # Compose with ExprCond with integers for src1/src2 and intergers => # propagage integers # {XXX?(0x0,0x1)?(0x0,0x1),0,8, 0x0,8,32} => XXX?(int1, int2) diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c index 5f25b707..35633b7f 100644 --- a/miasm2/jitter/vm_mngr_py.c +++ b/miasm2/jitter/vm_mngr_py.c @@ -235,7 +235,7 @@ PyObject* vm_get_mem(VmMngr* self, PyObject* args) ret = vm_read_mem(&self->vm_mngr, addr, &buf_out, size); if (ret < 0) { - RAISE(PyExc_TypeError,"Cannot find address"); + RAISE(PyExc_RuntimeError,"Cannot find address"); } obj_out = PyString_FromStringAndSize(buf_out, size); diff --git a/test/arch/x86/unit/mn_pushpop.py b/test/arch/x86/unit/mn_pushpop.py index ffcc3fa5..7ac400c0 100755 --- a/test/arch/x86/unit/mn_pushpop.py +++ b/test/arch/x86/unit/mn_pushpop.py @@ -39,6 +39,7 @@ class Test_PUSHAD_32(Asm_Test_32): ''' def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x4 * 8 buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x4 * 8) assert(buf == self.buf) @@ -65,6 +66,7 @@ class Test_PUSHA_32(Asm_Test_32): ''' def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x2 * 8 buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x2 * 8) assert(buf == self.buf) @@ -91,6 +93,7 @@ class Test_PUSHA_16(Asm_Test_16): ''' def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x2 * 8 buf = self.myjit.vm.get_mem(self.myjit.cpu.SP, 0x2 * 8) assert(buf == self.buf) @@ -117,12 +120,202 @@ class Test_PUSHAD_16(Asm_Test_16): ''' def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x4 * 8 buf = self.myjit.vm.get_mem(self.myjit.cpu.SP, 0x4 * 8) assert(buf == self.buf) +class Test_PUSH_mode32_32(Asm_Test_32): + MYSTRING = "test push mode32 32" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + init_regs(self) + self.buf = "" + self.buf += pck32(0x11223344) + + TXT = ''' + main: + PUSH 0x11223344 + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x4 + buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x4) + assert(buf == self.buf) + + +class Test_PUSH_mode32_16(Asm_Test_32): + MYSTRING = "test push mode32 16" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + init_regs(self) + self.buf = "" + self.buf += pck16(0x1122) + + TXT = ''' + main: + PUSHW 0x1122 + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x2 + buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x2) + assert(buf == self.buf) + + +class Test_PUSH_mode16_16(Asm_Test_16): + MYSTRING = "test push mode16 16" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + init_regs(self) + self.buf = "" + self.buf += pck16(0x1122) + + TXT = ''' + main: + PUSHW 0x1122 + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x2 + buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x2) + assert(buf == self.buf) + + +class Test_PUSH_mode16_32(Asm_Test_16): + MYSTRING = "test push mode16 32" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + init_regs(self) + self.buf = "" + self.buf += pck32(0x11223344) + + TXT = ''' + main: + .byte 0x66, 0x68, 0x44, 0x33, 0x22, 0x11 + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin - 0x4 + buf = self.myjit.vm.get_mem(self.myjit.cpu.ESP, 0x4) + assert(buf == self.buf) + + +class Test_POP_mode32_32(Asm_Test_32): + MYSTRING = "test pop mode32 32" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + self.value = 0x11223344 + self.myjit.push_uint32_t(self.value) + init_regs(self) + + TXT = ''' + main: + POP EAX + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin + 0x4 + assert self.myjit.cpu.EAX == self.value + + +class Test_POP_mode32_16(Asm_Test_32): + MYSTRING = "test pop mode32 16" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + self.value = 0x1122 + self.myjit.push_uint16_t(self.value) + init_regs(self) + + TXT = ''' + main: + POPW AX + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin + 0x2 + assert self.myjit.cpu.AX == self.value + + +class Test_POP_mode16_16(Asm_Test_16): + MYSTRING = "test pop mode16 16" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + self.value = 0x1122 + self.myjit.push_uint16_t(self.value) + init_regs(self) + + TXT = ''' + main: + POPW AX + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin + 0x2 + assert self.myjit.cpu.AX == self.value + + +class Test_POP_mode16_32(Asm_Test_16): + MYSTRING = "test pop mode16 32" + + def prepare(self): + self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr) + + def test_init(self): + self.value = 0x11223344 + self.myjit.cpu.SP -= 0x4 + self.myjit.vm.set_mem(self.myjit.cpu.SP, pck32(self.value)) + init_regs(self) + + TXT = ''' + main: + POP EAX + JMP lbl_ret + ''' + + def check(self): + assert self.myjit.cpu.ESP == self.stk_origin + 0x4 + assert self.myjit.cpu.EAX == self.value + + if __name__ == "__main__": [test(*sys.argv[1:])() for test in [Test_PUSHA_16, Test_PUSHA_32, - Test_PUSHAD_16, Test_PUSHAD_32 + Test_PUSHAD_16, Test_PUSHAD_32, + Test_PUSH_mode32_32, + Test_PUSH_mode32_16, + Test_PUSH_mode16_16, + Test_PUSH_mode16_32, + Test_POP_mode32_32, + Test_POP_mode32_16, + Test_POP_mode16_16, + Test_POP_mode16_32, ] ] diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py index 60c328dc..efabddb5 100644 --- a/test/expression/simplifications.py +++ b/test/expression/simplifications.py @@ -314,6 +314,11 @@ to_test = [(ExprInt(1, 32) - ExprInt(1, 32), ExprInt(0, 32)), (ExprOp("imod", ExprInt(0x0123, 16), ExprInt(0xfffb, 16))[:8], ExprInt(0x01, 8)), + (ExprCompose(ExprInt(0x0123, 16), ExprMem(a + ExprInt(0x40, a.size), 16), + ExprMem(a + ExprInt(0x42, a.size), 16), ExprInt(0x0321, 16)), + ExprCompose(ExprInt(0x0123, 16), ExprMem(a + ExprInt(0x40, a.size), 32), + ExprInt(0x0321, 16))), + ] for e, e_check in to_test[:]: |