views:

251

answers:

4

I have a compiler which compiles assembly language to machine language (in memory). My project is in c# .net. Is there any way to run the memory on a thread? How can DEP prevent it?

byte[] a:
01010101 10111010 00111010 10101011 ...

+2  A: 

I doubt there's a supported way. I don't know and haven't researched it, but here are some guesses:

The easiest way might be to launch it as a process: write it into a *.com file and then tell the O/S to run that executable.

Alternatively, pass the memory as a parameter to the CreateThread function (but you'll need to wrorry about the code having the right calling conventions, expecting the specified parameters, preserving registers, and being in memory which is executable).

Another possibility is to write the opcodes into memory which is know is already going to be executed (e.g. overwrite existing code in a recently-loaded DLL).

ChrisW
A `.com` file is restricted to 16-bit DOS code, and while this may be sufficient for some purposes, it is not a general solution. It incurs the cost of loading NTVDM to execute the 16-bit code.
Greg Hewgill
JulianR's answer looks good.
ChrisW
+1  A: 

You can whitelist your application from the control panel http://ask-leo.com/how%5Fdo%5Fi%5Fturn%5Foff%5Fdata%5Fexecution%5Fprevention%5Ferrors.html

I doubt you can whitelist it programattically, but certainly not without admin access - that would defeat the purpose of this security feature.

Drew Hoskins
+3  A: 

It's possible to execute bytes as code:

Inline x86 ASM in C#

It does require the use of unsafe code.

I thought that this was just a fun fact but useless in practice, but perhaps your application actually has a use for this :)

JulianR
Not recommended - is not supported in x64 applications.
Danny Varod
In what way not? Is it inherently broken, or just that the example is not very portable?
JulianR
Microsoft's C++ compiler just never did the work to support it for 64-bit. By the time 64-bit became popular, it just wasn't as important to people to program in assembly as it had been.
Drew Hoskins
i wish i could vote twice.
Behrooz
+6  A: 

The key is to put the executable code into a block of memory allocated with VirtualAlloc such that the buffer is marked as executable.

IntPtr pExecutableBuffer = VirtualAlloc(
  IntPtr.Zero,
  new IntPtr(byteCount),
  AllocationType.MEM_COMMIT | AllocationType.MEM_RESERVE,
  MemoryProtection.PAGE_EXECUTE_READWRITE);

(then use VirtualFree to clean up after yourself).

This tells Windows that the memory should be marked as executable code so that it won't trigger a DEP check.

homeInAStar
+1 Probably less hacky than my method :p
JulianR