Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a file is a .NET assembly

I've seen some methods of checking if a PEFile is a .NET assembly by examining the binary structure.

Is that the fastest method to test multiple files? I assume that trying to load each file (e.g. via Assembly.ReflectionOnlyLoad) file might be pretty slow since it'll be loading file type information.

Note: I'm looking for a way to check files programmatically.

like image 922
Jon Galloway Avatar asked Dec 01 '08 04:12

Jon Galloway


People also ask

What is a .NET assembly file?

NET-based applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (. dll) files, and are the building blocks of . NET applications.

How do I know if a file is .NET assembly?

Call the GetMetadataReader method on the PE reader instance to create a metadata reader. Check the value of the IsAssembly property. If the value is true , the file is an assembly.

How can I tell if a file is .NET PE?

The PE signature starts at offset 0x80, with the magic number 'PE' (0x50, 0x45, 0x00, 0x00), identifying this file as a PE executable, followed by the PE file header (also known as the COFF header).

Where does .NET look for assemblies?

The runtime always begins probing in the application's base, which can be either a URL or the application's root directory on a computer. If the referenced assembly is not found in the application base and no culture information is provided, the runtime searches any subdirectories with the assembly name.


2 Answers

I guess Stormenet's answer isn't technically programmatic, so I'll seperate my response into an answer.

For best performance, nothing is going to beat opening the file(s) with a StreamReader, reading the first (n) bytes and checking for the .NET file signature data structures in the byte stream.

Pretty much the same way you'd verify something is a DOS executable:

http://en.wikipedia.org/wiki/DOS_executable

Look for the "MZ" header bytes, which also happen to be the initials of Mark Zbikowski, one of the developers of MS-DOS..

like image 139
Jeff Atwood Avatar answered Sep 20 '22 20:09

Jeff Atwood


Maybe this helps

from https://web.archive.org/web/20110930194955/http://www.grimes.demon.co.uk/dotnet/vistaAndDotnet.htm

Next, I check to see if it is a .NET assembly. To do this I check to see if the file contains the CLR header. This header contains important information about the location of the .NET code in the file and the version of the framework that was used to write that code. The location of this header is given in the file's Data Directory table. If the data directory item has zero values then the file is unmanaged, if it has non-zero values then the file is a .NET assembly.

You can test this yourself using the dumpbin utility with the /headers switch. This utility will print the various headers in a file on the command line. At the end of the Optional Header Values you'll see a list of the Data Directories (there will always be 16 of them) and if the COM Descriptor Directory has a non-zero location it indicates that the file is a .NET assembly. The contents of the CLR header can also be listed using the /clrheader switch (if the file is unmanaged this will show no values). XP tests for the CLR header when it executes a file and if the CLR header is present it will initialize the runtime and pass the entry point of the assembly to the runtime, so that the file runs totally within the runtime.

like image 35
Stormenet Avatar answered Sep 19 '22 20:09

Stormenet