Beispiel #1
0
def _process_offset(offset, ea, next_offset):
    """Process an offset in a __got section."""
    # Convert the address containing the offset into an offset in IDA, but continue if it fails.
    if not idc.OpOff(ea, 0, 0):
        _log(1, 'Could not convert {:#x} into an offset', ea)
    # Get the name to which the offset refers.
    name = idau.get_ea_name(offset, user=True)
    if not name:
        _log(3, 'Offset at address {:#x} has target {:#x} without a name', ea,
             offset)
        return False
    # Make sure this isn't an offset to another stub or to a jump function to another stub. See the
    # comment in _symbolicate_stub.
    if stub.symbol_references_stub(name):
        _log(
            1,
            'Offset at address {:#x} has target {:#x} (name {}) that references a stub',
            ea, offset, name)
        return False
    # Set the new name for the offset.
    symbol = next_offset(name)
    if symbol is None:
        _log(0, 'Could not generate offset symbol for {}: names exhausted',
             name)
        return False
    if not idau.set_ea_name(ea, symbol, auto=True):
        _log(2, 'Could not set name {} for offset at {:#x}', symbol, ea)
        return False
    return True
Beispiel #2
0
def create_offset(addr):
    if idc.OpOff(addr, 1, 0):
        return True
    else:
        common._debug('Unable to make an offset for string @ 0x%x ' % addr)

    return False
Beispiel #3
0
def add_xrefs(addr, end=idc.BADADDR):
    """
        https://github.com/xyzz/vita-ida-physdump/blob/master/vita_phys_dump.py
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to things that look like addresses
    """
    while addr < end and addr != BADADDR:
        addr = idc.NextHead(addr)
        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False
            next_addr = addr
            for x in range(16):
                next_addr = idc.NextHead(next_addr)
                if idc.GetMnem(next_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [
                        "R0", "R1", "R2", "R3"
                ]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(next_addr) in ["MOVT",
                                              "MOVT.W"] and idc.GetOpnd(
                                                  next_addr, 0) == reg:
                    if idc.GetOpnd(next_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(next_addr, 1) * (2**16)
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd(
                        next_addr, 1) == reg:
                    break
            if val & 0xFFFF0000 == 0:
                continue
            if found:
                # pair of MOV/MOVT
                try:
                    idc.OpOffEx(addr, 1, idc.REF_LOW16, val, 0, 0)
                    idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0)
                except:
                    print "Failed xref @ %x next_addr %x val %x" % (
                        addr, next_addr, val)
            else:
                # a single MOV instruction
                try:
                    idc.OpOff(addr, 1, 0)
                except:
                    print "Failed xref at addr %x" % (addr)
    def req_patch(self, hash):
        addr, value, length = hash['addr'], hash['value'], hash['len']
        if length != 4 and length != 8:
            print("[x] unsupported length: %d" % length)
            return
        if length == 4:
            prev_value = Dword(addr)
            if MakeDword(addr) != 1:
                print("[x] MakeDword failed")
            if PatchDword(addr, value) != 1:
                print("[x] PatchDword failed")
            if not idc.OpOff(addr, 0, 0):
                print("[x] OpOff failed")
        elif length == 8:
            prev_value = Qword(addr)
            if MakeQword(addr) != 1:
                print("[x] MakeQword failed")
            if PatchQword(addr, value) != 1:
                print("[x] PatchQword failed")
            if not idc.OpOff(addr, 0, 0):
                print("[x] OpOff failed")

        print("[*] patched 0x%x = 0x%x (previous was 0x%x)" %
              (addr, value, prev_value))
Beispiel #5
0
def initialize_data_offsets():
    """Convert offsets in data segments into offsets in IDA.

    Segment names must be initialized with segments.initialize_segments() first.
    """
    # Normally, for user-space programs, this operation would be dangerous because there's a good
    # chance that a valid userspace address would happen to show up in regular program data that is
    # not actually an address. However, since kernel addresses are numerically much larger, the
    # chance of this happening is much less.
    for seg in idautils.Segments():
        name = idc.SegName(seg)
        if not (name.endswith('__DATA_CONST.__const') or name.endswith('__got')
                or name.endswith('__DATA.__data')):
            continue
        for word, ea in idau.ReadWords(seg, idc.SegEnd(seg), addresses=True):
            if idau.is_mapped(word, value=False):
                idc.OpOff(ea, 0, 0)
Beispiel #6
0
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        print "Converting remaining data to DWORDs...",

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if idc.isUnknown(flags) or idc.isByte(flags):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        print "done."
Beispiel #7
0
    def init_vtable(self):
        my_start_idx = self.vtable_start_idx()

        # Fix: support 64bit work
        if idc.__EA64__:
            pointer_size = idaapi.DEF_ADDRSIZE
            pfn_make_ptr = idc.MakeQword
            pfn_get_ptr_value = idc.Qword
        else:
            pointer_size = idaapi.DEF_ADDRSIZE
            pfn_make_ptr = idc.MakeDword
            pfn_get_ptr_value = idc.Dword

        for idx, ea in enumerate(range(self.vtable_start, self.vtable_end, pointer_size)):
            pfn_make_ptr(ea)
            idc.OpOff(ea, 0, 0)
            dst = pfn_get_ptr_value(ea)

            if idx < my_start_idx:
                base_method = self.base.vmethods[idx]
                if base_method.is_dst_equal(dst):                   # Method from base class
                    self.vmethods.append(self.base.vmethods[idx])
                elif Method.s_is_pure_virtual_dst(dst):             # New pure virtual override
                    opvm = PureVirtualOverrideMethod(self, base_method, idx)
                    opvm.refresh()
                    self.vmethods.append(opvm)
                elif Method.s_is_deleted_virtual_dst(dst):          # New deleted override
                    dom = DeletedOverrideMethod(self, base_method, idx)
                    dom.refresh()
                    self.vmethods.append(dom)
                else:                                               # New override
                    om = OverrideMethod(dst, self, base_method, idx)
                    om.refresh()
                    self.vmethods.append(om)
            elif Method.s_is_pure_virtual_dst(dst):                 # New pure virtual
                pvm = PureVirtualMethod(self, 'vf%X' % (idx*4), idx)
                pvm.refresh()
                self.vmethods.append(pvm)
            elif Method.s_is_deleted_virtual_dst(dst):              # New deleted virtual
                pvm = DeletedVirtualMethod(self, 'vf%X' % (idx*4), idx)
                pvm.refresh()
                self.vmethods.append(pvm)
            else:                                                   # New virtual
                vm = VirtualMethod(dst, self, 'vf%X' % (idx*4), idx)
                vm.refresh()
                self.vmethods.append(vm)
Beispiel #8
0
def add_xrefs():
    """
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to things that look like addresses
    """
    addr = 0
    while addr != idc.BADADDR:
        addr = idc.NextHead(addr)
        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False
            next_addr = addr
            for x in range(16):
                next_addr = idc.NextHead(next_addr)
                if idc.GetMnem(next_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [
                        "R0", "R1", "R2", "R3"
                ]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(next_addr) in ["MOVT",
                                              "MOVT.W"] and idc.GetOpnd(
                                                  next_addr, 0) == reg:
                    if idc.GetOpnd(next_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(next_addr, 1) * (2**16)
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd(
                        next_addr, 1) == reg:
                    break
            if val & 0xFFFF0000 == 0:
                continue
            if found:
                # pair of MOV/MOVT
                idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0)
            else:
                # a single MOV instruction
                idc.OpOff(addr, 1, 0)
Beispiel #9
0
    def datify(self):
        ea = self.get_start_ea(self.DATA)
        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        self.say("Converting remaining data to DWORDs...", )

        while ea != idc.BADADDR:
            flags = idc.GetFlags(ea)

            if (idc.isUnknown(flags) or idc.isByte(flags)) and ((ea % 4) == 0):
                idc.MakeDword(ea)
                idc.OpOff(ea, 0, 0)

            ea = idc.NextAddr(ea)

        self.say("done.")

        self._fix_data_offsets()
Beispiel #10
0
def convert_vtable_to_offsets(vtable, length=None):
    """Convert a vtable into a sequence of offsets.

    Arguments:
        vtable: The address of the virtual method table.

    Options:
        length: The length of the vtable, if known.

    Returns:
        True if the data was successfully converted into offsets.
    """
    if length is None:
        length = vtable_length(vtable)
    if not length:
        _log(0, 'Address {:#x} is not a vtable', vtable)
        return False
    successful = True
    for address in idau.Addresses(vtable, length=length, step=idau.WORD_SIZE):
        if not idc.OpOff(address, 0, 0):
            _log(0, 'Could not change address {:#x} into an offset', address)
            successful = False
    return successful
    def fix_names(self):
        """ 
            Fix the table of imports and map enums to apis.
        """
        start_addr  = idc.AskAddr(idc.here(), "Enter table start address")

        ## check if address is within the base address and maximum address
        if (start_addr < idc.MinEA()) or (start_addr > idc.MaxEA()):
            idc.Warning("You have entered an invalid start address")
            idc.Exit

        self.start_addr = start_addr    
        current_addr = self.start_addr

        #Current size of PoisonIvy IAT
        end_addr = current_addr + 568

        # Walk the table 8 bytes at a time
        while current_addr <= end_addr:

            idc.MakeQword(current_addr)
            print "DEBUG: Current address - 0x%08x" % current_addr
            addr = idc.Qword(current_addr)
            print "DEBUG: address - 0x%08x" % addr
            if addr == -1:
                print "[!] Skipping address 0x%08x - 0x%08x" % (current_addr, addr)
                current_addr += 8
                continue

            # Make the current address an offset
            idc.OpOff(current_addr,0,0)
            # We need to undefine the bytes incase IDA autoanalysis had converted an incorrect byte
            idc.MakeUnkn(addr, 1)
            # Create code at this address 
            idc.MakeCode(addr)
            # Create function at the same address
            idc.MakeFunction(addr, addr+16)
            # Read the second operand at the address which should be the negative API address value
            imp_addr = idc.GetOperandValue(addr, 1)

            if imp_addr == -1:
                print "[!] Couldn't get operand at address - 0x%08x" % addr
                current_addr +=8
                continue             

            # try:
            #     int_addr = int(imp_addr,16)
            # except ValueError as e:
            #     print "[!] Failed on: %s - %s\n" % (imp_addr, e)
            #     current_addr +=8 
            #     continue
            
            # if we know about this value then let's do the work
            if imp_addr in self.enums.keys():
                enum_id = self.enums[imp_addr]
                # Convert operand to enum 
                idc.OpEnumEx(addr, 1, enum_id,0)
                const_id = idc.GetConstEx(enum_id, imp_addr, 0, -1)
                fn_name = "fn_"+idc.GetConstName(const_id)
                off_name = "ptr_"+idc.GetConstName(const_id)
                # Rename the function to the symbol name.
                # We append fn_ to the symbol for the function name
                # and ptr_ to the offset in the table.
                if not idc.MakeNameEx(addr, fn_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename function %s at 0x%08x\n" % (fn_name, addr)
                if not idc.MakeNameEx(current_addr, off_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename offset %s at 0x%08x\n" % (off_name,current_addr)

            current_addr += 8

        return 
Beispiel #12
0
 def ida_make_offset(f, ea):
     if f.armv7:
         idc.MakeDword(ea)
     else:
         idc.MakeQword(ea)
     idc.OpOff(ea, 0, 0)
def untag_pointer(ea, tp):
    _log(4, 'Untagging pointer at {:x}', ea)
    idau.patch_word(ea, tagged_pointer_untag(tp))
    idc.OpOff(ea, 0, 0)
def untag_pointer(ea, tp):
    idau.patch_word(ea, tagged_pointer_untag(tp))
    idc.OpOff(ea, 0, 0)
Beispiel #15
0
def add_xrefs():
    """
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to addresses
    """
    addr = 0
    while addr != idc.BADADDR:
        addr = idc.NextHead(addr)

        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False

            lower16_addr = addr
            upper16_addr = addr
            for x in range(16):
                upper16_addr = idc.NextHead(upper16_addr)
                if idc.GetMnem(upper16_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(upper16_addr) in ["BL", "BLX"] and reg in ["R0", "R1", "R2", "R3"]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(upper16_addr) in ["MOVT", "MOVT.W"] and idc.GetOpnd(upper16_addr, 0) == reg:
                    if idc.GetOpnd(upper16_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(upper16_addr, 1) << 16
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(upper16_addr, 0) == reg or idc.GetOpnd(upper16_addr, 1) == reg:
                    break

            # check if is valid address
            if idaapi.getseg(val) is not None:
                if found:
                    # pair of MOV/MOVT
                    idc.OpOffEx(lower16_addr, 1, idc.REF_LOW16, val, 0, 0)
                    idc.OpOffEx(upper16_addr, 1, idc.REF_HIGH16, val, 0, 0)
                else:
                    # a single MOV instruction
                    idc.OpOff(addr, 1, 0)
            else:
                val_string = hex(val)
                if val != 0:
                    val_string += " (" + str(val)
                    float_repr = struct.unpack("<f", struct.pack("<I", val))[0]
                    if float_repr > 0.00000001:
                        val_string +=  ", " + str(float_repr) + ")"
                    else:
                        val_string += ")"

                if found:
                    # pair of MOV/MOVT
                    idc.MakeComm(lower16_addr, "lower16:" + val_string)
                    idc.MakeComm(upper16_addr, "upper16:" + val_string)
                else:
                    # a single MOV instruction
                    if val != 0:
                        idc.MakeComm(addr, val_string)
Beispiel #16
0
            if op == 1:
                index = int(idaapi.cmd.Op1.addr)
            else:
                index = int(idaapi.cmd.Op2.addr)
        if index:
            if displace.has_key(index) == False:
                displace[index] = []
            displace[index].append(curr_addr)

for x in displace[0x130]:
    print hex(x), idc.GetDisasm(x)

#遍历所有函数,尝试将带有立即数寻址方式的指令中立即数转化为对数据的偏移

min = MinEA()
max = MaxEA()
#遍历所有已知的函数
for func in idautils.Functions():
    flags = idc.GetFunctionFlags(func)
    #跳过库函数和简单的跳转函数
    if flags & FUNC_LIB or flags & FUNC_THUNK:
        continue
    dism_addr = list(idautils.FuncItems(func))
    for curr_addr in dism_addr:
        if idc.GetOpType(curr_addr, 0) == o_imm and (min < idc.GetOperandValue(
                curr_addr, 0) < max):
            idc.OpOff(curr_addr, 0, 0)  #将操作数转换为一个偏移
        if idc.GetOpType(curr_addr, 1) == o_imm and (min < idc.GetOperandValue(
                curr_addr, 1) < max):
            idc.OpOff(curr_addr, 1, 0)  #将操作数转换为一个偏移