Skip to content

Commit

Permalink
Implemented the GlobalVariable type change/monitoring (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
themaks authored Oct 14, 2024
1 parent 54bad0f commit 805da6a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
18 changes: 17 additions & 1 deletion libbs/decompilers/ida/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -1263,14 +1263,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

0 comments on commit 805da6a

Please sign in to comment.