Executable memory

Adam D. Ruppe destructionator at gmail.com
Fri Oct 4 15:00:35 PDT 2013


I'm just playing at this point and I'm pretty sure these hacks 
won't quite work or might even be kinda useless... but one way to 
avoid the hassle of making the machine code yourself is to get 
the compiler to do it.

So we'll write our function (just 32 bit here, the 64 bit didn't 
work and I'm not sure why, could be because of this 
http://stackoverflow.com/a/6313264/1457000 ) in D then copy it 
into the magic memory:

void sayHello() {
	asm {
		naked;
	}
	static immutable hello = "hello!\n";
	auto sptr = hello.ptr;
	auto slen = hello.length;
	version(D_InlineAsm_X86)
	asm { // 32 bit
		mov ECX, sptr;
		mov EDX, slen;
		mov EBX, 1; // stdout
		mov EAX, 4; // sys_write
		int 0x80;
	}

	asm {
		ret;
	}
}
void sayHelloEnd(){} // I'm using this with the assumption that 
the two functions will be right next to each other in memory, 
thus sayHello's code goes from &sayHello .. &sayHelloEnd. idk if 
that is really true but it seems to work for me

import core.sys.posix.sys.mman;

void main()
{
        // NOTE: you did uint* before, now i'm doing ubyte* since 
we're really working in bytes, not ints
         ubyte[] opcodes = (cast(ubyte*) mmap(null, 4096, 
PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0))[0 .. 4096];
	assert(opcodes !is null);
	scope(exit)
		munmap(opcodes.ptr, 4096);

        // copy the code from our sayHello function that dmd 
compiled for us into the executable memory area
	auto f = cast(ubyte*) &sayHello;
	auto fe = cast(ubyte*) &sayHelloEnd;
	auto len = fe - f;
	import std.stdio;
	writeln("length: ", len); // shouldn't be very large
         opcodes[0 .. len] = f[0 .. len]; // copy it over
         void* function() func = cast(void* function()) opcodes;
         func(); // and run it

	writeln("ending function normally!");

       // then write over it to prove we still can...
	opcodes[0] = 0xcc;
	func(); // this should trap
}




Perhaps you could string together a bunch of little functions 
written in D and inline asm to build your executable code most 
easily using tricks like this. Assuming it continues to work in 
more complex situations!


More information about the Digitalmars-d-learn mailing list