开发者

Injecting code into executable at runtime

开发者 https://www.devze.com 2023-03-10 12:24 出处:网络
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 ju

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 wond开发者_StackOverflow社区er how executable loader do this?


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).


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消