diff options
| -rw-r--r-- | example/jitter/unpack_upx.py | 5 | ||||
| -rw-r--r-- | miasm2/core/cpu.py | 4 | ||||
| -rw-r--r-- | miasm2/core/locationdb.py | 12 | ||||
| -rw-r--r-- | miasm2/core/parse_asm.py | 3 | ||||
| -rw-r--r-- | miasm2/expression/expression_reduce.py | 164 | ||||
| -rw-r--r-- | miasm2/expression/simplifications.py | 2 | ||||
| -rw-r--r-- | miasm2/expression/simplifications_common.py | 19 |
7 files changed, 163 insertions, 46 deletions
diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py index 665fa15a..6bcef1ab 100644 --- a/example/jitter/unpack_upx.py +++ b/example/jitter/unpack_upx.py @@ -55,12 +55,11 @@ mdis = sb.machine.dis_engine(sb.jitter.bs) mdis.dont_dis_nulstart_bloc = True asmcfg = mdis.dis_multiblock(sb.entry_point) -leaves = list(asmcfg.get_bad_blocks_predecessors()) +leaves = list(asmcfg.get_bad_blocks()) assert(len(leaves) == 1) l = leaves.pop() logging.info(l) - -end_offset = mdis.loc_db.get_location_offset(l) +end_offset = mdis.loc_db.get_location_offset(l.loc_key) logging.info('final offset') logging.info(hex(end_offset)) diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py index bd30e0f8..4605a033 100644 --- a/miasm2/core/cpu.py +++ b/miasm2/core/cpu.py @@ -1028,6 +1028,10 @@ class instruction(object): if '_' in names: fixed_expr[exprloc] = self.get_asm_next_offset(exprloc) continue + arg_int = symbols.get_location_offset(loc_key) + if arg_int is not None: + fixed_expr[exprloc] = m2_expr.ExprInt(arg_int, exprloc.size) + continue if not names: raise ValueError('Unresolved symbol: %r' % exprloc) diff --git a/miasm2/core/locationdb.py b/miasm2/core/locationdb.py index 21e2d713..7d84c491 100644 --- a/miasm2/core/locationdb.py +++ b/miasm2/core/locationdb.py @@ -214,7 +214,7 @@ class LocationDB(object): raised. Otherwise: If a location with @offset or @name already exists, the corresponding - LocKey will be returned. + LocKey may be updated and will be returned. """ # Deprecation handling @@ -262,14 +262,8 @@ class LocationDB(object): elif offset_loc_key is not None: if name is not None: - # This is an error. Check for already known name are checked above - raise ValueError( - "Location with offset 0x%x already exists." - "To add a name to this location, use the dedicated API" - "'add_location_name(%r, %r)'" % ( - offset_loc_key, - name - )) + # Check for already known name are checked above + return self.add_location_name(offset_loc_key, name) # Offset already known, no name specified return offset_loc_key diff --git a/miasm2/core/parse_asm.py b/miasm2/core/parse_asm.py index e60c8ca7..7ddf838c 100644 --- a/miasm2/core/parse_asm.py +++ b/miasm2/core/parse_asm.py @@ -198,9 +198,6 @@ def parse_txt(mnemo, attrib, txt, loc_db=None): line = line[:line.find(';')] line = line.strip(' ').strip('\t') instr = mnemo.fromstring(line, loc_db, attrib) - - if instr.dstflow(): - instr.dstflow2label(loc_db) lines.append(instr) asmblock.log_asmblock.info("___pre asm oki___") diff --git a/miasm2/expression/expression_reduce.py b/miasm2/expression/expression_reduce.py index 22ac8d8d..ab38dfdb 100644 --- a/miasm2/expression/expression_reduce.py +++ b/miasm2/expression/expression_reduce.py @@ -14,38 +14,128 @@ log_reduce.addHandler(console_handler) log_reduce.setLevel(logging.WARNING) + class ExprNode(object): """Clone of Expression object with additionnal information""" def __init__(self, expr): self.expr = expr - # Generic field to store custom node information - self.info = None - self.arg, self.args = None, None - self.cond, self.src1, self.src2 = None, None, None + +class ExprNodeInt(ExprNode): + def __init__(self, expr): + assert expr.is_int() + super(ExprNodeInt, self).__init__(expr) + self.arg = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: + out = str(self.expr) + return out + + +class ExprNodeId(ExprNode): + def __init__(self, expr): + assert expr.is_id() + super(ExprNodeId, self).__init__(expr) + self.arg = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: + out = str(self.expr) + return out + + +class ExprNodeLoc(ExprNode): + def __init__(self, expr): + assert expr.is_loc() + super(ExprNodeLoc, self).__init__(expr) + self.arg = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: + out = str(self.expr) + return out + + +class ExprNodeMem(ExprNode): + def __init__(self, expr): + assert expr.is_mem() + super(ExprNodeMem, self).__init__(expr) + self.arg = None def __repr__(self): - expr = self.expr if self.info is not None: out = repr(self.info) - elif expr.is_int() or expr.is_id() or expr.is_loc(): - out = str(expr) - elif expr.is_mem(): + else: out = "@%d[%r]" % (self.expr.size, self.arg) - elif expr.is_slice(): - out = "%r[%d:%d]" % (self.arg, expr.start, expr.stop) - elif expr.is_op(): + return out + + +class ExprNodeOp(ExprNode): + def __init__(self, expr): + assert expr.is_op() + super(ExprNodeOp, self).__init__(expr) + self.args = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: if len(self.args) == 1: - out = "(%s(%r))" % (expr.op, self.args[0]) + out = "(%s(%r))" % (self.expr.op, self.args[0]) else: - out = "(%s)" % expr.op.join(repr(arg) for arg in self.args) - elif expr.is_compose(): + out = "(%s)" % self.expr.op.join(repr(arg) for arg in self.args) + return out + + +class ExprNodeSlice(ExprNode): + def __init__(self, expr): + assert expr.is_slice() + super(ExprNodeSlice, self).__init__(expr) + self.arg = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: + out = "%r[%d:%d]" % (self.arg, self.expr.start, self.expr.stop) + return out + + +class ExprNodeCompose(ExprNode): + def __init__(self, expr): + assert expr.is_compose() + super(ExprNodeCompose, self).__init__(expr) + self.args = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) + else: out = "{%s}" % ', '.join(repr(arg) for arg in self.args) - elif expr.is_cond(): - out = "(%r?%r:%r)" % (self.cond, self.src1, self.src2) + return out + + +class ExprNodeCond(ExprNode): + def __init__(self, expr): + assert expr.is_cond() + super(ExprNodeCond, self).__init__(expr) + self.cond = None + self.src1 = None + self.src2 = None + + def __repr__(self): + if self.info is not None: + out = repr(self.info) else: - raise TypeError("Unknown node Type %r", type(expr)) + out = "(%r?%r:%r)" % (self.cond, self.src1, self.src2) return out @@ -76,22 +166,30 @@ class ExprReducer(object): @expr: Expression to analyze """ - if isinstance(expr, (ExprId, ExprLoc, ExprInt)): - node = ExprNode(expr) - elif isinstance(expr, (ExprMem, ExprSlice)): + if isinstance(expr, ExprId): + node = ExprNodeId(expr) + elif isinstance(expr, ExprLoc): + node = ExprNodeLoc(expr) + elif isinstance(expr, ExprInt): + node = ExprNodeInt(expr) + elif isinstance(expr, ExprMem): + son = self.expr2node(expr.arg) + node = ExprNodeMem(expr) + node.arg = son + elif isinstance(expr, ExprSlice): son = self.expr2node(expr.arg) - node = ExprNode(expr) + node = ExprNodeSlice(expr) node.arg = son elif isinstance(expr, ExprOp): sons = [self.expr2node(arg) for arg in expr.args] - node = ExprNode(expr) + node = ExprNodeOp(expr) node.args = sons elif isinstance(expr, ExprCompose): sons = [self.expr2node(arg) for arg in expr.args] - node = ExprNode(expr) + node = ExprNodeCompose(expr) node.args = sons elif isinstance(expr, ExprCond): - node = ExprNode(expr) + node = ExprNodeCond(expr) node.cond = self.expr2node(expr.cond) node.src1 = self.expr2node(expr.src1) node.src2 = self.expr2node(expr.src2) @@ -118,15 +216,19 @@ class ExprReducer(object): expr = node.expr log_reduce.debug("\t" * lvl + "Reduce...: %s", node.expr) - if isinstance(expr, (ExprId, ExprInt, ExprLoc)): - pass + if isinstance(expr, ExprId): + node = ExprNodeId(expr) + elif isinstance(expr, ExprInt): + node = ExprNodeInt(expr) + elif isinstance(expr, ExprLoc): + node = ExprNodeLoc(expr) elif isinstance(expr, ExprMem): arg = self.categorize(node.arg, lvl=lvl + 1, **kwargs) - node = ExprNode(ExprMem(arg.expr, expr.size)) + node = ExprNodeMem(ExprMem(arg.expr, expr.size)) node.arg = arg elif isinstance(expr, ExprSlice): arg = self.categorize(node.arg, lvl=lvl + 1, **kwargs) - node = ExprNode(ExprSlice(arg.expr, expr.start, expr.stop)) + node = ExprNodeSlice(ExprSlice(arg.expr, expr.start, expr.stop)) node.arg = arg elif isinstance(expr, ExprOp): new_args = [] @@ -134,7 +236,7 @@ class ExprReducer(object): new_a = self.categorize(arg, lvl=lvl + 1, **kwargs) assert new_a.expr.size == arg.expr.size new_args.append(new_a) - node = ExprNode(ExprOp(expr.op, *[x.expr for x in new_args])) + node = ExprNodeOp(ExprOp(expr.op, *[x.expr for x in new_args])) node.args = new_args expr = node.expr elif isinstance(expr, ExprCompose): @@ -145,13 +247,13 @@ class ExprReducer(object): new_args.append(arg) new_expr_args.append(arg.expr) new_expr = ExprCompose(*new_expr_args) - node = ExprNode(new_expr) + node = ExprNodeCompose(new_expr) node.args = new_args elif isinstance(expr, ExprCond): cond = self.categorize(node.cond, lvl=lvl + 1, **kwargs) src1 = self.categorize(node.src1, lvl=lvl + 1, **kwargs) src2 = self.categorize(node.src2, lvl=lvl + 1, **kwargs) - node = ExprNode(ExprCond(cond.expr, src1.expr, src2.expr)) + node = ExprNodeCond(ExprCond(cond.expr, src1.expr, src2.expr)) node.cond, node.src1, node.src2 = cond, src1, src2 else: raise TypeError("Unknown Expr Type %r", type(expr)) diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py index 712488e3..d3628ae8 100644 --- a/miasm2/expression/simplifications.py +++ b/miasm2/expression/simplifications.py @@ -42,6 +42,8 @@ class ExpressionSimplifier(object): simplifications_common.simp_subwc_cf, simplifications_common.simp_subwc_of, simplifications_common.simp_sign_subwc_cf, + simplifications_common.simp_double_zeroext, + simplifications_common.simp_double_signext, simplifications_common.simp_zeroext_eq_cst, ], diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 5f947f8a..b01b1d1d 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -987,6 +987,25 @@ def simp_sign_subwc_cf(expr_s, expr): return ExprOp("FLAG_SIGN_SUB", op1, op2) +def simp_double_zeroext(expr_s, expr): + # A.zeroExt(X).zeroExt(Y) => A.zeroExt(Y) + if not (expr.is_op() and expr.op.startswith("zeroExt")): + return expr + arg1 = expr.args[0] + if not (arg1.is_op() and arg1.op.startswith("zeroExt")): + return expr + arg2 = arg1.args[0] + return ExprOp(expr.op, arg2) + +def simp_double_signext(expr_s, expr): + # A.signExt(X).signExt(Y) => A.signExt(Y) + if not (expr.is_op() and expr.op.startswith("signExt")): + return expr + arg1 = expr.args[0] + if not (arg1.is_op() and arg1.op.startswith("signExt")): + return expr + arg2 = arg1.args[0] + return ExprOp(expr.op, arg2) def simp_zeroext_eq_cst(expr_s, expr): # A.zeroExt(X) == int => A == int[:A.size] |