Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting code into executable at runtime

I'm working on application (written in C++), which generate some machine code at runtime (Linux, x86-64 now, but I plan to migrate on ARM). Next it store generated code in memory and execute it by jumping to memory location. For a long time I had a problem with allocating executable memory, but I finally solved it using:

uint8_t *memory = mmap (NULL, length, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

So far it works, but I'm not sure if it's elegant way to do such things. I wonder how executable loader do this?

like image 937
Goofy Avatar asked Jun 03 '11 19:06

Goofy


2 Answers

Your solution is mostly what should be done: have the OS consider the pages as executable. However, some operating systems will enforce the so-called W^X policy, in which a page can be either writable or executable, but not both simultaneously. For such systems (namely OpenBSD, but there are modified Linux versions which do it too), your mmap() above will fail. So the complete solution would entail first allocating some pages with mmap() and PROT_READ | PROT_WRITE, then use mprotect() to switch the pages to PROT_READ | PROT_EXEC when the code has been generated.

Even if the OS does not enforce W^X, a call to mprotect() is highly recommended because of cache effects (data access and execution are quite separate from each other in the CPU; you want to be sure that the CPU will use your newly written opcodes and not what was in RAM immediately before; mprotect() contains the necessary magic for that).

like image 186
Thomas Pornin Avatar answered Nov 05 '22 01:11

Thomas Pornin


This is essentially how executable loaders do things; in their case they perform a mmap of a file, not an anonymous mapping, but apart from that it's essentially the same.

Note that it's a good idea not to have both write and execute access at the same time, as it makes certain types of security exploits easier. You can use mprotect to adjust the protection flags after the initial mapping.

like image 13
bdonlan Avatar answered Nov 05 '22 00:11

bdonlan