diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2017-02-13 16:05:29 +0100 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2017-02-13 16:26:05 +0100 |
| commit | eb7d90bb498f013ef09acf56b0d92b58a347ff31 (patch) | |
| tree | 8c9796f26f0c9957d86d6417ac642c302cf4422f /example/expression | |
| parent | 827c6cb8e1cdcc6e501c319353f89615b9cc09c9 (diff) | |
| download | miasm-eb7d90bb498f013ef09acf56b0d92b58a347ff31.tar.gz miasm-eb7d90bb498f013ef09acf56b0d92b58a347ff31.zip | |
Expression: add ExprReduce
Diffstat (limited to 'example/expression')
| -rw-r--r-- | example/expression/expr_reduce.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/example/expression/expr_reduce.py b/example/expression/expr_reduce.py new file mode 100644 index 00000000..b5fc96c8 --- /dev/null +++ b/example/expression/expr_reduce.py @@ -0,0 +1,93 @@ +from miasm2.expression.expression import ExprId, ExprInt, ExprMem +from miasm2.expression.expression_reduce import ExprReducer + + +class StructLookup(ExprReducer): + """ + ExprReduce example. + This example retrieve the nature of a given expression + Input: + ECX is a pointer on a structure STRUCT_A + + Reduction rules: + ECX -> FIELD_A_PTR + ECX + CST -> FIELD_A_PTR + ECX + CST*CST... -> FIELD_A_PTR + @ECX -> FIELD_A + @(ECX + CST) -> FIELD_A + """ + CST = "CST" + FIELD_A_PTR = "FIELD_A_PTR" + FIELD_A = "FIELD_A" + + def reduce_int(self, node, _): + """ + Reduction: int -> CST + """ + if node.expr.is_int(): + return self.CST + return None + + def reduce_ptr_struct(self, node, _): + """ + Reduction: ECX -> FIELD_A_PTR + """ + if node.expr.is_id("ECX"): + return self.FIELD_A_PTR + return None + + def reduce_ptr_plus_int(self, node, _): + """ + Reduction: ECX + CST -> FIELD_A_PTR + """ + if not node.expr.is_op('+'): + return None + if [arg.info for arg in node.args] == [self.FIELD_A_PTR, self.CST]: + return self.FIELD_A_PTR + return None + + def reduce_cst_op(self, node, _): + """ + Reduction: CST + CST -> CST + """ + if not node.expr.is_op(): + return None + if set(arg.info for arg in node.args) == set([self.CST]): + return self.CST + return None + + def reduce_at_struct_ptr(self, node, _): + """ + Reduction: @FIELD_A_PTR -> FIELD_A + """ + if not node.expr.is_mem(): + return None + return self.FIELD_A + + reduction_rules = [reduce_int, + reduce_ptr_struct, + reduce_ptr_plus_int, + reduce_cst_op, + reduce_at_struct_ptr + ] + + +def test(): + struct_lookup = StructLookup() + + ptr = ExprId('ECX') + int4 = ExprInt(4, 32) + tests = [ + (ptr, StructLookup.FIELD_A_PTR), + (ptr + int4, StructLookup.FIELD_A_PTR), + (ptr + int4 * int4, StructLookup.FIELD_A_PTR), + (ExprMem(ptr), StructLookup.FIELD_A), + (ExprMem(ptr + int4 * int4), StructLookup.FIELD_A), + ] + + for expr_in, result in tests: + assert struct_lookup.reduce(expr_in).info == result + + +if __name__ == "__main__": + test() |