|
|
@ -1,7 +1,7 @@ |
|
|
|
from mythril.disassembler.asm import * |
|
|
|
from mythril.disassembler.asm import * |
|
|
|
import pytest |
|
|
|
import pytest |
|
|
|
|
|
|
|
|
|
|
|
valid_names = [("PUSH1", 0x60), ("STOP", 0x0), ("RETURN", 0xf3)] |
|
|
|
valid_names = [("PUSH1", 0x60), ("STOP", 0x0), ("RETURN", 0xF3)] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("operation_name, hex_value", valid_names) |
|
|
|
@pytest.mark.parametrize("operation_name, hex_value", valid_names) |
|
|
@ -22,36 +22,90 @@ def test_get_unknown_opcode(): |
|
|
|
|
|
|
|
|
|
|
|
sequence_match_test_data = [ |
|
|
|
sequence_match_test_data = [ |
|
|
|
# Normal no match |
|
|
|
# Normal no match |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 1, False), |
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
1, |
|
|
|
|
|
|
|
False, |
|
|
|
|
|
|
|
), |
|
|
|
# Normal match |
|
|
|
# Normal match |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], 1, True), |
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
1, |
|
|
|
|
|
|
|
True, |
|
|
|
|
|
|
|
), |
|
|
|
# Out of bounds pattern |
|
|
|
# Out of bounds pattern |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 3, False), |
|
|
|
( |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 2, False), |
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
3, |
|
|
|
|
|
|
|
False, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
2, |
|
|
|
|
|
|
|
False, |
|
|
|
|
|
|
|
), |
|
|
|
# Double option match |
|
|
|
# Double option match |
|
|
|
((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], 1, True), |
|
|
|
( |
|
|
|
((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 1, True), |
|
|
|
(["PUSH1", "PUSH3"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
1, |
|
|
|
|
|
|
|
True, |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1", "PUSH3"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
1, |
|
|
|
|
|
|
|
True, |
|
|
|
|
|
|
|
), |
|
|
|
# Double option no match |
|
|
|
# Double option no match |
|
|
|
((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 0, False), |
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1", "PUSH3"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
0, |
|
|
|
|
|
|
|
False, |
|
|
|
|
|
|
|
), |
|
|
|
] |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("pattern, instruction_list, index, expected_result", sequence_match_test_data) |
|
|
|
@pytest.mark.parametrize( |
|
|
|
|
|
|
|
"pattern, instruction_list, index, expected_result", sequence_match_test_data |
|
|
|
|
|
|
|
) |
|
|
|
def test_is_sequence_match(pattern, instruction_list, index, expected_result): |
|
|
|
def test_is_sequence_match(pattern, instruction_list, index, expected_result): |
|
|
|
# Act |
|
|
|
# Act |
|
|
|
return_value = is_sequence_match(pattern, instruction_list, index) |
|
|
|
return_value = is_sequence_match(pattern, instruction_list, index) |
|
|
|
# Assert |
|
|
|
# Assert |
|
|
|
assert return_value == expected_result |
|
|
|
assert return_value == expected_result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
find_sequence_match_test_data = [ |
|
|
|
find_sequence_match_test_data = [ |
|
|
|
# Normal no match |
|
|
|
# Normal no match |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], []), |
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], |
|
|
|
|
|
|
|
[], |
|
|
|
|
|
|
|
), |
|
|
|
# Normal match |
|
|
|
# Normal match |
|
|
|
((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], [1, 3]), |
|
|
|
( |
|
|
|
|
|
|
|
(["PUSH1"], ["EQ"]), |
|
|
|
|
|
|
|
[ |
|
|
|
|
|
|
|
{"opcode": "PUSH1"}, |
|
|
|
|
|
|
|
{"opcode": "PUSH1"}, |
|
|
|
|
|
|
|
{"opcode": "EQ"}, |
|
|
|
|
|
|
|
{"opcode": "PUSH1"}, |
|
|
|
|
|
|
|
{"opcode": "EQ"}, |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
[1, 3], |
|
|
|
|
|
|
|
), |
|
|
|
] |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("pattern, instruction_list, expected_result", find_sequence_match_test_data) |
|
|
|
@pytest.mark.parametrize( |
|
|
|
|
|
|
|
"pattern, instruction_list, expected_result", find_sequence_match_test_data |
|
|
|
|
|
|
|
) |
|
|
|
def test_find_op_code_sequence(pattern, instruction_list, expected_result): |
|
|
|
def test_find_op_code_sequence(pattern, instruction_list, expected_result): |
|
|
|
# Act |
|
|
|
# Act |
|
|
|
return_value = list(find_op_code_sequence(pattern, instruction_list)) |
|
|
|
return_value = list(find_op_code_sequence(pattern, instruction_list)) |
|
|
|