Skip to content

Instantly share code, notes, and snippets.

@Joe-K-Sewell
Created September 8, 2018 02:27
Show Gist options
  • Save Joe-K-Sewell/16bcb6ae63651acbc4ccc8ff122a94fc to your computer and use it in GitHub Desktop.
Save Joe-K-Sewell/16bcb6ae63651acbc4ccc8ff122a94fc to your computer and use it in GitHub Desktop.
Get the kind of assembly using System.Reflection.Metadata
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Reflection.Emit;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace SoCSharp
{
class Program
{
static void Main(string[] args)
{
try
{
foreach (PEFileKinds kind in Enum.GetValues(typeof(PEFileKinds)))
{
var program = new Program(kind);
program.WriteWithSREmit();
program.ReadWithSRMetadata();
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex);
}
}
private readonly PEFileKinds peFileKind;
private readonly string filename, extension, filenameAndExtension;
private Program(PEFileKinds kind)
{
switch (kind)
{
case PEFileKinds.Dll:
filename = "Library";
extension = ".dll";
break;
case PEFileKinds.ConsoleApplication:
filename = "ConsoleApp";
extension = ".exe";
break;
case PEFileKinds.WindowApplication:
filename = "WindowsApp";
extension = ".exe";
break;
default:
throw new NotImplementedException();
}
peFileKind = kind;
filenameAndExtension = filename + extension;
}
private void WriteWithSREmit()
{
Console.WriteLine($"Writing {filenameAndExtension} with System.Reflection.Emit");
Console.WriteLine($" Kind: {peFileKind}");
var asmName = new AssemblyName(filename);
var asm = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save);
var mod = asm.DefineDynamicModule(filenameAndExtension);
var type = mod.DefineType("MyType", TypeAttributes.Public);
var method = type.DefineMethod("EntryPoint", MethodAttributes.Public | MethodAttributes.Static);
var methodIL = method.GetILGenerator();
methodIL.Emit(OpCodes.Ret);
type.CreateType();
asm.SetEntryPoint(method, peFileKind);
asm.Save(filenameAndExtension, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
}
private void ReadWithSRMetadata()
{
using (var stream = File.OpenRead(filenameAndExtension))
{
using (var peFile = new PEReader(stream))
{
var headers = peFile.PEHeaders;
Console.WriteLine($"Reading {filenameAndExtension} with System.Reflection.Metadata");
Console.WriteLine($" IsDll: {headers.IsDll}");
Console.WriteLine($" IsExe: {headers.IsExe}");
Console.WriteLine($" IsConsoleApplication: {headers.IsConsoleApplication}");
PEFileKinds reverseEngineeredKind;
// NOTE: the header values cause IsConsoleApplication to return
// true for DLLs, so we need to check IsDll first
if (headers.IsDll)
{
reverseEngineeredKind = PEFileKinds.Dll;
}
else if (headers.IsConsoleApplication)
{
reverseEngineeredKind = PEFileKinds.ConsoleApplication;
}
else
{
reverseEngineeredKind = PEFileKinds.WindowApplication;
}
Console.WriteLine($" Reverse-engineered kind: {reverseEngineeredKind}");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment