diff --git a/ExecutableTest/Program.cs b/ExecutableTest/Program.cs index 35b337ce..a49ce286 100644 --- a/ExecutableTest/Program.cs +++ b/ExecutableTest/Program.cs @@ -24,101 +24,162 @@ namespace ExecutableTest { Console.WriteLine($"Checking possible path: {arg}"); - // Check the file exists - if (!File.Exists(arg)) + // Check if the file or directory exists + if (File.Exists(arg)) { - Console.WriteLine($"{arg} does not exist or is not a file, skipping..."); - continue; + PrintFileInfo(arg); } - - using (Stream stream = File.OpenRead(arg)) + else if (Directory.Exists(arg)) { - // Read the first 4 bytes - byte[] magic = stream.ReadBytes(2); - if (magic[0] != 'M' || magic[1] != 'Z') + foreach (string path in Directory.EnumerateFiles(arg, "*", SearchOption.AllDirectories)) { - Console.WriteLine("Not a recognized executable format, skipping..."); - Console.WriteLine(); - continue; - } - - // Build the executable information - Console.WriteLine("Creating MS-DOS executable builder"); - Console.WriteLine(); - - stream.Seek(0, SeekOrigin.Begin); - var msdos = MSDOS.Create(stream); - if (msdos == null) - { - Console.WriteLine("Something went wrong parsing MS-DOS executable"); - Console.WriteLine(); - continue; - } - - // Print the executable info to screen - msdos.Print(); - - // Check for a valid new executable address - if (msdos.NewExeHeaderAddr >= stream.Length) - { - Console.WriteLine("New EXE header address invalid, skipping additional reading..."); - Console.WriteLine(); - continue; - } - - // Try to read the executable info - stream.Seek(msdos.NewExeHeaderAddr, SeekOrigin.Begin); - magic = stream.ReadBytes(4); - - // New Executable - if (magic[0] == 'N' && magic[1] == 'E') - { - stream.Seek(0, SeekOrigin.Begin); - var newExecutable = NewExecutable.Create(stream); - if (newExecutable == null) - { - Console.WriteLine("Something went wrong parsing New Executable"); - Console.WriteLine(); - continue; - } - - // Print the executable info to screen - newExecutable.Print(); - } - - // Linear Executable - else if (magic[0] == 'L' && (magic[1] == 'E' || magic[1] == 'X')) - { - Console.WriteLine($"Linear executable found. No parsing currently available."); - Console.WriteLine(); - continue; - } - - // Portable Executable - else if (magic[0] == 'P' && magic[1] == 'E' && magic[2] == '\0' && magic[3] == '\0') - { - stream.Seek(0, SeekOrigin.Begin); - var portableExecutable = PortableExecutable.Create(stream); - if (portableExecutable == null) - { - Console.WriteLine("Something went wrong parsing Portable Executable"); - Console.WriteLine(); - continue; - } - - // Print the executable info to screen - portableExecutable.Print(); - } - - // Unknown - else - { - Console.WriteLine($"Unrecognized header signature: {BitConverter.ToString(magic).Replace("-", string.Empty)}"); - Console.WriteLine(); - continue; + PrintFileInfo(path); } } + else + { + Console.WriteLine($"{arg} does not exist, skipping..."); + } } } + + /// + /// Print information for a single file, if possible + /// + private static void PrintFileInfo(string file) + { + using (Stream stream = File.OpenRead(file)) + { + // Read the first 4 bytes + byte[] magic = stream.ReadBytes(2); + + if (!IsMSDOS(magic)) + { + Console.WriteLine("Not a recognized executable format, skipping..."); + Console.WriteLine(); + return; + } + + // Build the executable information + Console.WriteLine("Creating MS-DOS executable builder"); + Console.WriteLine(); + + stream.Seek(0, SeekOrigin.Begin); + var msdos = MSDOS.Create(stream); + if (msdos == null) + { + Console.WriteLine("Something went wrong parsing MS-DOS executable"); + Console.WriteLine(); + return; + } + + // Print the executable info to screen + msdos.Print(); + + // Check for a valid new executable address + if (msdos.NewExeHeaderAddr >= stream.Length) + { + Console.WriteLine("New EXE header address invalid, skipping additional reading..."); + Console.WriteLine(); + return; + } + + // Try to read the executable info + stream.Seek(msdos.NewExeHeaderAddr, SeekOrigin.Begin); + magic = stream.ReadBytes(4); + + // New Executable + if (IsNE(magic)) + { + stream.Seek(0, SeekOrigin.Begin); + var newExecutable = NewExecutable.Create(stream); + if (newExecutable == null) + { + Console.WriteLine("Something went wrong parsing New Executable"); + Console.WriteLine(); + return; + } + + // Print the executable info to screen + newExecutable.Print(); + } + + // Linear Executable + else if (IsLE(magic)) + { + Console.WriteLine($"Linear executable found. No parsing currently available."); + Console.WriteLine(); + return; + } + + // Portable Executable + else if (IsPE(magic)) + { + stream.Seek(0, SeekOrigin.Begin); + var portableExecutable = PortableExecutable.Create(stream); + if (portableExecutable == null) + { + Console.WriteLine("Something went wrong parsing Portable Executable"); + Console.WriteLine(); + return; + } + + // Print the executable info to screen + portableExecutable.Print(); + } + + // Unknown + else + { + Console.WriteLine($"Unrecognized header signature: {BitConverter.ToString(magic).Replace("-", string.Empty)}"); + Console.WriteLine(); + return; + } + } + } + + /// + /// Determine if the magic bytes indicate an MS-DOS executable + /// + private static bool IsMSDOS(byte[] magic) + { + if (magic == null || magic.Length < 2) + return false; + + return magic[0] == 'M' && magic[1] == 'Z'; + } + + /// + /// Determine if the magic bytes indicate a New Executable + /// + private static bool IsNE(byte[] magic) + { + if (magic == null || magic.Length < 2) + return false; + + return magic[0] == 'N' && magic[1] == 'E'; + } + + /// + /// Determine if the magic bytes indicate a Linear Executable + /// + private static bool IsLE(byte[] magic) + { + if (magic == null || magic.Length < 2) + return false; + + return magic[0] == 'L' && (magic[1] == 'E' || magic[1] == 'X'); + } + + /// + /// Determine if the magic bytes indicate a Portable Executable + /// + private static bool IsPE(byte[] magic) + { + if (magic == null || magic.Length < 4) + return false; + + return magic[0] == 'P' && magic[1] == 'E' && magic[2] == '\0' && magic[3] == '\0'; + } } } \ No newline at end of file