Exemple #1
0
    def activate(self, ctx):
        ida_auto.set_ida_state(ida_auto.st_Work)
        if self.with_labels:
            print('FakePDB/generate pdb (with function labels):')
        else:
            print('FakePDB/generate pdb:')

        dumper = DumpInfo()
        native = Native()

        #calculate locations
        idb_dir = os.path.dirname(ida_loader.get_path(
            ida_loader.PATH_TYPE_IDB))
        pe_filename_ext = ida_nalt.get_root_filename()
        pe_filename, _ = os.path.splitext(ida_nalt.get_root_filename())

        filepath_exe = ida_nalt.get_input_file_path()
        filepath_json = os.path.join(idb_dir, pe_filename_ext + ".json")
        filepath_pdb = os.path.join(idb_dir, pe_filename + ".pdb")

        #generate json
        print('    * generating JSON: %s' % filepath_json)
        dumper.dump_info(filepath_json)

        print('    * generating PDB: %s' % filepath_pdb)
        native.pdb_generate(filepath_exe, filepath_json, filepath_pdb,
                            self.with_labels)

        print('    * symserv EXE id: %s' % native.pe_timestamp(filepath_exe))
        print('    * symserv PDB id: %s' % native.pe_guidage(filepath_exe))
        print('    * done')

        ida_auto.set_ida_state(ida_auto.st_Ready)
        return 1
 def slot_export_to_x64dbg_script(self):
     if not self.doc:
         idaapi.info("No capa results to export.")
         return
     filename = idaapi.ask_file(
         True,
         os.path.splitext(ida_nalt.get_root_filename())[0] + ".x64dbg.txt",
         "Choose file")
     if not filename:
         return
     if os.path.exists(filename) and 1 != idaapi.ask_yn(
             1, "File already exists. Overwrite?"):
         return
     Tag_file = self.Parse_json(self.doc)
     xdbg_RVA = []
     xdbg_comment = []
     Basename = os.path.splitext(ida_nalt.get_root_filename())[0]
     Base_define = "$base=" + "\"" + Basename + ":base" + "\""
     Xdbg_script = Base_define + "\n"
     for k in range(0, len(Tag_file.split("\n")) - 1):
         xdbg_RVA.append(Tag_file.split("\n")[k].split(';')[0])
         xdbg_comment.append(Tag_file.split("\n")[k].split(';')[1])
         Xdbg_script += "cmt $base+" + xdbg_RVA[
             k] + "," + "\"" + xdbg_comment[k][:226] + "\"" + "\n"
         Xdbg_script += "bookmark $base+" + xdbg_RVA[k] + "\n"
     f = open(filename, "w").write(Xdbg_script)
    def activate(self, ctx):
        # get active filename
        pe_filename_ext = ida_nalt.get_root_filename()
        if not pe_filename_ext:
            print('FakePDB/generate lib: file not loaded')
            return 1

        ida_auto.set_ida_state(ida_auto.st_Work)
        print('FakePDB/generate lib:')

        dumper = DumpInfo()
        native = Native()

        #calculate locations
        idb_dir = os.path.dirname(ida_loader.get_path(
            ida_loader.PATH_TYPE_IDB))

        pe_filename, _ = os.path.splitext(ida_nalt.get_root_filename())

        filepath_exe = ida_nalt.get_input_file_path()
        filepath_json = os.path.join(idb_dir, pe_filename_ext + ".json")
        filepath_lib = os.path.join(idb_dir, pe_filename + ".lib")

        #generate json
        print('    * generating JSON: %s' % filepath_json)
        dumper.dump_info(filepath_json)

        print('    * generating LIB: %s' % filepath_lib)
        native.coff_createlib(filepath_json, filepath_lib)

        print('    * done')

        ida_auto.set_ida_state(ida_auto.st_Ready)
        return 1
Exemple #4
0
def get_module_file_name(cpu_context, func_name, func_args):
    r"""
    Get the fully qualified path for the file that contains the specified module.

    Using the real filename prefixed by "%INPUT_FILE_DIR%\" to indicate the file path for this emulator.
    """
    wide = func_name.endswith("W")
    module_handle, filename_ptr, max_size = func_args

    # We don't support getting filename for modules that aren't itself.
    if module_handle != 0:
        return

    # Getting input file path as module path.
    # Since we shouldn't expose the user's real file path structure we'll use %INPUT_FILE_DIR% instead.
    # Must be truncated to fit in max_size filename_ptr (-1 for the terminator)
    file_path = "%INPUT_FILE_DIR%\\" + ida_nalt.get_root_filename()
    file_path = file_path[:max_size - 1]

    logger.debug("Writing module path %s to 0x%08X", file_path, filename_ptr)
    cpu_context.write_data(
        filename_ptr,
        file_path,
        data_type=constants.WIDE_STRING if wide else constants.STRING,
    )

    return len(file_path)
Exemple #5
0
    def _create_project_accepted(self, dialog):
        """Called when the project creation dialog is accepted."""
        name = dialog.get_result()
        # Ensure we don't already have a project with that name
        # Note: 2 different groups can have two projects with the same name
        # and it will effectively be 2 different projects
        if any(project.name == name for project in self._projects):
            failure = QMessageBox()
            failure.setIcon(QMessageBox.Warning)
            failure.setStandardButtons(QMessageBox.Ok)
            failure.setText("A project with that name already exists!")
            failure.setWindowTitle("New Project")
            icon_path = self._plugin.plugin_resource("upload.png")
            failure.setWindowIcon(QIcon(icon_path))
            failure.exec_()
            return

        # Get all the information we need and sent it to the server
        hash = ida_nalt.retrieve_input_file_md5()
        # Remove the trailing null byte, if exists
        if hash.endswith(b'\x00'):
            hash = hash[0:-1]
        # This decode is safe, because we have an hash in hex format
        hash = binascii.hexlify(hash).decode('utf-8')
        file = ida_nalt.get_root_filename()
        ftype = ida_loader.get_file_type_name()
        date_format = "%Y/%m/%d %H:%M"
        date = datetime.datetime.now().strftime(date_format)
        project = Project(self._group.name, name, hash, file, ftype, date)
        d = self._plugin.network.send_packet(CreateProject.Query(project))
        d.add_callback(partial(self._project_created, project))
        d.add_errback(self._plugin.logger.exception)
Exemple #6
0
    def inputFile(self):
        """Return the (full) path of the input file that was used to create the database.

        Return Value:
            Path to the input file
        """
        return ida_nalt.get_root_filename()
Exemple #7
0
    def _create_project_accepted(self, dialog):
        """Called when the project creation dialog is accepted."""
        name = dialog.get_result()

        # Ensure we don't already have a project with that name
        if any(project.name == name for project in self._projects):
            failure = QMessageBox()
            failure.setIcon(QMessageBox.Warning)
            failure.setStandardButtons(QMessageBox.Ok)
            failure.setText("A project with that name already exists!")
            failure.setWindowTitle("New Project")
            icon_path = self._plugin.plugin_resource("upload.png")
            failure.setWindowIcon(QIcon(icon_path))
            failure.exec_()
            return

        # Get all the information we need and sent it to the server
        hash = ida_nalt.retrieve_input_file_md5().lower()
        file = ida_nalt.get_root_filename()
        type = ida_loader.get_file_type_name()
        date_format = "%Y/%m/%d %H:%M"
        date = datetime.datetime.now().strftime(date_format)
        project = Project(name, hash, file, type, date)
        d = self._plugin.network.send_packet(CreateProject.Query(project))
        d.add_callback(partial(self._project_created, project))
        d.add_errback(self._plugin.logger.exception)
Exemple #8
0
	def __call__(self):
		target_pid = -1

		if idaapi.is_debugger_on():
			idaapi.msg("[%s] the debugger is currently running\n" % PLUGNAME)
			return -1

		if not self.times%5:
			idaapi.msg("[%s] waiting for the process (%ds left)...\n" % \
				(PLUGNAME, self.times))

		filename = ida_nalt.get_root_filename()
		pis = ida_idd.procinfo_vec_t()
		ida_dbg.get_processes(pis)

		for proc in pis:
			proc_name = proc.name.split(" ")[1]
			idx = proc_name.rfind("/")

			if idx != -1:
				proc_name = proc_name[idx+1:]

			if filename == proc_name:
				target_pid = proc.pid
				break

		if target_pid != -1:
			idaapi.msg("[%s] found. start debug (PID: %d)\n" % (PLUGNAME, target_pid))
			ida_dbg.attach_process(target_pid, -1)
			ida_dbg.wait_for_next_event(ida_dbg.WFNE_SUSP, -1)
			ida_dbg.continue_process()
			return -1

		self.times -= 1
		return -1 if self.times == 0 else self.interval
Exemple #9
0
def prepare_debug_noui():
    target_pid = -1
    idaapi.msg("[%s] waiting...\n" % (PLUGNAME))

    filename = ida_nalt.get_root_filename()
    pis = ida_idd.procinfo_vec_t()
    ida_dbg.get_processes(pis)

    for proc in pis:
        proc_name = proc.name.split(" ")[1]
        idx = proc_name.rfind("/")

        if idx != -1:
            proc_name = proc_name[idx + 1:]

        if filename == proc_name:
            target_pid = proc.pid
            break

    if target_pid != -1:
        idaapi.msg("[%s] start debug (PID: %d)\n" % (PLUGNAME, target_pid))
        ida_dbg.attach_process(target_pid, -1)
        idc.GetDebuggerEvent(idc.WFNE_SUSP, -1)
        ida_dbg.continue_process()
    else:
        idaapi.msg("[%s] exit waiting\n" % (PLUGNAME))
Exemple #10
0
    def _new_repo_accepted(self, dialog):
        """
        Called when the new repository dialog is accepted by the user.

        :param dialog: the dialog
        """
        name = dialog.get_result()
        if any(repo.name == name for repo in self._repos):
            failure = QMessageBox()
            failure.setIcon(QMessageBox.Warning)
            failure.setStandardButtons(QMessageBox.Ok)
            failure.setText("A repository with that name already exists!")
            failure.setWindowTitle("New Repository")
            iconPath = self._plugin.resource('upload.png')
            failure.setWindowIcon(QIcon(iconPath))
            failure.exec_()
            return

        hash = ida_nalt.retrieve_input_file_md5().lower()
        file = ida_nalt.get_root_filename()
        type = ida_loader.get_file_type_name()
        dateFormat = "%Y/%m/%d %H:%M"
        date = datetime.datetime.now().strftime(dateFormat)
        repo = Repository(name, hash, file, type, date)
        d = self._plugin.network.send_packet(NewRepository.Query(repo))
        d.add_callback(partial(self._on_new_repo, repo))
        d.add_errback(logger.exception)
Exemple #11
0
    def devirtualize_calls(self, call_list, modules):
        ida_file_name = get_root_filename()

        call_cnt = 0

        for module in modules:
            if module["name"] == ida_file_name:
                loaded_module = module
                break
        
        start = int(loaded_module["base"], 16)
        end = start + loaded_module["size"]

        print("[*] Adding virtual calls for module " + ida_file_name)

        for v_call in call_list:
            for call in v_call:
                # Check if call belongs to the current module
                if start <= int(call, 16) <= end:

                    src = int(call, 16) - start
                    dst = int(v_call[call]) - start
                    add_cref(src, dst, fl_CN | XREF_USER)

                    call_cnt += 1

            print("[*] Added {} virtual calls for module {}!".format(call_cnt, ida_file_name))
Exemple #12
0
def search():
    """
    Attempts to find potential device names in the currently opened binary, it starts by searching for Unicode device names,
    if this fails then it utilises FLOSS to search for stack based and obfuscated strings.
    """

    if not find_unicode_device_name():
        print(
            "Unicode device name not found, attempting to find obfuscated and stack based strings."
        )
        try:
            import floss
            import floss.identification_manager
            import floss.main
            import floss.stackstrings
            import viv_utils
        except ImportError:
            print(
                "Please install FLOSS to continue, see: https://github.com/fireeye/flare-floss/"
            )
            return
        logging.basicConfig(
        )  #To avoid logger handler not found errors, from https://github.com/fireeye/flare-floss/blob/66f67a49a38ae028a5e86f1de743c384d5271901/scripts/idaplugin.py#L154
        logging.getLogger('vtrace.platforms.win32').setLevel(logging.ERROR)
        sample_file_path = ida_nalt.get_root_filename()

        try:
            vw = viv_utils.getWorkspace(sample_file_path, should_save=False)
        except Exception as e:
            print("Vivisect failed to load the input file: {0}".format(
                e.message))
            return

        functions = set(vw.getFunctions())
        plugins = floss.main.get_all_plugins()
        device_names = set()

        stack_strings = floss.stackstrings.extract_stackstrings(vw,
                                                                functions,
                                                                4,
                                                                no_filter=True)
        for i in stack_strings:
            device_names.add(i)
        dec_func_candidates = floss.identification_manager.identify_decoding_functions(
            vw, plugins, functions)
        decoded_strings = floss.main.decode_strings(vw,
                                                    dec_func_candidates,
                                                    4,
                                                    no_filter=True)
        if len(decoded_strings) > 0:
            for i in decoded_strings:
                device_names.add(str(i.s))
            print("Potential device names from obfuscated or stack strings:")
            for i in device_names:
                print(i)
        else:
            print("No obfuscated or stack strings found :(")
Exemple #13
0
def backup_database():
    """ Backup the database to a file similar to IDA's snapshot function. """
    time_string = strftime('%Y%m%d%H%M%S')
    file = ida_nalt.get_root_filename()		# For IDA 7.5
    if not file:
        raise NoInputFileException('No input file provided')
    input_file = rsplit(file, '.', 1)[0]
    backup_file = '%s_%s.idb' % (input_file, time_string)
    g_logger.info('Backing up database to file ' + backup_file)
    idc.save_database(backup_file, idaapi.DBFL_BAK)
Exemple #14
0
 def wrapper(*args, **kwargs):
     if cls.get_dbg_mode():
         cur_workpath = os.getcwd()
         log_filename = '%s.xdbg' % ida_nalt.get_root_filename()
         log_filepath = os.path.join(cur_workpath, log_filename)
         cls.log_path = log_filepath
         if cls.log_fd:
             cls.log_fd.close()
             cls.log_fd = None
         cls.log_fd = open(cls.log_path, 'a')
     return func(*args, **kwargs)
def get_define(ioctl_code):
    """Decodes an ioctl code and returns a C define for it using the CTL_CODE macro"""

    function = get_function(ioctl_code)
    device_name, device_code = get_device(ioctl_code)
    method_name, method_code = get_method(ioctl_code)
    access_name, access_code = get_access(ioctl_code)

    name = "%s_0x%08X" % (ida_nalt.get_root_filename().split('.')[0],
                          ioctl_code)
    return "#define %s CTL_CODE(0x%X, 0x%X, %s, %s)" % (
        name, device_code, function, method_name, access_name)
Exemple #16
0
 def init(self):
     self.is_server_start = False
     print("[IDACodeEditor] Loading ...")
     if not self.is_server_start:
         sockets = tornado.netutil.bind_sockets(0, '127.0.0.1')
         server = StartServer(sockets, title=ida_nalt.get_root_filename())
         server.daemon = True
         server.start()
         self.URL = "%s:%s" % (HOST, sockets[0].getsockname()[1])
         print("[IDACodeEditor] Server started %s." % self.URL)
         self.is_server_start = True
     return idaapi.PLUGIN_KEEP
 def slot_export_to_tag_file(self):
     if not self.doc:
         idaapi.info("No capa results to export.")
         return
     Tag_file = self.Parse_json(self.doc)
     filename = idaapi.ask_file(
         True,
         os.path.splitext(ida_nalt.get_root_filename())[0] + ".tag",
         "Choose file")
     if not filename:
         return
     if os.path.exists(filename) and 1 != idaapi.ask_yn(
             1, "File already exists. Overwrite?"):
         return
     f = open(filename, "w").write(Tag_file)
Exemple #18
0
def get_unicode_device_names():
    """Returns all Unicode strings within the binary currently being analysed in IDA which might be device names"""

    path = ida_nalt.get_root_filename()
    min_length = 4
    possible_names = set()
    with open(path, "rb") as f:
        b = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

        for s in extract_unicode_strings(b, n=min_length):
            s_str = str(s.s)
            if s_str.startswith('\\Device\\') or s_str.startswith(
                    '\\DosDevices\\'):
                possible_names.add(str(s.s))
    return possible_names
 def slot_export_pickle(self):
     """ export capa results as JSON file """
     if not self.doc:
         idaapi.info("No capa results to export.")
         return
     path = idaapi.ask_file(
         True,
         os.path.splitext(ida_nalt.get_root_filename())[0] + ".capa",
         "Choose file")
     if not path:
         return
     if os.path.exists(path) and 1 != idaapi.ask_yn(
             1, "File already exists. Overwrite?"):
         return
     with open(path, "wb") as export_file:
         pickle.dump(self.doc, export_file, -1)
    def activate(self, ctx):
        # get active filename
        if not ida_nalt.get_root_filename():
            print('FakePDB/import offsets: file not loaded')
            return 1

        screen_ea = ida_kernwin.get_screen_ea()

        finder = SignatureFinder()
        sig = finder.get_signature(screen_ea)
        print('FakePDB/signatures_find:')
        print('   * address  : %s' % hex(screen_ea))
        print('   * name     : %s' % ida_name.get_name(screen_ea))
        print('   * signature: %s' % sig)
        print('')
        return 0
Exemple #21
0
    def btn_import_all_bpt_addr(self, code=0):
        """
        导入离线断点
        """
        cur_workpath = os.getcwd()
        csv_filepath = os.path.join(
            cur_workpath, '%s_bpt.csv' % ida_nalt.get_root_filename())

        if os.path.exists(csv_filepath):
            with open(csv_filepath, 'r') as f:
                next(f)
                reader = csv.reader(f)
                for row in reader:
                    ida_dbg.add_bpt(int(row[0], 16), 0, idc.BPT_DEFAULT)
            FELogger.info("导入断点完成:%s" % csv_filepath)
        else:
            FELogger.warn("文件不存在:%s" % csv_filepath)
Exemple #22
0
    def btn_export_all_bpt_addr(self, code=0):
        """
        导出离线断点
        """
        cur_workpath = os.getcwd()
        csv_filepath = os.path.join(
            cur_workpath, '%s_bpt.csv' % ida_nalt.get_root_filename())

        bpt_list = self.get_all_bpt_list()
        bpt_list = [[format(bpt, '#010x')[2:]] for bpt in bpt_list]

        header = ['breakpoints']
        with open(csv_filepath, 'w', newline='') as f:
            ff = csv.writer(f)
            ff.writerow(header)
            ff.writerows(bpt_list)

        FELogger.info("导出断点完成:%s" % csv_filepath)
Exemple #23
0
    def activate(self, ctx):
        # get active filename
        if not ida_nalt.get_root_filename():
            print('FakePDB/import offsets: file not loaded')
            return 1

        importer = OffsetsImporter()

        print('FakePDB/import offsets:')

        f = ida_kernwin.ask_file(False, "*.json", "Select the file to load")
        if f and os.path.exists(f):
            importer.process_json(f)
            print('    * finished')
        else:
            print('    * canceled')

        print('')
        return 1
    def activate(self, ctx):
        # get active filename
        pe_filename_ext = ida_nalt.get_root_filename()
        if not pe_filename_ext:
            print('FakePDB/dumpinfo: file not loaded')
            return 1

        #calculate locations
        idb_dir = os.path.dirname(ida_loader.get_path(
            ida_loader.PATH_TYPE_IDB))

        filepath_json = os.path.join(idb_dir, pe_filename_ext + ".json")

        dumper = DumpInfo()
        print('FakePDB/dumpinfo:')
        ida_auto.set_ida_state(ida_auto.st_Work)
        dumper.dump_info(filepath_json)
        ida_auto.set_ida_state(ida_auto.st_Ready)
        print('   * done')
        return 1
Exemple #25
0
    def __process_general(self):
        info_struct = ida_idaapi.get_inf_structure()

        #architecture
        arch = info_struct.procname
        if arch == 'metapc':
            arch = 'x86'
        elif arch == 'ARM':
            arch = 'arm'

        #bitness
        bitness = 16
        if info_struct.is_64bit():
            bitness = 64
        elif info_struct.is_32bit():
            bitness = 32

        result = {
            'filename': ida_nalt.get_root_filename(),
            'architecture': arch,
            'bitness': bitness
        }

        return result
 def slot_export_to_r2_script(self):
     if not self.doc:
         idaapi.info("No capa results to export.")
         return
     filename = idaapi.ask_file(
         True,
         os.path.splitext(ida_nalt.get_root_filename())[0] + ".cutter.r2",
         "Choose file")
     if not filename:
         return
     if os.path.exists(filename) and 1 != idaapi.ask_yn(
             1, "File already exists. Overwrite?"):
         return
     Tag_file = self.Parse_json(self.doc)
     Cutter_RVA = []
     Cutter_comment = []
     Cutter_script = ""
     for k in range(0, len(Tag_file.split("\n")) - 1):
         Cutter_RVA.append(Tag_file.split("\n")[k].split(';')[0])
         Cutter_comment.append(Tag_file.split("\n")[k].split(';')[1])
         Cutter_script += "CCu base64:" + base64.b64encode(
             Cutter_comment[k].encode(
                 "utf-8")).decode() + " @ " + "$B+0x" + Cutter_RVA[k] + "\n"
     f = open(filename, "w").write(Cutter_script)
Exemple #27
0
 def __process_general(self):
     result = dict()
     result['filename'] = ida_nalt.get_root_filename()
     return result
Exemple #28
0
 def __init__(self, parent=None):
     super(WaitThread, self).__init__(parent)
     self.filename = ida_nalt.get_root_filename()
     self.target_pid = -1
            continue
        for block in idaapi.FlowChart(f):
            if start <= block.start_ea < end:
                if first == 0:
                    if block.start_ea >= 0x1000:
                        subtract_addr = 0x1000
                        first = 1
                        
                max_offset = max(max_offset, block.start_ea)
                patchpoints.add(block.start_ea - subtract_addr)
            #else:
            #    print("Warning: broken CFG?")

# Round up max_offset to page size
size = max_offset
rem = size % 0x1000
if rem != 0:
    size += 0x1000 - rem

print("Writing to " + home + "/Desktop/patches.txt")

with open(home + "/Desktop/patches.txt", "w") as f:
    f.write(ida_nalt.get_root_filename() + ':' + hex(size) + '\n')
    f.write('\n'.join(map(hex, sorted(patchpoints))))
    f.write('\n')

print("Done, found {} patchpoints".format(len(patchpoints)))

# For headless script running remove the comment from the next line
#ida_pro.qexit()
Exemple #30
0
nimps = idaapi.get_import_module_qty()

nt_power_information = None
for i in range(0, nimps):
    name = idaapi.get_import_module_name(i)
    if not name:
        continue

    if "ntdll" in name:
        idaapi.enum_import_names(i, imp_cb)
        if nt_power_information is not None:
            break

output_filename = basename(ida_nalt.get_input_file_path()) \
                     + ida_nalt.get_root_filename() + ".dec"
if nt_power_information:
    ida_auto.auto_wait()

    if ida_loader.load_plugin("hexx64") and ida_hexrays.init_hexrays_plugin():
        code_xrefs = idautils.CodeRefsTo(nt_power_information, 1)
        for cx in code_xrefs:
            cf = ida_hexrays.decompile(cx)
            if cf:
                with open(output_filename, "a") as fd:
                    fd.write(str(cf) + '\n')
            else:
                with open(output_filename, "a") as fd:
                    fd.write("[!] Decompilation failed\n")
    else:
        with open(output_filename, "a") as fd: