Exemplo n.º 1
0
        /// <summary>
        /// Validates the project file after it has been loaded from an INI file.
        /// </summary>
        public void ValidateProject()
        {
            // Validate stub
            ValidateStubIcon();
            ValidateStubPadding();
            ValidateManifest();

            // Validate sources
            ValidateSources();
            ValidateCompression();
            ValidateEofData();

            // Validate actions
            ValidateActions();
            ValidateRunPE();
            ValidateInvoke();
            ValidateDrop();
            ValidateMessageBox();

            void ValidateStubIcon()
            {
                // Validate stub icon
                if (Project.Stub.IconPath != null)
                {
                    // Validate that stub icon has .ico or .exe extension
                    string extension = Path.GetExtension(Project.Stub.IconPath);

                    if (extension.Equals(".ico", StringComparison.OrdinalIgnoreCase))
                    {
                        // Validate that stub icon is a valid .ico file
                        if (!IconExtractor.HasIcon(Project.Stub.IconPath))
                        {
                            Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "File '" + Path.GetFileName(Project.Stub.IconPath) + "' is not a valid icon.");
                        }
                    }
                    else if (extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        // Validate that stub icon is an executable file with an icon
                        if (!IconExtractor.HasIcon(Project.Stub.IconPath))
                        {
                            Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Could not extract icon from '" + Path.GetFileName(Project.Stub.IconPath) + "'.");
                        }
                    }
                    else
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Stub icon must have '.ico' or '.exe' extension.");
                    }
                }
            }

            void ValidateStubPadding()
            {
                // Validate that stub has padding
                if (Project.Stub.Padding < 50)
                {
                    Errors.Add(ErrorSource.Project, ErrorSeverity.Warning, "Padding is less than 50. The compiled binary will be of high-entropy and may be detected as a packer.");
                }
            }

            void ValidateManifest()
            {
                // Validate that manifest is not set to both template and cutom file
                if (Project.Manifest.Template != null && Project.Manifest.Path != null)
                {
                    Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Both manifest template and path specified. Please specify only one.");
                }
            }

            void ValidateSources()
            {
                // Validate duplicate source ID's
                for (int i = 0; i < Project.Sources.Count; i++)
                {
                    if (Project.Sources.Skip(i + 1).Any(source => source.Id == Project.Sources[i].Id))
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Duplicate source ID '" + Project.Sources[i].Id + "'.");
                    }
                }

                // Exclude unused sources
                foreach (ProjectSource source in Project.Sources.ToArray())
                {
                    if (Project.Actions.None(action => action.Source == source))
                    {
                        Project.RemoveSource(source);
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Warning, "Source '" + source.Id + "' was excluded, because it is not used.");
                    }
                }
            }

            void ValidateCompression()
            {
                // Validate that compressed files are smaller than 100 MB
                foreach (EmbeddedSource source in Project.Sources.OfType <EmbeddedSource>())
                {
                    if (source.Compress && source.Path != null && new FileInfo(source.Path).Length > 1024 * 1024 * 100)
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Warning, "File '" + Path.GetFileName(source.Path) + "' is bigger than 100 MB. It is recommended to disable compression.");
                    }
                }
            }

            void ValidateEofData()
            {
                IEnumerable <EmbeddedSource> eofSources = Project.Sources.OfType <EmbeddedSource>().Where(source => source.EofData);

                // Validate that only PE files are used as EOF data sources
                foreach (EmbeddedSource source in eofSources)
                {
                    if (new[] { ".exe", ".dll" }.None(extension => Path.GetExtension(source.Path).Equals(extension, StringComparison.OrdinalIgnoreCase)))
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Cannot write EOF data of file '" + Path.GetFileName(source.Path) + "'. Only executable files contain EOF data.");
                    }
                }

                // Validate that only one file's EOF data is written
                foreach (EmbeddedSource source in eofSources.Skip(1))
                {
                    Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Cannot write EOF data of file '" + Path.GetFileName(source.Path) + "'. Only one file's EOF data can be written.");
                }
            }

            void ValidateActions()
            {
                // Validate that at least one action exists
                if (Project.Actions.None())
                {
                    Errors.Add(ErrorSource.Project, ErrorSeverity.Warning, "The project is empty.");
                }
            }

            void ValidateRunPE()
            {
                // Validate that RunPE files have an .exe extension
                foreach (RunPEAction action in Project.Actions.OfType <RunPEAction>())
                {
                    if (action.Source is EmbeddedSource embeddedSource &&
                        embeddedSource.Path != null &&
                        !Path.GetExtension(embeddedSource.Path).Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "RunPE file must have '.exe' extension.");
                    }
                }
            }

            void ValidateInvoke()
            {
                // Validate that invoke files have an .exe extension
                foreach (InvokeAction action in Project.Actions.OfType <InvokeAction>())
                {
                    if (action.Source is EmbeddedSource embeddedSource &&
                        embeddedSource.Path != null &&
                        !Path.GetExtension(embeddedSource.Path).Equals(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Errors.Add(ErrorSource.Project, ErrorSeverity.Error, "Invoked file must have '.exe' extension.");
                    }
                }

                // Validate that invoke actions are only used in a .NET stub
                if (CSharp.EqualsNone(Project.Stub.Type, StubType.DotNet32, StubType.DotNet64) && Project.Actions.OfType <InvokeAction>().Any())
                {
                    Errors.Add(ErrorSource.Project, ErrorSeverity.Error, ".NET invocation is only supported in a .NET stub.");
                }
            }

            void ValidateDrop()
            {
                // Validate that a UAC manifest is included, if files are dropped in privileged directories
                IEnumerable <string> privilegedDropFileNames = Project.Actions
                                                               .OfType <DropAction>()
                                                               .Where(action => CSharp.EqualsAny(action.Location, DropLocation.WindowsDirectory, DropLocation.SystemDirectory, DropLocation.ProgramFiles, DropLocation.CDrive))
                                                               .Select(action =>
                {
                    if (action.FileName != null)
                    {
                        return(action.FileName);
                    }
                    else if (action.Source is EmbeddedSource embeddedSource && embeddedSource.Path != null)
                    {
                        return(Path.GetFileName(embeddedSource.Path));
                    }