Executable memory

Alan alanpotteiger at gmail.com
Fri Oct 4 15:12:43 PDT 2013


On Friday, 4 October 2013 at 22:00:36 UTC, Adam D. Ruppe wrote:
> 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!

Hmm interesting... I'll have to work with it some! I get a 
segmentation fault with this code though :| It outputs:
length: 24
Segmentation fault (core dumped)

Thanks for the help though!


More information about the Digitalmars-d-learn mailing list