def disasm_one_inst(self, inst, addr): if addr % 4 != 0: if not os.getenv("IDP_UNALIGNED_WARNING"): Warning("Unaligned instruction address: {:x} ".format(addr)) os.environ["IDP_UNALIGNED_WARNING"] = "Warned." self.log_with_addr("Unaligned instruction address.") if len(self.disasm_cache) > 0x10000: # TODO: Ideally disasm_cache would be an OrderedDict, but there's no C implementation in Pyhton 2, and this really slows it down. self.disasm_cache = {} # I'm assuming the jumps are always to packet start addresses, so I also disassemble # the rest of the packet instructions # TODO: can i assume that? i still have to disassemble till the end of the packet, always. for packet_addr in range(addr, addr + PACKET_MAX_SIZE, INST_SIZE): if idaapi.isLoaded(packet_addr): hi = self.disasm_wrapper(idaapi.get_long(packet_addr), packet_addr) if addr == packet_addr: self.log_with_addr( "Disassembling packet {:08x}: {:s}".format( packet_addr, str(hi.text))) if hi.end_packet: break else: break return self.disasm_wrapper(inst, addr)
def getConst(ea, offset): strings = [] consts = [] optype1 = idc.get_operand_type(ea, offset) if optype1 == idaapi.o_imm: imm_value = idc.get_operand_value(ea, offset) if 0<= imm_value <= 10: consts.append(imm_value) else: if idaapi.isLoaded(imm_value) and ida_segment.getseg(imm_value): str_value = idc.get_strlit_contents(imm_value) if str_value is None: str_value = idc.get_strlit_contents(imm_value+0x40000) if str_value is None: consts.append(imm_value) else: re = all(40 <= ord(c) < 128 for c in str_value) if re: strings.append(str_value) else: consts.append(imm_value) else: re = all(40 <= ord(c) < 128 for c in str_value) if re: strings.append(str_value) else: consts.append(imm_value) else: consts.append(imm_value) return strings, consts
def disasm_one_inst(self, inst, addr): if addr % 4 != 0: if not os.getenv("IDP_UNALIGNED_WARNING"): Warning("Unaligned instruction address: {:x} ".format(addr)) os.environ["IDP_UNALIGNED_WARNING"] = "Warned." self.log_with_addr("Unaligned instruction address.") if len(self.disasm_cache) > 0x10000: # TODO: Ideally disasm_cache would be an OrderedDict, but there's no C implementation in Pyhton 2, and this really slows it down. self.disasm_cache = {} # I'm assuming the jumps are always to packet start addresses, so I also disassemble # the rest of the packet instructions # TODO: can i assume that? i still have to disassemble till the end of the packet, always. for packet_addr in range(addr, addr + PACKET_MAX_SIZE, INST_SIZE): if idaapi.isLoaded(packet_addr): hi = self.disasm_wrapper(idaapi.get_long(packet_addr), packet_addr) if addr == packet_addr: self.log_with_addr("Disassembling packet {:08x}: {:s}".format(packet_addr, str(hi.text))) if hi.end_packet: break else: break return self.disasm_wrapper(inst, addr)
def find_ioctls(p, dispatch_addr): """ Returns a list of potential IOCTL codes by symbolically executing starting at the provided function address """ import pyvex import simuvex import claripy s = p.factory.blank_state(addr=dispatch_addr) pg = p.factory.path_group(s) generic_reg_vals = set() val_addr = {} steps = 0 while len(pg.active) > 0 and steps < 25: for i in pg.active: if not idaapi.isLoaded(i.addr): print('Non mapped value for addr: {}'.format(hex(i.addr))) continue print('step: {}, addr: {}'.format(steps, hex(i.addr))) for reg in i.state.arch.default_symbolic_registers: try: val = i.state.se.eval(getattr(i.state.regs, reg)) #Always use first occurrence generic_reg_vals.add(val) if val not in val_addr: val_addr[val] = i.addr except simuvex.SimUnsatError: print("failed to get {}".format(reg)) pass except claripy.errors.ClaripyZeroDivisionError: print("failed to get {}".format(reg)) pass pg.step() steps += 1 device_codes = {} generic_reg_vals = filter(lambda x: 0xfff0 > ((x >> 16) & 0xffff) > 0x10, generic_reg_vals) for i in generic_reg_vals: try: device_codes[((i >> 16) & 0xffff)] += 1 except: device_codes[((i >> 16) & 0xffff)] = 1 if len(device_codes.keys()) == 0: return [] print('potential device codes: {}'.format(device_codes)) likely_device_code = max(device_codes, key=device_codes.get) print "Likely device code: 0x%X" % (likely_device_code, ) out = [] for i in generic_reg_vals: addr = val_addr[i] if (i >> 16) & 0xffff == likely_device_code: out.append((addr, i)) return out
def set_operand_value(cpu_context, ip, value, opnd, optype, width=None): """ Function to set the operand to the specified value. :param cpu_context: current context of cpu :param ip: instruction pointer :param value: value to set operand to :param opnd: value returned by idc.GetOpnd() :param optype: value returned by idc.GetOpType() :param width: byte width of the operand value being set """ if optype == idc.o_reg: # Convert the value from string to integer... if isinstance(value, str): value = utils.struct_unpack(value) cpu_context.reg_write(opnd.upper(), value) elif optype in [idc.o_phrase, idc.o_displ]: # For data written to the frame or memory, this data MUST be in string form so convert it if numpy.issubdtype(type(value), numpy.integer): value = utils.struct_pack(value, signed=(value < 0), width=width) # These need to be handled in the same way even if they don't contain the same types of data. try: offset = utils.get_stack_offset(cpu_context, ip, 0) except ValueError: # Not a stack variable, calculate the displacement and set it using .memctrlr addr = utils.calc_displacement(cpu_context, ip, 0) cpu_context.mem_write(addr, value) else: cpu_context.mem_write(offset, value) elif optype == idc.o_mem: # FS, GS are identified as memory addresses, rather use them as registers if "fs" in opnd: cpu_context.reg_write("FS", value) elif "gs" in opnd: cpu_context.reg_write("GS", value) else: if numpy.issubdtype(type(value), numpy.integer): value = utils.struct_pack(value, signed=(value < 0), width=width) cpu_context.mem_write(idc.GetOperandValue(ip, 0), value) elif optype == idc.o_imm: offset = idc.GetOperandValue(ip, 0) if idaapi.isLoaded(offset): cpu_context.mem_write(offset, value)
def get_consts(start_addr, end_addr): consts = [] for h in idautils.Heads(start_addr, end_addr): insn = DecodeInstruction(h) if insn: for op in insn.Operands: if op.type == idaapi.o_imm: # get operand value imm_value = op.value # check if addres is loaded in idb if not idaapi.isLoaded(imm_value): consts.append(imm_value) return consts
def process_section_data(arch, section, section_end): log_message('Fetching data for section...') section_data = list() for addr in range(section, section_end): if idaapi.isLoaded(addr): section_data.append(chr(idc.Byte(addr))) else: # If there's undefined data in the middle # of a section, nothing after that point # is exported break section_data = ''.join(section_data) sect = Section(idc.SegName(section), 0, section, section_end, section_data) log_message('Inserting section data (%d bytes)...' % (len(section_data))) instrumentation.new_section(sect)
def process_section_data(arch, section, section_end): log_message('Fetching data for section...') section_data = list() for addr in range(section, section_end): if idaapi.isLoaded(addr): section_data.append( chr(idc.Byte(addr)) ) else: # If there's undefined data in the middle # of a section, nothing after that point # is exported break section_data = ''.join(section_data) sect = Section(idc.SegName(section), 0, section, section_end, section_data) log_message('Inserting section data (%d bytes)...' % (len(section_data))) instrumentation.new_section(sect)
def apply_functions(self, rename=False): ''' Apply colors to the IDA view for the selected process, and update hook so that the context option is shown whenever we right click on an address with a call within the selected process ''' self.current_selected_pid = self.get_combo_pid() for proc in self.procs: if proc.pid == self.current_selected_pid: for (addr_from, addr_to) in self.addrs[proc]: idc.SetColor(addr_from, idc.CIC_ITEM, 0x8aa7ff) if rename: for call in self.addrs[proc][(addr_from, addr_to)]: call_addr = idc.PrevHead(call.ret_addr) mnemonic = idc.GetMnem(call_addr) if mnemonic == "jmp" or mnemonic == "call": addr_to_rename = idc.GetOperandValue(call_addr, 0) if idaapi.isLoaded(addr_to_rename): idc.MakeName(addr_to_rename, call.fun) idc.MakeComm(call_addr, call.fun) # Update hooks self.hooks.set_addrs(self.addrs[proc])