Sure, you can employ a simple scheme where you write stuff in another part of the OS (like registry in Windows) and then rely on goodwill of your potential clients they will register your demo. But such a scheme is easy to abuse. So how about one that's a bit harder like having a self-modifying demo that will write stuff onto itself and check themselves to stop running after 30 days. Bonus points if your demo also has some database that is hosted inside the executable so it has legit reasons for doing the self-modifying bit. Even with a debugger attached you made to eventual cracker life 100 times harder. Sure, anything can be cracked but it's all about your hours vs cracker hours in the end.
> Cosmopolitan Libc makes C a build-once run-anywhere language, like Java, except it doesn't need an interpreter or virtual machine. Instead, it reconfigures stock GCC and Clang to output a POSIX-approved polyglot format that runs natively on Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS with the best possible performance and the tiniest footprint imaginable.
> Please note that your APE binary will assimilate itself as a conventional resident of your platform after the first run, so it can be fast and efficient for subsequent executions.
We have an internal CLI for our developers that auto-updates itself by replacing the binary on-disk. The auto-update bit only runs when the developer uses our CLI, and at most once every 24 hour. If an update is triggered, it prints out a message saying it was updated and asks the developer to re-run the command.
The upshot is we didn't have to write and distribute a second application to handle auto-updates as a background daemon, and we can be reasonably confident anybody using our CLI is +/- one version.
If for some reason it leaves the binary in a bad state, devs can still install over it with homebrew, or downloading from the releases page - haven't had to do that though in the 2 years we've had it.
https://engineering.backtrace.io/2021-12-19-bounded-dynamici...
This is basically to make it zero cost (as far as I remember)
Google uses a similar system of feature flags, but as far as I know there's no self-modifying code. I guess Backtrace wants to put the flags in tight inner loops.
dtrace and I believe systemtap patch the executable at runtime, for similar performance reasons. But those are kernel features and not user applications.
----
One example:
My understanding is that static initialization in C/C++ is sometimes done with self-modifying code.
Eg:
ExpensiveObject &getInstance() {
static ExpensiveObject obj;
return obj;
}
So, the first time through, the generated assembly would run some "if object is not initialized, run the constructor" conditional code. Then, it would rewrite itself to not do that check for subsequent calls.Obviously, that's all in the "hidden behind the scenes" generated assembly code, and the rust compiler could pull similar tricks, but you might also want to allow client code to do such things, for extreme performance cases.
You can see example here: https://godbolt.org/z/7f1qbh5r5
There are no code modifications - all compiler generated is extra byte check ("if" statement) and then acquire/release lock around constructor to be threadsafe.
I guess it's not commonplace these days, but it is still allowed, it seems. I feel like my initial run-in with the concept was on some embedded systems stuff long ago, so maybe that was a more esoteric compiler.
https://elixir.bootlin.com/linux/latest/source/include/linux...
> A metamorphic virus is a type of malware that is capable of changing its code and signature patterns with each iteration. [1]
[1] https://www.techtarget.com/searchsecurity/definition/Metamor...
DOS (And even Windows now) runs a line from a batch file, and the re-opens the file to read the next line. Makes it super easy to edit files that are running, and even easier back in the days of DOS when you had edlin to help you do the editing.
My script would store state, options, journal entries, and other things I've long forgotten about in itself. Of course, it all came to a crashing halt when it managed to destroy itself.
For instance, you wrote the code to XOR a line to the screen. Maybe you also want an AND version and a OR version, but you don't want to pay the cost of having an "if" in the middle of the loop that checks what kind of operation you want to do. You also don't want to ship 3 nearly identical versions of the code, so you ship one version and patch it at runtime.
Obviously this has a lot of downsides but it's quite intriguing to have an executable with an embedded config.
I seriously question why you ever want to do this in any language except as a research effort. (for all practical purposes)
If anyone has any real applications I would like to be enlightened. Writing an interpreter, hoping to sandbox it, executing it with modifying code with it does not count, only modifying the original program as is.