├── LICENSE ├── README.md ├── install.py └── src ├── idascript └── idascript.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 devttys0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ABOUT 2 | 3 | IDAScript is a wrapper around IDA Pro that makes it easy to automate the execution of IDA scripts 4 | against target files from the command line. 5 | 6 | This version of idascript is based on the original idascript from Hex-Rays, but is written in Python 7 | for platform independance (disclaimer: currently only tested on Linux and OSX!). 8 | 9 | For more information on idascript, see the original idascript utility here: http://www.hexblog.com/?p=128 10 | 11 | INSTALL 12 | 13 | To install, run the included install.py script. You will be prompted for the path to your IDA install directory, 14 | You will typically need to run the install.py script as root/admin. 15 | 16 | On Linux/OSX platforms, idascript will be installed the first directory listed in $PATH. 17 | 18 | On Windows, idascript will be placed in the specified IDA install directory. 19 | 20 | USAGE 21 | 22 | IDAScript usage is very straight forward: 23 | 24 | $ idascript ./target.bin ./myscript.py arg1 arg2 arg3 25 | $ idascript --64 ./target64.bin ./myscript.py arg1 arg2 arg3 26 | 27 | IDASCRIPT SCRIPTS 28 | 29 | All IDAPython scripts intended for use with idascript must import the idascript Python module. If you want 30 | IDA to exit when the script is finished, the script must also call idascript.exit when done. Example: 31 | 32 | import idascript 33 | 34 | print "I am an IDA script. My first command line argument is:", sys.argv[1] 35 | 36 | idascript.exit() 37 | 38 | Scripts written in this manner can be used either through idascript utility or manually from inside the IDA GUI. 39 | The idascript module will detect when it is not being run via the idascript utility and will disable itself. 40 | -------------------------------------------------------------------------------- /install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import stat 6 | 7 | TARGET = 'idascript' 8 | IDA_INSTALL_PATH = '' 9 | 10 | try: 11 | IDA_INSTALL_PATH = sys.argv[1] 12 | except: 13 | pass 14 | 15 | if not os.path.isdir(IDA_INSTALL_PATH): 16 | print "Absolute path to your IDA install directory: ", 17 | IDA_INSTALL_PATH = sys.stdin.readline().strip() 18 | print "" 19 | 20 | if sys.platform == 'win32': 21 | BIN_INSTALL_PATH = os.path.join(IDA_INSTALL_PATH, TARGET) 22 | else: 23 | try: 24 | BIN_INSTALL_PATH = os.path.join(os.getenv("PATH").split(':')[0], TARGET) 25 | except: 26 | BIN_INSTALL_PATH = '/usr/local/bin/' + TARGET 27 | 28 | files = [(os.path.join('src', TARGET), BIN_INSTALL_PATH), (os.path.join('src', TARGET + '.py'), os.path.join(IDA_INSTALL_PATH, 'python', TARGET + '.py'))] 29 | 30 | replacements = [('%%IDA_INSTALL_PATH%%', IDA_INSTALL_PATH)] 31 | 32 | print "Installing idascript to '%s'" % BIN_INSTALL_PATH 33 | print "Installing support files to '%s'" % IDA_INSTALL_PATH 34 | 35 | for (srcname, dstname) in files: 36 | data = open(srcname).read() 37 | 38 | for (replaceme, withme) in replacements: 39 | data = data.replace(replaceme, withme) 40 | 41 | open(dstname, 'w').write(data) 42 | os.chmod(dstname, (stat.S_IROTH | stat.S_IXOTH | stat.S_IRWXU)) 43 | 44 | -------------------------------------------------------------------------------- /src/idascript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ############################################################### 3 | # Python version of the idascript utility for IDA. 4 | # 5 | # Original idascript utility: http://www.hexblog.com/?p=128 6 | # 7 | # Craig Heffner 8 | # 14-November-2012 9 | # http://www.tacnetsol.com 10 | # http://www.devttys0.com 11 | ############################################################### 12 | 13 | from __future__ import print_function 14 | import os 15 | import sys 16 | import tempfile 17 | import subprocess 18 | 19 | IDA_INSTALL_PATH = "%%IDA_INSTALL_PATH%%" 20 | try: 21 | import magic 22 | except: 23 | print("libmagic module not found, automatic detection of 64bit binaries won't work", file=sys.stderr) 24 | magic = None 25 | 26 | fd, OUTFILE = tempfile.mkstemp() 27 | idc_args = ['__idascript_active__', OUTFILE] 28 | 29 | # Check usage 30 | if len(sys.argv) < 2: 31 | print("", file=sys.stderr) 32 | print("Usage: %s [--64bit] [script arguments]" % os.path.basename(sys.argv[0]), file=sys.stderr) 33 | print("", file=sys.stderr) 34 | sys.exit(1) 35 | 36 | # Always use the 64-bit version of IDA if it was explicitly specified 37 | if sys.argv[1] == '--64bit': 38 | suffix = '64' 39 | sys.argv.pop(1) 40 | else: 41 | suffix = '' 42 | 43 | # Get IDB / script file from command line 44 | if len(sys.argv) >= 3: 45 | idb = os.path.abspath(sys.argv[1]) 46 | idc = os.path.abspath(sys.argv[2]) 47 | idc_args += sys.argv[3:] 48 | 49 | if idb.endswith('.i64'): 50 | suffix = '64' 51 | 52 | if not magic is None: 53 | try: 54 | m=magic.open(magic.MAGIC_NONE) 55 | m.load() 56 | if '64-bit' in m.file(idb): 57 | suffix = '64' 58 | except: 59 | print("The 'import magic' module is not from the expected 'file-magic' package. Automatic detection of 64bit binaries won't work.", file=sys.stderr) 60 | 61 | else: 62 | idc = os.path.abspath(sys.argv[1]) 63 | idb = "-t" 64 | idc_args += sys.argv[2:] 65 | 66 | # Use the right IDA executable for the right platform 67 | if sys.platform == 'win32': 68 | ida = 'idaw' + suffix 69 | else: 70 | ida = 'idal' + suffix 71 | 72 | # Windows has a .exe file extension 73 | if sys.platform == 'win32': 74 | ida += '.exe' 75 | 76 | # Run IDA 77 | subprocess.call([os.path.join(IDA_INSTALL_PATH, ida), '-A', '-S' + idc + ' ' + ' '.join(idc_args), idb]) 78 | 79 | # Display contents of output file, then clean up 80 | if os.path.exists(OUTFILE): 81 | print("") 82 | print(open(OUTFILE).read()) 83 | os.unlink(OUTFILE) 84 | 85 | -------------------------------------------------------------------------------- /src/idascript.py: -------------------------------------------------------------------------------- 1 | ################################################################################################## 2 | # Python module for IDAPython scripts executed via idascript. 3 | # 4 | # Copied from the original idascript utility, with minor changes: http://www.hexblog.com/?p=128 5 | # 6 | # Craig Heffner 7 | # 14-November-2012 8 | # http://www.tacnetsol.com 9 | # http://www.devttys0.com 10 | ################################################################################################## 11 | 12 | import os 13 | import sys 14 | import tempfile 15 | import idc 16 | import idaapi 17 | import re 18 | 19 | import traceback 20 | 21 | __idascript_active__ = False 22 | 23 | def exit(code=0): 24 | if __idascript_active__: 25 | idc.Exit(code) 26 | 27 | class ToFileStdOut(object): 28 | def __init__(self, outfile): 29 | self.outfile = open(outfile, 'w') 30 | 31 | def write(self, text): 32 | self.outfile.write(text) 33 | 34 | def flush(self): 35 | self.outfile.flush() 36 | 37 | def isatty(self): 38 | return False 39 | 40 | def __del__(self): 41 | self.outfile.close() 42 | 43 | def loadAllPythonPlugins(): 44 | plugins_dir = idaapi.idadir('plugins') 45 | print("idascript: loading all .py plugins in %s" % plugins_dir) 46 | files = [f for f in os.listdir(plugins_dir) if re.match(r'.*\.py', f)] 47 | for path in files: 48 | idaapi.load_plugin(path) 49 | 50 | if len(idc.ARGV) > 1 and idc.ARGV[1] == '__idascript_active__': 51 | __idascript_active__ = True 52 | idc.ARGV.pop(1) 53 | outfile=idc.ARGV.pop(1) 54 | 55 | # Redirect stdout and stderr to the output file 56 | sys.stdout = sys.stderr = ToFileStdOut(os.path.join(tempfile.gettempdir(), outfile)) 57 | # Make the normal sys.argv and sys.exit function properly 58 | sys.argv = idc.ARGV 59 | sys.exit = idc.Exit 60 | 61 | try: 62 | loadAllPythonPlugins() 63 | except: 64 | traceback.print_exc() 65 | exit(1) 66 | 67 | # Wait for IDA's auto analysis to finish 68 | idaapi.autoWait() 69 | 70 | --------------------------------------------------------------------------------