def dump(self, dst: Union[pathlib.Path, git.IndexFile]): if isinstance(dst, str): dst = pathlib.Path(dst) # dump metadata self.dump_metadata(dst) # dump functions, one file per function in ./functions/ for addr, func in self.functions.items(): path = pathlib.Path('functions').joinpath("%08x.toml" % addr) self._dump_data(dst, path, func.dump().encode()) # dump structs, one file per struct in ./structs/ for s_name, struct in self.structs.items(): path = pathlib.Path('structs').joinpath(f"{s_name}.toml") self._dump_data(dst, path, struct.dump().encode()) # dump comments self._dump_data(dst, 'comments.toml', toml.dumps(Comment.dump_many(self.comments)).encode()) # dump patches self._dump_data(dst, 'patches.toml', toml.dumps(Patch.dump_many(self.patches)).encode()) # dump global vars self._dump_data( dst, 'global_vars.toml', toml.dumps(GlobalVariable.dump_many(self.global_vars)).encode()) # dump enums self._dump_data(dst, 'enums.toml', toml.dumps(Enum.dump_many(self.enums)).encode())
def global_vars(self) -> Dict[int, GlobalVariable]: return { addr: GlobalVariable(addr, self.bv.get_symbol_at(addr) or f"data_{addr:x}") for addr, var in self.bv.data_vars.items() }
def global_var(addr): name = idaapi.get_name(addr) if not name: return None size = idaapi.get_item_size(addr) return GlobalVariable(addr, name, size=size, last_change=int(time()))
def global_var(self, addr) -> Optional[GlobalVariable]: try: var = self.bv.data_vars[addr] except KeyError: return None gvar = GlobalVariable(addr, self.bv.get_symbol_at(addr) or f"data_{addr:x}", type_str=str(var.type), size=var.type.width) return gvar
def renamed(self, ea, new_name, local_name): # #print("renamed(ea = %x, new_name = %s, local_name = %d)" % (ea, new_name, local_name)) if ida_struct.is_member_id(ea) or ida_struct.get_struc( ea) or ida_enum.get_enum_name(ea): return 0 ida_func = idaapi.get_func(ea) # global var renaming if ida_func is None: size = idaapi.get_item_size(ea) self.binsync_state_change(self.controller.push_artifact, GlobalVariable(ea, new_name, size=size)) # function name renaming elif ida_func.start_ea == ea: # grab the name instead from ida name = idc.get_func_name(ida_func.start_ea) self.binsync_state_change(self.controller.push_artifact, FunctionHeader(name, ida_func.start_ea)) return 0
def global_vars(): gvars = {} known_segs = [".data", ".bss"] for seg_name in known_segs: seg = idaapi.get_segm_by_name(seg_name) if not seg: continue for seg_ea in range(seg.start_ea, seg.end_ea): xrefs = idautils.XrefsTo(seg_ea) try: next(xrefs) except StopIteration: continue name = idaapi.get_name(seg_ea) if not name: continue gvars[seg_ea] = GlobalVariable(seg_ea, name) return gvars
def parse(cls, src: Union[pathlib.Path, git.Tree], version=None, client=None): if isinstance(src, str): src = pathlib.Path(src) state = cls(None, version=version, client=client) # load metadata try: metadata = load_toml_from_file(src, "metadata.toml", client=client) except: # metadata is not found raise MetadataNotFoundError() state.user = metadata["user"] state.version = version if version is not None else metadata["version"] # load functions function_files = list_files_in_dir(src, "functions", client=client) for func_file in function_files: try: func_toml = load_toml_from_file(src, func_file, client=client) except: pass else: func = Function.load(func_toml) state.functions[func.addr] = func # load comments try: comments_toml = load_toml_from_file(src, "comments.toml", client=client) except: pass else: comments = {} for comment in Comment.load_many(comments_toml): comments[comment.addr] = comment state.comments = comments # load patches try: patches_toml = load_toml_from_file(src, "patches.toml", client=client) except: pass else: patches = {} for patch in Patch.load_many(patches_toml): patches[patch.offset] = patch state.patches = SortedDict(patches) # load global_vars try: global_vars_toml = load_toml_from_file(src, "global_vars.toml", client=client) except: pass else: global_vars = {} for global_var in GlobalVariable.load_many(global_vars_toml): global_vars[global_var.addr] = global_var state.global_vars = SortedDict(global_vars) # load enums try: enums_toml = load_toml_from_file(src, "enums.toml", client=client) except: pass else: state.enums = { enum.name: enum for enum in Enum.load_many(enums_toml) } # load structs struct_files = list_files_in_dir(src, "structs", client=client) for struct_file in struct_files: try: struct_toml = load_toml_from_file(src, struct_file, client=client) except: pass else: struct = Struct.load(struct_toml) state.structs[struct.name] = struct # clear the dirty bit state._dirty = False return state