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!