1#!/usr/bin/env python 2import os 3import sys 4import shutil 5import tempfile 6import subprocess 7from distutils.core import setup, Command 8from distutils.dir_util import remove_tree 9 10MODULE_NAME = "binwalk" 11SCRIPT_NAME = MODULE_NAME 12 13# Python2/3 compliance 14try: 15 raw_input 16except NameError: 17 raw_input = input 18 19# cd into the src directory, no matter where setup.py was invoked from 20os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src")) 21 22def which(command): 23 # /usr/local/bin is usually the default install path, though it may not be in $PATH 24 usr_local_bin = os.path.sep.join([os.path.sep, 'usr', 'local', 'bin', command]) 25 26 try: 27 location = subprocess.Popen(["which", command], shell=False, stdout=subprocess.PIPE).communicate()[0].strip() 28 except KeyboardInterrupt as e: 29 raise e 30 except Exception as e: 31 pass 32 33 if not location and os.path.exists(usr_local_bin): 34 location = usr_local_bin 35 36 return location 37 38def find_binwalk_module_paths(): 39 paths = [] 40 41 try: 42 import binwalk 43 paths = binwalk.__path__ 44 except KeyboardInterrupt as e: 45 raise e 46 except Exception: 47 pass 48 49 return paths 50 51def remove_binwalk_module(pydir=None, pybin=None): 52 if pydir: 53 module_paths = [pydir] 54 else: 55 module_paths = find_binwalk_module_paths() 56 57 for path in module_paths: 58 try: 59 remove_tree(path) 60 except OSError as e: 61 pass 62 63 if not pybin: 64 pybin = which(MODULE_NAME) 65 66 if pybin: 67 try: 68 sys.stdout.write("removing '%s'\n" % pybin) 69 os.remove(pybin) 70 except KeyboardInterrupt as e: 71 pass 72 except Exception as e: 73 pass 74 75class IDAUnInstallCommand(Command): 76 description = "Uninstalls the binwalk IDA plugin module" 77 user_options = [ 78 ('idadir=', None, 'Specify the path to your IDA install directory.'), 79 ] 80 81 def initialize_options(self): 82 self.idadir = None 83 self.mydir = os.path.dirname(os.path.realpath(__file__)) 84 85 def finalize_options(self): 86 pass 87 88 def run(self): 89 if self.idadir is None: 90 sys.stderr.write("Please specify the path to your IDA install directory with the '--idadir' option!\n") 91 return 92 93 binida_dst_path = os.path.join(self.idadir, 'plugins', 'binida.py') 94 binwalk_dst_path = os.path.join(self.idadir, 'python', 'binwalk') 95 96 if os.path.exists(binida_dst_path): 97 sys.stdout.write("removing %s\n" % binida_dst_path) 98 os.remove(binida_dst_path) 99 if os.path.exists(binwalk_dst_path): 100 sys.stdout.write("removing %s\n" % binwalk_dst_path) 101 shutil.rmtree(binwalk_dst_path) 102 103class IDAInstallCommand(Command): 104 description = "Installs the binwalk IDA plugin module" 105 user_options = [ 106 ('idadir=', None, 'Specify the path to your IDA install directory.'), 107 ] 108 109 def initialize_options(self): 110 self.idadir = None 111 self.mydir = os.path.dirname(os.path.realpath(__file__)) 112 113 def finalize_options(self): 114 pass 115 116 def run(self): 117 if self.idadir is None: 118 sys.stderr.write("Please specify the path to your IDA install directory with the '--idadir' option!\n") 119 return 120 121 binida_src_path = os.path.join(self.mydir, 'scripts', 'binida.py') 122 binida_dst_path = os.path.join(self.idadir, 'plugins') 123 124 if not os.path.exists(binida_src_path): 125 sys.stderr.write("ERROR: could not locate IDA plugin file '%s'!\n" % binida_src_path) 126 return 127 if not os.path.exists(binida_dst_path): 128 sys.stderr.write("ERROR: could not locate the IDA plugins directory '%s'! Check your --idadir option.\n" % binida_dst_path) 129 return 130 131 binwalk_src_path = os.path.join(self.mydir, 'binwalk') 132 binwalk_dst_path = os.path.join(self.idadir, 'python') 133 134 if not os.path.exists(binwalk_src_path): 135 sys.stderr.write("ERROR: could not locate binwalk source directory '%s'!\n" % binwalk_src_path) 136 return 137 if not os.path.exists(binwalk_dst_path): 138 sys.stderr.write("ERROR: could not locate the IDA python directory '%s'! Check your --idadir option.\n" % binwalk_dst_path) 139 return 140 141 binida_dst_path = os.path.join(binida_dst_path, 'binida.py') 142 binwalk_dst_path = os.path.join(binwalk_dst_path, 'binwalk') 143 144 if os.path.exists(binida_dst_path): 145 os.remove(binida_dst_path) 146 if os.path.exists(binwalk_dst_path): 147 shutil.rmtree(binwalk_dst_path) 148 149 sys.stdout.write("copying %s -> %s\n" % (binida_src_path, binida_dst_path)) 150 shutil.copyfile(binida_src_path, binida_dst_path) 151 152 sys.stdout.write("copying %s -> %s\n" % (binwalk_src_path, binwalk_dst_path)) 153 shutil.copytree(binwalk_src_path, binwalk_dst_path) 154 155class UninstallCommand(Command): 156 description = "Uninstalls the Python module" 157 user_options = [ 158 ('pydir=', None, 'Specify the path to the binwalk python module to be removed.'), 159 ('pybin=', None, 'Specify the path to the binwalk executable to be removed.'), 160 ] 161 162 def initialize_options(self): 163 self.pydir = None 164 self.pybin = None 165 166 def finalize_options(self): 167 pass 168 169 def run(self): 170 remove_binwalk_module(self.pydir, self.pybin) 171 172class CleanCommand(Command): 173 description = "Clean Python build directories" 174 user_options = [] 175 176 def initialize_options(self): 177 pass 178 179 def finalize_options(self): 180 pass 181 182 def run(self): 183 try: 184 remove_tree("build") 185 except KeyboardInterrupt as e: 186 raise e 187 except Exception: 188 pass 189 190 try: 191 remove_tree("dist") 192 except KeyboardInterrupt as e: 193 raise e 194 except Exception: 195 pass 196 197# The data files to install along with the module 198install_data_files = [] 199for data_dir in ["magic", "config", "plugins", "modules", "core"]: 200 install_data_files.append("%s%s*" % (data_dir, os.path.sep)) 201 202# Install the module, script, and support files 203setup(name = MODULE_NAME, 204 version = "2.1.1", 205 description = "Firmware analysis tool", 206 author = "Craig Heffner", 207 url = "https://github.com/devttys0/%s" % MODULE_NAME, 208 209 requires = [], 210 packages = [MODULE_NAME], 211 package_data = {MODULE_NAME : install_data_files}, 212 scripts = [os.path.join("scripts", SCRIPT_NAME)], 213 214 cmdclass = {'clean' : CleanCommand, 'uninstall' : UninstallCommand, 'idainstall' : IDAInstallCommand, 'idauninstall' : IDAUnInstallCommand} 215) 216 217