Ejemplo n.º 1
0
def main():
    kbase = min(Segments())
    define_funcs = []
    define_data = []

    # Add functions
    for ea in Functions():
        fname = idc.get_name(ea)
        ftype = idc.get_type(ea)
        fslide = ea - kbase
        if fname.startswith('sub_'):
            continue
        if ftype is None:
            if TYPED_FUNCS_ONLY:
                continue
            ftype = 'uint64_t (...)'
        define_funcs.append((fname, fslide, ftype))

    # Add data
    for ea, _ in Names():
        dname = idc.get_name(ea)
        dtype = idc.get_type(ea)
        dslide = ea - kbase
        flags = GetFlags(ea)
        if idc.is_code(flags) or idc.is_strlit(flags):
            continue
        if dtype is None:
            if TYPED_DATA_ONLY:
                continue
            dtype = 'void'
        define_data.append((dname, dslide, dtype))

    # Generate source files
    generate_sdk(define_funcs, define_data)
Ejemplo n.º 2
0
    def prepare_parse_type(typestr, addr):
        """
            idc.ParseType doesnt accept types without func / local name
            as exported by default GetType
            this is an ugly hack to fix it
        """
        lname = idc.get_name(addr)
        if lname is None:
            lname = "Default"

        # func pointers
        conventions = ["__cdecl *",
                       "__stdcall *",
                       "__fastcall *",
                       # "__usercall *",
                       # "__userpurge *",
                       "__thiscall *",
                       "__cdecl",
                       "__stdcall",
                       "__fastcall",
                       # "__usercall",
                       # "__userpurge",
                       "__thiscall"]

        mtype = None
        for conv in conventions:
            if conv in typestr:
                mtype = typestr.replace(conv, conv + " " + lname)
                break
        return mtype
Ejemplo n.º 3
0
 def populate_table(self):
     """
         Download the list of proposed names and display it
     """
     functions = self.skel_conn.get_proposed_names()
     items = []
     for func in functions:
         func_name = idc.get_name(func["address"])
         for name in func["proposed_names"]:
             item = self.SkelFuncListItem(
                 hex(func["address"]),
                 func_name,
                 hex(func["machoc_hash"]),
                 name)
             items.append(item)
     self.setRowCount(len(items))
     self.add_items_to_table(items)
Ejemplo n.º 4
0
def get_symbol_name(from_ea, ea=None, allow_dummy=False):
  if ea is None:
    ea = from_ea

  global _FORCED_NAMES
  if ea in _FORCED_NAMES:
    return _FORCED_NAMES[ea]

  flags = idc.get_full_flags(ea)
  if not allow_dummy and idaapi.has_dummy_name(flags):
    return ""

  name = ""
  try:
    name = name or idc.get_name(ea, 0) #calc_gtn_flags(from_ea, ea))
  except:
    pass

  try:
    name = name or idc.get_func_name(ea)
  except:
    pass

  return name
Ejemplo n.º 5
0
def NameEx(From, ea):
    return idc.get_name(ea, ida_name.GN_VISIBLE | calc_gtn_flags(From, ea))
Ejemplo n.º 6
0
def update_func_name_with_class(func_ea, class_name):
    name = idc.get_name(func_ea)
    if name.startswith("sub_"):
        new_name = class_name + VTABLE_DELIMITER + name
        return utils.set_func_name(func_ea, new_name), True
    return name, False
Ejemplo n.º 7
0
    def activate(self, ctx):
        if self.action in ACTION_CONVERT:
            # convert
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
                size = end - start
            elif idc.get_item_size(idc.get_screen_ea()) > 1:
                start = idc.get_screen_ea()
                size = idc.get_item_size(start)
                end = start + size
            else:
                return False

            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                print("\n[+] Dump 0x%X - 0x%X (%u bytes) :" %
                      (start, end, size))
                if self.action == ACTION_CONVERT[0]:
                    # escaped string
                    output = '"%s"' % "".join("\\x%02X" % b for b in data)
                elif self.action == ACTION_CONVERT[1]:
                    # hex string
                    output = "".join("%02X" % b for b in data)
                elif self.action == ACTION_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"
                elif self.action == ACTION_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i + 2])
                    output = output[:-2] + "\n};"
                elif self.action == ACTION_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i + 4])
                    output = output[:-2] + "\n};"
                elif self.action == ACTION_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%016X, " % u64(data[i:i + 8])
                    output = output[:-2] + "\n};"
                elif self.action == ACTION_CONVERT[6]:
                    # python list
                    output = "[%s]" % ", ".join("0x%02X" % b for b in data)
                elif self.action == ACTION_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    output = "[%s]" % ", ".join("0x%04X" % u16(data[i:i + 2])
                                                for i in range(0, size, 2))
                elif self.action == ACTION_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    output = "[%s]" % ", ".join("0x%08X" % u32(data[i:i + 4])
                                                for i in range(0, size, 4))
                elif self.action == ACTION_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    output = "[%s]" % ", ".join(
                        "%#018X" % u64(data[i:i + 8])
                        for i in range(0, size, 8)).replace("0X", "0x")
                copy_to_clip(output)
                print(output)
        elif self.action == ACTION_XORDATA:
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
            else:
                if idc.get_item_size(idc.get_screen_ea()) > 1:
                    start = idc.get_screen_ea()
                    end = start + idc.get_item_size(start)
                else:
                    return False

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            x = idaapi.ask_long(0, "Xor with...")
            if x:
                x &= 0xFF
                print("\n[+] Xor 0x%X - 0x%X (%u bytes) with 0x%02X:" %
                      (start, end, end - start, x))
                print(repr("".join(chr(b ^ x) for b in data)))
        elif self.action == ACTION_FILLNOP:
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
                idaapi.patch_bytes(start, b"\x90" * (end - start))
                print("\n[+] Fill 0x%X - 0x%X (%u bytes) with NOPs" %
                      (start, end, end - start))
        elif self.action == ACTION_SCANVUL:
            print("\n[+] Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(
                        addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                print("[!] Done! %d possible vulnerabilities found." %
                      len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                print("[-] No format string vulnerabilities found.")
        else:
            return 0

        return 1
Ejemplo n.º 8
0
 def cmd_get_named_addrs(self, a_start, a_end):
     # idautils.Names() does not work in 7.3
     return " ".join([
         self.fmt_addr(a) for a in range(int(a_start, 0), int(a_end, 0))
         if idc.get_name(a)
     ])
Ejemplo n.º 9
0
 def get_addr_name(self, ea):
     return idc.get_name(ea)
Ejemplo n.º 10
0
 def get_name():
     return idc.get_name(name["address"])
Ejemplo n.º 11
0
 def get_data_guids(self):
     '''
     rename GUIDs in idb
     '''
     EFI_GUID = 'EFI_GUID *'
     EFI_GUID_ID = idc.get_struc_id('EFI_GUID')
     segments = ['.text', '.data']
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.get_segm_name(seg) == segment:
                 seg_start = idc.get_segm_start(seg)
                 seg_end = idc.get_segm_end(seg)
                 break
         ea = seg_start
         while (ea <= seg_end - 15):
             prot_name = ''
             if idc.get_name(ea, ida_name.GN_VISIBLE).find('unk_') != -1:
                 find = False
                 cur_guid = []
                 cur_guid.append(idc.get_wide_dword(ea))
                 cur_guid.append(idc.get_wide_word(ea + 4))
                 cur_guid.append(idc.get_wide_word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.get_wide_byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for name in self.Protocols['Edk2Guids']:
                     if self.Protocols['Edk2Guids'][name] == cur_guid:
                         prot_name = name + '_' + '{addr:#x}'.format(
                             addr=ea)
                         record = {
                             'address': ea,
                             'service': 'unknown',
                             'guid': cur_guid,
                             'protocol_name': name,
                             'protocol_place': 'edk2_guids'
                         }
                         find = True
                         break
                 for name in self.Protocols['EdkGuids']:
                     if self.Protocols['EdkGuids'][name] == cur_guid:
                         prot_name = name + '_' + '{addr:#x}'.format(
                             addr=ea)
                         prot_name = name + '_' + '{addr:#x}'.format(
                             addr=ea)
                         record = {
                             'address': ea,
                             'service': 'unknown',
                             'guid': cur_guid,
                             'protocol_name': name,
                             'protocol_place': 'edk_guids'
                         }
                         find = True
                         break
                 for name in self.Protocols['AmiGuids']:
                     if self.Protocols['AmiGuids'][name] == cur_guid:
                         prot_name = name + '_' + '{addr:#x}'.format(
                             addr=ea)
                         prot_name = name + '_' + '{addr:#x}'.format(
                             addr=ea)
                         record = {
                             'address': ea,
                             'service': 'unknown',
                             'guid': cur_guid,
                             'protocol_name': name,
                             'protocol_place': 'ami_guids'
                         }
                         find = True
                         break
                 if find and (idc.get_name(ea, ida_name.GN_VISIBLE) !=
                              prot_name):
                     idc.SetType(ea, EFI_GUID)
                     self.apply_struct(ea, 16, EFI_GUID_ID)
                     idc.set_name(ea, prot_name)
                     self.Protocols['Data'].append(record)
             ea += 1
Ejemplo n.º 12
0
 def get_name(self, offset):
     """Get name for offset from IDB"""
     self.ret = idc.get_name(offset, ida_name.GN_VISIBLE)
     return self.ret
Ejemplo n.º 13
0
 def getName(self, addr):
     return idc.get_name(addr, idc.ida_name.GN_VISIBLE)
Ejemplo n.º 14
0
def get_thunks(ea, typename, funclist):
    funcidx = 0
    instance = (int, long) if version_info[0] < 3 else int
    for i in range(len(funclist)):
        if isinstance(funclist[i], instance):
            funcidx = i
            break

    # No thunks here
    if not funcidx:
        return [], []

    funcs = []
    gotthunks = False

    # Index all these thunks so they line up for when we check for an offset
    # Get rid of extra destructor too
    thunklist = [
        get_func_postname(i) for i in funclist[funcidx:]
        if not isinstance(i, instance) and not i.startswith("_ZTI")
        and not i.endswith(typename + "D1Ev")
    ]

    while ea != idc.BADADDR:
        size = idc.get_item_size(ea)

        # CTFRocketLauncher_DirectHit has its thunks below some random ass string
        # Don't know what's up with that but we'll check 2 more offsets beyond that
        if size != 4:
            ea = ida_bytes.next_not_tail(ea)
            size = idc.get_item_size(ea)
            if size != 4:
                ea = ida_bytes.next_not_tail(ea)
                size = idc.get_item_size(ea)
                if size != 4:  # This is really bad
                    break

        offs = idc.get_wide_dword(ea)
        name = idc.get_name(offs, ida_name.GN_VISIBLE)

        if name:
            if name.startswith("??_R4"):
                #				if typename not in name:
                #					break

                gotthunks = True
                ea = ida_bytes.next_not_tail(ea)
                continue
        else:
            s = "%02x" % offs
            if not s.lower().startswith("ffff"):
                ea = ida_bytes.next_not_tail(ea)
                continue

            break

        if gotthunks:
            funcs.append((offs, name))

        ea = ida_bytes.next_not_tail(ea)

    return funcs, thunklist
Ejemplo n.º 15
0
def prep_vtable(linuxtable, key, wintable, winv):
    if not linuxtable.get(key):
        return None

    funclist = linuxtable[key]
    # Compat for 2.7, strings are in unicode
    if version_info[0] < 3:
        funclist = [
            i if isinstance(i, (int, long)) else str(i)
            for i in linuxtable[key]
        ]
    thunks, thunklist = get_thunks(winv, key, funclist)

    # We've got the thunks, now we don't need anything beyond another typeinfo
    instance = (int, long) if version_info[0] < 3 else int
    for i, v in enumerate(funclist):
        if isinstance(v, instance):
            funclist = funclist[:i]  # Skipping thisoffs
            break

    # Get rid of extra destructor for linux
    for i, n in enumerate(funclist):
        name = idc.demangle_name(n, idc.get_inf_attr(idc.INF_SHORT_DN))
        if name:
            if "::~" in name:
                del funclist[i]
                break

    # Windows does overloads backwards, reverse them
    # Also check for thunks while we're at it
    i = 0
    funcoverloads = {}
    while i < len(funclist):  # and i < len(wintable):
        n = funclist[i]
        if n.startswith("__cxa"):
            i += 1
            continue

        # I shouldn't need to do this, but destructors are wonky
        if i == 0:
            demangled = idc.demangle_name(n,
                                          idc.get_inf_attr(idc.INF_SHORT_DN))
            if demangled and "::~" in demangled:
                i += 1
                continue

        overloadname = get_func_sname(n)
        shortname = get_func_postname(n)
        if not shortname:
            i += 1
            continue

        # Windows skips the vtable function if it exists in the thunks and
        # the thunk does not jmp into it (because the thunk is the function)
        try:
            thunkidx = thunklist.index(shortname)
            delete = 1
        except:
            thunkidx = -1
            delete = 0
        if i < len(wintable):
            if thunkidx != -1 and thunkidx < len(thunks):
                if not isinthunk(wintable[i], thunks[thunkidx]):
                    currname = idc.get_name(thunks[thunkidx][0],
                                            ida_name.GN_VISIBLE)

                    if currname and currname != funclist[
                            i] and EXPORT_MODE != Export_YesOnly:
                        nameflags = ida_name.SN_FORCE
                        if not currname.startswith("sub_"):
                            if not USE_WEAK_NAMES:
                                del funclist[i]
                                continue

                            nameflags |= ida_name.SN_WEAK
                        elif USE_WEAK_NAMES:
                            global FUNCS
                            FUNCS += 1

                        idc.set_name(thunks[thunkidx][0], funclist[i],
                                     nameflags)

                    del funclist[i]
                    continue
        else:  # Class has thunks at the end of the vtable
            # This doesn't change anything but it should link up the lengths of both tables
            if delete:
                del funclist[i]
                continue

        node = funcoverloads.get(overloadname, [])

        # Is this a half-ass decent overload
        go = 1
        for loadnode in range(len(node)):
            if not any(
                [i - funclist.index(val) > F**K for val in node[loadnode]]):
                node[loadnode].append(n)
                go = 0
                break

        if go:
            node.append([n])

        funcoverloads[overloadname] = node
        i += 1

    for k, value in get_bcompat_items(funcoverloads):
        #		if len(value) <= 1:
        #			continue

        #		split = []
        #
        #		# Since subclass overloads shouldn't scoot up next to their baseclass brethren
        #		# hackily separate overloads by classname
        #		for mname in value:
        #			found = 0
        #
        #			name = idc.demangle_name(mname, idc.get_inf_attr(idc.INF_SHORT_DN))
        #			typename = name[:name.find("::")]
        #
        #			for i2 in range(len(split)):
        #				for othermname in split[i2]:
        #					name = idc.demangle_name(othermname, idc.get_inf_attr(idc.INF_SHORT_DN))
        #					othertypename = name[:name.find("::")]
        #
        #					if typename == othertypename:
        #						found = 1
        #						split[i2].append(mname)
        #						break
        #
        #				if found:
        #					break
        #
        #			if not found:
        #				split.append([mname])

        for v in value:
            if len(v) <= 1:
                continue

            lowestidx = len(funclist)
            for func in v:
                temp = funclist.index(func)
                if lowestidx > temp:
                    lowestidx = temp

            count = 0
            while len(v):
                k = v.pop()
                funclist.insert(lowestidx + count,
                                funclist.pop(funclist.index(k)))
                count += 1

    diff = len(funclist) - len(wintable)
    if diff:
        print("WARNING: {} vtable may be wrong! L{} - W{} = {}".format(
            key, len(funclist), len(wintable), diff))

    return funclist
Ejemplo n.º 16
0
 def implement(self):
     if idc.get_name(self._ea, ida_name.GN_LOCAL) != self._name:
         ida_name.set_name(self._ea, self._name, ida_name.SN_LOCAL)
Ejemplo n.º 17
0
    def has_non_default_name(address: int, name: Optional[str]) -> bool:
        sym_name = idc.get_name(address, idaapi.GN_NOT_DUMMY)

        return False if sym_name == '' else (sym_name != name)
Ejemplo n.º 18
0
def GetTrueNameEx(From, ea):
    return idc.get_name(ea, calc_gtn_flags(From, ea))
Ejemplo n.º 19
0
                    item = []
                    item.append(addr + j * addr_gap)
                    func_addr, func_name = funcs[j].split()
                    item.append((int(func_addr, 16), func_name.strip("<>")))
                    items.append(item)

if items != []:
    print("============Find PLT Table============")
    for i in items:
        print("%x: %x  %s" % (i[0], i[1][0], i[1][1]))
    print("======================================")
else:
    print("No PLT Table found")
    exit()

print("Use Lowest 16bits Matching")

currentEA = ScreenEA()

segstart = idc.SegStart(currentEA)
segend = idc.SegEnd(currentEA)

for i in items:
    item_addr = i[0]
    if (segstart & addr_mask) < (item_addr & addr_mask) and (
            segend & addr_mask) > (item_addr & addr_mask):
        patch_addr = (item_addr & addr_mask) + (segstart & (~addr_mask))
        prev_name = idc.get_name(patch_addr)
        if prev_name == "" or in_default(prev_name):
            idc.MakeName(patch_addr, i[1][1] + suffix)
            print("MakeName: %x  %s" % (patch_addr, i[1][1]))
Ejemplo n.º 20
0
def makesig():
    addr = idc.get_screen_ea()
    addr = idc.get_func_attr(addr, idc.FUNCATTR_START)
    funcstart = addr
    if addr == idc.BADADDR:
        print("Make sure you are in a function!")
        return

    name = idc.get_name(addr, ida_name.GN_VISIBLE)
    funcend = idc.get_func_attr(addr, idc.FUNCATTR_END)

    sig = ""
    found = 0
    done = 0

    addr = funcstart
    while addr != idc.BADADDR:
        info = ida_ua.insn_t()
        if not ida_ua.decode_insn(info, addr):
            return None

        done = 0
        if info.Op1.type == ida_ua.o_near or info.Op1.type == ida_ua.o_far:
            if (idc.get_wide_byte(addr)) == 0x0F:  # Two-byte instruction
                sig = sig + ("0F %02X " %
                             idc.get_wide_byte(addr + 1)) + print_wildcards(
                                 get_dt_size(info.Op1.dtype))
            else:
                sig = sig + ("%02X " %
                             idc.get_wide_byte(addr)) + print_wildcards(
                                 get_dt_size(info.Op1.dtype))
            done = 1

        if not done:  # Unknown, just wildcard addresses
            i = 0
            size = idc.get_item_size(addr)
            while 1:  # Screw u python
                loc = addr + i
                if ((idc.get_fixup_target_type(loc)
                     & 0xF) == ida_fixup.FIXUP_OFF32):
                    sig = sig + print_wildcards(4)
                    i = i + 3
                else:
                    sig = sig + ("%02X " % idc.get_wide_byte(loc))

                i = i + 1

                if i >= size:
                    break

        if is_good_sig(sig):
            found = 1
            break

        addr = idc.next_head(addr, funcend)

    if found == 0:
        print(sig)
        print("Ran out of bytes to create unique signature.")
        return None

    l = len(sig) - 1
    smsig = r"\x"
    for i in range(l):
        c = sig[i]
        if c == " ":
            smsig = smsig + r"\x"
        elif c == "?":
            smsig = smsig + "2A"
        else:
            smsig = smsig + c

    print("Signature for %s:\n%s\n%s" % (name, sig, smsig))
    return smsig
Ejemplo n.º 21
0
def set_func_name(func_ea, new_name):
    if not idc.set_name(func_ea, new_name, ida_name.SN_CHECK | ida_name.SN_FORCE):
        log.warn("%08X Couldn't set func name '%s'", func_ea, new_name)
    return idc.get_name(func_ea)
Ejemplo n.º 22
0
 def get_name():
     return idc.get_name(name["address"])
Ejemplo n.º 23
0
def to_nice_str(ea):
    """ Shows address as function name + offset """
    func_start_ea = idc.get_func_attr(ea, idc.FUNCATTR_START)
    func_name = idc.get_name(func_start_ea)
    offset = ea - func_start_ea
    return "{}+0x{:X}".format(func_name, offset)
def kernelcache_find_virtual_method_overrides(classname=None, method=None):
    import idc
    import idaapi
    import ida_name
    import ida_kernelcache as kc

    # Define the form to ask for the arguments.
    class MyForm(idaapi.Form):
        def __init__(self):
            swidth = 40
            idaapi.Form.__init__(
                self, r"""STARTITEM 0
Find virtual method overrides

<#The class#Class :{classname}>
<#The virtual method#Method:{method}>""", {
                    'classname':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                    'method':
                    idaapi.Form.StringInput(tp=idaapi.Form.FT_IDENT,
                                            swidth=swidth),
                })

        def OnFormChange(self, fid):
            return 1

    kc.collect_class_info()

    if any(arg is None for arg in (classname, method)):
        f = MyForm()
        f.Compile()
        f.classname.value = classname or ''
        f.method.value = method or ''
        ok = f.Execute()
        if ok != 1:
            print('Cancelled')
            return False
        classname = f.classname.value
        method = f.method.value
        f.Free()

    if classname not in kc.class_info:
        print('Not a valid class: {}'.format(classname))
        return False

    print('Subclasses of {} that override {}:'.format(classname, method))
    baseinfo = kc.class_info[classname]
    found = False
    for classinfo in baseinfo.descendants():
        for _, override, _ in kc.vtable.class_vtable_overrides(
                classinfo, superinfo=baseinfo, methods=True):
            name = idc.get_name(
                override, ida_name.GN_VISIBLE
                | idc.calc_gtn_flags(idc.BADADDR, override))
            demangled = idc.demangle_name(
                name, idc.get_inf_attr(idc.INF_SHORT_DEMNAMES))
            name = demangled if demangled else name
            if method in name:
                print('{:#x}  {}'.format(override, classinfo.classname))
                found = True
    if not found:
        print('No subclass of {} overrides {}'.format(classname, method))
    return found
Ejemplo n.º 25
0
def make_func_sig(config, func):
    """
    type config: Config
    type func: idc.func_t
    """
    logger = logging.getLogger("idb2pat:make_func_sig")

    if func.end_ea - func.start_ea < config.min_func_length:
        logger.debug("Function is too short")
        raise FuncTooShortException()

    publics = []  # type: tuple(idc.ea_t, name)
    refs = {}  # type: dict(idc.ea_t, idc.ea_t)
    variable_bytes = set([])  # type: set of idc.ea_t

    func_len = func.end_ea - func.start_ea

    # get function name and all public names in function
    func_name = idc.get_func_name(func.start_ea)
    if func_name == "":
        func_name = "?"  # pat standard

    ea = func.start_ea
    while ea != idc.BADADDR and ea < func.end_ea:
        if ea > func.start_ea:  # skip first byte
            name = idc.get_name(ea)
            if name != "" and idaapi.is_uname(name):
                logger.debug(str("ea 0x%X has a name %s" % (ea, name)))
                publics.append((ea, name))

        ref = idc.get_first_dref_from(ea)
        if ref != idc.BADADDR:
            # data ref
            logger.debug(str("ea 0x%X has data ref 0x%X" % (ea, ref)))
            start, end = find_ref_loc(ea, ref)
            if start != idc.BADADDR:
                logger.debug(
                    str("data ref: %s - %X - %X - %X" %
                        (func_name, ea, start, end)))
                logger.debug(
                    str("\tref_loc: 0x%X - size %d" %
                        (ea + start, end - start)))
                for i in range(start, end):
                    logger.debug(str("\tvariable 0x%X" % (ea + i)))
                    variable_bytes.add(ea + i)
                refs[ea + start] = ref
        else:
            # code ref
            ref = idc.get_first_fcref_from(ea)
            if ref != idc.BADADDR:
                logger.debug(str("ea 0x%X has code ref 0x%X" % (ea, ref)))
                if ref < func.start_ea or ref >= func.end_ea:
                    # code ref is outside function
                    start, end = find_ref_loc(ea, ref)
                    if start != idc.BADADDR:
                        logger.debug(
                            str("code ref: %s - %X - %d - %d" %
                                (func_name, ea, start, end)))
                        logger.debug(
                            str("\tref_loc: 0x%X - size %d" %
                                (ea + start, end - start)))
                        for i in range(start, end):
                            logger.debug(str("\tvariable 0x%X" % (ea + i)))
                            variable_bytes.add(ea + i)
                        refs[ea + start] = ref

        ea = idc.next_not_tail(ea)

    # first 32 bytes, or til end of function
    sig = ""
    for ea in zrange(func.start_ea, min(func.start_ea + 32, func.end_ea)):
        if ea in variable_bytes:
            sig += ".."
        else:
            sig += "%02X" % (idaapi.get_byte(ea))

    if func_len > 32:
        crc_len = min(func_len - 32, 0xff)

        # for 255 bytes starting at index 32, or til end of function, or variable byte
        for off in range(crc_len):
            if func.start_ea + 32 + off in variable_bytes:
                crc_len = off
                break

        crc = crc16(idaapi.get_bytes(func.start_ea + 32, crc_len), crc=0xFFFF)
    else:
        sig += ".." * (32 - func_len)
        crc_len = 0
        crc = 0

    sig += " %02X" % (crc_len)
    sig += " %04X" % (crc)
    sig += " %04X" % min(func_len, MAX_FUNC_LEN)

    sig += " :0000 %s" % (func_name)

    for ea, name in publics:
        # @ at end of offset, for local public name, pat standard
        sig += " :%04X@ %s" % (ea - func.start_ea, name)

    for ref_loc, ref in sorted(refs.iteritems()):
        # HTC - remove dummy, auto names
        name = idc.get_name(ref)
        if name == "" or not idaapi.is_uname(name):
            continue

        logger.debug(
            str("ref_loc = 0x%X - ref = 0x%X - name = %s" %
                (ref_loc, ref, name)))

        if ref_loc >= func.start_ea:
            # this will be either " ^%04d %s" or " ^%08d %s"
            addr = ref_loc - func.start_ea
            ref_format = " ^%%0%dX %%s" % (config.pointer_size)
        else:
            # this will be either " ^-%04d %s" or " ^-%08d %s"
            addr = func.start_ea - ref_loc
            ref_format = " ^-%%0%dX %%s" % (config.pointer_size)
        sig += ref_format % (addr, name)

    # Tail of the module starts at the end of the CRC16 block.
    if func_len > 32 + crc_len:
        sig += " "
        for ea in range(func.start_ea + 32 + crc_len,
                        min(func.end_ea, func.start_ea + MAX_FUNC_LEN)):
            if ea in variable_bytes:
                sig += ".."
            else:
                sig += "%02X" % (idaapi.get_byte(ea))

    logger.debug("sig: %s", sig)
    return sig
Ejemplo n.º 26
0
 def cmd_get_label(self, addr):
     return idc.get_name(int(addr, 0))
Ejemplo n.º 27
0
def make_func_sigs(config):
    logger = logging.getLogger("idb2pat:make_func_sigs")
    sigs = []
    if config.mode == USER_SELECT_FUNCTION:
        f = idaapi.choose_func("Choose Function:", idc.BADADDR)
        if f is None:
            logger.error("No function selected")
            return []
        idc.jumpto(f.start_ea)
        if not idaapi.has_any_name(idc.get_full_flags(f.start_ea)):
            logger.error("Function doesn't have a name")
            return []

        try:
            sigs.append(make_func_sig(config, f))
        except Exception as e:
            logger.exception(e)
            logger.error("Failed to create signature for function at %s (%s)",
                         hex(f.start_ea),
                         idc.get_func_name(f.start_ea) or "")

    elif config.mode == NON_AUTO_FUNCTIONS:
        for f in get_functions():
            # HTC - remove check FUNC_LIB flag to include library functions
            if idaapi.has_name(idc.get_full_flags(f.start_ea)):
                # and f.flags & idc.FUNC_LIB == 0:
                try:
                    sigs.append(make_func_sig(config, f))
                except FuncTooShortException:
                    pass
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to create signature for function at %s (%s)",
                        hex(f.start_ea),
                        idc.get_name(f.start_ea) or "")

    elif config.mode == LIBRARY_FUNCTIONS:
        for f in get_functions():
            if idaapi.has_name(idc.get_full_flags(
                    f.start_ea)) and f.flags & idc.FUNC_LIB != 0:
                try:
                    sigs.append(make_func_sig(config, f))
                except FuncTooShortException:
                    pass
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to create signature for function at %s (%s)",
                        hex(f.start_ea),
                        idc.get_name(f.start_ea) or "")

    elif config.mode == PUBLIC_FUNCTIONS:
        for f in get_functions():
            if idaapi.is_public_name(f.start_ea):
                try:
                    sigs.append(make_func_sig(config, f))
                except FuncTooShortException:
                    pass
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to create signature for function at %s (%s)",
                        hex(f.start_ea),
                        idc.get_name(f.start_ea) or "")

    elif config.mode == ENTRY_POINT_FUNCTIONS:
        for i in zrange(idaapi.get_func_qty()):
            f = idaapi.get_func(idaapi.get_entry(idaapi.get_entry_ordinal(i)))
            if f is not None:
                try:
                    sigs.append(make_func_sig(config, f))
                except FuncTooShortException:
                    pass
                except Exception as e:
                    logger.exception(e)
                    logger.error(
                        "Failed to create signature for function at %s (%s)",
                        hex(f.start_ea),
                        idc.get_name(f.start_ea) or "")

    elif config.mode == ALL_FUNCTIONS:
        n = idaapi.get_func_qty()
        for i, f in enumerate(get_functions()):
            try:
                logger.info("[ %d / %d ] %s %s", i + 1, n,
                            idc.get_name(f.start_ea), hex(f.start_ea))
                sigs.append(make_func_sig(config, f))
            except FuncTooShortException:
                pass
            except Exception as e:
                logger.exception(e)
                logger.error(
                    "Failed to create signature for function at %s (%s)",
                    hex(f.start_ea),
                    idc.get_name(f.start_ea) or "")

    return sigs
Ejemplo n.º 28
0
    def activate(self, ctx):
        if self.action in ACTION_MENU_CONVERT:
            sel, start, end = lazy_read_selection()
            if not sel:
                idc.msg("[LazyIDA] Nothing to convert.")
                return False

            size = end - start
            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            assert size == len(data)

            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                output = None
                plg_print("Dump from 0x%X to 0x%X (%u bytes):" % (start, end - 1, size))
                if self.action == ACTION_MENU_CONVERT[0]:
                    # escaped string
                    output = '"%s"' % "".join("\\x%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[1]:
                    # hex string, space
                    output = " ".join("%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i+2])
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i+4])
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "%#018X, " % u64(data[i:i+8])
                    output = output[:-2] + "\n};"
                    output = output.replace("0X", "0x")

                elif self.action == ACTION_MENU_CONVERT[6]:
                    # python list
                    output = "[%s]" % ", ".join("0x%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    output = "[%s]" % ", ".join("0x%04X" % u16(data[i:i+2]) for i in range(0, size, 2))

                elif self.action == ACTION_MENU_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    output = "[%s]" % ", ".join("0x%08X" % u32(data[i:i+4]) for i in range(0, size, 4))

                elif self.action == ACTION_MENU_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    output = "[%s]" %  ", ".join("%#018X" % u64(data[i:i+8]) for i in range(0, size, 8)).replace("0X", "0x")

                elif self.action == ACTION_MENU_CONVERT[10]:
                    # MASM byte array
                    header = "%s db " % name
                    output = header
                    for i in range(size):
                        if i and i % 16 == 0:
                            output += "\n"
                            output += " " * len(header)
                        output += "0%02Xh, " % data[i]
                    output = output[:-2]

                elif self.action == ACTION_MENU_CONVERT[11]:
                    # GNU ASM byte array
                    header = "%s: .byte " % name
                    output = header
                    for i in range(size):
                        if i and i % 16 == 0:
                            output += "\n"
                            output += " " * len(header)
                        output += "0x%02X, " % data[i]
                    output = output[:-2]

                if output:
                    print(output)
                    copy_to_clip(output)
                    output = None

        elif self.action == ACTION_MENU_COPY_DATA:
            # added by merc, modified by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idaapi.get_bytes(start, end - start)
            if isinstance(data, str):
                data = bytearray(data)
            output = "".join("%02X" % b for b in data)
            copy_to_clip(output)
            plg_print("Hex string '%s' copied" % output)

        elif self.action == ACTION_MENU_DUMP_DATA:
            # add by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            size = end - start
            data = idaapi.get_bytes(start, size)
            assert len(data) == size
            if data and len(data) == size:
                dump_data_to_file("Dump_At_%X_Size_%d.dump" % (start, size), data)
            else:
                plg_print("0x%X: unable to get %d bytes" % (start, size))

        elif self.action == ACTION_MENU_XOR_DATA:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            size = end - start

            key = idaapi.ask_str("AA BB CC DD", 0, "Xor with hex values (or a string begin and end with\" or ')...")
            if not key:
                return 0

            bytes_key = bytearray()
            if is_str(key):
                bytes_key = str_to_bytes(key)
            else:
                bytes_key = hex_to_bytes(key)

            if not bytes_key:
                return 0

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)

            output = xor_data(data, bytes_key)
            if not output:
                plg_print("Sorry, error occurred. My bug :( Please report.")
                return 0

            assert size == len(output)

            plg_print("Xor result from 0x%X to 0x%X (%d bytes) with %s:" % (start, end, end - start, key))
            process_data_result(start, output)

        elif self.action == ACTION_MENU_FILL_NOP:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            idaapi.patch_bytes(start, b"\x90" * (end - start))
            idc.create_insn(start)
            plg_print("Fill 0x%X to 0x%X (%u bytes) with NOPs" % (start, end, end - start))

        elif self.action == ACTION_MENU_B64STD:
            base64_decode(True)

        elif self.action == ACTION_MENU_B64URL:
            base64_decode(False)

        elif self.action == ACTION_MENU_SCAN_VUL:
            plg_print("Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                plg_print("Done! %d possible vulnerabilities found." % len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                plg_print("No format string vulnerabilities found.")

        else:
            return 0

        return 1
Ejemplo n.º 29
0
 def name(self):
     return get_name(self.__ea, GN_VISIBLE)
Ejemplo n.º 30
0
def get_functions():
    functions = dict()
    for f_ea in idautils.Functions():
        functions[f_ea] = idc.get_name(f_ea)
    return functions
Ejemplo n.º 31
0
    def objc_msgsend_xref(self,
                          call_ea,
                          objc_self,
                          objc_selector,
                          create_xref=True):
        '''
        This function will create a code xref to an objc method
        
        call_ea : location of call/jmp objc_msgsend (regardless of direct/indirect)
        objc_self: ea where RDI is set to static value (or that we find it's from a previous call or the RDI of the current function)
        objc_selector: ea where RSI is set to static value
        
        This ignores the RDI register, which is the `self` argument to objc_msgsend()
        id objc_msgSend(id self, SEL op, ...);
        So far, this seems to be fine as far as the cross-references are concerned.

        '''

        # get instruction mnemonic at address - I guess to check and make sure
        # it's mov rsi, blah
        instruction = idc.GetDisasm(objc_selector)
        if self.debugflag:
            print ">>> objc_msgsend_xref 0x%08x %s" % (objc_selector,
                                                       instruction)

        # get outbound references in the appropriate segment
        # implicit assumption is there is exacltly one
        target_selref = None
        for _ref in idautils.DataRefsFrom(objc_selector):
            if idc.SegName(_ref) == "__objc_selrefs":
                target_selref = _ref

        if not target_selref:
            return False

        # get outbound references in the appropriate segment
        # implicit assumption is there is exacltly one
        target_methname = None
        for _ref in idautils.DataRefsFrom(target_selref):
            if idc.SegName(_ref) == "__objc_methname":
                target_methname = _ref

        if not target_methname:
            return False

        # get inbound references
        # __objc_const
        # must be a __objc2_meth
        # I hope this method is correct to find __objc2_meth structs
        # BUG: when the binary has mutiple objc methods by the same name, this logic fails
        # Track RDI register. have to figure out what instance/class is referenced
        objc2_meth_struct_id = ida_struct.get_struc_id("__objc2_meth")
        meth_struct_found = False
        target_method = None
        for _ref in idautils.DataRefsTo(target_methname):
            # multiple may match
            # we care about the __obj2_meth struct found in references
            if idc.SegName(_ref) == "__objc_const":
                # check the outbound references
                for _meth_ref in idautils.DataRefsFrom(_ref):
                    if _meth_ref == objc2_meth_struct_id:
                        meth_struct_found = True

                if meth_struct_found:
                    # only do this once
                    # TODO: check against RDI here to make sure it's the proper class
                    # meth_struct_found = False

                    for _meth_ref in idautils.DataRefsFrom(_ref):
                        # assumption made on function always being in text segment
                        if idc.SegName(_meth_ref) == "__text":
                            # save the method implementation -- this is the function ptr
                            if self.debugflag:
                                print "0x%08x checking for the proper method -- %s" % (
                                    _meth_ref,
                                    idc.get_name(
                                        idc.get_func_attr(
                                            _meth_ref, idc.FUNCATTR_START)))
                            target_method = _meth_ref

        if not target_method:
            return False

        # After dereferencing across the IDB file, we finally have a target function.
        # In other words, if there isn't a method **in this binary** no xref is made (IDA only loads one binary?)
        # that is referenced from the mov rsi, <selector> instruction
        if self.debugflag: print "Found target method 0x%08x" % target_method
        if create_xref:
            idc.AddCodeXref(objc_selector, target_method, idc.fl_CF)

        return True
Ejemplo n.º 32
0
    def draw(self, min_x, max_x, min_y):
        self.lines = {}

        root_tree = self.reader.roots[self.activeIndex]

        trees = [(root_tree, 0, 0)]
        while len(trees) > 0:
            tree, x, y = trees.pop(0)

            width = tree['size']

            if x + width > min_x and x < max_x:

                addr = tree['addr']

                if addr == 0:
                    name = '(root)'
                    theme = 'red'
                else:
                    symbol = self.reader.symbols.get(addr)

                    if symbol:
                        theme = 'purple'
                    else:
                        theme = 'green'

                    name = idc.get_name(addr)
                    if not name:
                        if symbol:
                            name = symbol
                        else:
                            name = "sub_%X" % (addr, )

                if addr not in self.colors:
                    self.colors[addr] = self.new_color(theme)

                if y >= min_y:
                    this_y = y - min_y
                    if this_y not in self.lines: self.lines[this_y] = []

                    self.lines[this_y].append({
                        'addr':
                        addr,
                        'x0':
                        max(0, x - min_x),
                        'x1':
                        min(max_x, x - min_x + width),
                        'color':
                        self.colors[addr],
                        'name':
                        name,
                        'cropped':
                        x - min_x < 0
                    })

                children = self.reader.get_children(tree)
                x_child = x + 1
                for child in children:
                    trees.append((child, x_child, y + 1))
                    x_child += child['size']

        return self.lines
Ejemplo n.º 33
0
def Name(ea):
    return idc.get_name(ea, ida_name.GN_VISIBLE)
Ejemplo n.º 34
0
    def activate(self, ctx):
        if self.action in ACTION_CONVERT:
            sel, start, end = lazy_read_selection()
            if not sel:
                idc.msg("[LazyIDA] Nothing to convert.")
                return False

            size = end - start
            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            assert size == len(data)

            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                print("\n[+] Dump 0x%X - 0x%X (%u bytes) :" % (start, end, size))
                if self.action == ACTION_CONVERT[0]:
                    # escaped string
                    print('"%s"' % "".join("\\x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[1]:
                    # hex string
                    print("".join("%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i+2])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i+4])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "%#018X, " % u64(data[i:i+8])
                    output = output[:-2] + "\n};"
                    print(output.replace("0X", "0x"))
                elif self.action == ACTION_CONVERT[6]:
                    # python list
                    print("[%s]" % ", ".join("0x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    print("[%s]" % ", ".join("0x%04X" % u16(data[i:i+2]) for i in range(0, size, 2)))
                elif self.action == ACTION_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    print("[%s]" % ", ".join("0x%08X" % u32(data[i:i+4]) for i in range(0, size, 4)))
                elif self.action == ACTION_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    print("[%s]" %  ", ".join("%#018X" % u64(data[i:i+8]) for i in range(0, size, 8)).replace("0X", "0x"))
        elif self.action == ACTION_COPYDATA:
            # added by merc, modfiy by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idaapi.get_bytes(start, end - start)
            data = data.encode('hex')
            copy_to_clip(data)
            print("[LazyIDA] copied hex string '%s'" % data)
        elif self.action == ACTION_XORDATA:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            x = idaapi.ask_long(0, "Xor with...")
            if x:
                x &= 0xFF
                print("\n[+] Xor 0x%X - 0x%X (%u bytes) with 0x%02X:" % (start, end, end - start, x))
                print(repr("".join(chr(b ^ x) for b in data)))
        elif self.action == ACTION_FILLNOP:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0
            idaapi.patch_bytes(start, b"\x90" * (end - start))
            print("\n[+] Fill 0x%X - 0x%X (%u bytes) with NOPs" % (start, end, end - start))
        elif self.action == ACTION_SCANVUL:
            print("\n[+] Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                print("[!] Done! %d possible vulnerabilities found." % len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                print("[-] No format string vulnerabilities found.")
        elif self.action == ACTION_COPYNAME:
            copy_highlight_name()
        elif self.action == ACTION_PASTENAME:
            paste_highlight_name()
        else:
            return 0

        return 1
Ejemplo n.º 35
0
    def generate(self):
        signatures = RizzoSignatures()

        # Generate unique string-based function signatures
        for (ea, string) in self.strings.items():
            # Only generate signatures on reasonably long strings with one xref
            if len(string.value) < 8 or len(string.xrefs) != 1:
                continue

            func = idaapi.get_func(string.xrefs[0])
            if not func:
                continue

            strhash = self.sighash(string.value)

            # Check for and remove string duplicate signatures (the same
            # string can appear more than once in an IDB).
            # If no duplicates, add this to the string signature dict.
            if strhash in signatures.strings:
                del signatures.strings[strhash]
                signatures.stringdups.add(strhash)
            elif strhash not in signatures.stringdups:
                signatures.strings[strhash] = func.start_ea

        # Generate formal, fuzzy, and immediate-based function signatures
        for ea in idautils.Functions():
            func = idaapi.get_func(ea)
            if not func:
                continue

            # Generate a signature for each block in this function
            blocks = self.function(func)

            # Build function-wide formal and fuzzy signatures by simply
            # concatenating the individual function block signatures.
            formal = self.sighash(''.join([str(e) for (e, f, i, c) in blocks]))
            fuzzy = self.sighash(''.join([str(f) for (e, f, i, c) in blocks]))

            # Add this signature to the function dictionary.
            signatures.functions[func.start_ea] = (idc.get_name(func.start_ea, ida_name.GN_VISIBLE), blocks)

            # Check for and remove formal duplicate signatures.
            # If no duplicates, add this to the formal signature dict.
            if formal in signatures.formal:
                del signatures.formal[formal]
                signatures.formaldups.add(formal)
            elif formal not in signatures.formaldups:
                signatures.formal[formal] = func.start_ea

            # Check for and remove fuzzy duplicate signatures.
            # If no duplicates, add this to the fuzzy signature dict.
            if fuzzy in signatures.fuzzy:
                del signatures.fuzzy[fuzzy]
                signatures.fuzzydups.add(fuzzy)
            elif fuzzy not in signatures.fuzzydups:
                signatures.fuzzy[fuzzy] = func.start_ea

            # Check for and remove immediate duplicate signatures.
            # If no duplicates, add this to the immediate signature dict.
            for (e, f, immediates, c) in blocks:
                for immediate in immediates:
                    if immediate in signatures.immediates:
                        del signatures.immediates[immediate]
                        signatures.immediatedups.add(immediate)
                    elif immediate not in signatures.immediatedups:
                        signatures.immediates[immediate] = func.start_ea

        # These need not be maintained across function calls,
        # and only add to the size of the saved signature file.
        signatures.fuzzydups = set()
        signatures.formaldups = set()
        signatures.stringdups = set()
        signatures.immediatedups = set()

        # DEBUG
        signatures.show()

        return signatures