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
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
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
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)
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)
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
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))
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))