예제 #1
0
def recover_variables(F, func_ea, blockset):
    """ Recover the stack variables from the function. It also collect
      the instructions referring to the stack variables.
  """
    # Checks for the stack frame; return if it is None
    if not is_code_by_flags(func_ea) or \
        not idc.GetFrame(func_ea):
        return

    functions = list()
    f_name = get_symbol_name(func_ea)
    f_ea = idc.GetFunctionAttr(func_ea, idc.FUNCATTR_START)
    f_vars = collect_function_vars(func_ea, blockset)
    functions.append({"ea": f_ea, "name": f_name, "stackArgs": f_vars})

    for offset in f_vars.keys():
        if f_vars[offset]["safe"] is False:
            continue

        var = F.stack_vars.add()
        var.sp_offset = offset
        var.name = f_vars[offset]["name"]
        var.size = f_vars[offset]["size"]
        for i in f_vars[offset]["writes"]:
            r = var.ref_eas.add()
            r.inst_ea = i["ea"]
            r.offset = i["offset"]

        for i in f_vars[offset]["reads"]:
            r = var.ref_eas.add()
            r.inst_ea = i["ea"]
            r.offset = i["offset"]
예제 #2
0
def getFunctionArgumentCount(ea):
    '''
    Bit of a hack, since IDA doesn't seem to have a good way to get this information.
    Gets the frame for a given function, and counts named members following the 'r'
    member.
    Note: IDA won't create a frame member for an unreferenced function arg... so you've
    been warned.
    '''
    rFound = False
    argCount = 0
    sid = idc.GetFrame(ea)
    midx = idc.GetFirstMember(sid)
    while midx != idc.BADADDR:
        name = idc.GetMemberName(sid, midx)
        if rFound and name is not None:
            argCount += 1 
            #print 'Found arg at 0x%x: "%s"' % (midx, name)
        elif name  == ' r':
            #print 'Found r at 0x%x:' % midx
            rFound = True
        else:
            #print 'Found nonarg at 0x%x: "%s"' % (midx, name)
            pass
        midx = idc.GetStrucNextOff(sid, midx)
    return argCount
예제 #3
0
def get_args(f):
    local_variables = []
    arguments = []
    current = local_variables

    frame = idc.GetFrame(f)
    arg_string = ""
    if frame == None:
        return None

    start = idc.GetFirstMember(frame)
    end = idc.GetLastMember(frame)
    count = 0
    max_count = 10000
    args_str = ""
    while start <= end and count <= max_count:
        size = idc.GetMemberSize(frame, start)
        count = count + 1
        if size == None:
            start = start + 1
            continue

        name = idc.GetMemberName(frame, start)
        start += size

        if name in [" r", " s"]:
            # Skip return address and base pointer
            current = arguments
            continue
        arg_string += " " + name
        current.append(name)
    if len(arguments) == 0:
        arguments.append("void")
    return arguments
예제 #4
0
    def factory(cls, string_location, string_reference, size=INVALID, offset=INVALID, key=INVALID):
        """
        Factory function to generate an EncodedString or EncodedStackString based on type.

        :param string_location:
            Data segment pointer for static strings or stack pointer for stack strings.
        :param string_reference:
            The location the string is referenced from.
            This is required to pull the stack frame when string_location is a stack pointer.
        :param size: The size of the string. Required to use self.get_bytes.
        :param offset: Used when there is an offset based accessing scheme.
        :param key: Used when there is a key that can vary by string.
        """
        if idc.isLoaded(string_location):
            return EncodedString(
                string_location, string_reference, size=size, offset=offset, key=key)

        # otherwise assume string_location is a pointer within the stack
        # (using function_tracingutils's CPU emulator) and create an EncodedStackString object.
        stack = idc.GetFrame(string_reference)
        # FIXME: This method isn't always super accurate because... IDA
        stack_offset = (
                string_location
                + function_tracingutils.RSP_OFFSET
                + idc.GetFrameLvarSize(string_reference)
                - function_tracingutils.STACK_BASE
        )

        return EncodedStackString(
            stack, stack_offset, string_reference=string_reference,
            size=size, offset=offset, key=key)
예제 #5
0
def delete_all_function_stack_members(func_ea, force=False):
    if g_vars["ERASE_STACK_MEMBERS"] or force:
        members, base = retrieve_stack_members(func_ea)
        stack_id = idc.GetFrame(func_ea)
        for k, v in members.items():
            if k != base and "arg_" not in v:
                idc.DelStrucMember(stack_id, k)
        g_functions_stack.add(func_ea.startEA)
def hasStackVars(ea):
    """
    :param ea: address of the function
    :return: whether the function has stack variables or not
    """
    id = idc.GetFrame(ea)
    firstMember = idc.GetFirstMember(id)
    return firstMember != idaapi.BADADDR and firstMember != -1
예제 #7
0
def build_stack_args(f):
  stackArgs = dict()
  name = idc.Name(f)
  end = idc.GetFunctionAttr(f, idc.FUNCATTR_END)
  _locals = idc.GetFunctionAttr(f, idc.FUNCATTR_FRSIZE)
  _uses_bp = 0 != (idc.GetFunctionFlags(f) & idc.FUNC_FRAME)
  frame = idc.GetFrame(f)
  if frame is None:
    return stackArgs

  func_type = idc.GetType(f)
  if (func_type is not None) and ("(" in func_type):
    args = func_type[ func_type.index('(')+1: func_type.rindex(')') ]
    args_list = [ x.strip() for x in args.split(',')]
    if "..." in args_list:
      return stackArgs

  if name in RECOVER_DEBUG_FL:
    return stackArgs

  #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.GetMemberOffset(frame, " s")
  if -1 == delta:
    #indicates that it wasn't found. Unsure exactly what to do
    # in that case, punting for now
    delta = 0

  offset = idc.GetFirstMember(frame)
  while -1 != _signed_from_unsigned(offset):
    memberName = idc.GetMemberName(frame, offset)
    if memberName is None:
      # gaps in stack usage are fine, but generate trash output
      # gaps also could indicate a buffer that IDA doesn't recognize
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    if (memberName == " r" or memberName == " s"):
      #the return pointer and start pointer, who cares
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    memberSize = idc.GetMemberSize(frame, offset)
    if offset >= delta:
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    memberFlag = idc.GetMemberFlag(frame, offset)
    #TODO: handle the case where a struct is encountered (FF_STRU flag)
    flag_str = _get_flags_from_bits(memberFlag)
    stackArgs[offset-delta] = {"name":memberName,
                               "size":memberSize,
                               "flags":flag_str,
                               "writes":list(),
                               "referent":list(),
                               "reads":list(),
                               "safe": False}
    offset = idc.GetStrucNextOff(frame, offset)

  return stackArgs
예제 #8
0
def find_WdfDriverCreate():
    function_offset = OFFSET_WdfDriverCreate

    # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1!
    try:
        call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm
    except StopIteration:
        # this is case 2!
        call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset)
        if call_pfnWdfDriverCreate != None:
            idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)
        else:
            call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset)
            idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)

    if call_pfnWdfDriverCreate != None:
        # First identify the RealDriverEntry :)
        current_func = idaapi.get_func(call_pfnWdfDriverCreate)
        idc.MakeName(current_func.startEA, "_DriverEntry_")

        argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0)
        register_DriverConfig = idc.GetOpnd(argument_DriverConfig_addr, 1)
        lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0)

        # Get stack and the stack operand offset
        current_func = idaapi.get_func(lea_DriverConfig_addr)
        stack_id = idc.GetFrame(current_func)
        opnd = idc.GetOpnd(lea_DriverConfig_addr, 1)
        if "rsp" in opnd:
            stack_member_offset = idc.GetOperandValue(lea_DriverConfig_addr, 1)
        elif "rbp" in opnd:
            var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80
            members, _ = retrieve_stack_members(current_func)
            inverted_members = {v:k for k, v in members.items()}
            try:
                stack_member_offset = inverted_members[var_x]
            except KeyError as msg:
                print msg
                return

        else:
            print("+] WdfDriverCreate() Unidentified register stack layout")
            return

        #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig")
        struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG")
        struct_size = idc.GetStrucSize(struct_id)

        # First check if we have already touch this function stack before
        #if function_stack_erased(current_func):
            # need to take care of the already defined structs
        #    pass
        #else:
        delete_all_function_stack_members(current_func, force=True)
        idc.AddStrucMember(stack_id, "driver_config",
                           stack_member_offset, idc.FF_BYTE|idc.FF_DATA,
                           -1, struct_size)
        idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1)
예제 #9
0
def build_stack_variable(func_ea):
  stack_vars = dict()

  frame = idc.GetFrame(func_ea)
  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.GetMemberOffset(frame, " s")
  if delta == -1:
    delta = 0

  if f_name not in _FUNC_UNSAFE_LIST:
    offset = idc.GetFirstMember(frame)
    while -1 != _signed_from_unsigned(offset):
      member_name = idc.GetMemberName(frame, offset)
      if member_name is None:
        offset = idc.GetStrucNextOff(frame, offset)
        continue
      if (member_name == " r" or member_name == " s"):
        offset = idc.GetStrucNextOff(frame, offset)
        continue

      member_size = idc.GetMemberSize(frame, offset)
      if offset >= delta:
        offset = idc.GetStrucNextOff(frame, offset)
        continue

      member_flag = idc.GetMemberFlag(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.GetStrucNextOff(frame, offset)
  else:
    offset = idc.GetFirstMember(frame)
    frame_size = idc.GetFunctionAttr(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 getStackVarDisasm(self):
        """
        if the function uses stack variables with SP, their symbols should be defined
        :return:
        """
        disasm = ''
        id = idc.GetFrame(self.func_ea)
        firstMember = idc.GetFirstMember(id)
        if hasStackVars(self.func_ea):
            # first, obtain the base by finding an instruction that uses one of the stack variables
            stackVars = getStackVars(self.func_ea)
            ea = self.func_ea
            base = -1

            # TODO: maybe use get_min_spd_ea(func_ea) to get the base pointer? this stands for stack pointer delta!

            # search function instructions to find base (TODO: hacky, but i dunno how else to find base yet)
            while ea < self.func_ea + self.getSize():
                d = Data.Data(ea)
                origDisasm = d.getOrigDisasm()
                # case where the stack frame is referenced
                for var, offset in stackVars:
                    if var in origDisasm and '#' in origDisasm:
                        # cases like LDR SP, [base+var_xx]
                        if '[' in origDisasm:
                            # grab the base
                            if '+' in origDisasm:
                                base = int(
                                    origDisasm[origDisasm.index('#') +
                                               1:origDisasm.index('+')], 16)
                            else:
                                base = 0
                            # obtained base! no need to continue looping
                            break
                        # some cases like ADD SP, base+var_xx don't have '['
                        elif '+' in origDisasm:
                            base = int(
                                origDisasm[origDisasm.index('#') +
                                           1:origDisasm.index('+')], 16)
                            # obtained base! no need to continue looping
                            break
                if base != -1:
                    break
                ea += d.getSize()
            # if base couldn't be found still, it's likely no SP access is done with variables
            if base == -1:
                base = 0

            # build up disasm based on stack vars using base-relative offsets
            for name, off in stackVars:
                relOff = base - off
                if relOff > 0:
                    disasm += ".equ %s, -0x%X\n" % (name, abs(relOff))
                else:
                    disasm += ".equ %s, 0x%X\n" % (name, abs(relOff))

        return disasm
예제 #11
0
def retrieve_stack_members(func_ea):
    members = {}
    base = None
    frame = idc.GetFrame(func_ea)
    for frame_member in idautils.StructMembers(frame):
        member_offset, member_name, _ = frame_member
        members[member_offset] = member_name
        if member_name == ' r':
            base = member_offset
    if not base:
        raise ValueError("Failed identifying the stack's base address using the return address hidden stack member")
    return members, base
예제 #12
0
def find_WdfIoQueueCreate():
    function_offset = OFFSET_WdfIoQueueCreate

    calls_to_pfn_list = []
    try:
        for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] +
                                     function_offset):
            call_pfnWdfIoQueueCreate = xref.frm
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
    except StopIteration:
        # this is case 2 or 3
        pass
    if len(calls_to_pfn_list) == 0:
        call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate(
            "call", 0, function_offset)
        if call_pfnWdfIoQueueCreate:
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
            idc.OpStroffEx(call_pfnWdfIoQueueCreate, 0,
                           (idaapi.get_struc_id("_WDFFUNCTIONS")), 0)

    if len(calls_to_pfn_list) == 0:
        call_pfnWdfIoQueueCreate = find_wdf_callback_through_immediate(
            "mov", 1, function_offset)
        if call_pfnWdfIoQueueCreate:
            calls_to_pfn_list.append(call_pfnWdfIoQueueCreate)
            idc.OpStroffEx(call_pfnWdfIoQueueCreate, 1,
                           (idaapi.get_struc_id("_WDFFUNCTIONS")), 0)

    for pfn_call in calls_to_pfn_list:
        lea_argument_addr = find_function_arg(pfn_call, "lea", "r8", 0)

        # Get stack and the stack operand offset
        current_func = idaapi.get_func(lea_argument_addr)
        stack_id = idc.GetFrame(current_func)
        stack_member_offset = idc.get_operand_value(lea_argument_addr, 1)

        struct_id = idaapi.get_struc_id("_WDF_IO_QUEUE_CONFIG")
        struct_size = idc.GetStrucSize(struct_id)

        # First check if we have already touch this function stack before
        if function_stack_erased(current_func):
            # need to take care of the already defined structs
            # If the arguments collide then this will fail
            pass
        else:
            delete_all_function_stack_members(current_func)
            print("Erased the stack members")

        idc.AddStrucMember(stack_id, "queue_config", stack_member_offset,
                           idc.FF_BYTE | idc.FF_DATA, -1, struct_size)
        idc.SetMemberType(stack_id, stack_member_offset,
                          idc.FF_STRU | idc.FF_DATA, struct_id, 1)
        print("IOQueue Creation at: " + hex(pfn_call))
예제 #13
0
def find_stack_members(func_ea):
    members = {}
    base = None
    frame = idc.GetFrame(func_ea)
    try:
        for frame_member in idautils.StructMembers(frame):
            member_offset, member_name, size = frame_member
            members[member_offset] = size
            if member_name == ' s':
                base = member_offset
        if not base:
            base = 3
    except:
        return 0, 0
    return members, base
def getStackVars(ea, base=-1):
    # type: (int, int) -> list[(str, int)]
    """
    Gets the stack variables associted with the function at ea
    If no base is specified, the offsets don't include the base calculation in them
    :param ea: the address of the function
    :param base: the stack base, must obtain to compute the offsets relative to it
    :return: a list of tuples, the stack variable name and its offset
    """
    stackVars = []
    id = idc.GetFrame(ea)

    firstMember = idc.GetFirstMember(id)
    # if the function has stack variables
    if firstMember != idaapi.BADADDR and firstMember != -1:
        # build up disasm based on stack vars
        lastMember = idc.GetLastMember(id)
        i = firstMember

        # Stack can be offset, first member might not be found at index 0, and all offsets must be adjusted by this
        foundFirstElement = False
        stackOffset = 0
        while i <= lastMember:
            name = idc.GetMemberName(id, i)
            off = idc.GetMemberOffset(
                id, name
            )  # this is the offset in the struct... which isn't always consistent!
            size = idc.GetMemberSize(id, i)
            # append if varname is found (sometimes, None is returned because the variables are not in the next index)
            if name:
                # first variable found! this is the stack of the stack variables!
                if not foundFirstElement:
                    stackOffset = i
                    foundFirstElement = True
                if base == -1:
                    # absolute offsets appended
                    stackVars.append((name, off - stackOffset))
                else:
                    # base-relative offsets appended
                    stackVars.append((name, base - off - stackOffset))
            # sometimes, for some reason, the offset for stack variables does not follow linearly
            if size:
                i += size
            else:
                # reach next var, which might not be one size unit after the last...
                while not idc.GetMemberSize(id, i) and i <= lastMember:
                    i += 1
    return stackVars
예제 #15
0
def append_lvar_comment(fva, frame_offset, s, repeatable=False):
    '''
    add the given string as a (possibly repeatable) stack variable comment to the given function.
    does not add the comment if it already exists.
    adds the comment on its own line.

    Args:
      fva (int): the address of the function with the stack variable.
      frame_offset (int): the offset into the stack frame at which the variable is found.
      s (str): the comment text.
      repeatable (bool): if True, set a repeatable comment.

    Raises:
      UnicodeEncodeError: if the given string is not ascii.
    '''
    s = s.encode('ascii')

    stack = idc.GetFrame(fva)
    if not stack:
        raise RuntimeError('failed to find stack frame for function: ' +
                           hex(fva))

    lvar_offset = idc.GetFrameLvarSize(fva) - frame_offset
    if not lvar_offset:
        raise RuntimeError('failed to compute local variable offset')

    if lvar_offset <= 0:
        raise RuntimeError('failed to compute positive local variable offset')

    string = idc.GetMemberComment(stack, lvar_offset, repeatable)
    if not string:
        string = s
    else:
        if s in string:  # ignore duplicates
            return
        string = string + "\\n" + s

    if not idc.SetMemberComment(stack, lvar_offset, string, repeatable):
        raise RuntimeError('failed to set comment')
예제 #16
0
파일: code.py 프로젝트: hakril/midap
 def stack(self):
     "Stack of the function"
     return stack.IDAStack(idc.GetFrame(self.addr), self)
예제 #17
0
파일: analysis.py 프로젝트: wzr/toolbag
    def argCount(self):
        end = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_END)
        start = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_START)
        frame = idc.GetFrame(start)
        localv = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_FRSIZE)
        frameSize = idc.GetFrameSize(start)  #idc.GetStrucSize(frame)

        reg_off = 0
        local_count = 0
        arg_count = 0
        sid = idc.GetFrame(self.addr)
        if sid:
            firstM = idc.GetFirstMember(sid)
            lastM = idc.GetLastMember(sid)
            arg_count = 0

            if lastM - firstM > 0x1000:
                return

            for i in xrange(firstM, lastM):
                mName = idc.GetMemberName(sid, i)
                mSize = idc.GetMemberSize(sid, i)
                mFlag = idc.GetMemberFlag(sid, i)
                off = idc.GetMemberOffset(sid, mName)
                #print "%s: %d, %x, off=%x" % (mName, mSize, mFlag, off)

                if mName == " r":
                    reg_off = off

            # XXX: just store the data, dont loop twice.
            for i in xrange(firstM, lastM):
                mName = idc.GetMemberName(sid, i)
                mSize = idc.GetMemberSize(sid, i)
                mFlag = idc.GetMemberFlag(sid, i)
                off = idc.GetMemberOffset(sid, mName)

                if off <= reg_off:
                    local_count += 1
                elif off > reg_off and reg_off != 0:
                    arg_count += 1

            if arg_count > 0:
                return arg_count / 4
            elif arg_count == 0:
                return 0

        # offset to return
        try:
            ret = idc.GetMemberOffset(frame, " r")
        except:
            if frameSize > localv:
                return (frameSize - localv) / 4
            # error getting function frame (or none exists)
            return -1

        if (ret < 0):
            if frameSize > localv:
                return (frameSize - localv) / 4
            return -1

        firstArg = ret + 4
        args = frameSize - firstArg
        numArgs = args / 4

        return numArgs
예제 #18
0
 def run(self):
     try:
         logger.debug('Starting up')
         dlg = StructTyperWidget()
         dlg.setStructs(loadStructs())
         oldTo = idaapi.set_script_timeout(0)
         res = dlg.exec_()
         idaapi.set_script_timeout(oldTo)
         if res == QtWidgets.QDialog.Accepted:
             regPrefix = dlg.getRegPrefix()
             sid = None
             struc = None
             if dlg.ui.rb_useStackFrame.isChecked():
                 ea = idc.here()
                 if using_ida7api:
                     sid = idc.get_frame_id(ea)
                 else:
                     sid = idc.GetFrame(ea)
                 struc = idaapi.get_frame(ea)
                 logger.debug('Dialog result: accepted stack frame')
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError(
                         'Failed to get sid for stack frame at 0x%x' % ea)
                 if (struc is None) or (struc == 0) or (struc
                                                        == idc.BADADDR):
                     raise RuntimeError(
                         'Failed to get struc_t for stack frame at 0x%x' %
                         ea)
                 if using_ida7api:
                     pass
                 else:
                     #need the actual pointer value, not the swig wrapped struc_t
                     struc = long(struc.this)
             else:
                 structName = dlg.getActiveStruct()
                 if structName is None:
                     print("No struct selected. Bailing out")
                     return
                 logger.debug('Dialog result: accepted %s "%s"',
                              type(structName), structName)
                 if using_ida7api:
                     sid = idc.get_struc_id(structName)
                 else:
                     sid = idc.GetStrucIdByName(structName)
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get sid for %s' %
                                        structName)
                 tid = idaapi.get_struc_id(structName)
                 if (tid is None) or (tid == 0) or (tid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get tid_t for %s' %
                                        structName)
                 if using_ida7api:
                     struc = idaapi.get_struc(tid)
                 else:
                     struc = g_dll.get_struc(tid)
                 if (struc is None) or (struc == 0) or (struc
                                                        == idc.BADADDR):
                     raise RuntimeError('Failed to get struc_t for %s' %
                                        structName)
             foundMembers = self.processStruct(regPrefix, struc, sid)
             if dlg.ui.rb_useStackFrame.isChecked() and (foundMembers != 0):
                 #reanalyze current function if we're analyzing a stack frame & found some func pointers
                 if using_ida7api:
                     funcstart = idc.get_func_attr(idc.here(),
                                                   idc.FUNCATTR_START)
                     funcend = idc.get_func_attr(idc.here(),
                                                 idc.FUNCATTR_END)
                 else:
                     funcstart = idc.GetFunctionAttr(
                         idc.here(), idc.FUNCATTR_START)
                     funcend = idc.GetFunctionAttr(idc.here(),
                                                   idc.FUNCATTR_END)
                 if (funcstart != idc.BADADDR) and (funcend != idc.BADADDR):
                     if using_ida7api:
                         idc.plan_and_wait(funcstart, funcend)
                     else:
                         idc.AnalyzeArea(funcstart, funcend)
         elif res == QtWidgets.QDialog.Rejected:
             logger.info('Dialog result: canceled by user')
         else:
             logger.debug('Unknown result')
             raise RuntimeError('Dialog unknown result')
     except Exception, err:
         logger.exception("Exception caught: %s", str(err))
예제 #19
0
import idautils
import ida_frame
import idc

idc.GetFrame()

# Locate local variables of function stack frames.
#
# based on: https://reverseengineering.stackexchange.com/a/14726


# from: https://gist.github.com/nirizr/fe0ce9948b3db05555da42bbfe0e5a1e
def find_stack_members(func_ea):
    members = {}
    base = None
    frame = idc.GetFrame(func_ea)
    for frame_member in idautils.StructMembers(frame):
        member_offset, member_name, _ = frame_member
        members[member_offset] = member_name
        if member_name == ' r':
            base = member_offset
    if not base:
        raise ValueError(
            "Failed identifying the stack's base address using the return address hidden stack member"
        )
    return members, base


# func_frames maps from function address to a record of the function's stack
# frame size and local variables.
func_frames = {}