Live data from Hacker News

Writing a Self-Mutating x86_64 C Program (2013)

shanetully.com

31–40 of 61 posts

Re: Writing a Self-Mutating x86_64 C Program (2013)

#31
post #26

I was on board until `PROT_READ | PROT_WRITE | PROT_EXEC`

I mean, how else are you going to write self-modifying code? It's kind of implicit in the name of the thing that it's going to need to at a minimum have write and exec permission, and read is kind of important to make sure you're actually modifying the right stuff. Yes it's a terrible idea to have write and execute permissions on the same piece of memory, but that's part of why literally the very first line of the article says it's a terrible idea to write self-mutating code.

Re: Writing a Self-Mutating x86_64 C Program (2013)

#32
post #16
post #13

Earlier quoted context omitted.

Sometimes they will also make small changes to code that was generated earlier, typically by changing a branch instruction to point somewhere else. Dynamic linkers may do that, too, though glibc doesn't normally do it, as far as I know: it prefers to update a pointer to code: same result without needing memory that is both writable and executable and without having to invalidate the instruction cache.

From my delve into such things, in Linux at least the linker is a binary called before the program runs, so its a separate program potentially modifying the code. Interesting philosophical question whether that's still self modifying though.

I appear to be getting downvoted.

Assuming its because you think I'm wrong about the separate program. Look up the manpage for ld.so .

If you run the strings program on a dynamically linked program the first thing it spits out should be the path to ld.so

If you run that program without arguments, it even gives you a usage message.

Re: Writing a Self-Mutating x86_64 C Program (2013)

#33
post #12

Earlier quoted context omitted.

> Are there any languages that could actually make use of self modifying code? Kernel livepatching (and by that ftrace) would come to mind.

Would they not just write a new patched page, and swap out the original? Seems less error prone?

As I understand it they make the compiler add a few noops in the beginning of each non-static function.

Then to add tracing or change the behavior of the function, the noops are overwritten by a jump to the new code.

Re: Writing a Self-Mutating x86_64 C Program (2013)

#34
post #29

I once read about a clever use of self-modifying x86 code. The 8086 and 8088 are nearly identical chips, with the difference being that the 8086 has 16-bit I/O and the 8088 has 8-bit. The only way for a program to know which chip it's running on is to write a bit of self modifying code that takes advantage of this difference in I/O size. Both chips use prefetch, but they prefetch words, not bytes, and 8086 words are…

I think you probably read it in Dr Dobbs: http://www.drdobbs.com/embedded-systems/processor-detection-... Not exactly what you described, but very similar: "Differentiating between 8088s and 8086s is trickier. The easiest way I've found to do it is to modify code that's five bytes ahead of IP. Since the prefetch queue of an 8088 is four bytes and the prefetch queue of an 8086 is six bytes, an instruction five bytes a…

Interesting! Does this effect work on modern CPU? I'd imagine that if CPU modifies memory which was consumed by prefetcher, it should reset and reread everything or something like this.

Re: Writing a Self-Mutating x86_64 C Program (2013)

#39
post #12

Earlier quoted context omitted.

> Are there any languages that could actually make use of self modifying code? Kernel livepatching (and by that ftrace) would come to mind.

Would they not just write a new patched page, and swap out the original? Seems less error prone?

It's almost always a better idea to create something new, verify it was created successfully, do any syncing, switchover, optionally re-check for correct syncing, and then delete or take down original. That's pretty much how robust clustering works.

Re: Writing a Self-Mutating x86_64 C Program (2013)

#40

Earlier quoted context omitted.

The real issue with self-modifying code is that it's basically a security bug waiting to happen, plus you have other complications like having to flush the instruction cache on architectures like ARM. Generally, the benefits are not worth it unless except for very specific cases.

I've seen points like these made before, but never really understood how. Can you give an example of self-modifying code becoming a security issue?

There's a security feature called W^X [0] (also called DEP in Windows). Basically you can use special mode which prevents memory pages to be writeable and executable at the same time, so self-modifying code is not allowed, but it prevents exploits from modifying memory containing executable code. OpenBSD uses it as well.

0: https://en.wikipedia.org/wiki/W%5EX

Post reply on HN