예제 #1
0
    def _CreateOutputDir(self):
        """Windows templates also include the nanny."""
        build_helpers.MakeBuildDirectory(context=self.context)
        output_dir = build_helpers.BuildWithPyInstaller(context=self.context)

        # Get any dll's that pyinstaller forgot:
        for module in _EnumMissingModules():
            logging.info("Copying additional dll %s.", module)
            shutil.copy(module, output_dir)

        self.BuildNanny(output_dir)

        # Generate a prod and a debug version of nanny executable.
        shutil.copy(os.path.join(output_dir, "GRRservice.exe"),
                    os.path.join(output_dir, "dbg_GRRservice.exe"))
        with io.open(os.path.join(output_dir, "GRRservice.exe"), "rb+") as fd:
            build_helpers.SetPeSubsystem(fd, console=False)
        with io.open(os.path.join(output_dir, "dbg_GRRservice.exe"),
                     "rb+") as fd:
            build_helpers.SetPeSubsystem(fd, console=True)

        # Generate a prod and a debug version of client executable.
        shutil.copy(os.path.join(output_dir, "grr-client.exe"),
                    os.path.join(output_dir, "dbg_grr-client.exe"))
        with io.open(os.path.join(output_dir, "grr-client.exe"), "rb+") as fd:
            build_helpers.SetPeSubsystem(fd, console=False)
        with io.open(os.path.join(output_dir, "dbg_grr-client.exe"),
                     "rb+") as fd:
            build_helpers.SetPeSubsystem(fd, console=True)

        self.CopyBundledFleetspeak(output_dir)

        return output_dir
예제 #2
0
    def _MakeSelfExtractingZip(self, payload_data, output_path):
        """Repack the installer into the payload.

    Args:
      payload_data: data payload for zip file
      output_path: filename for the zip output

    Raises:
      RuntimeError: if the ClientBuilder.unzipsfx_stub doesn't require admin.
    Returns:
      output_path: filename string of zip output file
    """
        context = self.context + ["Client Context"]

        src_zip = zipfile.ZipFile(io.BytesIO(payload_data), mode="r")
        zip_data = io.BytesIO()
        output_zip = zipfile.ZipFile(zip_data,
                                     mode="w",
                                     compression=zipfile.ZIP_DEFLATED)

        config_file_name = config.CONFIG.Get("ClientBuilder.config_filename",
                                             context=context)
        # Copy the rest of the files from the package to the new zip.
        for template_file in src_zip.namelist():
            if template_file != config_file_name:
                # Avoid writing the config file twice if we're repacking a binary that
                # has already been run through deployment. We write it in the next step,
                # so no need to copy over from the original here.
                _CopyFileInZip(src_zip, template_file, output_zip)

        client_config_content = build_helpers.GetClientConfig(context)
        self._ValidateEndConfig(client_config_content)

        output_zip.writestr(
            config_file_name,
            client_config_content.encode("utf-8"),  # pytype: disable=attribute-error
            compress_type=zipfile.ZIP_STORED)

        # The zip file comment is used by the self extractor to run the installation
        # script. Comment has to be `bytes` object because `zipfile` module is not
        # smart enough to properly handle `unicode` objects.
        output_zip.comment = b"$AUTORUN$>%s" % config.CONFIG.Get(
            "ClientBuilder.autorun_command_line",
            context=context).encode("utf-8")

        output_zip.close()

        utils.EnsureDirExists(os.path.dirname(output_path))
        with io.open(output_path, "wb") as fd:
            # First write the installer stub
            stub_data = io.BytesIO()
            unzipsfx_stub = config.CONFIG.Get("ClientBuilder.unzipsfx_stub",
                                              context=context)
            stub_raw = io.open(unzipsfx_stub, "rb").read()

            # Check stub has been compiled with the requireAdministrator manifest.
            if b"level=\"requireAdministrator" not in stub_raw:
                raise RuntimeError(
                    "Bad unzip binary in use. Not compiled with the"
                    "requireAdministrator manifest option.")

            stub_data.write(stub_raw)

            # If in verbose mode, modify the unzip bins PE header to run in console
            # mode for easier debugging.
            build_helpers.SetPeSubsystem(stub_data,
                                         console=config.CONFIG.Get(
                                             "ClientBuilder.console",
                                             context=context))

            # Now patch up the .rsrc section to contain the payload.
            end_of_file = zip_data.tell() + stub_data.tell()

            # This is the IMAGE_SECTION_HEADER.Name which is also the start of
            # IMAGE_SECTION_HEADER.
            offset_to_rsrc = stub_data.getvalue().find(b".rsrc")

            # IMAGE_SECTION_HEADER.PointerToRawData is a 32 bit int.
            stub_data.seek(offset_to_rsrc + 20)
            start_of_rsrc_section = struct.unpack("<I", stub_data.read(4))[0]

            # Adjust IMAGE_SECTION_HEADER.SizeOfRawData to span from the old start to
            # the end of file.
            stub_data.seek(offset_to_rsrc + 16)
            stub_data.write(
                struct.pack("<I", end_of_file - start_of_rsrc_section))

            # Concatenate stub and zip file.
            out_data = io.BytesIO()
            out_data.write(stub_data.getvalue())
            out_data.write(zip_data.getvalue())

            # Then write the actual output file.
            fd.write(out_data.getvalue())

        if self.signer:
            self.signer.SignFile(output_path)

        logging.info("Deployable binary generated at %s", output_path)

        return output_path