Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented the GlobalVariable type change/monitoring #126

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion libbs/decompilers/ida/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -1261,14 +1261,30 @@ def global_var(addr):
if not name:
return None

type_ = idc.get_type(addr)
size = idaapi.get_item_size(addr)
return GlobalVariable(addr, name, size=size, last_change=datetime.datetime.now(tz=datetime.timezone.utc))
return GlobalVariable(addr, name, size=size, last_change=datetime.datetime.now(tz=datetime.timezone.utc), type_=type_)


@execute_write
def set_global_var_name(var_addr, name):
return idaapi.set_name(var_addr, name)

@execute_write
def set_global_var_type(var_addr, type_str):
"""
To make sure the type is correctly displayed (especially for arrays of structs, or arrayy of chars, a.k.a. strings),
we first undefine the items where the type is going to be applied.
Parse the applied type string to infer its size, and thus the number of bytes to undefine.
"""
tif = convert_type_str_to_ida_type(type_str)
if tif is None:
idc.del_items(var_addr, flags=idc.DELIT_SIMPLE)
else:
type_size = tif.get_size()
idc.del_items(var_addr, flags=idc.DELIT_SIMPLE, nbytes=type_size)
return idc.SetType(var_addr, type_str)


def ida_type_from_serialized(typ: bytes, fields: bytes):
tif = ida_typeinf.tinfo_t()
Expand Down
7 changes: 6 additions & 1 deletion libbs/decompilers/ida/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ def ti_changed(self, ea, type_, fields):
self.interface.function_header_changed(
FunctionHeader(None, ea, type_=curr_ret_type, args={})
)
elif not pfn:
# Must be a global variable type change
self.interface.global_variable_changed(
GlobalVariable(addr=ea, name=idaapi.get_name(ea), size=idaapi.get_item_size(ea), type_=idc.get_type(ea))
)

return 0

Expand Down Expand Up @@ -456,7 +461,7 @@ def renamed(self, ea, new_name, local_name):
# symbols changing without any corresponding func is assumed to be global var
if ida_func is None:
self.interface.global_variable_changed(
GlobalVariable(ea, new_name, size=idaapi.get_item_size(ea))
GlobalVariable(ea, new_name, size=idaapi.get_item_size(ea), type_=idc.get_type(ea))
)
# function name renaming
elif ida_func.start_ea == ea:
Expand Down
8 changes: 5 additions & 3 deletions libbs/decompilers/ida/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,13 @@ def _set_stack_variable(self, svar: StackVariable, **kwargs) -> bool:

# global variables
def _set_global_variable(self, gvar: GlobalVariable, **kwargs) -> bool:
# TODO: needs type setting implementation!
modified = False
if gvar.name:
return compat.set_global_var_name(gvar.addr, gvar.name)
modified |= compat.set_global_var_name(gvar.addr, gvar.name)
if gvar.type:
modified |= compat.set_global_var_type(gvar.addr, gvar.type)

return False
return modified

def _get_global_var(self, addr) -> Optional[GlobalVariable]:
return compat.global_var(addr)
Expand Down
Loading