about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/jitter/unpack_upx.py5
-rw-r--r--miasm2/core/cpu.py4
-rw-r--r--miasm2/core/locationdb.py12
-rw-r--r--miasm2/core/parse_asm.py3
-rw-r--r--miasm2/expression/expression_reduce.py164
-rw-r--r--miasm2/expression/simplifications.py2
-rw-r--r--miasm2/expression/simplifications_common.py19
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]