def addr(self): """Retrieves the address of the argument (if a memory/stack address)""" argloc = self._funcarg_obj.argloc loc_type = argloc.atype() if loc_type == ida_typeinf.ALOC_STACK: func = ida_funcs.get_func(self._func_sig.start_ea) if utils.is_x86_64(): retaddr_size = self._cpu_context.byteness else: retaddr_size = 0 # If we are in the function, we need to account for changes made to the stack. if self._cpu_context.ip == self._func_sig.start_ea \ or (func and func.contains(self._cpu_context.ip)): # Determine adjustment of stack based on what IDA reports as the current # ESP plus the size of the saved return address. # (More reliable and cross compatible than using ebp.) # TODO: This might be a x86 only thing. Need to make ARM version. if func: sp_adjust = ida_frame.get_spd( func, self._cpu_context.ip) # this is negative else: sp_adjust = 0 return self._cpu_context.sp - sp_adjust + retaddr_size + argloc.stkoff( ) # If we are in the caller, but in the middle of hooking the call instruction we need # to account for the pushed in return address. elif self._cpu_context.hooking_call == self._func_sig.start_ea: return self._cpu_context.sp + retaddr_size + argloc.stkoff() # Otherwise, we are in the caller and should base the address off the current stack. else: return self._cpu_context.sp + argloc.stkoff() elif loc_type == ida_typeinf.ALOC_RREL: return argloc.get_ea() return None
def _get_frame(self): result = False sp = get_sp_val() ip = get_ip_val() if ip and sp: f = get_func(ip) if f: frame = get_frame(f) if frame: self.framesize = get_struc_size(frame) n = frame.memqty frame_offs = f.frregs + f.frsize self.ea = sp - get_spd(f, ip) - frame_offs for i in xrange(n): m = frame.get_member(i) if m: lvar_name = get_member_name(m.id) lvar_ea = self.ea + m.soff lvar_size = m.eoff - m.soff self.members[lvar_ea] = (lvar_name, m.soff, lvar_size, frame_offs) result = True return result