using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
// Get some methods generated...
Func<object, int> getAddress = Get_GetAddress_Method();
Func<int, byte[]> getData = Get_ObjectAtAddress_Method<byte[]>();
const string greeting = "Hello";
// Print the greeting
Console.WriteLine(greeting);
// Get the address of the "Hello" string
int x = getAddress(greeting);
// Get a byte array on the same location
byte[] data = getData(x);
// Change some data...
SetString("Bye!!", data);
// And display the greeting again (remember, strings are immutable...)
Console.WriteLine(greeting);
// And just to show it against other bits of the framework...
Console.WriteLine(Assembly.GetExecutingAssembly().FullName);
SetString("Hacked!", getData(getAddress(Assembly.GetExecutingAssembly().FullName)));
Console.WriteLine(Assembly.GetExecutingAssembly().FullName);
}
/// <summary>
/// Return a method that gives the memory address of any object
/// </summary>
static Func<object, int> Get_GetAddress_Method()
{
DynamicMethod d = new DynamicMethod("", typeof (int), new Type[] {typeof (Object)},
Assembly.GetExecutingAssembly().ManifestModule);
ILGenerator ilGen = d.GetILGenerator();
ilGen.Emit(OpCodes.Ldarg_0); // Load arg_0 onto the stack (of type object)
ilGen.Emit(OpCodes.Ret); // And return - note that the return type is an int...
return (Func<object, int>)d.CreateDelegate(typeof(Func<object, int>));
}
/// <summary>
/// Return a method that "maps" any type to a particular memory location
/// </summary>
static Func<int, T> Get_ObjectAtAddress_Method<T>()
{
DynamicMethod d = new DynamicMethod("", typeof (T), new Type[] {typeof (int)},
Assembly.GetExecutingAssembly().ManifestModule);
ILGenerator ilGen = d.GetILGenerator();
ilGen.Emit(OpCodes.Ldarg_0); // Load arg_0 onto the stack (of type int)
ilGen.Emit(OpCodes.Ret); // And return - note that the return type is T
return (Func<int, T>)d.CreateDelegate(typeof(Func<int, T>));
}
/// <summary>
/// Little helper method to copy a string into a byte[]
/// </summary>
static void SetString(string requiredString, byte[] dest)
{
UnicodeEncoding encoder = new UnicodeEncoding();
byte[] requiredBytes = encoder.GetBytes(requiredString);
// Need to do the copy by hand, since Array.Copy bleats
// about the dimensions of the destination. No surprise really,
// since the destination isn't really an array...
for (int i = 0; i < requiredBytes.Length; i++)
{
dest[i] = requiredBytes[i];
}
}
}
}