diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-05-25 23:51:45 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-05-25 23:51:45 +0200 |
commit | 109badcd533844bf8991a260ed429fa62f863f8d (patch) | |
tree | 9c3744f0dae653c86947749c41c4986e5e45d133 /hemlock.c | |
download | memory-hemlock-109badcd533844bf8991a260ed429fa62f863f8d.tar.xz memory-hemlock-109badcd533844bf8991a260ed429fa62f863f8d.zip |
Diffstat (limited to 'hemlock.c')
-rw-r--r-- | hemlock.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/hemlock.c b/hemlock.c new file mode 100644 index 0000000..52779b0 --- /dev/null +++ b/hemlock.c @@ -0,0 +1,122 @@ +#define I_AM_A_COWARD + +/* + * Memory Hemlock + * by zx2c4 + * + * Chooses a random device from /proc/iomem, then chooses a random address + * from that device's memory range, and then writes a random byte into that + * address. It does this a random number of times between 1 and 23. It then + * sleeps for a random amount of time between 1 and 60 seconds. + * + * Last man standing? + * + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +enum { + DEVICE_MAX = 256, + DEVICE_NAME_LEN = 256 +}; + +struct device { + unsigned long start, end; + char name[DEVICE_NAME_LEN]; +}; + +static unsigned long random_integer(void) +{ + static int fd = -1; + unsigned long ret; + + if (fd < 0) + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + perror("open(\"/dev/urandom\")"); + exit(4); + } + if (read(fd, &ret, sizeof(ret)) != sizeof(ret)) { + perror("read(\"/dev/urandom\")"); + exit(5); + } + return ret; +} + +static unsigned long random_bounded(unsigned long bound) +{ + unsigned long ret; + const unsigned long max_mod_bound = (1 + ~bound) % bound; + + if (bound < 2) + return 0; + do + ret = random_integer(); + while (ret < max_mod_bound); + return ret % bound; +} + +static unsigned long random_range(unsigned long min, unsigned long max_plus_one) +{ + return random_bounded(max_plus_one - min) + min; +} + +int main(int argc, char *argv[]) +{ + int memfd, bad_count, device_count, device_index; + unsigned long location; + char byte; + struct device devices[DEVICE_MAX]; + FILE *iomem; + + iomem = fopen("/proc/iomem", "r"); + if (!iomem) { + perror("fopen(\"/proc/iomem\")"); + return 1; + } + device_count = 0; + while (fscanf(iomem, "%lx-%lx : %[^\n]\n", &devices[device_count].start, &devices[device_count].end, devices[device_count].name) == 3) { + if ((!strchr(devices[device_count].name, ':') && strcmp(devices[device_count].name, "reserved")) && ++device_count == DEVICE_MAX) { + fprintf(stderr, "You have too many devices.\n"); + return 2; + } + } + fclose(iomem); + + memfd = open("/dev/mem", O_RDWR); + if (memfd < 0) { + perror("open(\"/dev/mem\")"); + return 3; + } + + for (;;) { + device_index = random_range(0, device_count); + bad_count = random_range(1, 24); + printf("Doing bad things to %s (0x%lx-0x%lx) %d times:\n", devices[device_index].name, devices[device_index].start, devices[device_index].end, bad_count); + while (bad_count--) { + byte = random_range(0, 256); + location = random_range(devices[device_index].start, devices[device_index].end + 1); + printf("\t*0x%lx = 0x%hhx\n", location, byte); +#ifdef I_AM_A_COWARD +#warning "You are a coward." +#else +#warning "OMG JASON WHAT ARE YOU DOING YOU CRAZY PSYCHO." + if (pwrite(memfd, &byte, 1, location) != 1) + perror("\t\tpwrite"); +#endif + } + bad_count = random_range(1, 61); + printf("Sleeping for %d seconds.\n", bad_count); + sleep(bad_count); + } + + close(memfd); + return 0; +} |