def value(self): """The unpacked data the variable is pointing to.""" if self.is_func_ptr: return self.addr if self.is_stack: flag = idc.get_member_flag(self.frame_id, self.stack_offset) data_type = flag & idc.DT_TYPE # Unpack if an integer type. if data_type in self.SIZE_MAP: data_type_size = self.SIZE_MAP[data_type] if self.size == data_type_size: return utils.struct_unpack(self.data) else: # If data size is greater than type size, then we have an array. data = self.data return [ utils.struct_unpack(data[i:i + data_type_size]) for i in range(0, len(data), data_type_size) ] else: return self.data else: # TODO: Determine how to unpack based on type for global variables. return self.data
def _read_struct_member(struct, sid, union, ea, offset, name, size, asobject): """Read a member into a struct for read_struct.""" flags = idc.get_member_flag(sid, offset) assert flags != -1 # Extra information for parsing a struct. member_sid, member_ssize = None, None if ida_bytes.is_struct(flags): member_sid = idc.get_member_strid(sid, offset) member_ssize = ida_struct.get_struc_size(member_sid) # Get the address of the start of the member. member = ea if not union: member += offset # Now parse out the value. array = [] processed = 0 while processed < size: value, read = _read_struct_member_once(member + processed, flags, size, member_sid, member_ssize, asobject) assert size % read == 0 array.append(value) processed += read if len(array) == 1: value = array[0] else: value = array struct[name] = value
def __iter__(self): m_off = get_first_member(self._sid) while m_off != BADADDR and m_off != -1: if get_member_flag(self._sid, m_off) != -1: yield LocalVariable(self._sid, m_off) m_off = get_next_offset(self._sid, m_off)
def build_stack_variable(func_ea): stack_vars = dict() frame = idc.get_func_attr(func_ea, idc.FUNCATTR_FRAME) if not frame: return stack_vars f_name = get_symbol_name(func_ea) #grab the offset of the stored frame pointer, so that #we can correlate offsets correctly in referent code # e.g., EBP+(-0x4) will match up to the -0x4 offset delta = idc.get_member_offset(frame, " s") if delta == -1: delta = 0 if f_name not in _FUNC_UNSAFE_LIST: offset = idc.get_first_member(frame) while -1 != _signed_from_unsigned(offset): member_name = idc.get_member_name(frame, offset) if member_name is None: offset = idc.get_next_offset(frame, offset) continue if (member_name == " r" or member_name == " s"): offset = idc.get_next_offset(frame, offset) continue member_size = idc.get_member_size(frame, offset) if offset >= delta: offset = idc.get_next_offset(frame, offset) continue member_flag = idc.get_member_flag(frame, offset) flag_str = _get_flags_from_bits(member_flag) member_offset = offset - delta stack_vars[member_offset] = { "name": member_name, "size": member_size, "flags": flag_str, "writes": list(), "referent": list(), "reads": list(), "safe": False } offset = idc.get_next_offset(frame, offset) else: offset = idc.get_first_member(frame) frame_size = idc.get_func_attr(func_ea, idc.FUNCATTR_FRSIZE) flag_str = "" member_offset = _signed_from_unsigned(offset) - delta stack_vars[member_offset] = { "name": f_name, "size": frame_size, "flags": flag_str, "writes": list(), "referent": list(), "reads": list(), "safe": False } return stack_vars
def members(self): m_off = get_first_member(self._sid) while m_off != BADADDR and m_off != -1: if get_member_flag(self._sid, m_off) != -1: yield StructureMember(self._sid, m_off) m_off = get_next_offset(self._sid, m_off)