Esempio n. 1
0
def make_head(ea):
  flags = idc.GetFlags(ea)
  if not idc.isHead(flags):
    idc.SetFlags(ea, flags | idc.FF_DATA)
    idaapi.autoWait()
    return is_head(ea)
  return True
Esempio n. 2
0
def try_mark_as_function(ea):
  if not idc.MakeFunction(ea, idc.BADADDR):
    idc.MakeUnknown(ea, 1, idc.DOUNK_SIMPLE)
    idaapi.autoWait()
    if not idc.MakeFunction(ea, idc.BADADDR):
      debug("Unable to convert code to function:", hex(ea))
      return False
  idaapi.autoWait()
  return True
Esempio n. 3
0
 def __init__(self):
     """Constructor for SPIDA.  Waits for IDA Pro to finish analyzing
     the .exe, then builds a dictionary mapping EA's to imported APIs' names"""
     idaapi.autoWait()
     self.import_dict = dict()
     self.curr_mod_name = ""
     self.firstImport = True
     self.imports_segment_name = ""
     self.buildImportDictionary()
     self.makeMissedProcedures()
Esempio n. 4
0
def dump_symbol_info(output_filename):
    """Dump information for BAP's symbolizer into output_filename."""
    from idautils import Segments, Functions
    from idc import (
        SegStart, SegEnd, GetFunctionAttr,
        FUNCATTR_START, FUNCATTR_END
    )

    try:
        from idaapi import get_func_name2 as get_func_name
        # Since get_func_name is deprecated (at least from IDA 6.9)
    except ImportError:
        from idaapi import get_func_name
        # Older versions of IDA don't have get_func_name2
        # so we just use the older name get_func_name

    def func_name_propagate_thunk(ea):
        current_name = get_func_name(ea)
        if current_name[0].isalpha():
            return current_name
        func = idaapi.get_func(ea)
        temp_ptr = idaapi.ea_pointer()
        ea_new = idaapi.BADADDR
        if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK:
            ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast())
        if ea_new != idaapi.BADADDR:
            ea = ea_new
        propagated_name = get_func_name(ea) or ''  # Ensure it is not `None`
        if len(current_name) > len(propagated_name) > 0:
            return propagated_name
        else:
            return current_name
            # Fallback to non-propagated name for weird times that IDA gives
            #     a 0 length name, or finds a longer import name

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        for ea in Segments():
            fs = Functions(SegStart(ea), SegEnd(ea))
            for f in fs:
                out.write('(%s 0x%x 0x%x)\n' % (
                    func_name_propagate_thunk(f),
                    GetFunctionAttr(f, FUNCATTR_START),
                    GetFunctionAttr(f, FUNCATTR_END)))
Esempio n. 5
0
def dump_loader_info(output_filename):
    """Dump information for BAP's loader into output_filename."""
    from idautils import Segments
    import idc

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        info = idaapi.get_inf_structure()
        size = "r32" if info.is_32bit else "r64"
        out.write("(%s %s (" % (info.get_proc_name()[1], size))
        for seg in Segments():
            out.write("\n(%s %s %d (0x%X %d))" % (
                idaapi.get_segm_name(seg),
                "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
                idaapi.get_fileregion_offset(seg),
                seg, idaapi.getseg(seg).size()))
        out.write("))\n")
Esempio n. 6
0
def try_mark_as_code(address, end_address=0):
  flags = idc.GetFlags(address)
  if idc.isAlign(flags):
    return False

  if idc.isCode(flags):
    return True

  if idc.MakeCode(address):
    idaapi.autoWait()
    return True

  end_address = max(end_address, address + 1)
  idc.MakeUnknown(address, end_address - address + 1, idc.DOUNK_SIMPLE)
  
  if idc.MakeCode(address):
    idaapi.autoWait()
    return True

  return False
Esempio n. 7
0
def dump_brancher_info(output_filename):
    """Dump information for BAP's brancher into output_filename."""
    from idautils import CodeRefsFrom

    idaapi.autoWait()

    def dest(ea, flow):  # flow denotes whether normal flow is also taken
        return set(CodeRefsFrom(ea, flow))

    def pp(l):
        return ' '.join('0x%x' % e for e in l)

    with open(output_filename, 'w+') as out:
        for ea in all_valid_ea():
            branch_dests = dest(ea, False)
            if len(branch_dests) > 0:
                out.write('(0x%x (%s) (%s))\n' % (
                    ea,
                    pp(dest(ea, True) - branch_dests),
                    pp(branch_dests)
                ))
Esempio n. 8
0
def dump_brancher_info(output_filename):
    """Dump information for BAP's brancher into output_filename."""
    from idautils import CodeRefsFrom

    idaapi.autoWait()

    def dest(ea):
        return list(CodeRefsFrom(ea, flow=True))

    def branch(ea):
        return list(CodeRefsFrom(ea, flow=False))

    def fall(ea):
        return list(set(dest(ea)) - set(branch(ea)))

    def is_branch_insn(ea):  # Unconditional branches are also counted
        return len(branch(ea)) > 0

    def is_jump_insn(ea):  # Only unconditional branches
        return len(branch(ea)) == len(dest(ea)) == 1

    def labeled(addrs, label):
        l = lambda d: '(0x%x %s)' % (d, label)
        return ' '.join(map(l, addrs))

    with open(output_filename, 'w+') as out:
        out.write('(\n')
        for ea in all_valid_ea():
            if is_jump_insn(ea):
                out.write('(0x%x (%s))\n' % (
                    ea,
                    labeled(dest(ea), 'Jump')))
            elif is_branch_insn(ea):
                out.write('(0x%x (%s %s))\n' % (
                    ea,
                    labeled(branch(ea), 'Cond'),
                    labeled(fall(ea), 'Fall')))
            else:
                pass  # Normal instruction, uninteresting
        out.write(')\n')
Esempio n. 9
0
def init_analysis():
  analysis_flags = idc.GetShortPrm(idc.INF_START_AF)
  analysis_flags &= ~idc.AF_IMMOFF  
  idc.SetShortPrm(idc.INF_START_AF, analysis_flags)
  idaapi.autoWait()
Esempio n. 10
0
 def wait(cls):
     '''Wait until IDA's autoanalysis queues are empty.'''
     return idaapi.autoWait(
     ) if idaapi.__version__ < 7.0 else idaapi.auto_wait()
Esempio n. 11
0
 def wait_for_analysis_to_finish(self):
     logger.debug("[+] waiting for analysis to finish...")
     idaapi.autoWait()
     idc.Wait()
     logger.debug("[+] analysis finished.")
Esempio n. 12
0
def try_mark_as_code(ea):
  if is_code(ea) and not is_code_by_flags(ea):
    idc.MakeCode(ea)
    idaapi.autoWait()
    return True
  return False
Esempio n. 13
0
def main():
    imp_funcs = []
    xrefs = []
    cg = CallGraph()
    file_name = idc.get_root_filename()
    file_path = idc.GetInputFilePath()

    def get_file_ssdeep():
        if 'ssdeep' in sys.modules:
            return ssdeep.hash_from_file(file_path)
        else:
            return 'No ssdeep Modules. Please Install ssdeep.'

    def imp_cb(ea, name, ord):
        imp_funcs.append(ea)
        return True

    if 'batch' in idc.ARGV:
        idaapi.autoWait()

    for fea in Functions():
        func_flags = get_func_flags(fea)
        # NORMAL = 0
        # LIBRARY = 1
        # IMPORTED = 2
        # THUNK = 3
        if func_flags & FUNC_LIB:
            func_type = 1
        elif func_flags & FUNC_THUNK:
            func_type = 3
        else:
            func_type = 0

        cg.add_vertex(fea, func_type)
        cg.add_root(fea)

        items = FuncItems(fea)
        for item in items:
            for xref in XrefsFrom(item, 0):
                # https://www.hex-rays.com/products/ida/support/idadoc/313.shtml
                if xref.type != fl_F:
                    xrefs.append([fea, xref.to])

    # List Import Functions and Add to cg
    num_imp_module = idaapi.get_import_module_qty()
    for i in range(0, num_imp_module):
        idaapi.enum_import_names(i, imp_cb)
    imp_funcs.sort()
    for imp_func_ea in imp_funcs:
        cg.add_vertex(imp_func_ea, 2)

    for xref in xrefs:
        if xref[1] in cg.vertices:
            cg.connect_vertex(xref[0], xref[1])

    cg.set_roots()

    for root in cg.roots:
        cg.build_graph_pattern(root)

    if len(idc.ARGV) == 0:
        print('Graph MD5: %s' % cg.get_graph_md5())
        print('Graph SHA1: %s' % cg.get_graph_sha1())
        print('Graph SHA256: %s' % cg.get_graph_sha256())
        print('Graph SSDEEP: %s' % cg.get_graph_ssdeep())
        print('File SSDEEP: %s' % get_file_ssdeep())

    if 'out_pattern' in idc.ARGV:
        if not os.path.isdir('./out'):
            os.mkdir('./out')
        f = open('./out/' + file_name + '.bin', 'wb')
        f.write(cg.graph_pattern)
        f.close()

    if 'batch' in idc.ARGV:
        if not os.path.isdir('./out'):
            os.mkdir('./out')
        f = open('./out/result', 'a+')
        f.write('%s,%s,%s,%s\n' % (file_name, cg.get_graph_md5(),
                                   cg.get_graph_ssdeep(), get_file_ssdeep()))
        f.close()
        idc.Exit(0)
Esempio n. 14
0
        print('Vars collected.')
        return 1


class dump_info(custom_action_handler):
    def activate(self, ctx):
        with open(os.environ['COLLECTED_VARS'], 'wb') as vars_fh:
            pickle.dump(varmap, vars_fh)
            vars_fh.flush()
        return 1


if hasattr(idaapi, "auto_wait"):  # IDA 7.4+
    idaapi.auto_wait()
else:
    idaapi.autoWait()  # Old IDA
if not idaapi.init_hexrays_plugin():
    idaapi.load_plugin('hexrays')
    idaapi.load_plugin('hexx64')
    if not idaapi.init_hexrays_plugin():
        print('Unable to load Hex-rays')
    else:
        print(('Hex-rays version %s has been detected' %
               idaapi.get_hexrays_version()))


def main():
    cv = collect_vars()
    cv.activate(None)
    dv = dump_info()
    dv.activate(None)
Esempio n. 15
0
def try_mark_as_function(address):
    if not idaapi.add_func(address, idc.BADADDR):
        DEBUG("Unable to convert code to function: {}".format(address))
        return False
    idaapi.autoWait()
    return True
Esempio n. 16
0
def parse_str_ptr(addr):
    if idc.GetMnem(addr) != 'mov':
        return False

    # Validate that the string offset actually exists inside the binary
    if idc.get_segm_name(idc.GetOperandValue(addr, 1)) is None:
        return False

    # Check the operands' type:
    # - first one must be a register;
    # - second one must be a memory address
    if idc.GetOpType(addr, 0) != 1 or idc.GetOpType(addr, 1) != 2:
        return False

    addr_2 = idc.FindCode(addr, idaapi.SEARCH_DOWN)
    # same operands' type for addr_2
    if idc.GetMnem(addr_2) != 'mov' or idc.GetOpType(
            addr_2, 0) != 1 or idc.GetOpType(addr_2, 1) != 2:
        return False

    opnd_val_1 = idc.GetOperandValue(addr, 1)
    opnd_val_2 = idc.GetOperandValue(addr_2, 1)
    opnd_diff = opnd_val_1 - opnd_val_2
    # The 2 operands, one of addr of string length, another one is the addr of string pointer
    # and they must be side by side
    if opnd_diff != common.ADDR_SZ and opnd_diff != -common.ADDR_SZ:
        return False

    if opnd_diff > 0:
        str_len_addr, str_ptr_addr = opnd_val_1, opnd_val_2
    else:
        str_len_addr, str_ptr_addr = opnd_val_2, opnd_val_1

    str_len = common.read_mem(str_len_addr)
    str_ptr = common.read_mem(str_ptr_addr)
    str_addr = common.read_mem(str_ptr)

    # set max str len
    if str_len > 64:
        return False

    if 'rodata' not in idc.get_segm_name(
            str_ptr) and 'text' not in idc.get_segm_name(str_ptr):
        return False

    common._debug("------------------------------")
    common._debug("Possible str ptr:")
    common._debug("Code addr: 0x%x , str_ptr_addr: 0x%x , str_len_addr: 0x%x" %
                  (addr, str_ptr_addr, str_len_addr))
    common._debug("str_addr: 0x%x , str_len: 0x%x" % (str_ptr, str_len))
    #if create_string(str_addr, str_len):
    if str_len > 1:
        if idc.MakeStr(str_ptr, str_ptr + str_len):
            idaapi.autoWait()
            if opnd_diff > 0:
                idc.MakeComm(addr, "length: %d" % str_len)
                idaapi.add_dref(addr_2, str_ptr, idaapi.dr_O)
            else:
                idc.MakeComm(addr_2, "length: %d" % str_len)
                idaapi.add_dref(addr, str_ptr, idaapi.dr_O)
            idaapi.autoWait()
            return True

    return False
Esempio n. 17
0
    def parse(self, is_test=False):
        if is_test:
            common._info("Test firstmoduledata addr: 0x%x" % self.start_addr)

        self.pclntbl_addr = read_mem(self.start_addr, read_only=is_test)
        self.pclntbl_sz = read_mem(self.start_addr+ADDR_SZ, read_only=is_test)
        self.pclntbl_cap = read_mem(self.start_addr+2*ADDR_SZ, read_only=is_test)
        self.ftab_addr = read_mem(self.start_addr+3*ADDR_SZ, read_only=is_test)
        self.func_num = read_mem(self.start_addr+4*ADDR_SZ, read_only=is_test)
        self.ftab_cap = read_mem(self.start_addr+5*ADDR_SZ, read_only=is_test)
        self.filetab_addr = read_mem(self.start_addr+6*ADDR_SZ, read_only=is_test)
        self.srcfile_num = read_mem(self.start_addr+7*ADDR_SZ, read_only=is_test)
        self.srcfile_tab_cap = read_mem(self.start_addr+8*ADDR_SZ, read_only=is_test)
        self.findfunctab = read_mem(self.start_addr+9*ADDR_SZ, read_only=is_test)
        self.min_pc = read_mem(self.start_addr+10*ADDR_SZ, read_only=is_test)
        self.max_pc = read_mem(self.start_addr+11*ADDR_SZ, read_only=is_test)
        self.text_addr = read_mem(self.start_addr+12*ADDR_SZ, read_only=is_test)
        self.etext_addr = read_mem(self.start_addr+13*ADDR_SZ, read_only=is_test)
        if is_test:
            return
        self.noptrdata_addr = read_mem(self.start_addr+14*ADDR_SZ, read_only=is_test)
        self.enoptrdata_addr = read_mem(self.start_addr+15*ADDR_SZ, read_only=is_test)
        self.data_addr = read_mem(self.start_addr+16*ADDR_SZ, read_only=is_test)
        self.edata_addr = read_mem(self.start_addr+17*ADDR_SZ, read_only=is_test)
        self.bss_addr = read_mem(self.start_addr+18*ADDR_SZ, read_only=is_test)
        self.ebss_addr = read_mem(self.start_addr+19*ADDR_SZ, read_only=is_test)
        self.noptrbss_addr = read_mem(self.start_addr+20*ADDR_SZ, read_only=is_test)
        self.enoptrbss_addr = read_mem(self.start_addr+21*ADDR_SZ, read_only=is_test)
        self.end_addr = read_mem(self.start_addr+22*ADDR_SZ, read_only=is_test)
        self.gcdata_addr = read_mem(self.start_addr+23*ADDR_SZ, read_only=is_test)
        self.gcbss_addr = read_mem(self.start_addr+24*ADDR_SZ, read_only=is_test)
        self.types_addr = read_mem(self.start_addr+25*ADDR_SZ, read_only=is_test)
        self.etypes_addr = read_mem(self.start_addr+26*ADDR_SZ, read_only=is_test)
        self.textsecmap_addr = read_mem(self.start_addr+27*ADDR_SZ, read_only=is_test)
        self.textsecmap_len = read_mem(self.start_addr+28*ADDR_SZ, read_only=is_test)
        self.textsecmap_cap = read_mem(self.start_addr+29*ADDR_SZ, read_only=is_test)
        self.typelink_addr = read_mem(self.start_addr+30*ADDR_SZ, read_only=is_test)
        self.type_num = read_mem(self.start_addr+31*ADDR_SZ, read_only=is_test)
        self.type_cap = read_mem(self.start_addr+32*ADDR_SZ, read_only=is_test)
        self.itablink_addr = read_mem(self.start_addr+33*ADDR_SZ, read_only=is_test)
        self.itab_num = read_mem(self.start_addr+34*ADDR_SZ, read_only=is_test)
        self.itab_cap = read_mem(self.start_addr+35*ADDR_SZ, read_only=is_test)
        self.ptab_addr = read_mem(self.start_addr+36*ADDR_SZ, read_only=is_test)
        self.ptab_num = read_mem(self.start_addr+37*ADDR_SZ, read_only=is_test)
        self.ptab_cap = read_mem(self.start_addr+38*ADDR_SZ, read_only=is_test)

        pluginpath_addr = read_mem(self.start_addr+39*ADDR_SZ, read_only=is_test)
        pluginpath_len = read_mem(self.start_addr+40*ADDR_SZ, read_only=is_test)
        self.pluginpath = str(idc.GetManyBytes(pluginpath_addr, pluginpath_len))

        modulename_addr = read_mem(self.start_addr+44*ADDR_SZ, read_only=is_test)
        modulename_len = read_mem(self.start_addr+45*ADDR_SZ, read_only=is_test)
        self.modulename = str(idc.GetManyBytes(modulename_addr, modulename_len))

        self.hasmain = idc.Byte(self.start_addr+49*ADDR_SZ)
        self.next = read_mem(self.start_addr+54*ADDR_SZ+1, read_only=is_test)

        if not is_test:
            idc.MakeNameEx(self.start_addr, "runtime.firstmoduledata", flags=idaapi.SN_FORCE)
            idaapi.autoWait()

            idc.MakeComm(self.start_addr, "pclntbl addr")
            idc.MakeComm(self.start_addr + ADDR_SZ, "pclntbl size")
            idc.MakeComm(self.start_addr + 2*ADDR_SZ, "pclntbl capacity")
            idc.MakeComm(self.start_addr + 3*ADDR_SZ, "funcs table addr")
            idc.MakeComm(self.start_addr + 4*ADDR_SZ, "funcs number")
            idc.MakeComm(self.start_addr + 5*ADDR_SZ, "funcs table capacity")
            idc.MakeComm(self.start_addr + 6*ADDR_SZ, "source files table addr")
            idc.MakeComm(self.start_addr + 7*ADDR_SZ, "source files number")
            idc.MakeComm(self.start_addr + 8*ADDR_SZ, "source files table capacity")
            idc.MakeComm(self.start_addr + 9*ADDR_SZ, "findfunctable addr")
            idc.MakeComm(self.start_addr + 10*ADDR_SZ, "min pc")
            idc.MakeComm(self.start_addr + 11*ADDR_SZ, "max pc")
            idc.MakeComm(self.start_addr + 12*ADDR_SZ, "text start addr")
            idc.MakeComm(self.start_addr + 13*ADDR_SZ, "text end addr")
            idc.MakeComm(self.start_addr + 14*ADDR_SZ, "noptrdata start addr")
            idc.MakeComm(self.start_addr + 15*ADDR_SZ, "noptrdata end addr")
            idc.MakeComm(self.start_addr + 16*ADDR_SZ, "data section start addr")
            idc.MakeComm(self.start_addr + 17*ADDR_SZ, "data section end addr")
            idc.MakeComm(self.start_addr + 18*ADDR_SZ, "bss start addr")
            idc.MakeComm(self.start_addr + 19*ADDR_SZ, "bss end addr")
            idc.MakeComm(self.start_addr + 20*ADDR_SZ, "noptrbss start addr")
            idc.MakeComm(self.start_addr + 21*ADDR_SZ, "noptrbss end addr")
            idc.MakeComm(self.start_addr + 22*ADDR_SZ, "end addr of whole image")
            idc.MakeComm(self.start_addr + 23*ADDR_SZ, "gcdata addr")
            idc.MakeComm(self.start_addr + 24*ADDR_SZ, "gcbss addr")
            idc.MakeComm(self.start_addr + 25*ADDR_SZ, "types start addr")
            idc.MakeComm(self.start_addr + 26*ADDR_SZ, "types end addr")
            idc.MakeComm(self.start_addr + 27*ADDR_SZ, "test section map addr")
            idc.MakeComm(self.start_addr + 28*ADDR_SZ, "test section map length")
            idc.MakeComm(self.start_addr + 29*ADDR_SZ, "test section map capacity")
            idc.MakeComm(self.start_addr + 30*ADDR_SZ, "typelink addr")
            idc.MakeComm(self.start_addr + 31*ADDR_SZ, "types number")
            idc.MakeComm(self.start_addr + 32*ADDR_SZ, "types table capacity")
            idc.MakeComm(self.start_addr + 33*ADDR_SZ, "itabslink addr")
            idc.MakeComm(self.start_addr + 34*ADDR_SZ, "itabs number")
            idc.MakeComm(self.start_addr + 35*ADDR_SZ, "itabs caapacity")
            idc.MakeComm(self.start_addr + 36*ADDR_SZ, "ptab addr")
            idc.MakeComm(self.start_addr + 37*ADDR_SZ, "ptab num")
            idc.MakeComm(self.start_addr + 38*ADDR_SZ, "ptab capacity")
            idc.MakeComm(self.start_addr + 39*ADDR_SZ, "plugin path addr")
            idc.MakeComm(self.start_addr + 40*ADDR_SZ, "plugin path length")
            idc.MakeComm(self.start_addr + 44*ADDR_SZ, "module name addr")
            idc.MakeComm(self.start_addr + 45*ADDR_SZ, "module name length")
            idc.MakeComm(self.start_addr + 49*ADDR_SZ, "hasmain flag")
            idc.MakeComm(self.start_addr + 54*ADDR_SZ+1, "next moduledata addr")
            idaapi.autoWait()

            idc.MakeStr(modulename_addr, modulename_addr+modulename_len)
            idaapi.autoWait()
            idc.MakeStr(pluginpath_addr, pluginpath_addr+pluginpath_len)
            idaapi.autoWait()
Esempio n. 18
0
def wait_for_analysis_to_finish():
    idaapi.autoWait()
    idc.Wait()
Esempio n. 19
0
def open(f):
    ## we are allready inside inside ida
    idaapi.autoWait()
    return True
Esempio n. 20
0
def load_file(fd, neflags, format):
    global prologues
    size = 0
    base_addr = 0
    ea = 0
    nfunc = 0

    idaapi.set_processor_type("arm", idaapi.SETPROC_ALL)
    idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    if (neflags & idaapi.NEF_RELOAD) != 0:
        return 1

    fd.seek(0, idaapi.SEEK_END)
    size = fd.tell()

    segm = idaapi.segment_t()
    segm.bitness = 2  # 64-bit
    segm.start_ea = 0
    segm.end_ea = size
    idaapi.add_segm_ex(segm, "iBoot", "CODE", idaapi.ADDSEG_OR_DIE)

    fd.seek(0)
    fd.file2base(0, 0, size, false)

    idaapi.add_entry(0, 0, "start", 1)
    idc.MakeFunction(ea)

    print("[+] Marked as code")

    # heuristic
    while (true):
        mnemonic = idc.GetMnem(ea)

        if "LDR" in mnemonic:
            base_str = idc.GetOpnd(ea, 1)
            base_addr = int(base_str.split("=")[1], 16)

            break

        ea += 4

    print("[+] Rebasing to address 0x%x" % (base_addr))
    idaapi.rebase_program(base_addr, idc.MSF_NOFIX)
    idaapi.autoWait()

    segment_start = base_addr
    segment_end = idc.GetSegmentAttr(segment_start, idc.SEGATTR_END)

    ea = segment_start

    print("[+] Searching and defining functions")

    for prologue in prologues:
        while ea != idc.BADADDR:
            ea = idc.FindBinary(ea, idc.SEARCH_DOWN, prologue, 16)

            if ea != idc.BADADDR:
                ea = ea - 2

                if (ea % 4) == 0 and idc.GetFlags(ea) < 0x200:
                    # print("[+] Defining a function at 0x%x" % (ea))
                    idc.MakeFunction(ea)
                    nfunc = nfunc + 1

                ea = ea + 4

    idc.AnalyzeArea(segment_start, segment_end)
    idaapi.autoWait()

    print("[+] Identified %d new functions" % (nfunc))

    print("[+] Looking for interesting functions")
    find_interesting(segment_start)

    return 1
Esempio n. 21
0
def fix_all():

    # wait till autoanalysis is done
    idaapi.autoWait()

    ea = 0
    numInst = 0
    numAddRegPc = 0
    numFixed = 0
    t0 = time.clock()
    # last MOV/MOVT inst targeting the register, key=register number
    movVal = dict()
    movtVal = dict()
    global refs

    #old ver compat
    nextHeadArgCount = len(inspect.getargspec(idc.NextHead).args)

    cnt = 0
    while True:
        cnt += 1
        if nextHeadArgCount == 1:
            ea = idc.NextHead(ea)
        else:
            ea = idc.NextHead(ea, idc.BADADDR)
        if cnt & 0xfff == 0:
            print "[progress] ea: %x" % ea
        if ea == idc.BADADDR:
            break
        if not idaapi.isCode(idaapi.getFlags(ea)):
            continue
        numInst += 1
        # slow, is there any way to avoid it?..
        i = idautils.DecodeInstruction(ea)
        if not i:
            continue
        mnem = i.get_canon_mnem()

        if i[0].type != 1:  # only interested in register target operands
            continue
        target_reg = i[0].phrase
        if mnem == 'ADD':
            if i[1].type == 1 and i[1].phrase == 15:
                numAddRegPc += 1

                (val, mov_ea) = movVal.get(target_reg, (0, 0))
                (val_t, movt_ea) = movtVal.get(target_reg, (0, 0))
                if not mov_ea:
                    # No preceding MOV, bailing..
                    continue
                numFixed += 1

                target_addr = 0xffffFFFF & (ea + 4 + val + 0x10000 * val_t)
                # could be THUMB proc..
                if target_addr & 1 and idaapi.isCode(
                        idaapi.getFlags(target_addr - 1)):
                    target_name = idaapi.get_name(target_addr - 1,
                                                  target_addr - 1)
                else:
                    target_name = idaapi.get_name(target_addr, target_addr)
                refs.append((ea, target_addr, target_name))

        if i[1].type == 5:
            if mnem == 'MOV':
                movVal[target_reg] = (i[1].value, ea)
                movtVal[target_reg] = (0, 0
                                       )  # since movw clears top bits anyway
            elif mnem == 'MOVT':
                movtVal[target_reg] = (i[1].value, ea)
        else:
            movVal[target_reg] = (0, 0)
            movtVal[target_reg] = (0, 0)
    print "%u instructions scanned in %f seconds" % (numInst,
                                                     time.clock() - t0)

    add_refs()

    # work around an IDA bug
    for i in range(1, 5):
        idaapi.autoWait()
        add_refs()

    if numAddRegPc == 0:
        successRate = 100
    else:
        successRate = numFixed * 100.0 / numAddRegPc
    print "%u 'ADD Reg, PC' found, %u fixed: %u%%" % (numAddRegPc, numFixed,
                                                      successRate)

    global g_done
    g_done = 1
Esempio n. 22
0
 def wait(cls):
     '''Wait until IDA's autoanalysis queues are empty.'''
     return idaapi.autoWait() if idaapi.__version__ < 7.0 else idaapi.auto_wait()
    def lvar_type_changed(self, vu, v, tif):
        if (vu.cfunc):
            func_tif = ida_typeinf.tinfo_t()
            vu.cfunc.get_func_type(func_tif)

            funcdata = idaapi.func_type_data_t()
            got_data = func_tif.get_func_details(funcdata)

            if (not got_data):
                # self._log("Didnt get the data")
                pass

            lvars = vu.cfunc.get_lvars()
            for j in range(len(vu.cfunc.argidx)):
                # for i in vu.cfunc.argidx:
                i = vu.cfunc.argidx[j]
                if (lvars[i].name == v.name):
                    #self._log("lvar_type_changed: function argument changed = %s, index = %s, atype = %s" % (lvars[i].name, i, funcdata[j].argloc.atype()))
                    if (funcdata[i].argloc.atype() == 3):
                        #    self._log("lvar_type_changed: reg is : %s" %(funcdata[i].argloc.reg1()))
                        pass

                    if (funcdata[i].argloc.atype() != 3
                            or funcdata[i].argloc.reg1() != RCX_REG):
                        break

                    #self._log("applyName = %s" % (applyName))

                    firstPtrRemove = ida_typeinf.remove_pointer(tif)
                    #self._log("type name = %s" % (firstPtrRemove._print()))
                    #self._log("remove_pointer.is_ptr = %s" % (firstPtrRemove.is_ptr()))
                    #self._log("remove_pointer.is_struct = %s" % (firstPtrRemove.is_struct()))
                    if (firstPtrRemove.is_struct()
                            and not firstPtrRemove.is_ptr()):
                        currentFuncName = ida_name.get_ea_name(
                            vu.cfunc.entry_ea)
                        # self._log("before demangle current func name = %s" % (currentFuncName))
                        demangled = idc.Demangle(
                            currentFuncName, idc.GetLongPrm(idc.INF_SHORT_DN))
                        if (demangled != None):
                            self._log("Overriding mangled name = %s" %
                                      (currentFuncName))
                            currentFuncName = demangled
                        # self._log("after demangle current func name = %s" % (currentFuncName))
                        tokens = currentFuncName.split("::")
                        if len(tokens) > 1:
                            currentFuncName = tokens[1]
                        currentFuncName = currentFuncName.split("(")[0]
                        # self._log("current func name = %s" % (currentFuncName))
                        idc.MakeNameEx(
                            vu.cfunc.entry_ea,
                            firstPtrRemove._print() + "::" + currentFuncName,
                            idc.SN_NOWARN)
                        idaapi.autoWait()
                        # self._log("Decomp Res : %s" % idaapi.decompile(vu.cfunc.entry_ea))
                        idaapi.refresh_idaview_anyway()
                        vu.refresh_ctext()
                        idaapi.refresh_idaview_anyway()
                        vu.refresh_ctext()
                        vu.refresh_view(True)

                        current_widget = idaapi.get_current_widget()
                        vu1 = idaapi.get_widget_vdui(current_widget)
                        if vu1:
                            vu1.refresh_ctext()
                    break

        #self._log("lvar_type_changed: vu=%s, v=%s, tinfo=%s" % (vu, self._format_lvar(v), tif._print()))
        return 1
Esempio n. 24
0
def fix_all():
    
    # wait till autoanalysis is done
    idaapi.autoWait()
    
    ea = 0
    numInst = 0
    numAddRegPc = 0
    numFixed = 0
    t0 = time.clock()
    # last MOV/MOVT inst targeting the register, key=register number
    movVal = dict()
    movtVal = dict()
    global refs
    
    cnt = 0
    while True:
        cnt += 1
        ea = idc.NextHead(ea)
        if cnt & 0xfff == 0:
            print "[progress] ea: %x" % ea
        if ea == idc.BADADDR:
            break
        if not idaapi.isCode(idaapi.getFlags(ea)):
            continue
        numInst += 1
        # slow, is there any way to avoid it?..
        i = idautils.DecodeInstruction(ea)
        if not i:
            continue
        mnem = i.get_canon_mnem()

        if i[0].type != 1: # only interested in register target operands
            continue
        target_reg = i[0].phrase
        if mnem == 'ADD':
            if i[1].type == 1 and i[1].phrase == 15:
                numAddRegPc += 1

                (val, mov_ea) = movVal.get(target_reg, (0, 0))
                (val_t, movt_ea) = movtVal.get(target_reg, (0, 0))
                if not mov_ea:
                    # No preceding MOV, bailing..
                    continue
                numFixed += 1

                target_addr = 0xffffFFFF & (ea + 4 + val + 0x10000 * val_t)
                # could be THUMB proc..
                if target_addr & 1 and idaapi.isCode(idaapi.getFlags(target_addr - 1)):
                    target_name = idaapi.get_name(target_addr - 1, target_addr - 1)                    
                else:
                    target_name = idaapi.get_name(target_addr,target_addr)
                refs.append((ea, target_addr, target_name))

        if i[1].type == 5:
            if mnem == 'MOV':
                movVal[target_reg] = (i[1].value, ea)
                movtVal[target_reg] = (0, 0) # since movw clears top bits anyway
            elif mnem == 'MOVT':
                movtVal[target_reg] = (i[1].value, ea)
        else:
            movVal[target_reg] = (0, 0)
            movtVal[target_reg] = (0, 0)
    print "%u instructions scanned in %f seconds" % (numInst, time.clock() - t0)

    add_refs()

    # work around an IDA bug
    for i in range (1, 5):
	idaapi.autoWait()
    	add_refs()

    if numAddRegPc == 0:
        successRate = 100
    else:
        successRate = numFixed * 100.0 / numAddRegPc
    print "%u 'ADD Reg, PC' found, %u fixed: %u%%"  % (numAddRegPc, numFixed, successRate)

    global g_done
    g_done = 1
Esempio n. 25
0
def parse_pclntable(module_data):
    pPcHeader = module_data.pPcHeader
    pc_header = parse_pc_header(pMem=pPcHeader)
    ptrSize = pc_header.ptrSize
    numberOfFuncs = pc_header.nFunc

    log._info("Number of Functions : %d" % numberOfFuncs)

    pclntable_start = module_data.pPclnTable
    cur_addr = pclntable_start
    for idx in range(numberOfFuncs):
        cur_addr = pclntable_start + (2 * ptrSize) * idx
        func_rva = common.mem_read_integer(addr=cur_addr, read_size=ptrSize)
        _func_structure_offset = common.mem_read_integer(addr=cur_addr +
                                                         ptrSize,
                                                         read_size=ptrSize)
        _func_addr = pclntable_start + _func_structure_offset

        if not idc.GetFunctionName(func_rva):
            log._info("Unk Func @0x%x" % func_rva)
            idc.MakeUnkn(func_rva, idc.DOUNK_EXPAND)
            idaapi.autoWait()
            idc.MakeCode(func_rva)
            idaapi.autoWait()
            if idc.MakeFunction(func_rva):
                idaapi.autoWait()
                log._info("Create Func @0x%x" % func_rva)

        _func = parse__func(pMem=_func_addr)
        #args=_func.args
        #func_id=_func.args

        func_name_addr = module_data.pFuncNameTable + _func.nameoff
        func_name = idc.GetString(func_name_addr)
        if func_name:
            clean_func_name = utils.clean_function_name(func_name)
            log._info("@0x%x Name : [%s]" % (func_rva, func_name))
            idc.MakeComm(func_rva, "@0x" + str(hex(func_rva)) + " entry")
            idaapi.autoWait()

            if idc.MakeStr(func_name_addr,
                           func_name_addr + len(func_name) + 1):
                idaapi.autoWait()
            else:
                log._error("@0x%x Name : [%s] Failed..." %
                           (func_rva, func_name))

        _func_addr = idaapi.get_func(func_rva)
        if _func_addr is not None:
            if idc.MakeNameEx(_func_addr.startEA,
                              func_name,
                              flags=idaapi.SN_FORCE):
                idaapi.autoWait()
                log._info("@0x%x Name : [%s]" % (func_rva, func_name))
            else:
                log._error("@0x%x Name : [%s] Failed..." %
                           (func_rva, func_name))
Esempio n. 26
0
import idaapi
import idautils


def get_all_strings():
    #Get a list of strings stored in that segment
    list_of_strings = idautils.Strings()
    for string in list_of_strings:
        f.write(str(string) + '\n')


#Wait for analysis to complete
idaapi.autoWait()

#Write results to output file
output_dir = "C:\data\IDBstore\Strings_output\\"
output_filename = 'strings_' + str(GetInputFile()) + '.txt'
f = open(output_dir + output_filename, 'a')
get_all_strings()

#Close and exit
f.close()
idc.Exit(0)
Esempio n. 27
0
def PLUGIN_ENTRY():
    """
        IDAPython plugin wrapper
    """
    idaapi.autoWait()
    return SkelenoxPlugin()
Esempio n. 28
0
def mark_as_code(address):
    if not idc.isCode(idc.GetFlags(address)):
        idc.MakeCode(address)
        idaapi.autoWait()
Esempio n. 29
0
def try_mark_as_code(ea):
  if is_code(ea) and not is_code_by_flags(ea):
    idc.MakeCode(ea)
    idaapi.autoWait()
    return True
  return False
Esempio n. 30
0
#coding=utf-8

import idc
import idaapi
import idautils

idaapi.autoWait()  #等待IDA的分析完成

# 统计idb文件中所有指令的总数
# "D:\software\IDA 7.0\idat64.exe" -A -Scountrecord.py rundll32.idb

count = 0
for func in idautils.Functions():
    #忽略库函数
    flags = idc.GetFunctionFlags(func)
    if flags & FUNC_LIB:
        continue
    for instru in idautils.FuncItems(func):
        count += 1

f = open("instru_count.txt", "w")
print_me = "Instruction Count is %d" % (count)
f.write(print_me)
f.close()

idc.Exit(0)  #停止执行脚本 并关闭idb数据库文件
Esempio n. 31
0
def PLUGIN_ENTRY():
    """
        IDAPython plugin wrapper
    """
    idaapi.autoWait()
    return SkelenoxPlugin()
Esempio n. 32
0
def try_mark_as_function(address):
    if not idaapi.add_func(address, idc.BADADDR):
        DEBUG("Unable to convert code to function: {}".format(address))
        return False
    idaapi.autoWait()
    return True
Esempio n. 33
0
def reanalyze(segm):
    AnalyzeArea(segm.start_ea, segm.end_ea)
    idaapi.autoWait()
Esempio n. 34
0
    def parse_funcs(self):
        '''
        Parse function struct and rename function
        '''
        self.func_num = common.read_mem(self.start_addr + 8,
                                        forced_addr_sz=self.ptr_sz)
        common._info("Total functions number: %d\n" % self.func_num)

        self.func_tbl_sz = self.func_num * 2 * self.ptr_sz
        funcs_entry = self.start_addr + 8
        self.func_tbl_addr = funcs_entry + self.ptr_sz
        idc.MakeComm(funcs_entry, "Functions number")
        idc.MakeNameEx(funcs_entry, "funcs_entry", flags=idaapi.SN_FORCE)
        idaapi.autoWait()
        idc.MakeNameEx(self.func_tbl_addr, "pc0", flags=idaapi.SN_FORCE)
        idaapi.autoWait()

        for func_idx in xrange(self.func_num):
            curr_addr = self.func_tbl_addr + func_idx * 2 * self.ptr_sz

            func_addr = common.read_mem(curr_addr, forced_addr_sz=self.ptr_sz)
            if not idc.GetFunctionName(func_addr):
                common._debug("Creating function @ %x" % func_addr)
                idc.MakeUnkn(func_addr, idc.DOUNK_EXPAND)
                idaapi.autoWait()
                idc.MakeCode(func_addr)
                idaapi.autoWait()
                if idc.MakeFunction(func_addr):
                    idaapi.autoWait()
                    common._info("Create function @ 0x%x" % func_addr)

            name_off = common.read_mem(curr_addr + self.ptr_sz,
                                       forced_addr_sz=self.ptr_sz)
            name_addr = self.start_addr + self.ptr_sz + name_off
            func_st_addr = name_addr - self.ptr_sz
            func_st = FuncStruct(func_st_addr, self)
            func_st.parse()

            # Make comment for name offset
            idc.MakeComm(curr_addr + self.ptr_sz,
                         "Func Struct @ 0x%x" % func_st_addr)
            idaapi.autoWait()
Esempio n. 35
0
    def parse(self, is_test=False):
        func_addr = common.read_mem(self.addr,
                                    forced_addr_sz=self.pclntbl.ptr_sz,
                                    read_only=is_test)

        name_addr = common.read_mem(self.addr + self.pclntbl.ptr_sz, forced_addr_sz=4, read_only=is_test) \
            + self.pclntbl.start_addr
        raw_name_str = idc.GetString(name_addr)
        if raw_name_str and len(raw_name_str) > 0:
            self.name = common.clean_function_name(raw_name_str)

        if not is_test:
            idc.MakeComm(self.addr, "Func Entry")
            idaapi.autoWait()
            # make comment for func name offset
            idc.MakeComm(
                self.addr + self.pclntbl.ptr_sz,
                "Func name offset(Addr @ 0x%x), name string: %s" %
                (name_addr, raw_name_str))
            idaapi.autoWait()

            # Make name string
            if len(self.name) > 0:
                if idc.MakeStr(name_addr, name_addr + len(raw_name_str) + 1):
                    idaapi.autoWait()
                    common._debug("Match func_name: %s" % self.name)
                else:
                    common._error("Make func_name_str [%s] failed @0x%x" %
                                  (self.name, name_addr))

            # Rename function
            real_func = idaapi.get_func(func_addr)
            if real_func is not None:
                orig_func_name = idc.get_func_name(real_func.startEA)
                if len(self.name) > 0 and orig_func_name.startswith("sub_"):
                    if idc.MakeNameEx(real_func.startEA,
                                      self.name,
                                      flags=idaapi.SN_FORCE):
                        idaapi.autoWait()
                        common._debug("Rename function 0x%x: %s" %
                                      (real_func.startEA, self.name))
                    else:
                        common._error('Failed to rename function @ 0x%x' %
                                      real_func.startEA)

        self.args = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.frame = common.read_mem(self.addr + self.pclntbl.ptr_sz + 2 * 4,
                                     forced_addr_sz=4,
                                     read_only=is_test)
        self.pcsp = common.read_mem(self.addr + self.pclntbl.ptr_sz + 3 * 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.pcfile = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4 * 4,
                                      forced_addr_sz=4,
                                      read_only=is_test)
        self.pcln = common.read_mem(self.addr + self.pclntbl.ptr_sz + 5 * 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.nfuncdata = common.read_mem(self.addr + self.pclntbl.ptr_sz +
                                         6 * 4,
                                         forced_addr_sz=4,
                                         read_only=is_test)
        self.npcdata = common.read_mem(self.addr + self.pclntbl.ptr_sz + 7 * 4,
                                       forced_addr_sz=4,
                                       read_only=is_test)

        if not is_test:
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4, "args")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 2 * 4, "frame")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 3 * 4, "pcsp")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4 * 4, "pcfile")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 5 * 4, "pcln")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 6 * 4, "nfuncdata")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 7 * 4, "npcdata")
            idaapi.autoWait()
Esempio n. 36
0
def get_goroot():
    goroot_path_str = ""
    '''
    Get GOROOT path string
    '''
    func_goroot = find_func_by_name("runtime_GOROOT")
    if func_goroot is None:
        _error("Failed to find func contains goroot")
        return goroot_path_str

    goroot_flowchart = idaapi.FlowChart(f=func_goroot)
    ret_cbs = find_ret_cb(goroot_flowchart)
    '''
    runtime.GOROOT() normally has 2 return code blocks:
    1. False return
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

    2. True return(Which we needed):

        (1). goroot string length as ptr
        mov     rax, cs:runtime_internal_sys_DefaultGoroot
        mov     rcx, cs:qword_D9AB58
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

        (2). goroot string length as instant number
        lea     rax, unk_7220B5
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], 0Dh
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn
    '''
    for cb_idx in ret_cbs:
        if idc.GetOpType(goroot_flowchart[cb_idx].startEA, 0) == 1:
            # e.g.: mov     rax, cs:runtime_internal_sys_DefaultGoroot
            '''
            Op Types refer: https://www.hex-rays.com/products/ida/support/sdkdoc/ua_8hpp.html#aaf9da6ae7e8b201108fc225adf13b4d9
                o_void  =      0  # No Operand               
                o_reg  =       1  # General Register (al,ax,es,ds...)    reg
                o_mem  =       2  # Direct Memory Reference  (DATA)      addr
                o_phrase  =    3  # Memory Ref [Base Reg + Index Reg]    phrase
                o_displ  =     4  # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
                o_imm  =       5  # Immediate Value                      value
                o_far  =       6  # Immediate Far Address  (CODE)        addr
                o_near  =      7  # Immediate Near Address (CODE)        addr
                ......
            '''
            goroot_path_len = 0
            goroot_path_addr = 0

            curr_addr = goroot_flowchart[cb_idx].startEA
            goroot_path_addr_val = idc.GetOperandValue(curr_addr, 1)

            end_addr = goroot_flowchart[cb_idx].endEA
            curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)
            # find goroot path length and OpType of length(instant len number or addr of len)
            while curr_addr <= end_addr:
                len_optype = idc.GetOpType(curr_addr, 1)
                if len_optype == 2:
                    # addr of len
                    # mov     rcx, cs:qword_D9AB58
                    goroot_path_addr = read_mem(goroot_path_addr_val)
                    goroot_path_len = read_mem(goroot_path_addr_val + ADDR_SZ)
                    break
                elif len_optype == 5:
                    # instant number as len
                    # mov     [rsp+28h+arg_8], 0Dh
                    goroot_path_addr = goroot_path_addr_val
                    goroot_path_len = idc.GetOperandValue(curr_addr, 1)
                    break

                curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)

            if goroot_path_len == 0 or goroot_path_addr == 0:
                raise Exception("Invalid GOROOT Address ang Length")

            goroot_path_str = str(
                idc.GetManyBytes(goroot_path_addr, goroot_path_len))
            if goroot_path_str is None or len(goroot_path_str) == 0:
                raise Exception("Invalid GOROOT")
            idc.MakeStr(goroot_path_addr, goroot_path_addr + goroot_path_len)
            idaapi.autoWait()
            break

    if len(goroot_path_str) > 0:
        _info("Go ROOT Path: %s\n" % goroot_path_str)

    return goroot_path_str.replace("\\", "/")
        for name in funcs:
  	  each_function_disassembly = list(idautils.FuncItems(name))
  	  for e in each_function_disassembly:
  	    for vulnfunc in vuln_function_list:
  	      pattern=vulnfunc+r'$'
  	      m=re.search(pattern,idc.GetDisasm(e))
  	      if m:
  	        f.write(idc.GetFuncOffset(e)+' --> '+idc.GetDisasm(e)+'\n\n')
      else:
        f.write('Failed to get function names and hence cannot parse stuff\n')

vuln_function_list = []
pattern = []
conf = {}

#List of vulnerable functions that are searched for inside the IDB. Add more functions here.
vuln_function_list=['strcpy','strcat','gets','sprintf','vsprintf','scanf','memcpy','printf']

#Wait for analysis to complete
idaapi.autoWait()

#Write results to output file
output_dir="C:\data\IDBstore\\"
output_filename=str(GetInputFile())+'.txt'
f=open(output_dir+output_filename,'a')
search_for_vuln_api()

#Close and exit
f.close()
idc.Exit(0)
Esempio n. 38
0
def mark_as_code(address):
    if not idc.isCode(idc.GetFlags(address)):
        idc.MakeCode(address)
        idaapi.autoWait()