using System;
using System.Runtime.InteropServices;
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate uint Ret1ArgDelegate(uint arg1);
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize,
AllocationType flAllocationType, MemoryProtection flProtect);
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize,
FreeType freeType);
[Flags]
public enum AllocationType:uint
{
COMMIT=0x1000,
RESERVE=0x2000,
RESET=0x80000,
LARGE_PAGES=0x20000000,
PHYSICAL=0x400000,
TOP_DOWN=0x100000,
WRITE_WATCH=0x200000
}
[Flags]
public enum MemoryProtection:uint
{
EXECUTE=0x10,
EXECUTE_READ=0x20,
EXECUTE_READWRITE=0x40,
EXECUTE_WRITECOPY=0x80,
NOACCESS=0x01,
READONLY=0x02,
READWRITE=0x04,
WRITECOPY=0x08,
GUARD_Modifierflag=0x100,
NOCACHE_Modifierflag = 0x200,
WRITECOMBINE_Modifierflag = 0x400
}
[Flags]
public enum FreeType:uint
{
DECOMMIT = 0x4000,
RELEASE = 0x8000
}
public static byte[] asmBytesX86 = new byte[]
{
0x55, // push ebp
0x8B, 0xEC, // mov ebp, esp
0x8B, 0x45, 0x08, // mov eax, [ebp+8]
0xD1, 0xC8, // ror eax, 1
0x5D, // pop ebp
0xC3 // ret
};
public static byte[] asmBytesX64 = new byte[]
{
0x89, 0xC8, // mov rax, rcx
0xD1, 0xC8, // ror eax, 1
0xC3 // ret
};
static void Main(string[] args)
{
byte[] asmBytes = (IntPtr.Size == 4)?asmBytesX86:asmBytesX64;
IntPtr executableMemory = VirtualAlloc(IntPtr.Zero, (UIntPtr) asmBytes.Length, AllocationType.COMMIT, MemoryProtection.EXECUTE_READWRITE);
Marshal.Copy(asmBytes, 0, executableMemory, asmBytes.Length);
Ret1ArgDelegate del = (Ret1ArgDelegate) Marshal.GetDelegateForFunctionPointer (executableMemory, typeof(Ret1ArgDelegate));
uint n = (uint)0xFFFFFFFC;
n = del(n);
Console.WriteLine("{0:x}", n);
VirtualFree(executableMemory, UIntPtr.Zero, FreeType.DECOMMIT);
}
}