diff --git a/example/expression/interfer.py b/example/expression/interfer.py deleted file mode 100644 index 7e660b9b4..000000000 --- a/example/expression/interfer.py +++ /dev/null @@ -1,113 +0,0 @@ -from miasm.analysis.data_flow import State -from miasm.expression.expression import * - -""" -Test memory interferences - -A memory interference may appear when two ExprMem objects relate to the same area of memory: editing one may impact the other. -""" - -a32 = ExprId('a', 32) -b32 = ExprId('b', 32) - -a64 = ExprId('a', 64) -b64 = ExprId('b', 64) - -mem_a32_32 = ExprMem(a32, 32) -mem_b32_32 = ExprMem(b32, 32) - -mem_a64_32 = ExprMem(a64, 32) - -mem_a32_m1_8 = ExprMem(a32 + ExprInt(-1, 32), 8) -mem_a32_p0_8 = ExprMem(a32, 8) -mem_a32_p1_8 = ExprMem(a32 + ExprInt(1, 32), 8) -mem_a32_p2_8 = ExprMem(a32 + ExprInt(2, 32), 8) -mem_a32_p3_8 = ExprMem(a32 + ExprInt(3, 32), 8) -mem_a32_p4_8 = ExprMem(a32 + ExprInt(4, 32), 8) - - -mem_a32_m4_32 = ExprMem(a32 + ExprInt(-4, 32), 32) -mem_a32_m3_32 = ExprMem(a32 + ExprInt(-3, 32), 32) -mem_a32_m2_32 = ExprMem(a32 + ExprInt(-2, 32), 32) -mem_a32_m1_32 = ExprMem(a32 + ExprInt(-1, 32), 32) -mem_a32_p0_32 = ExprMem(a32, 32) -mem_a32_p1_32 = ExprMem(a32 + ExprInt(1, 32), 32) -mem_a32_p2_32 = ExprMem(a32 + ExprInt(2, 32), 32) -mem_a32_p3_32 = ExprMem(a32 + ExprInt(3, 32), 32) -mem_a32_p4_32 = ExprMem(a32 + ExprInt(4, 32), 32) - - -mem_a64_m4_32 = ExprMem(a64 + ExprInt(-4, 64), 32) -mem_a64_m3_32 = ExprMem(a64 + ExprInt(-3, 64), 32) -mem_a64_m2_32 = ExprMem(a64 + ExprInt(-2, 64), 32) -mem_a64_m1_32 = ExprMem(a64 + ExprInt(-1, 64), 32) -mem_a64_p0_32 = ExprMem(a64, 32) -mem_a64_p1_32 = ExprMem(a64 + ExprInt(1, 64), 32) -mem_a64_p2_32 = ExprMem(a64 + ExprInt(2, 64), 32) -mem_a64_p3_32 = ExprMem(a64 + ExprInt(3, 64), 32) -mem_a64_p4_32 = ExprMem(a64 + ExprInt(4, 64), 32) - - -state = State() - - -assert state.may_interfer(set([mem_a32_32]), mem_b32_32) == True -assert state.may_interfer(set([mem_b32_32]), mem_a32_32) == True - -# Test 8 bit accesses -assert state.may_interfer(set([mem_a32_m1_8]), mem_a32_32) == False -assert state.may_interfer(set([mem_a32_p0_8]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p1_8]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p2_8]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p3_8]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p4_8]), mem_a32_32) == False - -assert state.may_interfer(set([mem_a32_32]), mem_a32_m1_8) == False -assert state.may_interfer(set([mem_a32_32]), mem_a32_p0_8) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p1_8) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p2_8) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p3_8) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p4_8) == False - - -# Test 32 bit accesses -assert state.may_interfer(set([mem_a32_m4_32]), mem_a32_32) == False -assert state.may_interfer(set([mem_a32_m3_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_m2_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_m1_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p0_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p1_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p2_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p3_32]), mem_a32_32) == True -assert state.may_interfer(set([mem_a32_p4_32]), mem_a32_32) == False - -assert state.may_interfer(set([mem_a32_32]), mem_a32_m4_32) == False -assert state.may_interfer(set([mem_a32_32]), mem_a32_m3_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_m2_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_m1_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p0_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p1_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p2_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p3_32) == True -assert state.may_interfer(set([mem_a32_32]), mem_a32_p4_32) == False - -# Test 32 bit accesses with 64 bit memory address -assert state.may_interfer(set([mem_a64_m4_32]), mem_a64_32) == False -assert state.may_interfer(set([mem_a64_m3_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_m2_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_m1_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_p0_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_p1_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_p2_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_p3_32]), mem_a64_32) == True -assert state.may_interfer(set([mem_a64_p4_32]), mem_a64_32) == False - -assert state.may_interfer(set([mem_a64_32]), mem_a64_m4_32) == False -assert state.may_interfer(set([mem_a64_32]), mem_a64_m3_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_m2_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_m1_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_p0_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_p1_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_p2_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_p3_32) == True -assert state.may_interfer(set([mem_a64_32]), mem_a64_p4_32) == False diff --git a/example/expression/interfere.py b/example/expression/interfere.py new file mode 100644 index 000000000..83a7adb58 --- /dev/null +++ b/example/expression/interfere.py @@ -0,0 +1,113 @@ +from miasm.analysis.data_flow import State +from miasm.expression.expression import * + +""" +Test memory interferences + +A memory interference may appear when two ExprMem objects relate to the same area of memory: editing one may impact the other. +""" + +a32 = ExprId('a', 32) +b32 = ExprId('b', 32) + +a64 = ExprId('a', 64) +b64 = ExprId('b', 64) + +mem_a32_32 = ExprMem(a32, 32) +mem_b32_32 = ExprMem(b32, 32) + +mem_a64_32 = ExprMem(a64, 32) + +mem_a32_m1_8 = ExprMem(a32 + ExprInt(-1, 32), 8) +mem_a32_p0_8 = ExprMem(a32, 8) +mem_a32_p1_8 = ExprMem(a32 + ExprInt(1, 32), 8) +mem_a32_p2_8 = ExprMem(a32 + ExprInt(2, 32), 8) +mem_a32_p3_8 = ExprMem(a32 + ExprInt(3, 32), 8) +mem_a32_p4_8 = ExprMem(a32 + ExprInt(4, 32), 8) + + +mem_a32_m4_32 = ExprMem(a32 + ExprInt(-4, 32), 32) +mem_a32_m3_32 = ExprMem(a32 + ExprInt(-3, 32), 32) +mem_a32_m2_32 = ExprMem(a32 + ExprInt(-2, 32), 32) +mem_a32_m1_32 = ExprMem(a32 + ExprInt(-1, 32), 32) +mem_a32_p0_32 = ExprMem(a32, 32) +mem_a32_p1_32 = ExprMem(a32 + ExprInt(1, 32), 32) +mem_a32_p2_32 = ExprMem(a32 + ExprInt(2, 32), 32) +mem_a32_p3_32 = ExprMem(a32 + ExprInt(3, 32), 32) +mem_a32_p4_32 = ExprMem(a32 + ExprInt(4, 32), 32) + + +mem_a64_m4_32 = ExprMem(a64 + ExprInt(-4, 64), 32) +mem_a64_m3_32 = ExprMem(a64 + ExprInt(-3, 64), 32) +mem_a64_m2_32 = ExprMem(a64 + ExprInt(-2, 64), 32) +mem_a64_m1_32 = ExprMem(a64 + ExprInt(-1, 64), 32) +mem_a64_p0_32 = ExprMem(a64, 32) +mem_a64_p1_32 = ExprMem(a64 + ExprInt(1, 64), 32) +mem_a64_p2_32 = ExprMem(a64 + ExprInt(2, 64), 32) +mem_a64_p3_32 = ExprMem(a64 + ExprInt(3, 64), 32) +mem_a64_p4_32 = ExprMem(a64 + ExprInt(4, 64), 32) + + +state = State() + + +assert state.may_interfere(set([mem_a32_32]), mem_b32_32) == True +assert state.may_interfere(set([mem_b32_32]), mem_a32_32) == True + +# Test 8 bit accesses +assert state.may_interfere(set([mem_a32_m1_8]), mem_a32_32) == False +assert state.may_interfere(set([mem_a32_p0_8]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p1_8]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p2_8]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p3_8]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p4_8]), mem_a32_32) == False + +assert state.may_interfere(set([mem_a32_32]), mem_a32_m1_8) == False +assert state.may_interfere(set([mem_a32_32]), mem_a32_p0_8) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p1_8) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p2_8) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p3_8) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p4_8) == False + + +# Test 32 bit accesses +assert state.may_interfere(set([mem_a32_m4_32]), mem_a32_32) == False +assert state.may_interfere(set([mem_a32_m3_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_m2_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_m1_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p0_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p1_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p2_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p3_32]), mem_a32_32) == True +assert state.may_interfere(set([mem_a32_p4_32]), mem_a32_32) == False + +assert state.may_interfere(set([mem_a32_32]), mem_a32_m4_32) == False +assert state.may_interfere(set([mem_a32_32]), mem_a32_m3_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_m2_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_m1_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p0_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p1_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p2_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p3_32) == True +assert state.may_interfere(set([mem_a32_32]), mem_a32_p4_32) == False + +# Test 32 bit accesses with 64 bit memory address +assert state.may_interfere(set([mem_a64_m4_32]), mem_a64_32) == False +assert state.may_interfere(set([mem_a64_m3_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_m2_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_m1_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_p0_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_p1_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_p2_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_p3_32]), mem_a64_32) == True +assert state.may_interfere(set([mem_a64_p4_32]), mem_a64_32) == False + +assert state.may_interfere(set([mem_a64_32]), mem_a64_m4_32) == False +assert state.may_interfere(set([mem_a64_32]), mem_a64_m3_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_m2_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_m1_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_p0_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_p1_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_p2_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_p3_32) == True +assert state.may_interfere(set([mem_a64_32]), mem_a64_p4_32) == False diff --git a/miasm/analysis/data_flow.py b/miasm/analysis/data_flow.py index 23d0b3dd8..441ece4a1 100644 --- a/miasm/analysis/data_flow.py +++ b/miasm/analysis/data_flow.py @@ -1877,7 +1877,7 @@ class State(object): The state is represented using equivalence classes Each assignment can create/destroy equivalence classes. Interferences - between expression is computed using `may_interfer` function + between expression is computed using `may_interfere` function """ def __init__(self): @@ -1909,6 +1909,14 @@ def __ne__(self, other): return not self == other def may_interfer(self, dsts, src): + warnings.warn( + "This function is deprecated, use `may_interfere` instead", + DeprecationWarning, + stacklevel=2, + ) + return self.may_interfere(dsts, src) + + def may_interfere(self, dsts, src): """ Return True if @src may interfere with expressions in @dsts @dsts: Set of Expressions @@ -2084,7 +2092,7 @@ def eval_assignblock(self, assignblock): # Remove interfering known classes to_del = set() for node in list(classes.nodes()): - if self.may_interfer(dsts, node): + if self.may_interfere(dsts, node): # Interfere with known equivalence class self.equivalence_classes.del_element(node) if node.is_id() or node.is_mem(): @@ -2104,8 +2112,8 @@ def eval_assignblock(self, assignblock): if node.is_id() or node.is_mem(): self.undefined.add(node) - # Don't create equivalence if self interfer - if self.may_interfer(dsts, src): + # Don't create equivalence if self interfere + if self.may_interfere(dsts, src): if dst in self.equivalence_classes.nodes(): self.equivalence_classes.del_element(dst) if dst.is_id() or dst.is_mem(): diff --git a/test/test_all.py b/test/test_all.py index 85ebb31f6..67d4423f7 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -713,7 +713,7 @@ class ExampleExpression(Example): ["expr_random.py"], ["expr_translate.py"], ["expr_reduce.py"], - ["interfer.py"], + ["interfere.py"], ]: testset += ExampleExpression(script)