From 8dabdd428acd30aac4ebb7e17270505fc3ba4a59 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 28 Oct 2024 21:00:07 -0400 Subject: Eliminate AST parameter in high level rendering APIs, as it is already part of the HLIL instruction --- python/examples/pseudo_python.py | 170 ++++++++++++++++++++------------------- python/highlevelil.py | 10 ++- python/languagerepresentation.py | 23 +++--- 3 files changed, 108 insertions(+), 95 deletions(-) (limited to 'python') diff --git a/python/examples/pseudo_python.py b/python/examples/pseudo_python.py index b68b4786..6a9e401b 100644 --- a/python/examples/pseudo_python.py +++ b/python/examples/pseudo_python.py @@ -42,7 +42,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): def perform_get_expr_text( self, instr: HighLevelILInstruction, tokens: HighLevelILTokenEmitter, settings: Optional[DisassemblySettings], - as_full_ast: bool = True, precedence: OperatorPrecedence = OperatorPrecedence.TopLevelOperatorPrecedence, + precedence: OperatorPrecedence = OperatorPrecedence.TopLevelOperatorPrecedence, statement: bool = False ): with tokens.expr(instr): @@ -52,7 +52,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): # Emit the lines for each statement in the body for (idx, i) in enumerate(body): # Don't display trailing return statements that don't have values - if (as_full_ast and idx + 1 == len(body) and i.operation == HighLevelILOperation.HLIL_RET and + if (instr.as_ast and idx + 1 == len(body) and i.operation == HighLevelILOperation.HLIL_RET and len(i.src) == 0 and instr.expr_index == self.hlil.root.expr_index): continue @@ -66,18 +66,17 @@ class PseudoPythonFunction(LanguageRepresentationFunction): need_separator = has_blocks # Emit the lines for the statement itself - self.perform_get_expr_text(i, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) + self.perform_get_expr_text(i, tokens, settings, OperatorPrecedence.TopLevelOperatorPrecedence, True) tokens.new_line() elif instr.operation == HighLevelILOperation.HLIL_IF: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "if ")) self.perform_get_expr_text(instr.condition, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":\n")) - if as_full_ast: + if instr.as_ast: # Only display the if body when printing the full AST. When printing basic blocks in graph view, # the body of the if and the else part are rendered as other nodes in the graph. tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(instr.true, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.true, tokens, settings, OperatorPrecedence.TopLevelOperatorPrecedence, True) tokens.end_scope(ScopeType.BlockScopeType) @@ -88,10 +87,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): HighLevelILOperation.HLIL_UNREACHABLE]: if if_chain.operation == HighLevelILOperation.HLIL_IF: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "elif ")) - self.perform_get_expr_text(if_chain.condition, tokens, settings, as_full_ast) + self.perform_get_expr_text(if_chain.condition, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ":")) tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(if_chain.true, tokens, settings, as_full_ast, + self.perform_get_expr_text(if_chain.true, tokens, settings, OperatorPrecedence.TopLevelOperatorPrecedence, True) tokens.end_scope(ScopeType.BlockScopeType) if_chain = if_chain.false @@ -99,7 +98,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "else")) tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ":")) tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(if_chain, tokens, settings, as_full_ast, + self.perform_get_expr_text(if_chain, tokens, settings, OperatorPrecedence.TopLevelOperatorPrecedence, True) tokens.end_scope(ScopeType.BlockScopeType) break @@ -153,49 +152,57 @@ class PseudoPythonFunction(LanguageRepresentationFunction): if instr.update.operation != HighLevelILOperation.HLIL_NOP: self.perform_get_expr_text(instr.update, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":")) - tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(instr.body, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) - tokens.end_scope(ScopeType.BlockScopeType) + if instr.as_ast: + tokens.begin_scope(ScopeType.BlockScopeType) + self.perform_get_expr_text(instr.body, tokens, settings, + OperatorPrecedence.TopLevelOperatorPrecedence, True) + tokens.end_scope(ScopeType.BlockScopeType) elif instr.operation == HighLevelILOperation.HLIL_WHILE: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "while ")) - self.perform_get_expr_text(instr.condition, tokens, settings, as_full_ast) + self.perform_get_expr_text(instr.condition, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":")) - tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(instr.body, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) - tokens.end_scope(ScopeType.BlockScopeType) + if instr.as_ast: + tokens.begin_scope(ScopeType.BlockScopeType) + self.perform_get_expr_text(instr.body, tokens, settings, + OperatorPrecedence.TopLevelOperatorPrecedence, True) + tokens.end_scope(ScopeType.BlockScopeType) elif instr.operation == HighLevelILOperation.HLIL_DO_WHILE: - tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "do")) - tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":")) - tokens.begin_scope(ScopeType.BlockScopeType) - self.perform_get_expr_text(instr.body, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) - tokens.end_scope(ScopeType.BlockScopeType) - tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "while ")) - self.perform_get_expr_text(instr.condition, tokens, settings, as_full_ast) + if instr.as_ast: + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "do")) + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":")) + tokens.begin_scope(ScopeType.BlockScopeType) + self.perform_get_expr_text(instr.body, tokens, settings, + OperatorPrecedence.TopLevelOperatorPrecedence, True) + tokens.end_scope(ScopeType.BlockScopeType) + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "while ")) + self.perform_get_expr_text(instr.condition, tokens, settings) + else: + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "do ")) + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "while ")) + self.perform_get_expr_text(instr.condition, tokens, settings) elif instr.operation == HighLevelILOperation.HLIL_SWITCH: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "match ")) self.perform_get_expr_text(instr.condition, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, ":")) tokens.begin_scope(ScopeType.SwitchScopeType) - # Output each case - for case in instr.cases: - self.perform_get_expr_text(case, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) - tokens.new_line() + if instr.as_ast: + # Output each case + for case in instr.cases: + self.perform_get_expr_text(case, tokens, settings, + OperatorPrecedence.TopLevelOperatorPrecedence, True) + tokens.new_line() - # Check for default case - if instr.default is not None and instr.default.operation not in [HighLevelILOperation.HLIL_NOP, - HighLevelILOperation.HLIL_UNREACHABLE]: - tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "default")) - tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ":")) - tokens.begin_scope(ScopeType.CaseScopeType) - self.perform_get_expr_text(instr.default, tokens, settings, as_full_ast, - OperatorPrecedence.TopLevelOperatorPrecedence, True) - tokens.end_scope(ScopeType.CaseScopeType) - tokens.end_scope(ScopeType.SwitchScopeType) + # Check for default case + if instr.default is not None and instr.default.operation not in [HighLevelILOperation.HLIL_NOP, + HighLevelILOperation.HLIL_UNREACHABLE]: + tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "default")) + tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ":")) + tokens.begin_scope(ScopeType.CaseScopeType) + self.perform_get_expr_text(instr.default, tokens, settings, + OperatorPrecedence.TopLevelOperatorPrecedence, True) + tokens.end_scope(ScopeType.CaseScopeType) + tokens.end_scope(ScopeType.SwitchScopeType) elif instr.operation == HighLevelILOperation.HLIL_CASE: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "case ")) for (i, value) in enumerate(instr.values): @@ -204,7 +211,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): self.perform_get_expr_text(value, tokens, settings) tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, ":")) tokens.begin_scope(ScopeType.CaseScopeType) - self.perform_get_expr_text(instr.body, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.body, tokens, settings, OperatorPrecedence.TopLevelOperatorPrecedence, True) tokens.end_scope(ScopeType.CaseScopeType) elif instr.operation == HighLevelILOperation.HLIL_BREAK: @@ -212,7 +219,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): elif instr.operation == HighLevelILOperation.HLIL_CONTINUE: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "continue")) elif instr.operation == HighLevelILOperation.HLIL_CALL: - self.perform_get_expr_text(instr.dest, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.dest, tokens, settings, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) tokens.append_open_paren() for (i, param) in enumerate(instr.params): @@ -222,7 +229,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): tokens.append_close_paren() elif instr.operation == HighLevelILOperation.HLIL_TAILCALL: tokens.append(InstructionTextToken(InstructionTextTokenType.KeywordToken, "return ")) - self.perform_get_expr_text(instr.dest, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.dest, tokens, settings, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) tokens.append_open_paren() for (i, param) in enumerate(instr.params): @@ -278,7 +285,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): tokens.append_pointer_text_token(instr, instr.constant, settings, SymbolDisplayType.DereferenceNonDataSymbols, precedence) elif instr.operation == HighLevelILOperation.HLIL_ARRAY_INDEX: - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) tokens.append_open_bracket() self.perform_get_expr_text(instr.index, tokens, settings) @@ -301,7 +308,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): # For the right side of the assignment, only use zero confidence if the instruction does # not have any side effects with tokens.force_zero_confidence(appears_dead and not instr.src.has_side_effects): - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.AssignmentOperatorPrecedence) elif instr.operation == HighLevelILOperation.HLIL_VAR_DECLARE: tokens.append_var_text_token(instr.var, instr, instr.size) @@ -402,14 +409,14 @@ class PseudoPythonFunction(LanguageRepresentationFunction): # If the variable does not appear live, show the assignment as zero confidence (grayed out) with tokens.force_zero_confidence(appears_dead): - self.perform_get_expr_text(instr.dest, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.dest, tokens, settings, OperatorPrecedence.AssignmentOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " = ")) # For the right side of the assignment, only use zero confidence if the instruction does # not have any side effects with tokens.force_zero_confidence(appears_dead and not instr.src.has_side_effects): - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.AssignmentOperatorPrecedence) elif instr.operation == HighLevelILOperation.HLIL_ASSIGN_UNPACK: tokens.append_open_paren() @@ -419,13 +426,13 @@ class PseudoPythonFunction(LanguageRepresentationFunction): self.perform_get_expr_text(dest, tokens, settings) tokens.append_close_paren() tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " = ")) - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.AssignmentOperatorPrecedence) elif instr.operation == HighLevelILOperation.HLIL_STRUCT_FIELD: parens = precedence > OperatorPrecedence.MemberAndFunctionOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) self.append_field_text_tokens(instr.src, instr.offset, instr.member_index, instr.size, tokens) if parens: @@ -439,7 +446,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): SymbolDisplayType.DisplaySymbolOnly, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) else: - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.MemberAndFunctionOperatorPrecedence) self.append_field_text_tokens(instr.src, instr.offset, instr.member_index, instr.size, tokens) if parens: @@ -463,7 +470,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): if parens: tokens.append_open_paren() tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "*")) - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.UnaryOperatorPrecedence) if parens: tokens.append_close_paren() @@ -472,7 +479,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): if parens: tokens.append_open_paren() tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "&")) - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.UnaryOperatorPrecedence) if parens: tokens.append_close_paren() @@ -480,10 +487,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.EqualityOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.EqualityOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " == ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.EqualityOperatorPrecedence) if parens: tokens.append_close_paren() @@ -491,10 +498,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.EqualityOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.EqualityOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " != ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.EqualityOperatorPrecedence) if parens: tokens.append_close_paren() @@ -503,10 +510,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.CompareOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " < ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) if parens: tokens.append_close_paren() @@ -515,10 +522,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.CompareOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " <= ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) if parens: tokens.append_close_paren() @@ -527,10 +534,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.CompareOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " >= ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) if parens: tokens.append_close_paren() @@ -539,10 +546,10 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.CompareOperatorPrecedence if parens: tokens.append_open_paren() - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.left, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, " > ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.right, tokens, settings, OperatorPrecedence.CompareOperatorPrecedence) if parens: tokens.append_close_paren() @@ -561,7 +568,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): precedence = OperatorPrecedence.BitwiseAndOperatorPrecedence if parens: tokens.append_open_paren() - self.append_two_operand_tokens(operation, instr, tokens, settings, as_full_ast, precedence) + self.append_two_operand_tokens(operation, instr, tokens, settings, precedence) if parens: tokens.append_close_paren() elif instr.operation == HighLevelILOperation.HLIL_OR: @@ -579,7 +586,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): precedence = OperatorPrecedence.BitwiseOrOperatorPrecedence if parens: tokens.append_open_paren() - self.append_two_operand_tokens(operation, instr, tokens, settings, as_full_ast, precedence) + self.append_two_operand_tokens(operation, instr, tokens, settings, precedence) if parens: tokens.append_close_paren() elif instr.operation == HighLevelILOperation.HLIL_XOR: @@ -588,7 +595,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseOrOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("^", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("^", instr, tokens, settings, OperatorPrecedence.BitwiseXorOperatorPrecedence) if parens: tokens.append_close_paren() @@ -640,7 +647,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("+", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("+", instr, tokens, settings, OperatorPrecedence.AddOperatorPrecedence) if parens: tokens.append_close_paren() @@ -652,7 +659,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("-", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("-", instr, tokens, settings, OperatorPrecedence.SubOperatorPrecedence) if parens: tokens.append_close_paren() @@ -665,7 +672,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("*", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("*", instr, tokens, settings, OperatorPrecedence.MultiplyOperatorPrecedence) if parens: tokens.append_close_paren() @@ -678,7 +685,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("//", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("//", instr, tokens, settings, OperatorPrecedence.DivideOperatorPrecedence) if parens: tokens.append_close_paren() @@ -691,7 +698,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("%", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("%", instr, tokens, settings, OperatorPrecedence.DivideOperatorPrecedence) if parens: tokens.append_close_paren() @@ -703,7 +710,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): OperatorPrecedence.BitwiseXorOperatorPrecedence]) if parens: tokens.append_open_paren() - self.append_two_operand_tokens("/", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("/", instr, tokens, settings, OperatorPrecedence.DivideOperatorPrecedence) if parens: tokens.append_close_paren() @@ -711,7 +718,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.ShiftOperatorPrecedence if parens: tokens.append_open_paren() - self.append_two_operand_tokens("<<", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens("<<", instr, tokens, settings, OperatorPrecedence.ShiftOperatorPrecedence) if parens: tokens.append_close_paren() @@ -719,7 +726,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): parens = precedence > OperatorPrecedence.ShiftOperatorPrecedence if parens: tokens.append_open_paren() - self.append_two_operand_tokens(">>", instr, tokens, settings, as_full_ast, + self.append_two_operand_tokens(">>", instr, tokens, settings, OperatorPrecedence.ShiftOperatorPrecedence) if parens: tokens.append_close_paren() @@ -879,7 +886,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "not ")) else: tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "~")) - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.UnaryOperatorPrecedence) if parens: tokens.append_close_paren() @@ -888,7 +895,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): if parens: tokens.append_open_paren() tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, "-")) - self.perform_get_expr_text(instr.src, tokens, settings, as_full_ast, + self.perform_get_expr_text(instr.src, tokens, settings, OperatorPrecedence.UnaryOperatorPrecedence) if parens: tokens.append_close_paren() @@ -985,8 +992,7 @@ class PseudoPythonFunction(LanguageRepresentationFunction): f"# unimplemented {instr.operation.name}")) def append_two_operand_tokens(self, operation: str, instr: HighLevelILInstruction, tokens: HighLevelILTokenEmitter, - settings: Optional[DisassemblySettings], as_full_ast: bool, - precedence: OperatorPrecedence): + settings: Optional[DisassemblySettings], precedence: OperatorPrecedence): if precedence == OperatorPrecedence.SubOperatorPrecedence: # Treat left side of subtraction as same level as addition. This lets # (a - b) - c be represented as a - b - c, but a - (b - c) does not @@ -1000,9 +1006,9 @@ class PseudoPythonFunction(LanguageRepresentationFunction): else: left_precedence = precedence - self.perform_get_expr_text(instr.left, tokens, settings, as_full_ast, left_precedence) + self.perform_get_expr_text(instr.left, tokens, settings, left_precedence) tokens.append(InstructionTextToken(InstructionTextTokenType.OperationToken, f" {operation} ")) - self.perform_get_expr_text(instr.right, tokens, settings, as_full_ast, precedence) + self.perform_get_expr_text(instr.right, tokens, settings, precedence) def append_field_text_tokens(self, var: HighLevelILInstruction, offset: int, member_index: int, size: int, tokens: HighLevelILTokenEmitter): diff --git a/python/highlevelil.py b/python/highlevelil.py index 21359685..8a400c1e 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -696,7 +696,10 @@ class HighLevelILInstruction(BaseILInstruction): return variable.ConstantData(value, 0, state, core.max_confidence, self.core_instr.size, self.function.source_function) def get_expr(self, operand_index: int) -> 'HighLevelILInstruction': - return HighLevelILInstruction.create(self.function, ExpressionIndex(self.core_instr.operands[operand_index])) + return HighLevelILInstruction.create( + self.function, ExpressionIndex(self.core_instr.operands[operand_index]), + self.as_ast + ) def get_intrinsic(self, operand_index: int) -> 'lowlevelil.ILIntrinsic': if self.function.arch is None: @@ -2801,7 +2804,7 @@ class HighLevelILFunction: """ return core.BNGetHighLevelILExprCount(self.handle) - def get_expr(self, index: ExpressionIndex) -> Optional[HighLevelILInstruction]: + def get_expr(self, index: ExpressionIndex, as_ast: bool = True) -> Optional[HighLevelILInstruction]: """ ``get_expr`` retrieves the IL expression at a given expression index in the function. @@ -2809,12 +2812,13 @@ class HighLevelILFunction: they might not be used by the function and might not contain properly structured data. :param index: Index of desired expression in function + :param as_ast: Whether to return the expression as a full AST or a single instruction (defaults to AST) :return: A HighLevelILInstruction object for the expression, if it exists. Otherwise, None """ if index >= self.get_expr_count(): return None - return HighLevelILInstruction.create(self, index) + return HighLevelILInstruction.create(self, index, as_ast) def copy_expr(self, original: HighLevelILInstruction) -> ExpressionIndex: """ diff --git a/python/languagerepresentation.py b/python/languagerepresentation.py index 49a300c1..ac34c860 100644 --- a/python/languagerepresentation.py +++ b/python/languagerepresentation.py @@ -395,11 +395,11 @@ class LanguageRepresentationFunction: ): try: hlil = highlevelil.HighLevelILFunction(handle=core.BNNewHighLevelILFunctionReference(hlil)) - instr = hlil.get_expr(highlevelil.ExpressionIndex(expr_index)) + instr = hlil.get_expr(highlevelil.ExpressionIndex(expr_index), as_full_ast) tokens = HighLevelILTokenEmitter(core.BNNewHighLevelILTokenEmitterReference(tokens)) if settings is not None: settings = function.DisassemblySettings(core.BNNewDisassemblySettingsReference(settings)) - self.perform_get_expr_text(instr, tokens, settings, as_full_ast, precedence, statement) + self.perform_get_expr_text(instr, tokens, settings, precedence, statement) except: log_error(traceback.format_exc()) @@ -461,7 +461,7 @@ class LanguageRepresentationFunction: def perform_get_expr_text( self, instr: 'highlevelil.HighLevelILInstruction', tokens: HighLevelILTokenEmitter, - settings: Optional['function.DisassemblySettings'], as_full_ast: bool = True, + settings: Optional['function.DisassemblySettings'], precedence: OperatorPrecedence = OperatorPrecedence.TopLevelOperatorPrecedence, statement: bool = False ): """ @@ -481,15 +481,17 @@ class LanguageRepresentationFunction: def get_expr_text( self, instr: 'highlevelil.HighLevelILInstruction', settings: Optional['function.DisassemblySettings'], - as_full_ast: bool = True, precedence: OperatorPrecedence = OperatorPrecedence.TopLevelOperatorPrecedence, + precedence: OperatorPrecedence = OperatorPrecedence.TopLevelOperatorPrecedence, statement: bool = False ) -> List['function.DisassemblyTextLine']: """Gets the lines of tokens for a given High Level IL instruction.""" count = ctypes.c_ulonglong() if settings is not None: settings = settings.handle - lines = core.BNGetLanguageRepresentationFunctionExprText(self.handle, instr.function.handle, instr.expr_index, - settings, as_full_ast, precedence, statement, count) + lines = core.BNGetLanguageRepresentationFunctionExprText( + self.handle, instr.function.handle, instr.expr_index, + settings, instr.as_ast, precedence, statement, count + ) result = [] if lines is not None: result = [] @@ -507,8 +509,7 @@ class LanguageRepresentationFunction: def get_linear_lines( self, instr: 'highlevelil.HighLevelILInstruction', - settings: Optional['function.DisassemblySettings'] = None, - as_full_ast: bool = True + settings: Optional['function.DisassemblySettings'] = None ) -> List['function.DisassemblyTextLine']: """ Generates lines for the given High Level IL instruction in the style of the linear view. To get the lines @@ -517,8 +518,10 @@ class LanguageRepresentationFunction: count = ctypes.c_ulonglong() if settings is not None: settings = settings.handle - lines = core.BNGetLanguageRepresentationFunctionLinearLines(self.handle, instr.function.handle, instr.expr_index, - settings, as_full_ast, count) + lines = core.BNGetLanguageRepresentationFunctionLinearLines( + self.handle, instr.function.handle, instr.expr_index, + settings, instr.as_ast, count + ) result = [] if lines is not None: result = [] -- cgit v1.3.1