Andrew Mock
Andrew Mock

Reputation: 99

How do I get the hash of current .exe?

[SOLVED]: I copied the file and ran the hasher on that copy.

I need my app to find the EXE's current MD5. I can get the MD5 of any file. However, no matter what I do, I cannot get a FileStream to read the open EXE. I tried using FileOptions.Asynchronous but that didn't help.

EDIT: I guess I'm not very clear. I want my app to be be able to read itself.

EDIT to code:

private void GetMd5()
{
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

    FileInfo fi = new FileInfo(Process.GetCurrentProcess().MainModule.FileName);
    FileStream stream = File.Create(Process.GetCurrentProcess().MainModule.FileName, (int)fi.Length, FileOptions.Asynchronous);

    md5.ComputeHash(stream);

    stream.Close();

    string rtrn = "";
    for (int i = 0; i < md5.Hash.Length; i++)
    {
        rtrn += (md5.Hash[i].ToString("x2"));
    }
    MessageBox.Show(rtrn.ToUpper());
}

Upvotes: 4

Views: 11457

Answers (4)

user3723271
user3723271

Reputation:

Since I've tried these answers and found that none of them change every edit to the exe, or change at all, I found something that actually does work.

I did not edit any code here, all of this was from the referred page below.

Reference: http://www.vcskicks.com/self-hashing.php

internal static class ExecutingHash
{
    public static string GetExecutingFileHash()
    {
        return MD5(GetSelfBytes());
    }

    private static string MD5(byte[] input)
    {
        return MD5(ASCIIEncoding.ASCII.GetString(input));
    }

    private static string MD5(string input)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

        byte[] originalBytes = ASCIIEncoding.Default.GetBytes(input);
        byte[] encodedBytes = md5.ComputeHash(originalBytes);

        return BitConverter.ToString(encodedBytes).Replace("-", "");
    }

    private static byte[] GetSelfBytes()
    {
        string path = Application.ExecutablePath;

        FileStream running = File.OpenRead(path);

        byte[] exeBytes = new byte[running.Length];
        running.Read(exeBytes, 0, exeBytes.Length);

        running.Close();

        return exeBytes;
    }
}

Every test seems to output properly. I'd recommend to anyone seeing this to use this class or make something of it.

Upvotes: 0

mccdyl001
mccdyl001

Reputation: 182

Bit late to the party, but was recently trying to do this myself. In .NET 4.5 the following works quite nicely without the need for making a temporary copy. As said, if you can read the file to make a copy of it, you can read the file to generate a hash for it.

private string GetMD5()
{
    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
    System.IO.FileStream stream = new System.IO.FileStream(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    md5.ComputeHash(stream);

    stream.Close();

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    for (int i = 0; i < md5.Hash.Length; i++)
        sb.Append(md5.Hash[i].ToString("x2"));

    return sb.ToString().ToUpperInvariant();
}

Upvotes: 2

Mitch Wheat
Mitch Wheat

Reputation: 300719

The File.Create Method (String, Int32, FileOptions, FileSecurity):

Creates or overwrites the specified file with the specified buffer size, file options, and file security.

I'm fairly sure that's not what you intended to do. Presumably you want FileInfo.Open Method (FileMode, FileAccess):

FileInfo fi = new FileInfo(path); 
FileStream stream = File.Open(path, FileMode.Open); 

Upvotes: 4

Evan
Evan

Reputation: 6161

Change: FileStream stream = File.Create(path, (int)fi.Length, FileOptions.Asynchronous); to FileStream stream = File.Open(path, FileMode.Open);

Upvotes: 1

Related Questions