Skip to content

Instantly share code, notes, and snippets.

@vizv
Created October 4, 2018 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vizv/0423e37a7f2e2a2068ba78cbb6c86220 to your computer and use it in GitHub Desktop.
Save vizv/0423e37a7f2e2a2068ba78cbb6c86220 to your computer and use it in GitHub Desktop.
DumpAssembly module with example
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace DumpAssembly
{
class Loader
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MonoImage
{
public int refCount;
public IntPtr rawDataHandle;
public IntPtr rawData;
public int rawDataLen;
}
[DllImport("mono.dll", EntryPoint = "mono_image_open_from_data_with_name", CharSet = CharSet.Ansi)]
internal static extern IntPtr MonoOpenImage(
IntPtr data,
uint dataLen,
bool needCopy,
IntPtr status,
bool refOnly,
string name
);
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllPath);
public static byte[] Load(string monoPath, string assemblyPath)
{
IntPtr pData = IntPtr.Zero;
try
{
// prepare raw assembly data for native method call
byte[] assemblyData = File.ReadAllBytes(assemblyPath);
pData = Marshal.AllocHGlobal(assemblyData.Length);
Marshal.Copy(assemblyData, 0, pData, assemblyData.Length);
// load mono library and open the assembly
LoadLibrary(monoPath);
var pImage = MonoOpenImage(pData, (uint)assemblyData.Length, false, IntPtr.Zero, false, assemblyPath);
MonoImage loadedImage = (MonoImage)Marshal.PtrToStructure(pImage, typeof(MonoImage));
// dump the decoded assembly
byte[] dumpedData = new byte[loadedImage.rawDataLen];
Marshal.Copy(loadedImage.rawData, dumpedData, 0, loadedImage.rawDataLen);
return dumpedData;
}
finally
{
if (pData != IntPtr.Zero) Marshal.FreeHGlobal(pData);
}
// or throw error
}
}
}
using System;
using System.IO;
namespace DumpAssembly
{
class Program
{
static void Main(string[] args)
{
string monoPath;
string assemblyPath;
switch(args.Length)
{
case 0:
monoPath = @"Mono\EmbedRuntime\mono.dll";
string[] matches = Directory.GetFiles(
Directory.GetCurrentDirectory(),
"Assembly-CSharp.dll",
SearchOption.AllDirectories
);
if (matches.Length != 1) goto default;
assemblyPath = matches[0];
break;
case 2:
monoPath = args[0];
assemblyPath = args[1];
break;
default:
Console.WriteLine("Usage: DumpAssembly.exe [MONO_DLL_PATH] [ASSEMBLY_PATH]");
return;
}
Console.WriteLine(string.Format("mono.dll: {0}", monoPath));
Console.WriteLine(string.Format("Assembly-CSharp.dll: {0}", assemblyPath));
var dumpedData = Loader.Load(monoPath, assemblyPath);
File.WriteAllBytes(@"Dumped-Assembly-CSharp.dll", dumpedData);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment