diff --git a/decompiler/util/decoration.py b/decompiler/util/decoration.py index 3b73daf28..e6add9a4c 100644 --- a/decompiler/util/decoration.py +++ b/decompiler/util/decoration.py @@ -23,6 +23,8 @@ SwitchNode, TrueNode, ) +from decompiler.structures.ast.syntaxforest import AbstractSyntaxForest +from decompiler.structures.ast.syntaxgraph import AbstractSyntaxInterface from decompiler.structures.ast.syntaxtree import AbstractSyntaxTree from decompiler.structures.graphs.cfg import BasicBlock, BasicBlockEdge, BasicBlockEdgeCondition, ControlFlowGraph from decompiler.structures.logic.logic_condition import LogicCondition @@ -34,7 +36,7 @@ from pygments.lexers.c_like import CLexer try: - run(["graph-easy"], capture_output=True) + run(["graph-easy", "-v"], capture_output=True) GRAPH_EASY_INSTALLED = True except FileNotFoundError as _: GRAPH_EASY_INSTALLED = False @@ -198,25 +200,31 @@ def __init__(self, graph=None): self.condition_map: Dict[z3.BoolRef, Condition] = {} @classmethod - def from_ast(cls, ast: AbstractSyntaxTree) -> DecoratedAST: - """Generate a decorated graph based on the given AbstractSyntaxTree.""" + def from_ast(cls, ast: AbstractSyntaxInterface, with_reaching_condition: bool = False) -> DecoratedAST: + """Generate a decorated graph based on the given AbstractSyntaxTree or AbstractSyntaxForest.""" graph = cls() - graph.condition_map = ast.condition_map + graph.condition_map = dict() + if isinstance(ast, AbstractSyntaxForest): + graph.condition_map = ast.condition_handler.get_condition_map() + elif isinstance(ast, AbstractSyntaxTree): + graph.condition_map = ast.condition_map node_id = 0 for node in ast.topological_order(): if isinstance(node, (TrueNode, FalseNode)): continue - graph.decorate_node(node, node_id) + graph.decorate_node(node, node_id, with_reaching_condition) node_id += 1 graph._add_edges() return graph - def decorate_node(self, node: AbstractSyntaxTreeNode, node_id: int): + def decorate_node(self, node: AbstractSyntaxTreeNode, node_id: int, with_reaching_condition: bool = False): """Decorate the given node while adding it to the DecoratedAST.""" attributes = self.GENERAL_NODE_DECORATION.copy() attributes.update(self.NODE_DECORATION.get(type(node), {})) label = f"{node_id}. {node.__class__.__name__}" + if with_reaching_condition: + label += f"\n {node.reaching_condition.rich_string_representation(self.condition_map)}" if hasattr(node, "condition"): resolved_condition = node.condition.rich_string_representation(self.condition_map) diff --git a/tests/samples/src/systemtests/test_condition.c b/tests/samples/src/systemtests/test_condition.c index 2bfdf0cf7..7e72f4ee9 100644 --- a/tests/samples/src/systemtests/test_condition.c +++ b/tests/samples/src/systemtests/test_condition.c @@ -259,8 +259,170 @@ int test13() printf("'%c' is not an alphabet.", ch); } + return 0; +} + +int test14() +{ + int num1, num2; + printf("Enter two numbers: "); + scanf("%d%d", &num1, &num2); + + + if(num1 > 5){ + if(num2 > num1){ + printf("second number is larger than first"); + goto RETURN; + }else{ + printf("first number is larger than second"); + } + }else{ + printf("first number is <= 5"); + } + num1 = 5; + printf("set first number to 5"); + + RETURN: return num1; +} + +int test15() +{ + int num0, num1, num2; + printf("Enter two numbers: "); + scanf("%d%d%d", &num0, &num1, &num2); + + if(num0 > 10){ + if(num1 > 5){ + if(num2 > num1){ + printf("second number is larger than first"); + }else{ + printf("first number is larger than second"); + goto POS; + } + }else{ + printf("first number is <= 5"); + } + }else{ + POS: num0 += num2; + } + printf("The numbers are: %d, %d, %d", num0, num1, num2); + return 0; } + +int test16() +{ + int num0, num1, num2; + printf("Enter two numbers: "); + scanf("%d%d", &num0, &num1); + + if(num0 < 5){ + num0 += 5; + if(num1 < 5){ + num1 += num0; + } + }else{ + num0 -= 5; + } + printf("The numbers are: %d, %d", num0, num1); + return 0; +} + +int test17(int a){ + int week; + printf("Enter week number (1-7): "); + scanf("%d", &week); + + + if(week == 1){ + if(a == 7){ + printf("The Input is 7 and you choose week number %d", week); + goto STEP; + } + } + if(week == 2) + { + printf("Tuesday"); + } + if(week == 3) + { + printf("Wednesday"); + } + if(week == 4) + { + printf("Thursday"); + } + if(week == 5) + { + printf("Friday"); + } + if(week == 6) + { + printf("Saturday"); + } + if(week == 7) + { + printf("Sunday"); + } + + if(week == 1){ + printf("Monday"); + STEP: printf("common case"); + return 0; + } + return 0; +} + +int test18(int a){ + int week; + printf("Enter week number (1-7): "); + scanf("%d", &week); + + + if(week == 1){ + printf("Possible switch case but not the one we want"); + if(a > 5){ + goto CASE1; + }else{ + a += 5; + goto CASE2; + } + }else{ + if(week == 2){ + CASE2: printf("Tuesday"); + if(a > 10){ + goto CASE3; + }else{ + goto END; + } + }else{ + if(week == 3){ + CASE3: printf("Wednesday"); + if(week == 1){ + CASE1: printf("Monday"); + goto END; + } + goto CASE4; + }else{ + if(week == 4){ + CASE4: printf("Thursday"); + } + } + } + } + + END: return 0; +} + +int print_problem(){ + int b; + scanf("%d", &b); + printf("you entered: %d\n", b); + b *= b; + printf("squared: %d\n", b); + return 0; +} + int main() { test4(); diff --git a/tests/samples/src/systemtests/test_goto.c b/tests/samples/src/systemtests/test_goto.c index 1c1d38096..0e80a4391 100644 --- a/tests/samples/src/systemtests/test_goto.c +++ b/tests/samples/src/systemtests/test_goto.c @@ -45,6 +45,29 @@ int test1_b() return 0; } +int test1_c() +{ + /* local variable definition */ + int a = 10; + + /* do loop execution */ + LOOP:do { + + if( a == 15) { + /* skip the iteration */ + printf("We go to the loop head."); + a = a + 2; + goto LOOP; + } + + printf("value of a: %d\n", a); + a++; + + }while( a < 20 ); + + return 0; +} + int test2() { int needle; diff --git a/tests/samples/src/systemtests/test_loop.c b/tests/samples/src/systemtests/test_loop.c index 6b5ded213..b70b09905 100644 --- a/tests/samples/src/systemtests/test_loop.c +++ b/tests/samples/src/systemtests/test_loop.c @@ -291,6 +291,13 @@ int test10(int a, int b) printf("loop terminated\r\n"); } +int test11(int a, int b) +{ + while(1){ + } + return 0; +} + int main() { test1();