#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 #include #include #include #include #include #include #include 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; }