Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.34 - virus warning #58

Open
somera opened this issue Dec 30, 2024 · 7 comments
Open

v1.34 - virus warning #58

somera opened this issue Dec 30, 2024 · 7 comments

Comments

@somera
Copy link

somera commented Dec 30, 2024

Hi,

when I try to download the current version I get this

image

in Chrome.

And https://www.virustotal.com/gui/url/cbcd9b649a5c5f898ccc2e1216ba0731b66487994ad969f0f1e20f1e31571384

image

@irusanov
Copy link
Owner

I think that is some strange problem with the archiving method. I usually do it manually with 7zip, but used a programmatic creation of the archive this time. I've zipped the same files manually and Defender does not complain anymore. Don't think there's a real problem, but I will replace the zip with the one I've manually zipped. Need to update the checksum though.

@irusanov
Copy link
Owner

irusanov commented Dec 30, 2024

Thanks for letting me know. I wanted to automate the process a bit as there were too many manual operations to prepare a release.

I've compared the files in the bad archive and the ones I released from and manually zipped now and they are identical (binary compare), so I'm confident it is a false-positive. New zip works.

VirusTotal shows the same 2 "usual" detections

https://www.virustotal.com/gui/file/e7ff33418085e08ac53a20977923287794623233aebc589c09ec746e34cb55b2

This is the simple CLI app that I made to automate the process:

using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using System.Reflection;
using System.Security.Cryptography;

namespace ZenTimingsRelease
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Step 1: Clean up old files and directories if any
            string releaseDir = "release";
            string checksumsFilePath = "checksums.txt";
            string directoryPath = @"C:\GIT\ZenTimings\WPF\bin\Release";

            // Cleanup: Delete the 'release' directory if it exists
            if (Directory.Exists(releaseDir))
            {
                Directory.Delete(releaseDir, true);
                Console.WriteLine("Deleted old 'release' directory.");
            }

            // Step 3: Copy files to a new 'release' directory
            if (!Directory.Exists(releaseDir))
            {
                Directory.CreateDirectory(releaseDir);
                Console.WriteLine("Created 'release' directory.");
            }

            List<string> filesToCopy =
            [
                "AdonisUI.ClassicTheme.dll",
                "AdonisUI.dll",
                "AutoUpdater.NET.dll",
                "Changelog.txt",
                "InpOut.LICENSE.txt",
                "inpoutx64.dll",
                "README.txt",
                "remove_inpoutx64.reg",
                "uninstall_inpoutx64_driver(run_as_admin).bat",
                "WinIo32.dll",
                "WinIo32.LICENSE.txt",
                "WinIo32.sys",
                "WinRing0.LICENSE.txt",
                "ZenStates-Core.dll",
                "ZenTimings.exe",
                "ZenTimings.exe.config",
            ];

            foreach (string file in filesToCopy)
            {
                //if (File.Exists(file))
                {
                    string srcFile = Path.Combine(directoryPath, Path.GetFileName(file));
                    string destFile = Path.Combine(releaseDir, Path.GetFileName(file));
                    File.Copy(srcFile, destFile, overwrite: true);
                    Console.WriteLine($"Copied: {srcFile} to {destFile}");
                }
            }

            // Step 4: Get the assembly version of ZenTimings.exe
            string exeFilePath = Path.Combine(releaseDir, "ZenTimings.exe");
            string version = GetAssemblyVersion(exeFilePath);
            string zipReleasePath = "ZenTimings.zip";

            // If the version extraction was successful, use it for naming the zip file
            if (version != null)
            {
                zipReleasePath = $"ZenTimings_v{version}.zip";
            }
            else
            {
                Console.WriteLine("Could not extract version from ZenTimings.exe. Defaulting to 'ZenTimings.zip'.");

                //ZipFile.CreateFromDirectory(releaseDir, zipReleasePath, CompressionLevel.SmallestSize, false);
            }

            using (var archive = ZipArchive.Create())
            {
                archive.AddAllFromDirectory(releaseDir);
                archive.SaveTo(zipReleasePath, CompressionType.Deflate);
            }
            Console.WriteLine($"'release' directory zipped to {zipReleasePath}");

            //// Step 2: Compute checksums for ZenTimings.zip

            // Compute and output checksums
            if (File.Exists(zipReleasePath))
            {
                string md5Checksum = ComputeChecksum(zipReleasePath, MD5.Create());
                string sha1Checksum = ComputeChecksum(zipReleasePath, SHA1.Create());
                string sha256Checksum = ComputeChecksum(zipReleasePath, SHA256.Create());

                // Output checksums to checksums.txt
                File.WriteAllText(checksumsFilePath, $"MD5: {md5Checksum}\nSHA1: {sha1Checksum}\nSHA256: {sha256Checksum}\n");
                Console.WriteLine("Checksums computed and saved to checksums.txt");
            }
            else
            {
                Console.WriteLine($"File '{zipReleasePath}' not found.");
                return;
            }
        }

        // Helper function to compute checksum
        static string ComputeChecksum(string filePath, HashAlgorithm algorithm)
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                byte[] hashBytes = algorithm.ComputeHash(fs);
                return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            }
        }

        // Helper function to get assembly version from ZenTimings.exe
        static string GetAssemblyVersion(string filePath)
        {
            try
            {
                // Load the assembly and get the version info
                Assembly assembly = Assembly.LoadFrom(filePath);
                Version version = assembly.GetName().Version;
                return version.ToString(2); // Format version as Major.Minor (e.g., 1.33)
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error extracting version: {ex.Message}");
                return null; // Return null if version extraction fails
            }
        }
    }
}

@irusanov
Copy link
Owner

Some more details:

If I use the program to zip the files, but remove just the "ZenTimings.exe.config", then the resulting zip comes clean. If I zip just the config file and leave everything else, then the zip is also clean.

It's some sort of a heuristic pattern that is hit, I guess. Will use a manual zip for the next releases or just the simple

ZipFile.CreateFromDirectory(releaseDir, zipReleasePath, CompressionLevel.SmallestSize, false);

The config file is nothing special, only contains the target framework version

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="ZenTimings.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
    </sectionGroup>
</configSections>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
</configuration>

@somera
Copy link
Author

somera commented Dec 30, 2024

I assumed it was a false flag. But you never know.

@irusanov
Copy link
Owner

irusanov commented Dec 30, 2024

Well, to be fair, I panicked a bit that something might have gone wrong on my end. It's the last thing I would want, especially when there's an auto update. That would be a disaster...

@somera
Copy link
Author

somera commented Jan 10, 2025

I don't get any virus warning in 1.35.

@irusanov
Copy link
Owner

Yes, I'm sticking to manual zipping the files for now, which fixes the issue. I've also made sure to check not only with VirusTotal, but with Defender as well, which was detecting it before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants