diff options
author | user <user@localhost.localdomain> | 2019-10-23 17:41:22 -0400 |
---|---|---|
committer | user <user@localhost.localdomain> | 2019-10-23 17:41:22 -0400 |
commit | d8f8cd5415b448e0969b39e9e0bad5d0350bdcae (patch) | |
tree | ab10cc6405f6b162678fbb807389c973a86e8fdb /starts/random-selfmod/random.cpp | |
parent | c7768947b3e8857479ed1d9dc2c39c8eaab70791 (diff) | |
download | standingwithresilience-d8f8cd5415b448e0969b39e9e0bad5d0350bdcae.tar.gz standingwithresilience-d8f8cd5415b448e0969b39e9e0bad5d0350bdcae.zip |
move off rand-selfmod
Diffstat (limited to 'starts/random-selfmod/random.cpp')
-rw-r--r-- | starts/random-selfmod/random.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/starts/random-selfmod/random.cpp b/starts/random-selfmod/random.cpp new file mode 100644 index 0000000..afdf4c7 --- /dev/null +++ b/starts/random-selfmod/random.cpp @@ -0,0 +1,108 @@ +// let's try to make it very simple + +#include <fcntl.h> +#include <signal.h> +#include <sys/mman.h> +#include <unistd.h> + +// 1. write a function to randomly put data in a buffer +// [apparently one loaded from a file] + +#define MAPFNAME "random.bin" + +pid_t child = 0; +bool child_terminated = false; +void handleSigChld(int) +{ + child_terminated = true; +} + +static unsigned long long * count; + +void random(int mapfd, int randfd, void *addr) +{ + pid_t pid = getpid(); + + // *count is shared and stored + for (*count = 0; ; ++ *count) { + unsigned long long old_count = *count; + + // if successful child, update & kill parent + if (getpid() != pid) { + msync(addr + pos, size, MS_SYNC | MS_INVALIDATE); + + kill(pid, SIGTERM); + pid = getpid(); + + // add data to git. + system("git add " MAPFNAME); + system("git commit -m selfmod"); + } + + // handle crashes with fork() + child = fork(); + if (child == 0) { + // we are new child process + // self-modify by 1-8 bytes + uint16_t pos; + uint8_t size; + read(randfd, &pos, sizeof(pos)); + read(randfd, &size, sizeof(size)); + size = (size & 0x7) + 1; // self-modify by 1-8 bytes + read(randfd, addr + pos, size); + // loop + } else { + // old process: make sure new process succeeds within 1s + time_t then = time(0); + for (;;) { + if (child_terminated || time(0) > then) { + // child did not succeed + kill(child, SIGTERM); + child_terminated = false; + // try again + break; + } + if (old_count < *count + 1) { + // incremented count by 1: success; hand off to child + return; + } + } + } + } +} + +void random_tail() { +} + +void main() +{ + // handle SIGCHLD by setting a global flag + struct sigaction sigchld; + sigchld.sa_handler = handleSigChld; + sigchld.sa_flags = SA_NOCLDWAIT; + sigaction(SIGCHLD, &sigchld, NULL); + + int fd = open(MAPFNAME, O_RDWR); + if (fd == -1 && errno == ENOENT) { + // does not exist yet + fd = open("random.bin", O_RDWR | O_CREAT); + // 2. seed the buffer with the function that puts random data in it + count = 0; + write(fd, &count, sizeof(count)); + write(fd, &random, &random_tail - &random); + } + + int randfd = open("/dev/random", O_RDONLY); + + // a buffer of 1 gig working space; random data will fill it + void *buf = mmap(NULL, + 0x40000000, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_32BIT, + fd, + 0; + + // 3. execute the buffer + void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count); + buf_as_func(mapfname, mapfd, randfd, buf); +} |