Skip to content

Commit

Permalink
add type names to struct defs and detect complex strings
Browse files Browse the repository at this point in the history
  • Loading branch information
blattm committed May 21, 2024
1 parent 728ab55 commit fffb1b4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
42 changes: 42 additions & 0 deletions decompiler/backend/cexpressiongenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,60 @@
)
from decompiler.structures.pseudo import instructions as instructions
from decompiler.structures.pseudo import operations as operations
from decompiler.structures.pseudo.complextypes import Struct
from decompiler.structures.pseudo.operations import MemberAccess
from decompiler.structures.visitors.interfaces import DataflowObjectVisitorInterface
from decompiler.util.integer_util import normalize_int

MAX_GLOBAL_INIT_LENGTH = 128


def get_complex_string_struct_address_offset(vartype) -> str | None:
if not isinstance(vartype, Struct):
return None
if len(vartype.members) != 2:
return None
address_offset = None
length_offset = None
for offset, member in vartype.members.items():
match member.type:
case Pointer(type=Integer(size=8)):
address_offset = offset
case Integer():
length_offset = offset
case _:
return None
if address_offset is None or length_offset is None:
return None
return address_offset


INLINE_COMPLEX_STRINGS = False
DETECT_COMPLEX_STRINGS = True


def is_complex_string_struct(vartype) -> bool:
if not DETECT_COMPLEX_STRINGS:
return False
return get_complex_string_struct_address_offset(vartype) is not None


def get_data_of_complex_string_struct(variable) -> str:
address_offset = get_complex_string_struct_address_offset(variable.type)
address = variable.initial_value.value[address_offset]
return address


def inline_global_variable(var) -> bool:
if not var.is_constant:
return False
match var.type:
case ArrayType():
if var.type.type in [Integer.char(), CustomType.wchar16(), CustomType.wchar32()]:
return True
case Struct():
if INLINE_COMPLEX_STRINGS and is_complex_string_struct(var.type):
return True
case _:
return False
return False
Expand Down Expand Up @@ -212,6 +252,8 @@ def visit_variable(self, expr: expressions.Variable) -> str:
def visit_global_variable(self, expr: expressions.GlobalVariable):
"""Inline a global variable if its initial value is constant and not of void type"""
if inline_global_variable(expr):
if is_complex_string_struct(expr.type):
return self.visit(get_data_of_complex_string_struct(expr))
return self.visit(expr.initial_value)
return expr.name

Expand Down
12 changes: 10 additions & 2 deletions decompiler/backend/variabledeclarations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from collections import defaultdict
from typing import Iterable, Iterator, List

from decompiler.backend.cexpressiongenerator import CExpressionGenerator, inline_global_variable
from decompiler.backend.cexpressiongenerator import (
CExpressionGenerator,
get_data_of_complex_string_struct,
inline_global_variable,
is_complex_string_struct,
)
from decompiler.structures.ast.syntaxtree import AbstractSyntaxTree
from decompiler.structures.pseudo import GlobalVariable, Integer, Variable
from decompiler.structures.pseudo.complextypes import Struct
Expand Down Expand Up @@ -69,7 +74,10 @@ def _generate_definitions(global_variables: set[GlobalVariable]) -> Iterator[str
br, bl = "{", "}"
yield f"{base}{variable.type.type} {variable.name}[{hex(variable.type.elements)}] = {br}{CExpressionGenerator().visit(variable.initial_value)}{bl};"
case Struct():
string = f"struct {variable.name}" + "{\n"
if is_complex_string_struct(variable.type):
yield base + f"struct {variable.type.name} {variable.name} = {CExpressionGenerator().visit(get_data_of_complex_string_struct(variable))};"
continue
string = f"struct {variable.type.name} {variable.name}" + "{\n"
for m_type, m_value in zip(variable.type.members.values(), variable.initial_value.value.values()):
value = CExpressionGenerator().visit(m_value)
string += f"\t.{m_type.name} = {value};\n"
Expand Down

0 comments on commit fffb1b4

Please sign in to comment.