Esempio n. 1
0
    def _validate_and_create_project(self, options):
        self._target_path = options['target']
        if not self._target_path:
            logger.warn(
                'Creating a project without a target file, you will have to manually edit bootstrap.sh'
            )

        project_name = options['name']

        if self._target_path:
            # Check that the analysis target is valid
            if not os.path.isfile(self._target_path):
                raise CommandError(
                    'Cannot analyze %s because it does not seem to '
                    'exist' % self._target_path)

            # The default project name is the target program to be analyzed
            # (without any file extension)
            if not project_name:
                project_name, _ = \
                    os.path.splitext(os.path.basename(self._target_path))

        self._project_dir = self.env_path('projects', project_name)

        # Load the image JSON description. If it is not given, guess the image
        image = options['image']
        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
        templates = get_image_templates(img_build_dir)

        if not image:
            image = self._guess_image(templates, options['target_arch'])

        self._img_json = self._get_or_download_image(templates, image,
                                                     options['download_image'])

        if self._target_path:
            # Check architecture consistency
            if not is_valid_arch(options['target_arch'], self._img_json['os']):
                raise CommandError(
                    'Binary is x86_64 while VM image is %s. Please '
                    'choose another image' % self._img_json['os']['arch'])

        # Check if the project dir already exists
        # Do this after all checks have completed
        self._check_project_dir(options['force'])

        # Create the project directory
        os.mkdir(self._project_dir)
Esempio n. 2
0
    def _select_image(self, target, image=None, download_image=True):
        """
        Select an image to use for this project.

        If an image was specified, use it. Otherwise select an image to use
        based on the target's architecture. If the image is not available, it
        may be downloaded.

        Returns:
            A dictionary that describes the image that will be used, based on
            the image's JSON descriptor.
        """
        # Load the image JSON description. If it is not given, guess the image
        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
        img_templates = get_image_templates(img_build_dir)

        if not image:
            image = self._guess_image(target, img_templates)

        return self._get_or_download_image(img_templates, image, download_image)
Esempio n. 3
0
    def _print_image_list(self):
        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
        templates = get_image_templates(img_build_dir)

        if not templates:
            raise CommandError('No images available to build. Make sure that '
                               '%s exists and is valid' %
                               os.path.join(img_build_dir, 'images.json'))

        print('Available images:')
        print(' * all - Build all images')
        print(' * linux - Build all Linux images')
        print(' * windows - Build all Windows images')
        print('')
        for template, desc in sorted(templates.iteritems()):
            print(' * %s - %s' % (template, desc['name']))

        print('\nRun ``s2e image_build <name>`` to build an image. '
              'Note that you must run ``s2e build`` **before** building '
              'an image')
Esempio n. 4
0
    def _print_image_list(self, images, image_groups, image_descriptors):
        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
        templates = get_image_templates(img_build_dir)
        if not templates:
            images_json_path = os.path.join(img_build_dir, 'images.json')
            raise CommandError('No images available to build. Make sure that '
                               f'{images_json_path} exists and is valid')

        def get_max_len(lst):
            ret = 0
            for item in lst:
                if len(item) > ret:
                    ret = len(item)
            return ret

        print('Available image groups:')
        max_group_len = get_max_len(image_groups)
        for group in image_groups:
            print(f' * {group:{max_group_len}} - Build {group} images')

        print('\nAvailable images:')
        max_image_len = get_max_len(images)
        for image in sorted(images):
            print(f' * {image:{max_image_len}} - {image_descriptors[image]["name"]}')
Esempio n. 5
0
    def handle(self, *args, **options):
        # If DISPLAY is missing, don't use headless mode
        if options['gui']:
            self._headless = False

        # If KVM has been explicitly disabled, don't use it during the build
        if options['no_kvm']:
            self._use_kvm = False

        num_cores = options['cores']
        _check_core_num(num_cores)

        # The path could have been deleted by a previous clean
        if not os.path.exists(self.image_path()):
            os.makedirs(self.image_path())

        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])

        if options['clean']:
            self._invoke_make(img_build_dir, ['clean'], num_cores)
            return

        image_name = options['name']
        if not image_name:
            self._print_image_list()
            return

        templates = get_image_templates(img_build_dir)

        image_names = _translate_image_name(templates, image_name)
        logger.info('The following images will be built:')
        for image in image_names:
            logger.info(' * %s', image)

        if options['download']:
            image_downloader = ImageDownloader(templates)
            image_downloader.download_images(image_names, self.image_path())

            logger.info('Successfully downloaded images: %s',
                        ', '.join(image_names))
            return

        rule_names = image_names

        if options['archive']:
            archive_rules = []
            for r in rule_names:
                archive_rules.append(
                    os.path.join(self.image_path(), '%s.tar.xz' % r))

            rule_names = archive_rules
            logger.info('The following archives will be built:')
            for a in archive_rules:
                logger.info(' * %s', a)

        iso_dir = os.path.abspath(
            options['iso_dir']) if options['iso_dir'] else None

        # Check for optional product keys and iso directories.
        # These may or may not be required, depending on the set of images.
        _check_product_keys(templates, image_names)
        _check_iso(templates, iso_dir, image_names)

        if self._use_kvm:
            _check_kvm()
            _check_groups_kvm()

        _check_groups_docker()
        _check_vmlinux()
        _check_virtualbox()

        # Clone kernel if needed.
        # This is necessary if the s2e env has been initialized with -b flag.
        self._clone_kernel()

        self._invoke_make(img_build_dir, rule_names, num_cores, iso_dir)

        logger.success('Built image \'%s\'', image_name)
Esempio n. 6
0
 def _get_image_templates(self):
     img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
     return get_image_templates(img_build_dir)
Esempio n. 7
0
    def handle(self, *args, **options):
        # If DISPLAY is missing, don't use headless mode
        if options['gui']:
            self._headless = False

        # If KVM has been explicitly disabled, don't use it during the build
        if options['no_kvm']:
            self._use_kvm = False

        self._num_cores = options['cores']

        # The path could have been deleted by a previous clean
        if not os.path.exists(self.image_path()):
            os.makedirs(self.image_path())

        img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])

        if options['clean']:
            self._invoke_make(img_build_dir, ['clean'])
            return

        image_names = options['name']
        templates = get_image_templates(img_build_dir)
        app_templates = get_app_templates(img_build_dir)
        images, image_groups, image_descriptors = get_all_images(templates, app_templates)

        if not image_names:
            self._print_image_list(images, image_groups, image_descriptors)
            print('\nRun ``s2e image_build <name>`` to build an image. '
                  'Note that you must run ``s2e build`` **before** building '
                  'an image')
            return

        image_names = translate_image_name(images, image_groups, image_names)
        logger.info('The following images will be built:')
        for image in image_names:
            logger.info(' * %s', image)

        if options['download']:
            _download_images(self.image_path(), image_names, templates)
            return

        rule_names = image_names

        if options['archive']:
            rule_names = _get_archive_rules(self.image_path(), image_names)

        iso_dir = os.path.abspath(options['iso_dir']) if options['iso_dir'] else None

        # Check for optional product keys and iso directories.
        # These may or may not be required, depending on the set of images.
        _check_product_keys(image_descriptors, image_names)
        _check_iso(templates, app_templates, iso_dir, image_names)

        if self._use_kvm:
            _check_kvm()
            _check_groups_kvm()

        _check_groups_docker()
        _check_vmlinux()

        self._has_cow = _check_cow(self.image_path())

        if self._use_kvm:
            _check_virtualbox()
            _check_vmware()

        if not _is_port_available(options['ftp_port']):
            raise CommandError(f'localhost:{options["ftp_port"]} is not available. Check that the port is free or '
                               'specify a port with --ftp-port')

        # Clone kernel if needed.
        # This is necessary if the s2e env has been initialized with -b flag.
        self._clone_kernel()

        server = _start_ftp_server(self.image_path(), options['ftp_port'])

        self._invoke_make(img_build_dir, rule_names, options['ftp_port'], iso_dir)

        logger.success('Built image(s) \'%s\'', ' '.join(image_names))

        server.close_all()
Esempio n. 8
0
 def _initialize_images(self):
     img_build_dir = self.source_path(CONSTANTS['repos']['images']['build'])
     self._img_templates = get_image_templates(img_build_dir)
     app_templates = get_app_templates(img_build_dir)
     self._images, self._image_groups, self._image_descriptors = get_all_images(
         self._img_templates, app_templates)