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!

Reply via email to