def activate_virtualenv_env(virtualenv=None, interactive=True): """ Activate a Virtualenv based virtual environment. """ folder = "Scripts" if os.name == "nt" else "bin" if virtualenv == None: virtualenv = os.environ.get("VIRTUAL_ENV") if not virtualenv and interactive: default_virtualenv = os.path.join(idaapi.get_user_idadir(), "virtualenv") virtualenv = idaapi.askstr(0, default_virtualenv, "Select a virtualenv") if not virtualenv: raise ValueError("No active virtualenv") if not os.path.isdir(virtualenv): raise ValueError("This path is not a dir: " + virtualenv) virtualenv_script = os.path.join(virtualenv, folder, "activate_this.py") if not os.path.isfile(virtualenv_script): raise ValueError('Enable to find "' + folder + os.sep + 'activate_this.py" in virtualenv: ' + virtualenv) with open(virtualenv_script) as infile: exec(infile.read(), dict(__file__=virtualenv_script)) return virtualenv
def __init__(self): self.name = "BinaryAI" cfg_dir = os.path.join(idaapi.get_user_idadir(), idaapi.CFG_SUBDIR) os.makedirs(cfg_dir) if not os.path.exists(cfg_dir) else None self.cfg = Config(os.path.join(cfg_dir, "{}.cfg".format(bai.__name__)), BinaryAIManager.Default) self._client = None self._netnode = Netnode(BinaryAIManager.BINARYAI_NETNODE_NAMESPACE)
def install(): """ Install FA ida plugin :return: None """ fa_plugin_dir = os.path.join( idaapi.get_user_idadir(), 'plugins') if not os.path.exists(fa_plugin_dir): os.makedirs(fa_plugin_dir) fa_plugin_filename = os.path.join(fa_plugin_dir, PLUGIN_FILENAME) if os.path.exists(fa_plugin_filename): IdaLoader.log('already installed') return with open(fa_plugin_filename, 'w') as f: f.writelines("""from __future__ import print_function try: from fa.ida_plugin import PLUGIN_ENTRY, FAIDAPlugIn except ImportError: print("[WARN] Could not load FA plugin. " "FA Python package doesn\'t seem to be installed.") """) idaapi.load_plugin(PLUGIN_FILENAME) IdaLoader.log('Successfully installed :)')
def init(self): """Set up menu hooks and implements search methods.""" valid_config = False self.menu = None config_file = os.path.join(idaapi.get_user_idadir(), 'virustotal.conf') vtsetup = VTpluginSetup(config_file) if vtsetup.check_version(): ida_kernwin.info( 'VirusTotal\'s IDA Pro Plugin\nNew version available!') logging.info('[VT Plugin] There\'s a new version of this plugin!') else: logging.debug('[VT Plugin] No update available.') if os.path.exists(config_file): valid_config = vtsetup.read_config() else: answer = vtsetup.show_warning() if answer == 1: # OK vtsetup.auto_upload = True valid_config = vtsetup.write_config() elif answer == 0: # NO vtsetup.auto_upload = False valid_config = vtsetup.write_config() elif answer == -1: # Cancel valid_config = False if valid_config: checksample = CheckSample(vtsetup.auto_upload, vtsetup.file_path) checksample.start() self.menu = Popups() self.menu.hook() arch_info = idaapi.get_inf_structure() try: if arch_info.procName in self.SUPPORTED_PROCESSORS: VTGrepWildcards.register(self, 'Search for similar code') VTGrepWildCardsStrict.register( self, 'Search for similar code (strict)') VTGrepWildCardsFunction.register( self, 'Search for similar functions') else: logging.info('\n - Processor detected: %s', arch_info.procName) logging.info( ' - Searching for similar code is not available.') VTGrepBytes.register(self, 'Search for bytes') VTGrepStrings.register(self, 'Search for string') except: logging.error('[VT Plugin] Unable to register popups actions.') else: logging.info( '[VT Plugin] Plugin disabled, restart IDA to proceed. ') ida_kernwin.warning('Plugin disabled, restart IDA to proceed.') return idaapi.PLUGIN_KEEP
def __init__(self, path=None, default=None): if path is None: path = os.path.join(idaapi.get_user_idadir(), idaapi.CFG_SUBDIR) if not os.path.exists(path): os.makedirs(path) path = os.path.join(path, "binaryai.cfg") if default is None: default = BinaryAIConfig.Default super(BinaryAIConfig, self).__init__(path, default)
def __init__(self): self.name = "BinaryAI" cfg_dir = os.path.join(idaapi.get_user_idadir(), idaapi.CFG_SUBDIR) os.makedirs(cfg_dir) if not os.path.exists(cfg_dir) else None self.cfg = Config(os.path.join(cfg_dir, "{}.cfg".format(bai.__name__)), BinaryAIManager.Default) bai_mark.color = int(self.cfg['color'], 16) self._client = None self._funcset = None self.cview = None
def __init__(self, sim): ''' Class constructor. @sim - idasimulator_t class instance. Returns None. ''' self.cfg = None self.sim = sim self.idb = idc.GetIdbPath() self.confile = os.path.join(idaapi.get_user_idadir(), self.CONFIG_FILE)
def init(self): info = idaapi.get_inf_structure() # IDA 6/7 compat procname = info.procname if hasattr( info, 'procname') else info.get_proc_name()[0] if procname != 'metapc' and procname != 'ARM' and procname != 'PPC': bc_log.info("CPU '%s' is not supported, not loading BinCAT", procname) return idaapi.PLUGIN_SKIP try: from pybincat import cfa as cfa_module global cfa_module except: bc_log.warning("Failed to load 'pybincat.cfa' python module\n%s", repr(sys.exc_info())) return idaapi.PLUGIN_SKIP PluginOptions.init() # add plugin's 'bin' dir to PATH userdir = idaapi.get_user_idadir() bin_path = os.path.join(userdir, "plugins", "idabincat", "bin") if os.path.isdir(bin_path): path_env_sep = ';' if os.name == 'nt' else ':' os.environ['PATH'] += path_env_sep + bin_path if no_spawn: bc_exe = None else: # Check if bincat is available bc_exe = distutils.spawn.find_executable('bincat') if bc_exe is None: if no_spawn: bc_exe = os.path.join(bin_path, "bincat") else: bc_exe = distutils.spawn.find_executable('bincat') if bc_exe is None and no_spawn is False: bc_log.warning( 'Could not find bincat binary, will not be able to run local analysis' ) if PluginOptions.get("autostart") != "True": # will initialize later return idaapi.PLUGIN_OK bc_log.info("Autostarting") self.state = State() self.initialized = True bc_log.info("IDABinCAT ready.") return idaapi.PLUGIN_KEEP
def __init__(self, parent=None): self._logger = logging.getLogger(__name__ + '.' + self.__class__.__name__) self._logger.debug('Starting UI') QtWidgets.QDialog.__init__( self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.setWindowTitle("MSDN Annotations Configuration") # Parse configuration file to dictionary self.file_path = os.path.abspath( os.path.join(idaapi.get_user_idadir(), CONFIG_FILE)) self.config_parser = ConfigParser() self.config_parser.read(self.file_path) self.config = self.read_config() self.populate_form()
def init(self): procname = idaapi.get_inf_structure().get_proc_name() if procname[0] != 'metapc': bc_log.info("Not on x86, not loading BinCAT") return idaapi.PLUGIN_SKIP try: from pybincat import cfa as cfa_module global cfa_module except: bc_log.warning("Failed to load 'pybincat.cfa' python module\n%s", repr(sys.exc_info())) return idaapi.PLUGIN_SKIP PluginOptions.init() if no_spawn: bc_exe = None else: # Check if bincat_native is available bc_exe = distutils.spawn.find_executable('bincat_native') if bc_exe is None and os.name == 'nt': # add to PATH userdir = idaapi.get_user_idadir() bin_path = os.path.join(userdir, "plugins", "idabincat", "bin") if os.path.isdir(bin_path): os.environ['PATH'] += ";" + bin_path if no_spawn: bc_exe = os.path.join(bin_path, "bincat_native.exe") else: bc_exe = distutils.spawn.find_executable('bincat_native') if bc_exe is None and no_spawn is False: bc_log.warning( 'Could not find bincat_native binary, will not be able to run analysis' ) if PluginOptions.get("autostart") != "True": # will initialize later return idaapi.PLUGIN_OK bc_log.info("Autostarting") self.state = State() self.initialized = True bc_log.info("IDABinCAT ready.") return idaapi.PLUGIN_KEEP
def activate_virtualenv_env(virtualenv=None, interactive=True): folder = "Scripts" if os.name == "nt" else "bin" if virtualenv == None: virtualenv = os.environ.get("VIRTUAL_ENV") if not virtualenv and interactive: default_virtualenv = os.path.join(idaapi.get_user_idadir(), "virtualenv") virtualenv = idaapi.askstr(0, default_virtualenv, "Select a virtualenv") if not virtualenv: raise ValueError("No virtualenv env") if not os.path.isdir(virtualenv): raise ValueError("This path is not a dir: " + virtualenv) virtualenv_script = os.path.join(virtualenv, folder, "activate_this.py") if not os.path.isfile(virtualenv_script): raise ValueError('Enable to find "' + folder + os.sep + 'activate_this.py" in virtualenv: ' + virtualenv) execfile(virtualenv_script, dict(__file__=virtualenv_script)) return virtualenv
def update_pythonrc(): rcpath = os.path.join(idaapi.get_user_idadir(), "idapythonrc.py") sep_with_ver = SEP[0] + __version__ payload = '%s\n%s\n%s' % (sep_with_ver, RC.strip(), SEP[1]) if os.path.isfile(rcpath): with open(rcpath, 'rb') as f: py = f.read() if payload in py and all(x in py for x in SEP): py = py.split(SEP[0], 1) py = py[0] + py[1].split(SEP[1], 1)[1] else: py = payload print('Removed idapkg from idapythonrc.py. ' 'I hope to see you again! :)') print(' You can remove ~/idapkg directory to remove packages and configurations.') with open(rcpath, 'wb') as f: f.write(py)
def load_signatures(): db = idadir("plugins/findhash.xml") if not os.path.isfile(db): db = os.path.join(get_user_idadir(), "plugins/findhash.xml") root = ET.parse(db).getroot() signature = [] for p in root: name, data = p.attrib['t'].split(" [") bits, size = data[:-1].split(".") bits = int(bits) signature.append({ "name": name, "bits": bits, "size": int(size), "data": codecs.decode(p.text, ('hex')), }) return signature
def update_pythonrc(): rcpath = os.path.join(idaapi.get_user_idadir(), "idapythonrc.py") sep_with_ver = SEP[0] + __version__ payload = '%s\n%s\n%s' % (sep_with_ver, RC.strip(), SEP[1]) if os.path.isfile(rcpath): with open(rcpath, 'rb') as f: py = f.read() if payload in py: return if all(x in py for x in SEP): py = py.split(SEP[0], 1) py = py[0] + py[1].split(SEP[1], 1)[1] py = payload + py print('Updating idapkg into idapythonrc.py.') else: py = payload print('Added idapkg into idapythonrc.py. Will work after restarting!') with open(rcpath, 'wb') as f: f.write(py)
def __init__(self, plugin): global PLUGIN_HOTKEY self.__plugin = plugin self.__loaded = False self.__configName = idaapi.get_user_idadir() + '\\pySigMaker.config' # 0 disables limit self.maxRefs = 0 # False creates less reliable sigs IE: they break easier on updates self.bOnlyReliable = True # Controls how sig is selected from multiple unique sigs self.SigSelect = SigSelect.OPT_LENGTH # Type of sig to return self.SigType = SigType.SIG_IDA self.LogLevel = LogOptions.LOG_ERROR # Max sig length IE: 'E9 ?' is length of 2 self.maxSigLength = 100 # Sig test history self._history = [] # default hot key self.hotkey = PLUGIN_HOTKEY # form info self.x = -1 self.y = -1 self.w = -1 self.h = -1
help = pydoc.Helper(input=IDAPythonHelpPrompter(), output=sys.stdout) # Assign a default sys.argv sys.argv = [""] # Have to make sure Python finds our modules sys.path.append(_idaapi.idadir("python")) # Remove current directory from the top of the patch search if '' in sys.path: # On non Windows, the empty path is added sys.path.remove('') if os.getcwd() in sys.path: sys.path.remove(os.getcwd()) # ...and add it to the end if needed if not IDAPYTHON_REMOVE_CWD_SYS_PATH: sys.path.append(os.getcwd()) # Import all the required modules from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall, Form from idc import * from idautils import * import idaapi # Load the users personal init file userrc = os.path.join(get_user_idadir(), "idapythonrc.py") if os.path.exists(userrc): idaapi.IDAPython_ExecScript(userrc, globals()) # All done, ready to rock.
import IPython.utils.frame import ipykernel.iostream import sys import os import idaapi # The IPython kernel will override sys.std{out,err}. We keep a copy to let the # existing embeded IDA console continue working, and also let IPython output to # it. _ida_stdout = sys.stdout _ida_stderr = sys.stderr # Path to a file to load into the kernel's namespace during its creation. # Similar to the idapythonrc.py file. IPYIDARC_PATH = os.path.join(idaapi.get_user_idadir(), 'ipyidarc.py') if sys.__stdout__ is None or sys.__stdout__.fileno() < 0: # IPython insist on using sys.__stdout__, however it's not available in IDA # on Windows. We'll replace __stdout__ to the "nul" to avoid exception when # writing and flushing on the bogus file descriptor. sys.__stdout__ = open(os.devnull, "w") # IPython will override sys.excepthook and send exception to sys.__stderr__. IDA # expect exception to be written to sys.stderr (overridden by IDA) to print them # in the console window. Used by wrap_excepthook. _ida_excepthook = sys.excepthook def is_using_ipykernel_5(): import ipykernel
import os import idaapi import itertools PLUGINS_LIST = "plugins.list" USER_PLUGIN_LIST_PATH = os.path.join(idaapi.get_user_idadir(), PLUGINS_LIST) SYS_PLUGIN_LIST_PATH = os.path.join(idaapi.idadir(idaapi.CFG_SUBDIR), PLUGINS_LIST) def message(*messages): for msg in messages: for line in msg.splitlines(): idaapi.msg("[PluginLoader] {}\n".format(line)) def iter_without_duplicates(*iterables): visited = set() chained_iterables = itertools.chain(*iterables) for item in chained_iterables: if item in visited: continue yield item visited.add(item) def iter_paths(filepath): try: with open(filepath) as f: for line in f: # Use `#` for comments
def main(config=None): g_logger.info('Starting script execution') if CREATE_BACKUP: # Backup database before making any changes try: backup_database() except NoInputFileException as e: g_logger.warn('Quitting execution: ' + e.message) return # Default config in case none is provided config['arg_description_format'] = '{argument_name}_{function_name}' if not config: config = {} config['functions_annotate'] = True config['functions_repeatable_comment'] = False config['arguments_annotate'] = True config['constants_import'] = True config['msdn_data_dir'] = os.path.abspath(os.path.join(idaapi.get_user_idadir(), 'MSDN_data')) # Parse XML files and populate dictionary msdn_data_dir = config['msdn_data_dir'] if not os.path.exists(msdn_data_dir): g_logger.error('Configured msdn data directory does not exist: %s', msdn_data_dir) return functions_map = parse_xml_data_files(msdn_data_dir) # Retrieve all imported functions, store data in dictionaries g_logger.debug('Retrieving imported functions') library_calls = {} # maps function_name -> CodeRefTo library_addr = {} # maps function_name -> ea in import table get_imports(library_calls, library_addr) # Append segment where function argument information will be stored try: g_logger.debug('Appending new segment %s' % NEW_SEGMENT_NAME) free_ea = append_segment(NEW_SEGMENT_NAME) except FailedToAppendSegmentException(Exception) as e: g_logger.debug(e.message) return g_logger.debug('Starting annotations') functions_not_found = [] for fct_name, eas in library_calls.iteritems(): if fct_name not in functions_map: # sometimes function info is available, but the import is more # specific, e.g., lstrcat vs. lstrcatA/W if fct_name[:-1] in functions_map: library_addr[fct_name[:-1]] = library_addr[fct_name] fct_name = fct_name[:-1] elif fct_name[6:] in functions_map: # handle mangled names (starting with __imp_) library_addr[fct_name[len('__imp_'):]] = library_addr[fct_name] fct_name = fct_name[len('__imp_'):] else: functions_not_found.append(fct_name) continue g_logger.debug('Working on function %s' % fct_name) if config['functions_annotate']: # Add function description to import table add_fct_descr(library_addr[fct_name], functions_map[fct_name], config['functions_repeatable_comment']) if config['constants_import']: # Add enums for extracted constant data num_added_enums = add_enums(functions_map[fct_name]) if num_added_enums: g_logger.debug(' Added {} ENUMs for {}'.format(num_added_enums, fct_name)) # Add argument description in newly created segment free_ea = add_arg_descr(functions_map[fct_name], free_ea, config['arg_description_format']) # Rename arguments and constants so they link to set names for ref in eas: g_logger.debug(' Enhancing argument and constant info for {} ({})' .format(fct_name, hex(ref))) rename_args_and_consts(ref, functions_map[fct_name], config['constants_import'], config['arguments_annotate'], config['arg_description_format']) # Report print '\n======================' print 'MSDN Annotator SUMMARY' print '======================' print ' Functions not found' print ' -------------------' i = 1 for f in functions_not_found: print ' {}\t{}'.format(i, f) i += 1 print ''
import shutil from io import StringIO import os import os.path import sys import idaapi try: import requests print("'requests' is installed, good.") except ImportError: print("requests is not installed, install it manually for remote server access") plugin_dir = os.path.join(idaapi.get_user_idadir(), "plugins") if not os.path.isdir(plugin_dir): print("Creating plugin dir") os.makedirs(plugin_dir) bincat_path = os.path.dirname(os.path.realpath(__file__)) src_idabincat = os.path.join(bincat_path, "idabincat") src_pybincat = os.path.join(bincat_path, "pybincat") if os.path.isdir(src_idabincat) and os.path.isdir(src_pybincat): try: print("Copying 'idabincat' to "+plugin_dir) shutil.copytree(src_idabincat, os.path.join(plugin_dir, "idabincat"), dirs_exist_ok=True) bin_path = os.path.join(plugin_dir, "idabincat", "bin") print("Copying 'bin' to "+bin_path) shutil.copytree(os.path.join(bincat_path, 'bin'), bin_path) print("Copying 'pybincat' to "+plugin_dir)
def get_temp_dir(self): """Get path to temporary directory""" self.ret = idaapi.get_user_idadir() return self.ret
# Assign a default sys.argv sys.argv = [""] # Have to make sure Python finds our modules sys.path.append(_idaapi.idadir("python")) # Remove current directory from the top of the patch search if '' in sys.path: # On non Windows, the empty path is added sys.path.remove('') if os.getcwd() in sys.path: sys.path.remove(os.getcwd()) # ...and add it to the end if needed if not IDAPYTHON_REMOVE_CWD_SYS_PATH: sys.path.append(os.getcwd()) # Import all the required modules from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall, Form from idc import * from idautils import * import idaapi # Load the users personal init file userrc = os.path.join(get_user_idadir(), "idapythonrc.py") if os.path.exists(userrc): idaapi.IDAPython_ExecScript(userrc, globals()) # All done, ready to rock.
pip_install_cmd = [ sys.executable, "-m", "pip", "install", "--upgrade" ] with temp_file_as_stdout(): p = subprocess.Popen( pip_install_cmd + extra_args + [ package ], stdin=subprocess.PIPE, stdout=sys.stdout ) ret = p.wait() return ret if pip_install(IPYIDA_PACKAGE_LOCATION) != 0: print("[.] ipyida system-wide package installation failed, trying user install") if pip_install(IPYIDA_PACKAGE_LOCATION, [ "--user" ]) != 0: raise Exception("ipyida package installation failed") if not os.path.exists(idaapi.get_user_idadir()): os.makedirs(idaapi.get_user_idadir(), 0755) ida_python_rc_path = os.path.join(idaapi.get_user_idadir(), "idapythonrc.py") rc_file_content = "" if os.path.exists(ida_python_rc_path): with file(ida_python_rc_path, "r") as rc: rc_file_content = rc.read() if "# BEGIN IPyIDA loading" in rc_file_content: print("[.] Old IPyIDA loading script present in idapythonrc.py. Removing.") in_ipyida_block = False for line in fileinput.input(ida_python_rc_path, inplace=1, backup='.ipyida_old'): if line.startswith("# BEGIN IPyIDA loading code"): in_ipyida_block = True
""" I started writing climacros in Python first but I hit a deadend due to Qt and its inability to let me really intercept the text. I stopped this project and switched to writing it in C++ (c) Elias Bachaalany <*****@*****.**> """ import time, os, re import idaapi import idc from ida_kernwin import Choose LOCK_FILENAME = 'cli_macros.lck' MACROS_FILENAME = os.path.join(idaapi.get_user_idadir(), 'cli_macros.lst') DEFAULT_MACROS = { "$!": ("'0x%x' % idc.here()", "Current cursor location (0x...)"), "$!": ("'%x' % idc.here()", "Current cursor location"), "$[": ("'0x%x' % SelStart()", "Selection start"), "$@b": ("'0x%x' % idc.Byte(idc.here())", "Byte value at current cursor location (0x..)"), "$@B": ("'%x' % idc.Byte(idc.here())", "Byte value at current cursor location"), "$@d": ("'0x%x' % idc.Dword(idc.here())", "Dword value at current cursor location (0x..)"), "$@D": ("'%x' % idc.Dword(idc.here())", "Dword value at current cursor location"), "$]": ("'0x%x' % idc.SelEnd()", "Selection end"), "$#": ("'0x%x' % (idc.SelEnd() - idc.SelStart())", "Selection size"), }
'show_splash' : True, # architecture 'architecture' : (lambda: idc.__EA64__ and "64" or "32")(), # filesystem options # valid options are 'netnode' or 'segment' 'file_system_type' : 'netnode', 'netnode_num' : 0xBEEFFACE, 'segment_size' : 0x200000, 'segment_name' : '.zip', 'file_name' : idaapi.get_root_filename()[:-4] + ".DB", 'full_file_name' : (lambda x: "." in x and x.split(".")[0] + ".DB" or x + ".DB")(idaapi.get_root_filename()), 'ida_user_dir' : idaapi.get_user_idadir(), 'user_scripts_dir' : idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin", 'vtrace_scripts_dir' : idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin" + os.sep + "vtrace", 'toolbag_dir' : idaapi.get_user_idadir() + os.sep + "toolbag", # hotkeys 'history_hotkey' : 'Ctrl-Space', 'undo_history' : 'Ctrl-Z', 'create_mark_hotkey' : 'Alt-M', 'jump_mark_hotkey' : 'Ctrl-M', 'path_start' : 'Ctrl-S', 'path_end' : 'Ctrl-E', 'add_edge_src' : 'Ctrl-[', 'add_edge_dst' : 'Ctrl-]', # these two are currently deprecated, ScreenEA() is used
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import os import idaapi LOCAL_PATH = os.path.join(idaapi.get_user_idadir(), '.idaconnect') def local_resource(dirname, filename): """ Get the absolute path of a local resource. :param dirname: the directory name :param filename: the file name :return: the path """ resDir = os.path.join(LOCAL_PATH, dirname) if not os.path.exists(resDir): os.makedirs(resDir) return os.path.join(resDir, filename)
# valid options are 'netnode' or 'segment' 'file_system_type': 'netnode', 'netnode_num': 0xBEEFFACE, 'segment_size': 0x200000, 'segment_name': '.zip', 'file_name': idaapi.get_root_filename()[:-4] + ".DB", 'full_file_name': (lambda x: "." in x and x.split(".")[0] + ".DB" or x + ".DB")( idaapi.get_root_filename()), 'ida_user_dir': idaapi.get_user_idadir(), 'user_scripts_dir': idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin", 'vtrace_scripts_dir': idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin" + os.sep + "vtrace", 'toolbag_dir': idaapi.get_user_idadir() + os.sep + "toolbag", # hotkeys 'history_hotkey': 'Ctrl-Space', 'undo_history': 'Ctrl-Z', 'create_mark_hotkey': 'Alt-M',
def main(config=None): g_logger.info('Starting script execution') if CREATE_BACKUP: # Backup database before making any changes try: backup_database() except NoInputFileException as e: g_logger.warn('Quitting execution: ' + e.message) return # Default config in case none is provided config['arg_description_format'] = '{argument_name}_{function_name}' if not config: config = {} config['functions_annotate'] = True config['functions_repeatable_comment'] = False config['arguments_annotate'] = True config['constants_import'] = True config['msdn_data_dir'] = os.path.abspath( os.path.join(idaapi.get_user_idadir(), 'MSDN_data')) # Parse XML files and populate dictionary msdn_data_dir = config['msdn_data_dir'] if not os.path.exists(msdn_data_dir): g_logger.error('Configured msdn data directory does not exist: %s', msdn_data_dir) return functions_map = parse_xml_data_files(msdn_data_dir) # Retrieve all imported functions, store data in dictionaries g_logger.debug('Retrieving imported functions') library_calls = {} # maps function_name -> CodeRefTo library_addr = {} # maps function_name -> ea in import table get_imports(library_calls, library_addr) # Append segment where function argument information will be stored try: g_logger.debug('Appending new segment %s' % NEW_SEGMENT_NAME) free_ea = append_segment(NEW_SEGMENT_NAME) except FailedToAppendSegmentException(Exception) as e: g_logger.debug(e.message) return g_logger.debug('Starting annotations') functions_not_found = [] for fct_name, eas in library_calls.items(): if fct_name not in functions_map: # sometimes function info is available, but the import is more # specific, e.g., lstrcat vs. lstrcatA/W if fct_name[:-1] in functions_map: library_addr[fct_name[:-1]] = library_addr[fct_name] fct_name = fct_name[:-1] elif fct_name[6:] in functions_map: # handle mangled names (starting with __imp_) library_addr[fct_name[len('__imp_'):]] = library_addr[fct_name] fct_name = fct_name[len('__imp_'):] else: functions_not_found.append(fct_name) continue g_logger.debug('Working on function %s' % fct_name) if config['functions_annotate']: # Add function description to import table add_fct_descr(library_addr[fct_name], functions_map[fct_name], config['functions_repeatable_comment']) if config['constants_import']: # Add enums for extracted constant data num_added_enums = add_enums(functions_map[fct_name]) if num_added_enums: g_logger.debug(' Added {} ENUMs for {}'.format( num_added_enums, fct_name)) # Add argument description in newly created segment free_ea = add_arg_descr(functions_map[fct_name], free_ea, config['arg_description_format']) # Rename arguments and constants so they link to set names for ref in eas: g_logger.debug( ' Enhancing argument and constant info for {} ({})'.format( fct_name, hex(ref))) rename_args_and_consts(ref, functions_map[fct_name], config['constants_import'], config['arguments_annotate'], config['arg_description_format']) # Report logging.info('\n======================') logging.info('MSDN Annotator SUMMARY') logging.info('======================') logging.info(' Functions not found') logging.info(' -------------------') i = 1 for f in functions_not_found: logging.info(' {}\t{}'.format(i, f)) i += 1 logging.info('')
# - Bryce Boe for his VirusTotal Python code # import idaapi import idc from idaapi import Choose2, plugin_t import BboeVt as vt import webbrowser import urllib import os PLUGIN_TEST = 0 # ----------------------------------------------------------------------- # Configuration file VT_CFGFILE = os.path.join(idaapi.get_user_idadir(), "virustotal.cfg") # ----------------------------------------------------------------------- # VirusTotal Icon in PNG format VT_ICON = ( "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" "\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2" "\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C" "\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00" "\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51" "\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB" "\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29" "\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8" "\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E"
def add_structures_annotations(config): """import structure annotations for ones which are both in IDA structures tab and the xml database from xml database to IDA. Arguments: config -- a dictionary which contains user specified configure """ g_logger.info('Starting script execution') if CREATE_BACKUP: # Backup database before making any changes try: backup_database() except NoInputFileException as e: g_logger.warn('Quitting execution: ' + e.message) return # Default config in case none is provided config['mem_description_format'] = '{member_name}_{stucture_name}' if not config: config = {} config['structures_annotate'] = True config['structures_repeatable_comment'] = False config['members_annotate'] = True config['constants_import'] = True config['msdn_data_dir'] = os.path.abspath(os.path.join(idaapi.get_user_idadir(), 'MSDN_data')) # Parse XML files and populate dictionary msdn_data_dir = config['msdn_data_dir'] if not os.path.exists(msdn_data_dir): g_logger.error('Configured msdn data directory does not exist: %s', msdn_data_dir) return structures_map = parse_structures_from_xml_data_files(msdn_data_dir) # Retrieve all imported structures, store data in dictionaries g_logger.debug('Retrieving imported structure') structures_import = get_structures() g_logger.debug('Starting annotations') structures_not_found = [] for sid, struc_name in structures_import.iteritems(): if struc_name not in structures_map: # alias if struc_name[1:] in structures_map: # start with '_' struc_name = struc_name[1:] elif re.match(r'^tag(.)*', struc_name) and \ struc_name[3:] in structures_map: # start with 'tag' struc_name = struc_name[3:] elif re.match(r'^_tag(.)*', struc_name) and \ struc_name[4:] in structures_map: # start with '_tag' struc_name = struc_name[4:] else: structures_not_found.append(struc_name) continue g_logger.debug('Working on structure %s' % struc_name) if config['structures_annotate']: # Add structure description to structure tablefig res = add_struc_descr(sid, structures_map[struc_name], config['structures_repeatable_comment']) if res: g_logger.debug('Added description for {}'.format(struc_name)) else: continue if config['constants_import']: # Add enums for extracted constant data num_added_enums = add_structure_enums(structures_map[struc_name]) if num_added_enums: g_logger.debug(' Added {} ENUMs for {}'.format(num_added_enums, struc_name)) # Add member description in newly created segment add_member_descr(structures_map[struc_name], sid) # TODO: if neccessary rename members and constants so they link to # set names # Report print '\n======================' print 'MSDN Annotator SUMMARY' print '======================' print ' Structures not found' print ' -------------------' i = 1 for s in structures_not_found: print ' {}\t{}'.format(i, s) i += 1 print ''
""" Deactivate the watchdog """ self.active = True def reset(self): """ Reset the timer, useful for long-running scripts """ self.timestamp = time.clock() def tracer(self, frame, event, arg): """ Tracer function that receives the tracing events """ if not self.active: return None if event == 'line': if time.clock() - self.timestamp > self.timeout: if AskYN(0, "The script has not finished in %d seconds\nWould you like to stop it now?" % self.timeout) == 1: raise KeyboardInterrupt else: self.timestamp = time.clock() return self.tracer watchdog = WatchDog(10) # Load the users personal init file userrc = get_user_idadir() + os.sep + "idapythonrc.py" if os.path.exists(userrc): runscript(userrc) # Remove the user script from the history del scriptbox.list[0] # All done, ready to rock.
with temp_file_as_stdout(): p = subprocess.Popen(sys.executable, stdin=subprocess.PIPE, stdout=sys.stdout) p.communicate(get_pip) try: import pip except: print("[-] Could not install pip.") raise with temp_file_as_stdout(): if pip.main(["install", "--upgrade", IPYIDA_PACKAGE_LOCATION]) != 0: print("[.] ipyida system-wide package installation failed, trying user install") if pip.main(["install", "--upgrade", "--user", IPYIDA_PACKAGE_LOCATION]) != 0: raise Exception("ipyida package installation failed") if not os.path.exists(idaapi.get_user_idadir()): os.path.makedirs(idaapi.get_user_idadir(), 0755) ida_python_rc_path = os.path.join(idaapi.get_user_idadir(), "idapythonrc.py") rc_file_content = "" if os.path.exists(ida_python_rc_path): with file(ida_python_rc_path, "r") as rc: rc_file_content = rc.read() if "# BEGIN IPyIDA loading" in rc_file_content: print("[+] IPyIDA loading script already present in idapythonrc.py") else: with file(ida_python_rc_path, "a") as rc: rc.write("\n") rc.write("# BEGIN IPyIDA loading code\n")
if pip_install(IPYIDA_PACKAGE_LOCATION) != 0: print( "[.] ipyida system-wide package installation failed, trying user install" ) if pip_install(IPYIDA_PACKAGE_LOCATION, ["--user"]) != 0: raise Exception("ipyida package installation failed") else: # If no packages were installed in user site-packages, the path may # not be in sys.path in current Python process. Importing ipyida will # fail until Python (or IDA) is restarted. We can "refresh" sys.path # using site.main(). import site if site.getusersitepackages() not in sys.path: site.main() if not os.path.exists(idaapi.get_user_idadir()): os.makedirs(idaapi.get_user_idadir(), 0o755) ida_python_rc_path = os.path.join(idaapi.get_user_idadir(), "idapythonrc.py") rc_file_content = "" if os.path.exists(ida_python_rc_path): with open(ida_python_rc_path, "r") as rc: rc_file_content = rc.read() if "# BEGIN IPyIDA loading" in rc_file_content: print("[.] Old IPyIDA loading script present in idapythonrc.py. Removing.") in_ipyida_block = False for line in fileinput.input(ida_python_rc_path, inplace=1, backup='.ipyida_old'):
def __init__(self, fn): self.lock_file = os.path.join(idaapi.get_user_idadir(), os.path.basename(fn))
# some general python modules import sys,os,logging,imp import idaapi # grab ida's user directory and add to path root = idaapi.get_user_idadir() sys.path = list(set(sys.path)) + [root] class __base__(object): '''Context related modules''' base = os.path.join(root, 'base') imp = imp _api = [(os.path.splitext(p)[0],os.path.realpath(os.path.join(base,p))) for p in os.listdir(base) if not os.path.basename(p).startswith('_') and os.path.splitext(p)[1] == '.py'] _cache = [imp.find_module(name,[base]) for name,_ in _api] assert all(p1 == p2 for (n1,p1),(_,p2,_) in zip(_api,_cache)) cache = dict((n,c) for (n,_),c in zip(_api,_cache)) @classmethod def find_module(cls, fullname, path=None): return cls if path is None and fullname in cls.cache.viewkeys() else None @classmethod def load_module(cls, fullname): if fullname not in cls.cache.viewkeys(): raise ImportError, fullname return __import__('sys').modules.setdefault(fullname, cls.imp.load_module(fullname, *cls.cache[fullname])) class __submodule__(object): '''A lazy-loaded module named according to the subdirectory the modules are in''' imp = imp
print "requests is not installed, trying to install" import pip # Fugly hack (cause IDA console is not a real one) saved_stdout = sys.stdout saved_stderr = sys.stderr sys.stdout = StringIO.StringIO() sys.stderr = StringIO.StringIO() pip.main(['install', "requests"]) sys.stdout.seek(0) sys.stderr.seek(0) saved_stdout.write(sys.stdout.read()) saved_stderr.write(sys.stderr.read()) sys.stdout = saved_stdout sys.stderr = saved_stderr userdir = idaapi.get_user_idadir() plugin_dir = os.path.join(userdir, "plugins") bincat_path = os.path.dirname(os.path.realpath(__file__)) if not os.path.isdir(plugin_dir) or not os.path.isdir(bincat_path): print "Something's wrong: %s or %s is not a dir" % (plugin_dir, bincat_path) p_idabincat = os.path.join(bincat_path, "python", "idabincat") p_pybincat = os.path.join(bincat_path, "python", "pybincat") if os.path.isdir(p_idabincat) and os.path.isdir(p_pybincat): try: print "Copying 'idabincat' to " + plugin_dir dir_util.copy_tree(p_idabincat, os.path.join(plugin_dir, "idabincat")) bin_path = os.path.join(plugin_dir, "idabincat", "bin")
import glob import os import itertools import idaapi import idc PLUGINS_LIST = "plugins-{}.list".format(idaapi.get_kernel_version()) USER_PLUGIN_LIST_PATH = os.path.join(idaapi.get_user_idadir(), PLUGINS_LIST) SYS_PLUGIN_LIST_PATH = os.path.join(idaapi.idadir(idaapi.CFG_SUBDIR), PLUGINS_LIST) if idc.GetIdbPath(): PROJECT_PLUGIN_LIST_PATH = os.path.join(os.path.dirname(idc.GetIdbPath()), PLUGINS_LIST) else: PROJECT_PLUGIN_LIST_PATH = None def message(*messages): for msg in messages: for line in msg.splitlines(): idaapi.msg("[PluginLoader] {}\n".format(line)) def iter_without_duplicates(*iterables): visited = set() chained_iterables = itertools.chain(*iterables) for item in chained_iterables: if item in visited: continue yield item
import idaapi import idautils import idc from PyQt5 import QtWidgets MIN_FUNC_SIZE = 0x20 MAX_FUNC_SIZE = 0x100 PLUGIN_NAME = "idenLib" PLUGIN_VERSION = "v0.4" IDENLIB_CONTACT = "Contact: Lasha Khasaia (@_qaz_qaz)" CAPSTONE_MODE = capstone.CS_MODE_64 if idc.__EA64__ else capstone.CS_MODE_32 SIG_EXT = ".sig64" if idc.__EA64__ else ".sig" symEx_dir = os.path.join(idaapi.get_user_idadir(), "SymEx") symEx_cache_dir = os.path.join(symEx_dir, "cache") idenLibCache = os.path.join(symEx_cache_dir, "idenLibCache" + ("64" if idc.__EA64__ else "")) idenLibCacheMain = os.path.join(symEx_cache_dir, "idenLibCacheMain" + ("64" if idc.__EA64__ else "")) g_func_sigs = {} g_main_sigs = {} decompressor = zstd.ZstdDecompressor() def getNames(): for _ea, name in idautils.Names(): yield name def getFiles(path): files = QtWidgets.QFileDialog.getOpenFileNames(None, "Select one or more sig files for function identification",
def add_functions_annotations(config=None): """import function annotations for imported functions which are also in MSDN databases Arguments: config -- a dictionary which contains user specified configure """ g_logger.info('Starting script execution') if CREATE_BACKUP: # Backup database before making any changes try: backup_database() except NoInputFileException as e: g_logger.warn('Quitting execution: ' + e.message) return # Default config in case none is provided config['arg_description_format'] = '{argument_name}_{function_name}' if not config: config = {} config['functions_annotate'] = True config['functions_repeatable_comment'] = False config['arguments_annotate'] = True config['constants_import'] = True config['msdn_data_dir'] = os.path.abspath(os.path.join(idaapi.get_user_idadir(), 'MSDN_data')) # Parse XML files and populate dictionary msdn_data_dir = config['msdn_data_dir'] if not os.path.exists(msdn_data_dir): g_logger.error('Configured msdn data directory does not exist: %s', msdn_data_dir) return functions_map = parse_xml_data_files(msdn_data_dir) # Retrieve all imported functions, store data in dictionaries g_logger.debug('Retrieving imported functions') library_calls = {} # maps function_name -> CodeRefTo library_addr = {} # maps function_name -> ea in import table get_imports(library_calls, library_addr) # Append segment where function argument information will be stored try: g_logger.debug('Appending new segment %s' % NEW_SEGMENT_NAME) free_ea = append_segment(NEW_SEGMENT_NAME) except FailedToAppendSegmentException(Exception) as e: g_logger.debug(e.message) return g_logger.debug('Starting annotations') functions_not_found = [] for fct_name, eas in library_calls.iteritems(): if fct_name not in functions_map: # sometimes function info is available, but the import is more # specific, e.g., lstrcat vs. lstrcatA/W if fct_name[:-1] in functions_map: library_addr[fct_name[:-1]] = library_addr[fct_name] fct_name = fct_name[:-1] elif fct_name[6:] in functions_map: # handle mangled names (starting with __imp_) library_addr[fct_name[len('__imp_'):]] = library_addr[fct_name] fct_name = fct_name[len('__imp_'):] else: elms = [] nor_name = fct_name if re.match(r'(__imp__)([?]*)([a-zA-Z])(\w)*@(\d)+', fct_name): #@bc.handle names like '__imp__SafeArrayPutElement@12' nor_name = re.split(r'^__imp__[?]*[0-9]*', fct_name)[1].split('@')[0] elif re.match(r'[?]+(\d)*([a-zA-Z])+(\w)*@([a-zA-Z])+(\w)*@@(.)*', fct_name): #@bc. handle names like '?what@exception@@UBEPBDXZ' #@bc. parsed to 'exception.what' elms = re.split(r'^[?]+[0-9]*', fct_name)[1].split('@') nor_name = elms[1] + '.' + elms[0] elif re.match(r'[?]+(\d)*([a-zA-Z])+(\w)*@@(.)*', fct_name): #@bc. handle names like '??0exception@@QAE@ABQBD@Z' #@bc. parsed to 'exception.execution' elms = re.split(r'[?]+[0-9]*', fct_name)[1].split('@@') nor_name = elms[0] + '.' + elms[0] elif re.match(r'__imp_[?]*(\d)*([a-zA-Z])+(\w)*@@(.)*', fct_name): #@bc. handle names like '__imp_??0CPrintPreviewState@@QAE@XZ' #@bc. parsed to 'CPrintPreviewState.CPrintPreviewState' elms = re.split(r'__imp_[?]*[0-9]*', fct_name)[1].split('@@') nor_name = elms[0] + '.' + elms[0] elif re.match(r'__imp_[?]*(\d)*([a-zA-Z])+(\w)*@([a-zA-Z])+(\w)*@@(.)*', fct_name): #@bc. handle names like '__imp_?EnableDocking@CFrameWnd@@QAEXK@Z' #@bc. parsed to 'CFrameWnd.EnableDocking' elms = re.split(r'__imp_[?]*[0-9]*', fct_name)[1].split('@') nor_name = elms[1] + '.' + elms[0] if nor_name in functions_map: library_addr[nor_name] = library_addr[fct_name] fct_name = nor_name else: functions_not_found.append(fct_name) continue g_logger.debug('Working on function %s' % fct_name) if config['functions_annotate']: # Add function description to import table add_fct_descr(library_addr[fct_name], functions_map[fct_name], config['functions_repeatable_comment']) if config['constants_import']: # Add enums for extracted constant data num_added_enums = add_enums(functions_map[fct_name]) if num_added_enums: g_logger.debug(' Added {} ENUMs for {}'.format(num_added_enums, fct_name)) # Add argument description in newly created segment free_ea = add_arg_descr(functions_map[fct_name], free_ea, config['arg_description_format']) # Rename arguments and constants so they link to set names for ref in eas: g_logger.debug(' Enhancing argument and constant info for {} ({})' .format(fct_name, hex(ref))) rename_args_and_consts(ref, functions_map[fct_name], config['constants_import'], config['arguments_annotate'], config['arg_description_format']) # Report print '\n======================' print 'MSDN Annotator SUMMARY' print '======================' print ' Functions not found' print ' -------------------' i = 1 for f in functions_not_found: print ' {}\t{}'.format(i, f) i += 1 print ''
"pypath_linux": "python", # default tabs enabled "enabled_tabs": ["File System", "Pathfinding", "Scripts"], # show splash boolean "show_splash": True, # architecture "architecture": (lambda: idc.__EA64__ and "64" or "32")(), # filesystem options # valid options are 'netnode' or 'segment' "file_system_type": "netnode", "netnode_num": 0xBEEFFACE, "segment_size": 0x200000, "segment_name": ".zip", "file_name": idaapi.get_root_filename()[:-4] + ".DB", "full_file_name": (lambda x: "." in x and x.split(".")[0] + ".DB" or x + ".DB")(idaapi.get_root_filename()), "ida_user_dir": idaapi.get_user_idadir(), "user_scripts_dir": idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin", "vtrace_scripts_dir": idaapi.get_user_idadir() + os.sep + "user" + os.sep + "bin" + os.sep + "vtrace", "toolbag_dir": idaapi.get_user_idadir() + os.sep + "toolbag", # hotkeys "history_hotkey": "Ctrl-Space", "undo_history": "Ctrl-Z", "create_mark_hotkey": "Alt-M", "jump_mark_hotkey": "Ctrl-M", "path_start": "Ctrl-S", "path_end": "Ctrl-E", "add_edge_src": "Ctrl-[", "add_edge_dst": "Ctrl-]", # these two are currently deprecated, ScreenEA() is used "bb_path_start": "Ctrl-Shift-S", "bb_path_end": "Ctrl-Shift-E",
# - Bryce Boe for his VirusTotal Python code # import idaapi import idc from idaapi import plugin_t from ida_kernwin import Choose import BboeVt as vt import webbrowser import urllib import os PLUGIN_TEST = 0 # ----------------------------------------------------------------------- # Configuration file VT_CFGFILE = os.path.join(idaapi.get_user_idadir(), "virustotal.cfg") # ----------------------------------------------------------------------- # VirusTotal Icon in PNG format VT_ICON = ("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52" "\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2" "\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C" "\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00" "\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51" "\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB" "\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29" "\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8" "\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E" "\xC5\x16\x2D\x54\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82")
def get_disassembler_user_directory(self): return idaapi.get_user_idadir()