[HN Gopher] Writing a Self-Mutating x86_64 C Program (2013)
___________________________________________________________________
Writing a Self-Mutating x86_64 C Program (2013)
Author : kepler471
Score : 62 points
Date : 2025-05-25 17:00 UTC (6 hours ago)
(HTM) web link (ephemeral.cx)
(TXT) w3m dump (ephemeral.cx)
| belter wrote:
| I guess in OpenBSD because of W ^ X this would not work?
| akdas wrote:
| I was thinking the same thing. Usually, you'd want to write the
| new code to a page that you mark as read and write, then switch
| that page to read and execute. This becomes tricky if the code
| that's doing the modifying is in the same page as the code
| being modified.
| timewizard wrote:
| The way it's coded it wouldn't; however, you can map the same
| shared memory twice. Once with R|W and a second time with R|X.
| Then you can write into one region and execute out of it's
| mirrored mapping.
| rkeene2 wrote:
| In Linux it also needs mprotect() to change the permissions on
| the page so it can write it. The OpenBSD man page[0] indicate
| that it supports this as well, though notes that not all
| implementations are guaranteed to allow it, but my guess is it
| would generally work.
|
| [0] https://man.openbsd.org/mprotect.2
| Retr0id wrote:
| It's not _required_ on linux, if the ELF headers are set up
| such that the page is mapped rwx to begin with. (but rwx
| mappings are generally frowned upon from a security
| perspective)
| mananaysiempre wrote:
| Not as is, but I think OpenBSD permits you to map the same
| memory twice, once as W and once as X (which would be a
| reasonable hoop to jump through for JITs etc., except there's
| no portable way to do it). ARM64 MacOS doesn't even permit
| that, and you need to use OS-specific incantations[1] that
| essentially prohibit two JITs coexisting in the same process.
|
| [1] https://developer.apple.com/documentation/apple-
| silicon/port...
| alcover wrote:
| I often think this could maybe allow fantastic runtime
| optimisations. I realise this would be hardly debuggable but
| still..
| Retr0id wrote:
| It already does, in the form of JIT compilation.
| alcover wrote:
| OK but I meant in already native code, like in a C program -
| no bytecode.
| Retr0id wrote:
| I mean that, too.
| connicpu wrote:
| LuaJIT has a wonderful dynamic code generation system in
| the form of the DynASM[1] library. You can use it
| separately from LuaJIT for dynamic runtime code generation
| to create machine code optimized for a particular problem.
|
| [1]: https://luajit.org/dynasm.html
| vbezhenar wrote:
| I used GNU lightning library once for such optimisation. I
| think it was ICFPC 2006 task. I had to write an interpreter for
| virtual machine. Naive approach worked but was slow, so I
| decided to speed it up a bit using JIT. It wasn't a 100% JIT, I
| think I just implemented it for loops but it was enough to
| tremendously speed it up.
| userbinator wrote:
| Programs from the 80s-90s are likely to have such tricks. I
| have done something similar to "hardcode" semi-constants like
| frame sizes and quantisers in critical loops related to audio
| and video decompression, and the performance gain is indeed
| measurable.
| alcover wrote:
| > "hardcode" semi-constants
|
| You mean you somehow avoided a _load_. But what if the
| constant was already placed in a register ? Also how could
| you pinpoint the reference to your constant in the machine
| code ? I 'm quite profane about all this.
| ronsor wrote:
| > Also how could you pinpoint the reference to your
| constant in the machine code?
|
| Not OP, but often one uses an easily identifiable dummy
| pattern like 0xC0DECA57 or 0xDEADBEEF which can be
| substituted without also messing up the machine code.
| mananaysiempre wrote:
| If you're willing to parse object files (a much easier
| proposition for ELF than for just about anything else),
| another option is to have the source code mention the
| constants as addresses of external symbols, then parse
| the relocations in the compiled object. Unfortunately,
| I've been unable to figure out a reliable recipe to get a
| C compiler to emit absolute relocations in position-
| independent code, even after restricting myself to GCC
| and Clang for x86 Linux; in some configurations it works
| and in others you (rather pointlessly) get a PC-relative
| one followed by an add.
| userbinator wrote:
| All the registers were already taken.
|
| You use a label.
| oxcabe wrote:
| It's impressive how well laid out the content in this article is.
| The spacing, tables, and code segments all look pristine to me,
| which is especially helpful given how dense and technical the
| content is.
| ivanjermakov wrote:
| I had a great experience writing self modified programs is a
| single instruction programming game SIC-1:
| https://store.steampowered.com/app/2124440/SIC1/
___________________________________________________________________
(page generated 2025-05-25 23:00 UTC)