4

I have written the following code:

public DataTable GetDotNetAssemblies(string baseDirectory)
{
    DataTable MethodResult = null;
    try
    {
        if (Directory.Exists(baseDirectory))
        {
            List<string> FilePaths = NetworkConnection.GetAllFilesUnderDirectory(baseDirectory);

            DataTable dt = new DataTable();
            dt.Columns.Add("Directory");
            dt.Columns.Add("Filename");
            dt.Columns.Add("Date modified");
            dt.Columns.Add("Bytes");
            dt.Columns.Add("User modified");

            foreach (string FilePath in FilePaths)
            {
                DataRow dr = dt.NewRow();

                FileInfo f = new FileInfo(FilePath);

                List<string> AllowedExtensions = new List<string>();
                AllowedExtensions.Add(".exe");
                AllowedExtensions.Add(".dll");

                if (AllowedExtensions.Contains(f.Extension.ToLower()))
                {
                    dr["Directory"] = f.Directory;
                    dr["Filename"] = f.Name;
                    dr["Date modified"] = f.LastWriteTime;
                    dr["Bytes"] = f.Length.ToString();

                    string UserModified = "";

                    try
                    {
                        UserModified = f.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();

                    }
                    catch
                    {
                        UserModified = "Unknown";

                    }

                    dr["User modified"] = UserModified;

                    dt.Rows.Add(dr);

                }

            }

            dt.AcceptChanges();

            MethodResult = dt;

        }
        else
        {
            MessageBox.Show("Unable to connect to directory:\n" + baseDirectory);

        }

    }
    catch (Exception ex)
    {
        ex.HandleException();
    }
    return MethodResult;
}

I am already filtering by file extension, which you can see by the line:

if (AllowedExtensions.Contains(f.Extension.ToLower()))

What I need is to filter the assembly files further, by checking whether they are .Net assemblies or not.

Is there a test I can perform on a file?

Additionally, if it's possible to discover which version of .Net CLR is used in the assembly then that would be better still.

WonderWorker
  • 8,539
  • 4
  • 63
  • 74

3 Answers3

4

You could try using the GetAssemblyName() method to attempt to resolve if it was an actual assembly similar to the technique mentioned in this MSDN documentation :

public string bool IsValidAssembly(string path)
{
    try
    {
          // Attempt to resolve the assembly
          var assembly = GetAssemblyName(path);
          // Nothing blew up, so it's an assembly
          return true;
    }
    catch(Exception ex)
    {
          // Something went wrong, it is not an assembly (specifically a 
          // BadImageFormatException will be thrown if it could be found
          // but it was NOT a valid assembly
          return false;
    }   
}

So you could consider using the following in your code :

// Check that it is a valid extension and a valid assembly
if (AllowedExtensions.Contains(f.Extension.ToLower()) && IsValidAssembly(FilePath))
{
     // At this point it should be valid, so continue
}
Rion Williams
  • 74,820
  • 37
  • 200
  • 327
1

I believe you may need to use AssemblyName.GetAssemblyName(path) - it doesn't load the assembly but open/closes the file to read the assembly manifest (and throws the System.BadImageFormatException if not ok)

https://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getassemblyname.aspx

NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51
-1

Modified code

Modified to filter .Net assemblies:

    public DataTable GetDotNetAssemblies(string baseDirectory)
    {
        DataTable MethodResult = null;
        try
        {
            if (Directory.Exists(baseDirectory))
            {
                List<string> FilePaths = NetworkConnection.GetAllFilesUnderDirectory(baseDirectory);

                DataTable dt = new DataTable();
                dt.Columns.Add("Directory");
                dt.Columns.Add("Filename");
                dt.Columns.Add("Date modified");
                dt.Columns.Add("Bytes");
                dt.Columns.Add("User modified");
                dt.Columns.Add(".Net CLR version");

                foreach (string FilePath in FilePaths)
                {
                    DataRow dr = dt.NewRow();

                    FileInfo f = new FileInfo(FilePath);

                    List<string> AllowedExtensions = new List<string>();
                    AllowedExtensions.Add(".exe");
                    AllowedExtensions.Add(".dll");

                    bool IsDotNetAssembly = false;

                    try
                    {
                        AssemblyName a = AssemblyName.GetAssemblyName(FilePath);

                        IsDotNetAssembly = true;

                    } catch {}

                    if (AllowedExtensions.Contains(f.Extension.ToLower()) && IsDotNetAssembly)
                    {
                        dr["Directory"] = f.Directory;
                        dr["Filename"] = f.Name;
                        dr["Date modified"] = f.LastWriteTime;
                        dr["Bytes"] = f.Length.ToString();

                        try
                        {
                            Assembly a = Assembly.GetAssembly(AssemblyName.GetAssemblyName(FilePath).GetType());

                            dr[".Net CLR version"] = a.ImageRuntimeVersion.ToString();

                        }
                        catch //(Exception ex2)
                        {
                            //ex2.HandleException();
                        }

                        string UserModified = "";

                        try
                        {
                            UserModified = f.GetAccessControl().GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();

                        }
                        catch
                        {
                            UserModified = "Unknown";

                        }

                        dr["User modified"] = UserModified;

                        dt.Rows.Add(dr);

                    }

                }

                dt.AcceptChanges();

                MethodResult = dt;

            }
            else
            {
                MessageBox.Show("Unable to connect to directory:\n" + baseDirectory);

            }

        }
        catch //(Exception ex)
        {
            //ex.HandleException();
        }
        return MethodResult;
    }

Test 1

A slightly modified version of the C# example found here.

An exception will be thrown if the file is not a .Net assembly.

bool IsDotNetAssembly = false;

try
{
    AssemblyName a = AssemblyName.GetAssemblyName(FilePath);

    IsDotNetAssembly = true;

} catch {}

Test 2

Tells your the version of CLR, which is the .NET compiler version:

Assembly a = Assembly.GetAssembly(AssemblyName.GetAssemblyName(FilePath).GetType());

dr[".Net CLR version"] = a.ImageRuntimeVersion.ToString();
WonderWorker
  • 8,539
  • 4
  • 63
  • 74