def members(id): """Yields the members of the structure identified by ``id``. Each iteration yields the ((offset,size),(name,comment,repeatable-comment)) of each member. """ st = idaapi.get_struc(id) if not st: # empty structure return size = idaapi.get_struc_size(st) offset = 0 for i in range(st.memqty): m = st.get_member(i) ms = idaapi.get_member_size(m) left, right = m.soff, m.eoff if offset < left: yield (offset, left - offset), (idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 0), idaapi.get_member_cmt(m.id, 1)) offset = left yield (offset, ms), (idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 0), idaapi.get_member_cmt(m.id, 1)) offset += ms return
def renaming_struc_member(self, sptr, mptr, newname): """ Handles renaming of two things: 1. Global Structs 2. Stack Variables :param sptr: Struct Pointer :param mptr: Member Pointer :param newname: New Member Name :return: """ sname = ida_struct.get_struc_name(sptr.id) s_type = compat.parse_struct_type(sname) # stack offset variable if isinstance(s_type, int): func_addr = s_type # compute stack frame for offset frame = idaapi.get_frame(func_addr) frame_size = idc.get_struc_size(frame) last_member_size = idaapi.get_member_size( frame.get_member(frame.memqty - 1)) # stack offset stack_offset = mptr.soff - frame_size + last_member_size size = idaapi.get_member_size(mptr) type_str = self.controller._get_type_str(mptr.flag) # do the change on a new thread self.controller.make_controller_cmd( self.controller.push_stack_variable, func_addr, stack_offset, newname, type_str, size) # actual struct elif isinstance(s_type, str): print("Not implemented") else: print("Error: bad parsing") return 0
def ida_to_angr_stack_offset(func_addr, ida_stack_off): frame = idaapi.get_frame(func_addr) if not frame: return ida_stack_off frame_size = idc.get_struc_size(frame) last_member_size = idaapi.get_member_size( frame.get_member(frame.memqty - 1)) angr_stack_off = ida_stack_off - frame_size + last_member_size return angr_stack_off
def by_offset(self, offset): '''Return the member at the specified ``offset``.''' min, max = map(lambda sz: sz + self.baseoffset, (idaapi.get_struc_first_offset(self.owner.ptr), idaapi.get_struc_last_offset(self.owner.ptr))) mptr = idaapi.get_member(self.owner.ptr, max - self.baseoffset) msize = idaapi.get_member_size(mptr) if (offset < min) or (offset >= max + msize): raise LookupError( "{:s}.instance({:s}).members.by_offset : Requested offset {:+#x} not within bounds ({:#x},{:#x})" .format(__name__, self.owner.name, offset, min, max + msize)) mem = idaapi.get_member(self.owner.ptr, offset - self.baseoffset) if mem is None: raise LookupError( "{:s}.instance({:s}).members.by_offset : Unable to find member at offset : {:+#x}" .format(__name__, self.owner.name, offset)) index = self.index(mem) return self[index]
def members(id): st = idaapi.get_struc(id) if not st: # empty structure return size = idaapi.get_struc_size(st) offset = 0 for i in range(st.memqty): m = st.get_member(i) ms = idaapi.get_member_size(m) left,right = m.soff,m.eoff if offset < left: yield (offset,left-offset), (None,None) offset = left yield (offset,ms),(idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 1)) offset += ms return
def members(id): """Return the ((offset,size),(name,comment)) of each member within the specified structure""" st = idaapi.get_struc(id) if not st: # empty structure return size = idaapi.get_struc_size(st) offset = 0 for i in range(st.memqty): m = st.get_member(i) ms = idaapi.get_member_size(m) left, right = m.soff, m.eoff if offset < left: yield (offset, left - offset), (None, None) offset = left yield (offset, ms), (idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 1)) offset += ms return
def size(self): return idaapi.get_member_size(self.ptr)
def size(self): '''Return the size of the member.''' return idaapi.get_member_size(self.ptr)
def fill_function(self, ida_func, user=None, state=None): """ Grab all relevant information from the specified user and fill the @ida_func. """ # == function name === # _func = self.pull_function(ida_func, user=user, state=state) if _func is None: return if compat.get_func_name(ida_func.start_ea) != _func.name: compat.set_ida_func_name(ida_func.start_ea, _func.name) # === comments === # # set the func comment func_comment = self.pull_comment(_func.addr, user=user, state=state) if func_comment is None: func_comment = "" #idc.set_func_cmt(_func.addr, func_comment, 1) #compat.set_ida_comment(_func.addr, func_comment, 1, func_cmt=True) # set the disassembly comments func_cmt_end = "\n" for start_ea, end_ea in idautils.Chunks(ida_func.start_ea): for head in idautils.Heads(start_ea, end_ea): if head == _func.addr: continue comment = self.pull_comment(head, user=user, state=state) if comment is not None: func_cmt_end += f"\n{hex(head)}: {comment}" #compat.set_decomp_comments(_func.addr, {head: comment}) #compat.set_ida_comment(head, comment, 0, func_cmt=False) func_comment += func_cmt_end compat.set_ida_comment(_func.addr, func_comment, 1, func_cmt=True) # === stack variables === # existing_stack_vars = {} frame = idaapi.get_frame(ida_func.start_ea) if frame is None or frame.memqty <= 0: _l.debug( "Function %#x does not have an associated function frame. Skip variable name sync-up.", ida_func.start_ea) return frame_size = idc.get_struc_size(frame) last_member_size = idaapi.get_member_size( frame.get_member(frame.memqty - 1)) for i in range(frame.memqty): member = frame.get_member(i) stack_offset = member.soff - frame_size + last_member_size existing_stack_vars[stack_offset] = member for offset, stack_var in self.pull_stack_variables( ida_func, user=user, state=state).items(): ida_offset = stack_var.get_offset(StackOffsetType.IDA) # skip if this variable already exists if ida_offset in existing_stack_vars: type_str = self._get_type_str( existing_stack_vars[ida_offset].flag) else: type_str = None if ida_offset in existing_stack_vars: if idc.get_member_name(frame.id, existing_stack_vars[ida_offset].soff) == stack_var.name \ and type_str is not None \ and stack_var.type == type_str: continue # rename the existing variable idaapi.set_member_name(frame, existing_stack_vars[ida_offset].soff, stack_var.name) # TODO: retype the existing variable # ===== update the psuedocode ==== # compat.refresh_pseudocode_view(_func.addr)