Esempio n. 1
0
	def set_jit_info(self, method_id, start):

		end = self.get_func_end(start)

		if (end < start or end - start > self.jit_max_size):
			return

		method = next((x for x in self.as3dump if x["id"] == method_id), None)

		if (method is None):
			return

		stackvars = self.get_stack_vars(start, end)
		save_eip = self.get_save_eip(method, stackvars)

		ea = start
		while (ea < end):
	
			if ("ebp" in idc.print_operand(ea, 0) and idc.get_operand_type(ea, 1) == idc.o_imm):
	
				op0 = idc.get_operand_value(ea, 0)
				op1 = idc.get_operand_value(ea, 1)
	
				if (op0 == save_eip):
					idc.set_cmt(ea, method["instructions"][op1], 0)
		
			ea += idc.get_item_size(ea)
Esempio n. 2
0
 def find_main_x86(self):
     start = ida_ida.inf_get_start_ea()
     fn = idaapi.get_func(start)
     f_start, f_end = fn.start_ea, fn.end_ea
     eas = list(idautils.Heads(f_start, f_end))
     mnem = idc.print_insn_mnem(eas[-1])
     if mnem == 'jmp':
         return idc.get_operand_value(eas[-1], 0)
     elif mnem == 'call':
         for i in range(len(list(eas)) - 2, -1, -1):
             mnem = idc.print_insn_mnem(eas[i])
             if mnem == 'push':
                 return idc.get_operand_value(eas[i], 0)
     else:
         print(idc.GetDisasm(eas[-1]))
         return 0
Esempio n. 3
0
def getMinorDispatchTableAddress(ea):
    """find address of last lea in function"""
    start = idc.get_func_attr(ea, idc.FUNCATTR_START)
    end = idc.prev_head(idc.get_func_attr(ea, idc.FUNCATTR_END), start)
    res = prevMnemonic(end, 'lea', start)
    assert res != idc.BADADDR
    return idc.get_operand_value(res, 1)
Esempio n. 4
0
def find_lua_function_array(start, end):
    for head in idautils.Heads(start, end):
        disasm = idc.generate_disasm_line(head, 2)
        if disasm.startswith('lea '):
            result = idc.get_operand_value(head, 1)
            return result
    raise RuntimeError('Unable to find Lua function array near 0x%08x' % start)
Esempio n. 5
0
def disassemble_func(address):
    func_dis = {}
    symbolic_calls = {}
    inst_num = 0
    flags = get_func_flags(address)
    last_addr = address
    asm = ''
    for addr in FuncItems(address):
        ins = DecodeInstruction(addr)
        # print('decoded')
        byte_instr = get_bytes(addr, ins.size)
        asm = asm + str(binascii.hexlify(byte_instr))
        inst_num = inst_num + 1
        last_addr = addr
        if idc.print_insn_mnem(addr) in ["call"]:
            # print('Call:'+str(ins))
            call_address = idc.get_operand_value(addr, 0)
            # print(call_address)
            start_addr = first_func_chunk(call_address)
            symbolic_calls[start_addr] = idc.get_func_name(call_address)

    func_dis['bytecode'] = asm
    func_dis['symbolic_calls'] = symbolic_calls
    func_dis['start_address'] = first_fusnc_chunk(address)
    func_dis['end_address'] = last_addr
    func_dis['segment_address'] = get_segm_start(address)
    func_dis['segment_name'] = SegName(address)
    func_dis['name'] = idc.get_func_name(address)
    func_dis['inst_numbers'] = inst_num
    # attenzione sta cosa ci da la roba riconosciuta con flirt.
    func_dis['library_flag'] = flags & FUNC_LIB
    return func_dis
Esempio n. 6
0
 def handle_mov(self, state):
     """Updates the state of the stack string finding based on a mov instruction"""
     op1 = tracing.get_opnd_replacement(state.ea, POS_FIRST)
     if '[' in op1:
         offset = tracing.get_operand_value_replacement(state.ea, POS_FIRST, state)
         self.set_stack(offset, state.ea, POS_SECOND, state)
     else:
         reg = tracing.get_reg_fam(op1)
         type_ = idc.get_operand_type(state.ea, POS_SECOND)
         if reg:
             if type_ != idc.o_phrase and type_ != idc.o_displ:
                 if type_ == idc.o_reg:
                     reg2 = tracing.get_reg_fam(tracing.get_opnd_replacement(state.ea, POS_SECOND))
                     if reg2 and reg2[0] in state.regs:
                         val = state.regs[reg2[0]][0]
                     else:
                         val = None
                 else:
                     val = idc.get_operand_value(state.ea, POS_SECOND)
                 if val is not None:
                     state.regs[reg[0]] = (val, state.ea)
             else:
                 offset = tracing.get_operand_value_replacement(state.ea, POS_SECOND, state)
                 value = state.stack.get(offset, None)
                 if value is not None:
                     state.regs[reg[0]] = value
                 else:
                     self.clear_reg_if_needed(reg, state.regs)
Esempio n. 7
0
 def lookForOpArgs(self, start, end):
     for head in idautils.Heads(start, end):
         try:
             for i in range(2):
                 if using_ida7api:
                     t = idc.get_operand_type(head, i)
                 else:
                     t = idc.GetOpType(head, i)
                 if t == idc.o_imm:
                     if using_ida7api:
                         opval = idc.get_operand_value(head, i)
                     else:
                         opval = idc.GetOperandValue(head, i)
                     if self.params.useXORSeed:
                         opval = opval ^ self.params.XORSeed
                     for h in self.params.hashTypes:
                         hits = self.dbstore.getSymbolByTypeHash(
                             h.hashType, opval)
                         for sym in hits:
                             logger.info("0x%08x: %s", head, str(sym))
                             self.addHit(head, sym)
                             self.markupLine(head, sym,
                                             self.params.useDecompiler)
         except Exception as err:
             logger.exception("Exception: %s", str(err))
Esempio n. 8
0
def find_WdfControlDeviceInitAllocate():
    function_offset = OFFSET_WdfControlDeviceInitAllocate
    call_pfn = None
    try:
        for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] +
                                     function_offset):
            call_pfn = xref.frm
    except StopIteration:
        # this is case 2 or 3
        pass
    if call_pfn is None:
        call_pfn = find_wdf_callback_through_immediate("call", 0,
                                                       function_offset)
        if call_pfn:
            idc.OpStroffEx(call_pfn, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")),
                           0)

    if call_pfn is None:
        call_pfn = find_wdf_callback_through_immediate("mov", 1,
                                                       function_offset)
        if call_pfn:
            idc.OpStroffEx(call_pfn, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")),
                           0)

    lea_sddl = find_function_arg(call_pfn, "lea", "r8", 0)
    unicode_sddl = idc.get_operand_value(lea_sddl, 1)
    idc.set_name(unicode_sddl, 'control_device_sddl')
    assign_struct_to_address(unicode_sddl, "_UNICODE_STRING")
    print(("Control Device SDDL at: ", hex(unicode_sddl)))
Esempio n. 9
0
    def value(self):
        """
        Retrieve the value of the operand as it is currently in the cpu_context.
        NOTE: We can't cache this value because the value may change based on the cpu context.

        :return int: An integer of the operand value.
        """
        if self.is_hidden:
            return None

        if self.is_immediate:
            value = idc.get_operand_value(self.ip, self.idx)
            # Create variable/reference if global.
            if idc.is_loaded(value):
                self._cpu_context.variables.add(value, reference=self.ip)
            return value

        if self.is_register:
            value = self._cpu_context.registers[self.text]
            # Record reference if register is a variable address.
            if value in self._cpu_context.variables:
                self._cpu_context.variables[value].add_reference(self.ip)
            return value

        # TODO: Determine if this is still necessary.
        # FS, GS (at least) registers are identified as memory addresses.  We need to identify them as registers
        # and handle them as such
        if self.type == idc.o_mem:
            if "fs" in self.text:
                return self._cpu_context.registers.fs
            elif "gs" in self.text:
                return self._cpu_context.registers.gs

        # If a memory reference, return read in memory.
        if self.is_memory_reference:
            addr = self.addr

            # Record referenc if address is a variable address.
            if addr in self._cpu_context.variables:
                self._cpu_context.variables[addr].add_reference(self.ip)

            # If a function pointer, we want to return the address.
            # This is because a function may be seen as a memory reference, but we don't
            # want to dereference it in case it in a non-call instruction.
            # (e.g.  "mov  esi, ds:LoadLibraryA")
            # NOTE: Must use internal function to avoid recursive loop.
            if utils.is_func_ptr(addr):
                return addr

            # Return empty
            if not self.width:
                logger.debug("Width is zero for {}, returning empty string.".format(self.text))
                return b""

            # Otherwise, dereference the address.
            value = self._cpu_context.mem_read(addr, self.width)
            return utils.struct_unpack(value)

        raise FunctionTracingError("Invalid operand type: {}".format(self.type), ip=self.ip)
Esempio n. 10
0
def get_opnd_replacement(ea, pos):
    """ A replacement for IDA's idc.print_operand that can de-alias register names"""
    # TODO: Support renames in other operand types
    if idc.get_operand_type(ea, pos) == idc.o_reg:
        return idaapi.get_reg_name(idc.get_operand_value(ea, pos),
                                   get_byte_size_of_operand(ea, pos))
    else:
        return idc.print_operand(ea, pos)
Esempio n. 11
0
def getDispatchCode(ea):
    # get dispatch code out of an instruction
    first, second = (idc.print_operand(ea, 0), idc.get_operand_value(ea, 1))
    if first == 'eax':
        return second
    raise ValueError(
        "Search resulted in address %08x, but instruction '%s' does fulfill requested constraints"
        % (ea, idc.print_insn_mnem(ea)))
Esempio n. 12
0
 def is_libc_syscall(self, mnemonic, instr_addr):
     """
     Is it a libc _syscall()?
     """
     if mnemonic in self.call_mnemonics:
         target = idc.get_operand_value(instr_addr, 0)
         target_name = idc.GetFunctionName(target)
         return target_name in self.syscall_functions
Esempio n. 13
0
 def set_types(self):
     """ handle (EFI_BOOT_SERVICES *) type """
     RAX = 0
     O_REG = 1
     O_MEM = 2
     EFI_BOOT_SERVICES = "EFI_BOOT_SERVICES *"
     empty = True
     for service in self.gBServices:
         for address in self.gBServices[service]:
             ea = address
             num_of_attempts = 10
             for _ in range(num_of_attempts):
                 ea = idc.prev_head(ea)
                 if (idc.GetMnem(ea) == "mov"
                         and idc.get_operand_type(ea, 1) == O_MEM):
                     if (idc.get_operand_type(ea, 0) == O_REG
                             and idc.get_operand_value(ea, 0) == RAX):
                         gBs_var = idc.get_operand_value(ea, 1)
                         gBs_var_type = idc.get_type(gBs_var)
                         if (gBs_var_type == "EFI_BOOT_SERVICES *"):
                             empty = False
                             print("[{0}] EFI_BOOT_SERVICES->{1}".format(
                                 hex(address).replace("L", ""), service))
                             print("\t [address] {0}".format(
                                 hex(gBs_var).replace("L", "")))
                             print("\t [message] type already applied")
                             break
                         if idc.SetType(gBs_var, EFI_BOOT_SERVICES):
                             empty = False
                             old_name = idc.Name(gBs_var)
                             idc.MakeName(gBs_var, "gBs_" + old_name)
                             print("[{0}] EFI_BOOT_SERVICES->{1}".format(
                                 hex(address).replace("L", ""), service))
                             print("\t [address] {0}".format(
                                 hex(gBs_var).replace("L", "")))
                             print("\t [message] type successfully applied")
                         else:
                             empty = False
                             print("[{0}] EFI_BOOT_SERVICES->{1}".format(
                                 hex(address).replace("L", ""), service))
                             print("\t [address] {0}".format(
                                 hex(gBs_var).replace("L", "")))
                             print("\t [message] type not applied")
                         break
     if empty:
         print(" * list is empty")
Esempio n. 14
0
def _get_decompiled_function(offset: int) -> "ida_hexrays.cfuncptr_t":
    """
    Attempt to decompile the function containing offset and return the obtained cfuncptr_t object. Additionaly sets the
    type for all decompiled functions.
    :param offset: offset of interest
    :return: a cfuncptr_t object or None
    """
    # This requires Hexrays decompiler, load it and make sure it's available before continuing.
    if not ida_hexrays.init_hexrays_plugin():
        if is_x86_64():
            idc.load_and_run_plugin("hexrays", 0) or idc.load_and_run_plugin(
                "hexx64", 0)
        else:
            idc.load_and_run_plugin("hexarm", 0) or idc.load_and_run_plugin(
                "hexarm64", 0)
    if not ida_hexrays.init_hexrays_plugin():
        raise RuntimeError("Unable to load Hexrays decompiler.")

    decompiled = None
    offsets_to_decompile = [offset]  # LIFO list of offsets to try to decompile
    offsets_attempted = set(
    )  # Offsets already attempted to decompile, whether successful or not
    offsets_decompiled = set()  # Set of offsets that successfully decompiled
    # Continue trying to decompile until the list of offsets to decompile is empty or we get an error we can't handle
    # TODO: Determine what errors we can actually handle
    while offsets_to_decompile:
        _offset = offsets_to_decompile.pop()
        # This check means we have probably hit a snag preventing us from decompiling all together, and should prevent
        # an endless loop of continuously trying to decompile
        if _offset in offsets_decompiled:  # already decompiled, but still causing a problem?
            raise RuntimeError(
                "Unable to decompile function 0x{:X}".format(offset))

        offsets_attempted.add(_offset)
        decompiled, hf = _decompile(_offset)
        if decompiled and not hf.code:  # successful decompilation, add to set of decompiled, and remove from attempted
            # set the type
            _set_decompiled_func_type(_offset, decompiled)
            offsets_decompiled.add(_offset)
            offsets_attempted.remove(_offset)
        else:  # unsuccessful...
            if not hf.code in DECOMPILE_ERRORS:  # cannot possibly recover
                raise RuntimeError(
                    "Unable to decompile function at 0x{:X}".format(offset))

            # Can possibly recover by decompiling called functions
            # add the current offset back to the LIFO list to try decompiling a second time
            offsets_to_decompile.append(_offset)
            # get the address where the analysis failed, pull its operand, and add to the stack
            call_ea = idc.get_operand_value(hf.errea, 0)
            # can't continue if this address was already attempted
            if call_ea in offsets_attempted:
                raise RuntimeError(
                    "Unable to decompile function at 0x{:X}".format(offset))

            offsets_to_decompile.append(call_ea)

    return decompiled
Esempio n. 15
0
 def set_types(self):
     """
     handle (EFI_BOOT_SERVICES *) type
     and (EFI_SYSTEM_TABLE *) for x64 images
     """
     RAX = 0
     O_REG = 1
     O_MEM = 2
     EFI_BOOT_SERVICES = 'EFI_BOOT_SERVICES *'
     EFI_SYSTEM_TABLE = 'EFI_SYSTEM_TABLE *'
     empty = True
     for service in self.gBServices:
         for address in self.gBServices[service]:
             ea = address
             num_of_attempts = 10
             for _ in range(num_of_attempts):
                 ea = idc.prev_head(ea)
                 if (idc.print_insn_mnem(ea) == 'mov'
                         and idc.get_operand_type(ea, 1) == O_MEM):
                     if (idc.get_operand_type(ea, 0) == O_REG
                             and idc.get_operand_value(ea, 0) == RAX):
                         gvar = idc.get_operand_value(ea, 1)
                         gvar_type = idc.get_type(gvar)
                         # if (EFI_SYSTEM_TABLE *)
                         if ((gvar_type != 'EFI_SYSTEM_TABLE *')
                                 and (idc.print_operand(
                                     address, 0).find('rax') == 1)):
                             if self._find_est(gvar, ea, address):
                                 print(
                                     f'[ {gvar:016X} ] Type ({EFI_SYSTEM_TABLE}) successfully applied'
                                 )
                                 empty = False
                                 break
                         # otherwise it (EFI_BOOT_SERVICES *)
                         if (gvar_type != 'EFI_BOOT_SERVICES *'
                                 and gvar_type != 'EFI_SYSTEM_TABLE *'):
                             if idc.SetType(gvar, EFI_BOOT_SERVICES):
                                 empty = False
                                 idc.set_name(gvar, f'gBS_{gvar:X}')
                                 print(
                                     f'[ {gvar:016X} ] Type ({EFI_BOOT_SERVICES}) successfully applied'
                                 )
                         break
     if empty:
         print(' * list is empty')
Esempio n. 16
0
    def find_iat_ptrs(self, pe, image_base, size, get_word):
        """Find all likely IAT pointers"""
        iat_ptrs = []

        next_offset = image_base

        while next_offset < image_base + size:
            offset = next_offset
            next_offset = ida_bytes.next_addr(offset)

            # Attempt to read the current instruction's effective memory address operand (if present)
            mnem = idc.print_insn_mnem(offset).lower()
            ptr = 0

            if mnem in ["call", "push", "jmp"]:
                if idc.get_operand_type(offset, 0) == idc.o_mem:
                    # Get memory offset for branch instructions
                    ptr = idc.get_operand_value(offset, 0)
            elif mnem in ["mov", "lea"]:
                if idc.get_operand_type(offset, 0) == idc.o_reg and idc.get_operand_type(offset, 1) == idc.o_mem:
                    # Get memory offset for mov/lea instructions
                    ptr = idc.get_operand_value(offset, 1)

            # Does the instruction's memory address operand seem somewhat valid?!
            if ptr < 0x1000:
                continue

            # Resolve pointer from memory operand
            iat_offset = get_word(ptr)

            # Ignore offset if it is in our image
            if image_base <= iat_offset <= image_base + size:
                continue

            # Get module and API name for offset
            module, api = self.resolve_address(iat_offset)

            # Ignore the offset if it is in a debug segment or stack etc
            if api and module and module.endswith(".dll"):
                if not iat_offset in iat_ptrs:
                    # Add IAT offset, address to patch, module name and API name to list
                    iat_ptrs.append((iat_offset, offset + idc.get_item_size(offset) - 4, module, api))

        self.ret = iat_ptrs
        return self.ret
Esempio n. 17
0
 def _find_est(self, gvar, start, end):
     REG_RAX = 0
     BS_OFFSET = 0x60
     EFI_SYSTEM_TABLE = "EFI_SYSTEM_TABLE *"
     if self.arch == "x86":
         BS_OFFSET = 0x3C
     ea = start
     while ea < end:
         if (
             (idc.print_insn_mnem(ea) == "mov")
             and (idc.get_operand_value(ea, 0) == REG_RAX)
             and (idc.get_operand_value(ea, 1) == BS_OFFSET)
         ):
             if idc.SetType(gvar, EFI_SYSTEM_TABLE):
                 idc.set_name(gvar, f"gST_{gvar:X}")
                 return True
         ea = idc.next_head(ea)
     return False
Esempio n. 18
0
 def get_boot_services(self):
     for ea_start in idautils.Functions():
         for ea in idautils.FuncItems(ea_start):
             for service_name in OFFSET:
                 if (idc.GetMnem(ea) == "call" and \
                     idc.get_operand_value(ea, 0) == OFFSET[service_name]
                     ):
                     if self.gBServices[service_name].count(ea) == 0:
                         self.gBServices[service_name].append(ea)
def getLastImmediateRegisterValue(address, regIndex):
    while True:

        if (idc.get_operand_value(address, 0) == regIndex):
            mnem = idc.print_insn_mnem(address)

            if (mnem == "li"):
                return idc.get_operand_value(address, 1)
            elif (mnem == "move"):
                regIndex = idc.get_operand_value(address, 1)
                if (regIndex == 0):
                    return 0

                return getLastImmediateRegisterValue(address - 4, regIndex)
            else:
                return getLastImmediateRegisterValue(address - 4, regIndex)

        address -= 4
Esempio n. 20
0
File: insn.py Progetto: clayne/capa
def extract_insn_obfs_call_plus_5_characteristic_features(f, bb, insn):
    """
    parse call $+5 instruction from the given instruction.
    """
    if not idaapi.is_call_insn(insn):
        return

    if insn.ea + 5 == idc.get_operand_value(insn.ea, 0):
        yield Characteristic("call $+5"), insn.ea
Esempio n. 21
0
def can_be_ignored(instr_addr):
    """
    Checks whether or not an instruction can be ignored.
    An instruction can be ignored if it does not actually an arithmetic or bitwise computation,
    although it has a mnemonic that falls into that category.
    Example: xor eax, eax
    """
    # ignore instructions that are "abused" for non-arithmetic purposes
    if idc.GetMnem(instr_addr) in ['xor', 'sub']:
        same_op_type = idc.get_operand_type(instr_addr,
                                            0) == idc.get_operand_type(
                                                instr_addr, 1)
        same_op_value = idc.get_operand_value(instr_addr,
                                              0) == idc.get_operand_value(
                                                  instr_addr, 1)
        if same_op_type and same_op_value:
            return True

        return False
Esempio n. 22
0
	def get_stack_vars(self, start, end):

		stackvars = {}
	
		ea = start
		while (ea < end):
	
			if ("ebp" in idc.print_operand(ea, 0) and idc.get_operand_type(ea, 1) == idc.o_imm):
	
				op0 = idc.get_operand_value(ea, 0)
				op1 = idc.get_operand_value(ea, 1)
	
				if (op0 in stackvars):
					stackvars[op0]["values"].append(op1)
				else:
					stackvars[op0] = {"values": [], "hits": 0}
	
			ea += idc.get_item_size(ea)

		return stackvars
Esempio n. 23
0
 def apply_iat(self, iat):
     min_ea = ida_ida.inf_get_min_ea()
     max_ea = ida_ida.inf_get_max_ea()
     image_base = ida_nalt.get_imagebase()
     idaapi.msg(f"{hex(min_ea)} - {hex(max_ea)} - {hex(image_base)} \n")
     for i in range(min_ea, max_ea):
         mnemonic = idc.print_insn_mnem(i)
         if mnemonic == "call" and str(idc.print_operand(
                 i, 0)).startswith("dword"):
             try:
                 idc.set_name(
                     idc.get_operand_value(i, 0),
                     iat[hex(idc.get_operand_value(i, 0))] +
                     str(random.randint(0, 1000))
                 )  # I added random.randint() because some functions already in the IAT are dynamically resolved again, so renaming them causes a conflict, if you want remove it. (Sample causing the problem: https://bazaar.abuse.ch/sample/49fd52a3f3d1d46dc065217e588d1d29fba4d978cd8fdb2887fd603320540f71/)
                 open("resolved_iat.txt",
                      "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
             except:
                 open("unresolved_iat.txt",
                      "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
Esempio n. 24
0
def get_position_and_translate():
    """
    Gets the current selected address and decodes the second parameter to the instruction if it exists/is an immediate
    then adds the C define for the code as a comment and prints a summary table of all decoded IOCTL codes.
    """

    pos = idc.get_screen_ea()
    if idc.get_operand_type(pos, 1) != 5:   # Check the second operand to the instruction is an immediate
        return
    
    value = idc.get_operand_value(pos)
    ioctl_tracker.add_ioctl(pos, value)
    define = ioctl_decoder.get_define(value)
    make_comment(pos, define)
    # Print summary table each time a new IOCTL code is decoded
    ioctls = []
    for inst in ioctl_tracker.ioctl_locs:
        value = idc.get_operand_value(inst)
        ioctls.append((inst, value))
    ioctl_tracker.print_table(ioctls)
Esempio n. 25
0
    def find_main(rom_addr, rom_end):
        # '00 00 00 00 ? ? ? ? 00 00 00 00 4D 00 00 00'
        addr, _ = masked_search(rom_addr, rom_end,
                                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4D\x00\x00\x00',
                                b'\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')

        if addr != idaapi.BADADDR:
            addr += 4
            addr = idc.get_operand_value(addr, 0)

        return addr
Esempio n. 26
0
 def value(self):
     # operand is an immediate value  => immediate value
     # operand has a displacement     => displacement
     # operand is a direct memory ref => memory address
     # operand is a register          => register number
     # operand is a register phrase   => phrase number
     # otherwise                      => -1
     value = get_operand_value(self.__ea, self.__n)
     if value == -1:
         raise Exception("get_operand_value() for %s has failed" % self)
     return value
Esempio n. 27
0
    def findRspRbpDifference(curr_ea):
        difference = 0
        for i in range(0, 256):
            mnem = idc.print_insn_mnem(curr_ea)
            debug(mnem)
            idaapi.decode_insn(insn, curr_ea)
            if mnem == 'push':
                push_offset = 8
                difference += push_offset
            elif mnem == 'sub':
                if idc.get_operand_value(
                        curr_ea, 0
                ) == OperandValueRegister.RSP and idc.get_operand_type(
                        curr_ea, 1) == OperandType.IMMEDIATE_VALUE:
                    rsp_substraction = idc.get_operand_value(curr_ea, 1)
                    difference += rsp_substraction
            elif mnem == 'mov' or mnem == 'lea':
                #debug('type: ', idc.get_operand_type(curr_ea, 0), ' val: ', idc.get_operand_value(curr_ea, 0))
                debug(idc.generate_disasm_line(curr_ea, 0))
                if idc.get_operand_value(curr_ea,
                                         0) == OperandValueRegister.RBP:
                    debug(
                        mnem, ' type: ', idc.get_operand_type(curr_ea,
                                                              1), ' val: ',
                        'bp: 0x{:X}'.format(idc.get_operand_value(curr_ea, 1)))

                    #case 1: mov
                    if mnem == 'mov':
                        if idc.get_operand_type(
                                curr_ea, 1
                        ) == OperandType.GENERAL_REG and idc.get_operand_value(
                                curr_ea, 1) == OperandValueRegister.RSP:
                            displacement = 0

                    #case 2: lea
                    if mnem == 'lea':
                        if idc.get_operand_type(curr_ea,
                                                1) == OperandType.MEMORY_REG:
                            if idc.get_operand_value(curr_ea,
                                                     1) > 0xF000000000000000:
                                displacement = 0x10000000000000000 - idc.get_operand_value(
                                    curr_ea, 1)
                                difference += displacement
                            else:
                                displacement = idc.get_operand_value(
                                    curr_ea, 1)
                                difference -= displacement
                    break

            curr_ea += insn.size
        return difference
Esempio n. 28
0
def get_cursor_func_ref():
    """
    Get the function reference under the user cursor.

    Returns BADADDR or a valid function address.
    """
    current_widget = idaapi.get_current_widget()
    form_type = idaapi.get_widget_type(current_widget)
    vu = idaapi.get_widget_vdui(current_widget)

    #
    # hexrays view is active
    #

    if vu:
        cursor_addr = vu.item.get_ea()

    #
    # disassembly view is active
    #

    elif form_type == idaapi.BWN_DISASM:
        cursor_addr = idaapi.get_screen_ea()
        opnum = idaapi.get_opnum()

        if opnum != -1:

            #
            # if the cursor is over an operand value that has a function ref,
            # use that as a valid rename target
            #

            op_addr = idc.get_operand_value(cursor_addr, opnum)
            op_func = idaapi.get_func(op_addr)

            if op_func and op_func.start_ea == op_addr:
                return op_addr

    # unsupported/unknown view is active
    else:
        return idaapi.BADADDR

    #
    # if the cursor is over a function definition or other reference, use that
    # as a valid rename target
    #

    cursor_func = idaapi.get_func(cursor_addr)
    if cursor_func and cursor_func.start_ea == cursor_addr:
        return cursor_addr

    # fail
    return idaapi.BADADDR
Esempio n. 29
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))
Esempio n. 30
0
    def addr(self):
        """
        Retrieves the referenced memory address of the operand.

        :return int: Memory address or None if operand is not a memory reference.
        """
        addr = None
        if self.has_phrase:
            # These need to be handled in the same way even if they don't contain the same types of data...
            addr = self._calc_displacement()
        elif self.type == idc.o_mem:
            addr = idc.get_operand_value(self.ip, self.idx)
        return addr
Esempio n. 31
0
    def _isImportStart(self, start: int) -> bool:
        """Check if the given function is imported or internal.
        """

        if start in self._importsSet:
            return True
        if print_insn_mnem(start) == 'call':
            return False
        # print(print_insn_mnem(start))
        op = get_operand_value(start, 0)
        if op in self._importsSet:
            return True
        return False
Esempio n. 32
0
 def lookForOpArgs(self, start, end):
     for head in idautils.Heads(start, end):
         try:
             for i in range(2):
                 if using_ida7api:
                     t = idc.get_operand_type(head, i)
                 else:
                     t = idc.GetOpType(head, i)
                 if t == idc.o_imm:
                     if using_ida7api:
                         opval = idc.get_operand_value(head, i)
                     else:
                         opval = idc.GetOperandValue(head, i)
                     for h in self.params.hashTypes:
                         hits = self.dbstore.getSymbolByTypeHash(h.hashType, opval)
                         for sym in hits:
                             logger.info("0x%08x: %s", head, str(sym))
                             self.addHit(head, sym)
                             self.markupLine(head, sym)
         except Exception, err:
            logger.exception("Exception: %s", str(err))