summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--hemlock.c122
2 files changed, 125 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..cbe9f36
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,3 @@
+CFLAGS ?= -march=native -O3 -fomit-frame-pointer
+
+hemlock:
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;
+}