Пример #1
0
    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
Пример #3
0
    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)
Пример #4
0
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
Пример #5
0
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)
Пример #6
0
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
Пример #7
0
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)
Пример #8
0
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])