Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Is this valid C code?

Name: Anonymous 2017-01-02 2:13

char x [5] = { 0xf0, 0x0f, 0xc7, 0xc8 };

main ()
{
void (*f)() = x;
f();
}


Found this on the Everything2 page for the Pentium F00F bug. My question is essentially whether it is indeed valid to write machine code subroutines as byte arrays and call them via a function pointer. Does the Standard have anything to say about this? And is executing code in the data segment even possible on modern architectures?

Name: Anonymous 2017-01-02 14:59

>>1
I'm not sure if C standard even considers the option of writing pure machine code as a char* and then treating the address as a function pointer, but having such an array act like a function written in machine code is a sane option - after all, you just allocate bytes and move your instruction pointer to their address.

as for whether it's possible to run code from the data section - it is because the processor does not know anything about data sections, it's a feature of executable file formats. what the processor knows is whether the area of memory is executable or not, and while stuff placed in data section will get marked as non-exectuable when running a binary, you can change that with syscalls (mprotect() on posix, VirtualProtect() on windows).

so the specific code in your example will probably segfault (disregard segfaults or sigills that will happen later due to lack of return instruction as it will attempt to execute junk data after f00f fails to cause a hardware error on a modern CPU) unless the compiler recognizes the construct and acts accordingly, but you can make it work with a single line of code.

>>4
what about this is gcc-specific? it's probably undefined but the most straightforward behavior for any compiler would be to invoke a call or equivalent instruction on the array address (because array = pointer)

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List