diff options
| -rw-r--r-- | example/expression/expr_translate.py | 11 | ||||
| -rw-r--r-- | miasm/analysis/data_flow.py | 26 | ||||
| -rw-r--r-- | miasm/arch/aarch64/arch.py | 3 | ||||
| -rw-r--r-- | miasm/ir/translators/python.py | 5 | ||||
| -rw-r--r-- | miasm/ir/translators/smt2.py | 4 | ||||
| -rw-r--r-- | test/arch/aarch64/arch.py | 2 |
6 files changed, 42 insertions, 9 deletions
diff --git a/example/expression/expr_translate.py b/example/expression/expr_translate.py index 8562975f..31408566 100644 --- a/example/expression/expr_translate.py +++ b/example/expression/expr_translate.py @@ -45,3 +45,14 @@ print("-> 0x%x" % eval(target_exprs["Python"])) print("[+] Validate the Miasm syntax rebuilding") exprRebuild = eval(target_exprs["Miasm"]) assert(expr == exprRebuild) + + +a = ExprId("a", 32) +b = ExprId("b", 32) +cst1 = ExprInt(1, 32) +eq_test = ExprOp("==", a, b + cst1) + +for lang in Translator.available_languages(): + translator = Translator.to_language(lang) + print("Translate to %s:" % lang) + print(translator.from_expr(eq_test)) diff --git a/miasm/analysis/data_flow.py b/miasm/analysis/data_flow.py index 40153f8b..0a96ae8d 100644 --- a/miasm/analysis/data_flow.py +++ b/miasm/analysis/data_flow.py @@ -1755,6 +1755,9 @@ class State(object): self.equivalence_classes = UnionFind() self.undefined = set() + def __str__(self): + return "{0.equivalence_classes}\n{0.undefined}".format(self) + def copy(self): state = self.__class__() state.equivalence_classes = self.equivalence_classes.copy() @@ -1983,6 +1986,9 @@ class State(object): def merge(self, other): """ Merge the current state with @other + Merge rules: + - if two nodes are equal in both states => in equivalence class + - if node value is different or non present in another state => undefined @other: State instance """ classes1 = self.equivalence_classes @@ -2000,6 +2006,7 @@ class State(object): for node in component: node_to_component2[node] = component + # Compute intersection of equivalence classes of states out = [] nodes_ok = set() while components1: @@ -2016,14 +2023,18 @@ class State(object): continue if node not in component2: continue + # Found two classes containing node common = component1.intersection(component2) if len(common) == 1: + # Intersection contains only one node => undefine node if node.is_id() or node.is_mem(): assert(node not in nodes_ok) undefined.add(node) component2.discard(common.pop()) continue if common: + # Intersection contains multiple nodes + # Here, common nodes don't interfer with any undefined nodes_ok.update(common) out.append(common) diff = component1.difference(common) @@ -2104,7 +2115,7 @@ class PropagateExpressions(object): """ Merge predecessors states of irblock at location @loc_key @ircfg: IRCfg instance - @sates: Dictionary linking locations to state + @states: Dictionary linking locations to state @loc_key: location of the current irblock """ @@ -2176,15 +2187,14 @@ class PropagateExpressions(object): state = state.copy() new_irblock, modified_irblock = self.update_state(irblock, state) - if ( - state_orig is not None and - state.equivalence_classes == state_orig.equivalence_classes and + if state_orig is not None: + # Merge current and previous state + state = state.merge(state_orig) + if (state.equivalence_classes == state_orig.equivalence_classes and state.undefined == state_orig.undefined - ): - continue + ): + continue - if state_orig: - state.undefined.update(state_orig.undefined) states[loc_key] = state # Propagate to sons for successor in ircfg.successors(loc_key): diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py index 16fbcaea..25bf5c12 100644 --- a/miasm/arch/aarch64/arch.py +++ b/miasm/arch/aarch64/arch.py @@ -1738,6 +1738,7 @@ simm7 = bs(l=7, cls=(aarch64_int64_noarg,), fname="imm", order=-1) nzcv = bs(l=4, cls=(aarch64_uint64_noarg, aarch64_arg), fname="nzcv", order=-1) uimm4 = bs(l=4, cls=(aarch64_uint64_noarg, aarch64_arg), fname="imm", order=-1) uimm5 = bs(l=5, cls=(aarch64_uint64_noarg, aarch64_arg), fname="imm", order=-1) +uimm6 = bs(l=6, cls=(aarch64_uint64_noarg, aarch64_arg), fname="imm", order=-1) uimm12 = bs(l=12, cls=(aarch64_uint64_noarg,), fname="imm", order=-1) uimm16 = bs(l=16, cls=(aarch64_uint64_noarg, aarch64_arg), fname="imm", order=-1) uimm7 = bs(l=7, cls=(aarch64_uint64_noarg,), fname="imm", order=-1) @@ -2136,7 +2137,7 @@ aarch64op("udiv", [sf, bs('0'), bs('0'), bs('11010110'), rm, bs('00001'), bs('0' # extract register p.150 -aarch64op("extr", [sf, bs('00100111'), bs(l=1, cls=(aarch64_eq,), ref="sf"), bs('0'), rm, simm6, rn, rd], [rd, rn, rm, simm6]) +aarch64op("extr", [sf, bs('00100111'), bs(l=1, cls=(aarch64_eq,), ref="sf"), bs('0'), rm, uimm6, rn, rd], [rd, rn, rm, uimm6]) # shift reg p.155 shiftr_name = {'LSL': 0b00, 'LSR': 0b01, 'ASR': 0b10, 'ROR': 0b11} diff --git a/miasm/ir/translators/python.py b/miasm/ir/translators/python.py index 0da2318d..4e5cc5e1 100644 --- a/miasm/ir/translators/python.py +++ b/miasm/ir/translators/python.py @@ -1,6 +1,7 @@ from builtins import map from miasm.expression.expression import ExprInt from miasm.ir.translators.translator import Translator +from miasm.expression.expression import ExprCond, ExprInt class TranslatorPython(Translator): @@ -71,6 +72,10 @@ class TranslatorPython(Translator): ) elif expr.op == "parity": return "(%s & 0x1)" % self.from_expr(expr.args[0]) + elif expr.op == "==": + return self.from_expr( + ExprCond(expr.args[0] - expr.args[1], ExprInt(0, 1), ExprInt(1, 1)) + ) elif expr.op in ["<<<", ">>>"]: amount_raw = expr.args[1] diff --git a/miasm/ir/translators/smt2.py b/miasm/ir/translators/smt2.py index c4260eb4..d3366b8b 100644 --- a/miasm/ir/translators/smt2.py +++ b/miasm/ir/translators/smt2.py @@ -4,6 +4,8 @@ import logging from miasm.ir.translators.translator import Translator from miasm.expression.smt2_helper import * +from miasm.expression.expression import ExprCond, ExprInt + log = logging.getLogger("translator_smt2") console_handler = logging.StreamHandler() @@ -226,6 +228,8 @@ class TranslatorSMT2(Translator): res = bv_rotate_left(res, arg, expr.size) elif expr.op == ">>>": res = bv_rotate_right(res, arg, expr.size) + elif expr.op == "==": + res = self.from_expr(ExprCond(expr.args[0] - expr.args[1], ExprInt(0, 1), ExprInt(1, 1))) else: raise NotImplementedError("Unsupported OP yet: %s" % expr.op) elif expr.op == 'parity': diff --git a/test/arch/aarch64/arch.py b/test/arch/aarch64/arch.py index c78007b8..dc505bdd 100644 --- a/test/arch/aarch64/arch.py +++ b/test/arch/aarch64/arch.py @@ -1730,6 +1730,8 @@ reg_tests_aarch64 = [ ("0006C588 EXTR W2, W2, W2, 0x1F", "427C8213"), + ("XXXXXXXX EXTR X12, X12, X12, 0x20", + "8C81CC93"), ("00458AB8 CCMP X3, X5, 0x8, GE", "68A045FA"), |