Skip to content

Instantly share code, notes, and snippets.

@nasser
Created May 17, 2018 20:33
Show Gist options
  • Save nasser/cad2dc96c4d1398271d259cb887d3db4 to your computer and use it in GitHub Desktop.
Save nasser/cad2dc96c4d1398271d259cb887d3db4 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <glib.h>
#include <mono/metadata/image.h>
#include <mono/metadata/verify.h>
#include <mono/metadata/class.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/object.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/tokentype.h>
#include <dis/get.h>
// for monodis
gboolean substitute_with_mscorlib_p = FALSE;
static char*
token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token)
{
// // ERROR_DECL (error);
// char *res, *desc;
// MonoClassField *field;
// gpointer data = NULL;
MonoClass *klass;
MonoImage* image = mono_class_get_image( mono_method_get_class( method ));
guint32 tokencode = mono_metadata_token_code(token);
MonoMethod *cmethod;
MonoClassField* field;
MonoClass *retklass;
MonoMethodDesc* mdesc;
MonoMethodSignature* sig;
return get_token(image, token, NULL);
}
// * disasm_ins:
// *
// * Produce a disassembled form of the IL instruction at IP. This is an extension
// * of mono_disasm_code_one () which can disasm tokens, handle wrapper methods, and
// * CEE_MONO_ opcodes.
FILE *output;
void
disasm_ins (MonoMethod *method)
{
output = stdout;
init_key_table ();
char *dis;
MonoDisHelper dh;
MonoMethodHeader *header = mono_method_get_header (method);
// printf("%s:", mono_method_full_name(method, TRUE));
memset (&dh, 0, sizeof (dh));
dh.newline = "\n";
dh.label_format = "IL_%04x: ";
dh.label_target = "IL_%04x";
dh.tokener = token_handler;
const unsigned char* header_code;
uint32_t header_size;
header_code = mono_method_header_get_code(header, &header_size, NULL);
char* il_code = mono_disasm_code(&dh, method, header_code, header_code + header_size);
printf("\n%s", il_code);
}
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
public static class Illness
{
[DllImport ("libillness.so", EntryPoint="disasm_ins")]
internal static extern void DisassembleMethodIL2(IntPtr m);
internal static Type GetInternalType(string name)
{
foreach(var a in AppDomain.CurrentDomain.GetAssemblies())
{
var t = a.GetType(name);
if (t != null)
return t;
}
return null;
}
static FieldInfo monoMethodMhandleField =
Illness.GetInternalType("System.Reflection.MonoMethod").
GetField("mhandle", BindingFlags.NonPublic |
BindingFlags.Instance);
static FieldInfo dynamicMethodMhandleField =
typeof(DynamicMethod).
GetField("mhandle", BindingFlags.NonPublic |
BindingFlags.Instance);
static IntPtr GetNativePtr(MethodInfo m)
{
if(m is DynamicMethod)
{
var rmh = (RuntimeMethodHandle)dynamicMethodMhandleField.GetValue(m);
if(rmh.Value == IntPtr.Zero)
throw new Exception(string.Format("DynamicMethod {0} has not been compiled. Call CreateDelegate first.", m));
return rmh.Value;
}
else
{
return (IntPtr)monoMethodMhandleField.GetValue(m);
}
}
public static void DisassembleIl2(MethodInfo m)
{
IntPtr mhandle = GetNativePtr(m);
DisassembleMethodIL2(mhandle);
}
}
using System;
using System.Numerics;
public static class Program
{
public static Vector3 AddVectors(Vector3 a, Vector3 b) {
return a + b;
}
public static void Main(string[] args)
{
Illness.DisassembleIl2(typeof(Program).GetMethod("AddVectors"));
}
}
☭ mono Program.exe
mono_os_mutex_lock: pthread_mutex_lock failed with "Invalid argument" (22)
Stacktrace:
at <unknown> <0xffffffff>
at (wrapper managed-to-native) Illness.DisassembleMethodIL2 (intptr) [0x00002] in <6ec805cea31a4daa82ad7343f5670119>:0
at Illness.DisassembleIl2 (System.Reflection.MethodInfo) [0x00007] in <6ec805cea31a4daa82ad7343f5670119>:0
at Program.Main (string[]) [0x00026] in <702b57b0c75f465fbe1b40244ca86772>:0
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) [0x0004e] in <702b57b0c75f465fbe1b40244ca86772>:0
Native stacktrace:
0 mono 0x0000000104132a28 mono_handle_native_crash + 264
1 libsystem_platform.dylib 0x00007fffe8cc3b3a _sigtramp + 26
2 ??? 0x0000000000000003 0x0 + 3
3 libsystem_c.dylib 0x00007fffe8b48420 abort + 129
4 libmonosgen-2.0.1.dylib 0x00000001081e5939 monoeg_log_default_handler + 105
5 libmonosgen-2.0.1.dylib 0x00000001081e5a0e monoeg_g_log + 206
6 libmonosgen-2.0.1.dylib 0x000000010807c96f mono_assembly_load_reference + 1247
7 libmonosgen-2.0.1.dylib 0x000000010808305d mono_class_from_typeref_checked + 717
8 libmonosgen-2.0.1.dylib 0x00000001080c2bf0 method_from_memberref + 224
9 libmonosgen-2.0.1.dylib 0x00000001080c1073 mono_get_method_checked + 723
10 libmonosgen-2.0.1.dylib 0x00000001080c1437 mono_get_method_full + 23
11 libillness.so 0x00000001047821ef get_method_core + 63
12 libillness.so 0x0000000104783154 get_token + 500
13 libmonosgen-2.0.1.dylib 0x000000010809f8f6 dis_one + 278
14 libmonosgen-2.0.1.dylib 0x000000010809fc84 mono_disasm_code + 84
15 libillness.so 0x000000010477df4f disasm_ins + 159
16 ??? 0x0000000104621e3d 0x0 + 4368506429
17 mono 0x0000000104087117 mono_jit_runtime_invoke + 1383
18 mono 0x000000010427fbb4 do_runtime_invoke + 84
19 mono 0x0000000104283179 do_exec_main_checked + 137
20 mono 0x00000001040f493f mono_jit_exec + 287
21 mono 0x00000001040f78bd mono_main + 11069
22 mono 0x0000000104076acd main + 253
23 mono 0x00000001040769c4 start + 52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment