1

I have a byte[] that contains bytes that represents a method in assembly. For example a simple mov eax,1 - retn function:

var method = new byte[] { 0xB8,0x01,0x00,0x00,0x00,0xC3 };

Is it possible to create, in runtime, a method that I can call in C# using the byte array to create it?

Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47
  • You can pInvoke VirtualAlloc to allocate a pointer to your byte array then use Marshal.Copy to copy it to the Allocation Memory from VirtualAlloc. Then use Marshal.GetDelegateForFunctionPointer to get a delegate to the asm code. Then you can invoke the delegate. http://stackoverflow.com/questions/959087/is-it-possible-to-execute-an-x86-assembly-sequence-from-within-c – Ryan Mann Aug 26 '14 at 03:57
  • You don't need to convert your ASM to IL. .Net is a managed language, but once it's a running process the only difference between it and and a native process is it has the .net framework loaded. .Net JIT compiles the IL to X86 at runtime, once done, it's all x86 running on the processor it doesn't run as IL. That means at runtime, you can run a delegate to asm in a byte array just fine. In fact, you can inject the .Net framework into a native process and then load .Net dll's into it using the .Net C++ CLR headers. – Ryan Mann Aug 26 '14 at 03:59
  • @Ryios, by using Marshal.GetDelegateForFunctionPointer? – rufanov Aug 26 '14 at 04:08
  • The link I posted has an example, http://stackoverflow.com/questions/959087/is-it-possible-to-execute-an-x86-assembly-sequence-from-within-c – Ryan Mann Aug 26 '14 at 04:09
  • 1
    There are some gotchas though. If your asm accepts parameters you'll have to play around with different delegate signatures till you find one that maps right and works. In rare cases, it might be impossible and you'll need to adjust your asm to play nicer. E.g. if your asm returns an ascii string you need to use a byte array for the return value. If your method takes an 8 byte integer, use a ulong for the parameter, etc etc. If it returns a struct you'll need to write the struct in c# and use the LayoutKind and Pack attributes to get it's sizing to match up. – Ryan Mann Aug 26 '14 at 04:12
  • @Ryios, yes. it can be used. But with several oblivious restrictions: 1) you can't use anycpu assembly; 2) assembly target platform and bytecode platform must be same 2) for complicated code you must write simple x86 dissembler/assembler to correctly change offsets in all jumps/calls inside of bytecode. – rufanov Aug 26 '14 at 04:21
  • You can dynamically load two sets of x86 based on the platform. You can leave the target platform on AnyCpu, then use IntPtr.Size to determine what platform it is. If IntPtr is 4 bytes your on 32bit processor. if it's 8 bytes your on 64 bit processor. Load either the 32bit byte array or the 64 bit byte array pending on the platform. Then just make sure you use platform agnostic datatypes for the parameters/return from the x86 like IntPtr, uint ushort int short, etc. – Ryan Mann Aug 26 '14 at 04:58

1 Answers1

0

Yes, you can do it using Reflection Emit. But you should write logic that will read this byte array byte-by-byte and Emmit OpCodes that you need into ILGenerator.

It's really simple. First you create new DynamicMethod, call GetILGenerator from it, do series of "Emmit" calls from GetILGenerator, call CreateDelegate from DynamicMethod, and finally call the new method itself by calling this delegate.

Community
  • 1
  • 1
rufanov
  • 3,266
  • 1
  • 23
  • 41
  • Can you give me some example code on how to do this? I have to change asm code to IL code, is that right? I have no clue on how to do this, can you give more information? The function I want to do this is much more complex than a simple `return true;`, in this case. – Leandro Battochio Aug 26 '14 at 02:56
  • First can you describe what this byte array is? Why do you want to store some logic as byte array? Is this stream of this bytes are currently really don't have any specifications or it's something complicated like bytes from x86 application? – rufanov Aug 26 '14 at 03:08
  • I am working on a game and one of the encryption functions are sent from server to client as a byte array. This is one of them: http://pastebin.com/UjiZtMuS – Leandro Battochio Aug 26 '14 at 03:12
  • Leandro Battochio, it's seems like x86 assembly language from some disassembler. If you want to run it on top of .NET - you must rewrite this code to IL assembly language(just by writing app in any .NET lang and disassembling it latter using ILDasm). If not... Well you must write some native application/library(using C++ for example), that can load this bytes to own memory and call the code. .Net Framework can't execute x86 machine code, only IL. – rufanov Aug 26 '14 at 03:18
  • 1
    You don't have to convert the asm to ISL, see my comments under your answers. This has been answered before. – Ryan Mann Aug 26 '14 at 04:01
  • .Net can execute x86, it is x86. It's only IL on disk. .Net Dll's are stored in PE-Format like any other windows exe or dll with a special flag that says "Hey Im a .net assembly". When the windows loader is request to load a .Net assembly, it JIT's all the IL in it into the native language, on a pc that would be x86, then loads it. At that point it's a native process with special code called the .Net Framework running in it. – Ryan Mann Aug 26 '14 at 04:03