示例#1
0
    def _calc_displacement(self):
        """
        Calculate the displacement offset of the operand's text.

        e.g:
            word ptr [rdi+rbx]

        :return int: calculated value
        """
        addr = self.base + self.index * self.scale + self.offset
        logger.debug(
            "Calculating operand: %s -> 0x%X + 0x%X*0x%X %s 0x%X = 0x%X" %
            (self.text, self.base, self.index, self.scale,
             "-" if self.offset < 0 else "+", abs(self.offset), addr))
        if addr < 0:
            logger.debug("Address is negative, resorting to address of 0.")
            addr = 0

        # Before returning, record the stack variable that we have encountered.
        # Ignore if base is 0, because that means we don't have enough information to designate this to a variable.
        if self.base:
            stack_var = ida_frame.get_stkvar(self._insn, self._op, self.offset)
            if stack_var:
                frame_id = idc.get_frame_id(self.ip)
                member, stack_offset = stack_var
                # If the offset in the member object is different than the given stack_offset
                # then we are indexing into a variable.
                # We need to adjust the address to be pointing to the base variable address.
                var_addr = addr - (stack_offset - member.soff)
                self._cpu_context.variables.add(var_addr,
                                                frame_id=frame_id,
                                                stack_offset=member.soff,
                                                reference=self.ip)

        return addr
示例#2
0
    def _calc_displacement(self):
        """
        Calculate the displacement offset of the operand's text.

        e.g:
            word ptr [rdi+rbx]

        :return int: calculated value
        """
        size = 8 if idc.__EA64__ else 4
        insn = idaapi.insn_t()
        idaapi.decode_insn(insn, self.ip)
        op = insn.ops[self.idx]
        offset = utils.signed(op.addr, utils.get_bits())
        scale = utils.sib_scale(op)
        base_reg = utils.x86_base_reg(insn, op)
        indx_reg = utils.x86_index_reg(insn, op)
        base_val = self._cpu_context.registers[utils.reg2str(base_reg, size)]
        indx_val = self._cpu_context.registers[utils.reg2str(
            indx_reg, size)] if indx_reg != -1 else 0
        result = base_val + indx_val * scale + offset
        logger.debug("calc_displacement :: Displacement {} -> {}".format(
            self.text, result))

        # Before returning, record the frame_id and stack_offset for this address.
        # (This can become useful information for retrieving the original location of a variable)
        frame_id = idc.get_frame_id(self.ip)
        stack_var = ida_frame.get_stkvar(insn, op, offset)
        if stack_var:
            _, stack_offset = stack_var
            self._cpu_context.stack_variables[result] = (frame_id,
                                                         stack_offset)

        return result
示例#3
0
    def _calc_displacement(self):
        """
        Calculate the displacement offset of the operand's text.

        e.g:
            word ptr [rdi+rbx]

        :return int: calculated value
        """
        addr = self.base + self.index * self.scale + self.offset
        logger.debug(
            "calc_displacement :: Displacement {} -> {} + {}*{} + {} = {}".
            format(self.text, self.base, self.index, self.scale, self.offset,
                   addr))
        if addr < 0:
            logger.debug(
                'calc_displacement :: Address is negative, resorting to address of 0.'
            )
            addr = 0

        # Before returning, record the stack variable that we have encountered.
        stack_var = ida_frame.get_stkvar(self._insn, self._op, self.offset)
        if stack_var:
            frame_id = idc.get_frame_id(self.ip)
            member, stack_offset = stack_var
            # If the offset in the member object is different than the given stack_offset
            # then we are indexing into a variable.
            # We need to adjust the address to be pointing to the base variable address.
            var_addr = addr - (stack_offset - member.soff)
            self._cpu_context.variables.add(var_addr,
                                            frame_id=frame_id,
                                            stack_offset=member.soff,
                                            reference=self.ip)

        return addr
示例#4
0
 def _record_stack_variable(self, addr):
     """
     Record the stack variable encountered at the given address.
     """
     # Ignore if base is 0, because that means we don't have enough information to designate this to a variable.
     if self.base:
         stack_var = ida_frame.get_stkvar(self._insn, self._op, self.offset)
         if stack_var:
             frame_id = idc.get_frame_id(self.ip)
             member, stack_offset = stack_var
             # If the offset in the member object is different than the given stack_offset
             # then we are indexing into a variable.
             # We need to adjust the address to be pointing to the base variable address.
             var_addr = addr - (stack_offset - member.soff)
             self._cpu_context.variables.add(var_addr,
                                             frame_id=frame_id,
                                             stack_offset=member.soff,
                                             reference=self.ip)
示例#5
0
def get_stack_arg(func_addr):
    print func_addr
    args = []
    stack = idc.get_frame_id(func_addr)
    if not stack:
        return []
    firstM = idc.get_first_member(stack)
    lastM = idc.get_last_member(stack)
    i = firstM
    while i <= lastM:
        mName = idc.get_member_name(stack, i)
        mSize = idc.get_member_size(stack, i)
        if mSize:
            i = i + mSize
        else:
            i = i + 4
        if mName not in args and mName and ' s' not in mName and ' r' not in mName:
            args.append(mName)
    return args
def get_stackVariables(func_addr):
    #print func_addr
    args = []
    stack = idc.get_frame_id(func_addr)
    if not stack:
            return 0
    firstM = idc.get_first_member(stack)
    lastM = idc.get_last_member(stack)
    i = firstM
    while i <=lastM:
        mName = idc.get_member_name(stack,i)
        mSize = idc.get_member_size(stack,i)
        if mSize:
                i = i + mSize
        else:
                i = i+4
        if mName not in args and mName and 'var_' in mName:
            args.append(mName)
    return len(args)
示例#7
0
def get_local_vars(ea, stack_size):
    # can be used to get member size, type, etc.
    local_variables = []
    for mem in ida_struct.get_struc(idc.get_frame_id(ea)).members:
        local_variables.append(Local_variable(mem, stack_size, ea))
    return local_variables
示例#8
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))
示例#9
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))