def _create(self, config, force=False): project_dir = config['project_dir'] # Check if the project directory already exists _check_project_dir(project_dir, force) # Create the project directory os.mkdir(project_dir) if config['use_seeds'] and not os.path.isdir(config['seeds_dir']): os.mkdir(config['seeds_dir']) # Create symlinks to the target files (if they exist) if config['target_files']: self._symlink_project_files(project_dir, *config['target_files']) # Create a symlink to the guest tools directory self._symlink_guest_tools(project_dir, config['image']) # Create a symlink to guestfs (if it exists) if config['guestfs_path']: self._symlink_guestfs(project_dir, config['guestfs_path']) # Render the templates self._create_launch_script(project_dir, config) self._create_lua_config(project_dir, config) self._create_bootstrap(project_dir, config) # Save the project configuration as JSON _save_json_description(project_dir, config) # Generate recipes for PoV generation if config['use_recipes']: os.makedirs(config['recipes_dir']) call_command(RecipeCommand(), [], project=os.path.basename(project_dir)) # Display relevant messages to the user display_marker_warning = config['target_path'] and \ config['warn_input_file'] and \ not (config['use_symb_input_file'] or config['sym_args']) if display_marker_warning: logger.warning('You did not specify the input file marker @@. ' 'This marker is automatically substituted by a ' 'file with symbolic content. You will have to ' 'manually edit the bootstrap file in order to run ' 'the program on multiple paths.\n\n' 'Example: %s @@\n\n' 'You can also make arguments symbolic using the ' '``S2E_SYM_ARGS`` environment variable in the ' 'bootstrap file', config['target_path']) if config['use_seeds'] and not config['use_symb_input_file'] and config['warn_seeds']: logger.warning('Seed files have been enabled, however you did not ' 'specify an input file marker (i.e. \'@@\') to be ' 'substituted with a seed file. This means that ' 'seed files will be fetched but never used. Is ' 'this intentional?')
def _create(self, config, force=False): project_dir = config['project_dir'] target = config['target'] # Check if the project directory already exists _check_project_dir(project_dir, force) # Create the project directory os.makedirs(project_dir) if config['use_seeds'] and not os.path.isdir(config['seeds_dir']): os.mkdir(config['seeds_dir']) # Create symlinks to the target files (if they exist) if target.files: self._symlink_project_files(project_dir, *target.files) target.args.generate_symbolic_files(project_dir, config['use_seeds']) # Create symlinks to symbolic files if target.args.symbolic_files: self._symlink_project_files(project_dir, *target.args.symbolic_files) # Create a symlink to the guest tools directory self._symlink_guest_tools(project_dir, config['image']) # Create a symlink to guestfs (if it exists) if config['guestfs_paths']: self._symlink_guestfs(project_dir, config['guestfs_paths']) # Render the templates self._create_launch_script(project_dir, config) self._create_lua_config(project_dir, config) self._create_bootstrap(project_dir, config) # Even though the AbstractProject will save the project description, we # need it to be able to generate recipes below self._save_json_description(project_dir, config) # Generate recipes for PoV generation if config['use_recipes']: os.makedirs(config['recipes_dir']) call_command(RecipeCommand(), [], project=project_dir) # Display relevant messages to the user display_marker_warning = config['target'].path and \ config['warn_input_file'] and \ not config['single_path'] and \ not (config['target'].args.symbolic_files or config['sym_args']) if display_marker_warning: logger.warning( 'You did not specify any symbolic input. ' 'Symbolic execution requires symbolic inputs. You will have to ' 'manually edit the bootstrap file in order to run ' 'the program on multiple paths.\n\n' 'Example: %s @@\n\n' 'You can also make arguments symbolic using the ' '``S2E_SYM_ARGS`` environment variable in the ' 'bootstrap file', config['target'].path) seed_files_count = len(config['target'].args.blank_seed_files) if config['use_seeds'] and config['warn_seeds']: if not seed_files_count: logger.warning( 'Seed files have been enabled, however you did not ' 'specify an input file marker (i.e. \'@@\') to be ' 'substituted with a seed file. This means that ' 'seed files will be fetched but never used. Is ' 'this intentional?') if seed_files_count > 1: raise CommandError( 'You specified multiple symbolic inputs with @@. You may only have one ' 'when seeds are enabled.') return project_dir
def handle(self, *args, **options): self._validate_and_create_project(options) # Prepare the configuration for file templates config = { 'creation_time': str(datetime.datetime.now()), 'project_dir': self._project_dir, 'project_type': self._configurator.PROJECT_TYPE, 'image': self._img_json, 'target': os.path.basename(self._target_path) if self._target_path else None, 'target_path': self._target_path, 'target_arch': options['target_arch'], 'target_args': options['target_args'], # These contain all the files that must be downloaded into the guest 'target_files': [], # List of module names that go into ModuleExecutionDetector 'modules': options['modules'], # List of binaries that go into ProcessExecutionDetector # These are normally executable files 'processes': options['processes'], 'sym_args': options['sym_args'], # See _create_bootstrap for an explanation of the @@ marker 'use_symb_input_file': '@@' in options['target_args'], # The use of seeds is specified on the command line 'use_seeds': options['use_seeds'], 'seeds_dir': os.path.join(self._project_dir, 'seeds'), # The use of recipes is set by the configurator 'use_recipes': False, 'recipes_dir': os.path.join(self._project_dir, 'recipes'), # The use of guestfs is dependent on the specific image 'has_guestfs': True, 'guestfs_dir': os.path.join(self._project_dir, 'guestfs'), # These options are determined by the configurator's analysis 'dynamically_linked': False, 'modelled_functions': False, # Configurators can silence warnings in case they have specific # hard-coded options 'warn_seeds': True, 'warn_input_file': True, # Searcher options 'use_cupa': True, 'use_test_case_generator': True, 'use_fault_injection': False, # This will add analysis overhead, so disable unless requested by the user. # Also enabled by default for Decree targets. 'enable_pov_generation': options['enable_pov_generation'] } for tf in options['target_files']: if not os.path.exists(tf): raise CommandError('%s does not exist' % tf) config['target_files'].append(os.path.basename(tf)) # The configurator may modify the config dictionary here self._configurator.validate_configuration(config) display_marker_warning = self._target_path and \ config['warn_input_file'] and \ not (config['use_symb_input_file'] or config['sym_args']) if display_marker_warning: logger.warning( 'You did not specify the input file marker @@. This marker is automatically substituted by ' 'a file with symbolic content. You will have to manually edit the bootstrap file in order ' 'to run the program on multiple paths.\n\n' 'Example: %s @@\n\n' 'You can also make arguments symbolic using the ``S2E_SYM_ARGS`` environment variable in ' 'the bootstrap file', self._target_path) if config['use_seeds'] and not config[ 'use_symb_input_file'] and config['warn_seeds']: logger.warning('Seed files have been enabled, however you did not ' 'specify an input file marker (i.e. \'@@\') to be ' 'substituted with a seed file. This means that ' 'seed files will be fetched but never used. Is ' 'this intentional?') if config['use_seeds'] and not os.path.isdir(config['seeds_dir']): os.mkdir(config['seeds_dir']) if config['enable_pov_generation']: config['use_recipes'] = True if self._target_path: # Do some basic analysis on the target self._configurator.analyze(config) # Create a symlink to the target program self._symlink_target_files(options['target_files']) # Create a symlink to the guest tools directory self._symlink_guest_tools() # Create a symlink to guestfs (if it exists) if not self._symlink_guestfs(): config['has_guestfs'] = False # Render the templates logger.info('Creating launch script') self._create_launch_script(config) logger.info('Creating S2E configuration') self._create_lua_config(config) logger.info('Creating S2E bootstrap script') self._create_bootstrap(config) # Record some basic information on the project self._save_json_description(config) if config['use_recipes']: os.makedirs(config['recipes_dir']) project_name = os.path.basename(self._project_dir) cmd = RecipeCommand() cmd.handle_common_args(env=options['env'], project=project_name) cmd.handle() # Return the instructions to the user logger.success(_create_instructions(config))