Last active
September 26, 2022 14:12
-
-
Save michaelfm1211/1037faceaa7860ef41aa9955917fa01d to your computer and use it in GitHub Desktop.
simply polymorphic C program that changes it's own binary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this program has been tested on macOS and Alpine Linux, but not Windows. Both | |
// GCC Clang and GNU GCC have also been tested to work. Ideally, this program | |
// should work on any x86-64 machine. | |
// | |
// the program assumes it's binary is called "poly", so you must change the | |
// source code if you want to rename the executable to anything else. | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
// can be any arbitary value, just needs to be unique | |
#define MARKER 0x99999999 | |
// Prints the starting state of the program. | |
void print_state() { | |
volatile int __attribute__((unused)) MARK1 = MARKER; | |
int a = 0x99; | |
printf("Starting value (hardcoded into the binary): 0x%x\n", a); | |
} | |
// Increments a value based in the binary | |
void inc_val(unsigned long val_pos, FILE *file) { | |
// read the value at val_pos | |
int curr; | |
fseek(file, val_pos, SEEK_SET); | |
if (!fread(&curr, sizeof(int), 1, file)) { | |
perror("fread()"); | |
exit(1); | |
} | |
printf("Found value 0x%x at %lu.\n", curr, val_pos); | |
// increment the value and write it to the binary | |
curr++; | |
fseek(file, val_pos, SEEK_SET); | |
if (!fwrite(&curr, sizeof(int), 1, file)) { | |
perror("fwrite()"); | |
exit(1); | |
} | |
printf("Set %lu to 0x%x\n", val_pos, curr); | |
} | |
int main() { | |
print_state(); | |
puts(""); // empty line | |
// Copy binary to prevent "Resource busy" error | |
if (system("cp poly poly.tmp") != 0) { | |
fputs("Copy failed.\n", stderr); | |
return 1; | |
} | |
// open binary | |
FILE *file = fopen("poly.tmp", "r+b"); | |
if (file == NULL) { | |
perror("fopen()"); | |
return 1; | |
} | |
// get size of binary file | |
fseek(file, 0, SEEK_END); | |
unsigned long len = ftell(file); | |
rewind(file); | |
// read the binary into memory | |
uint8_t *buf = malloc(len); | |
if (fread(buf, 1, len, file) < len) { | |
perror("fread()"); | |
return 1; | |
} | |
// search for the marker, then increment the value. value is at a set offset | |
// from the marker | |
for (unsigned long i = 0; i < len-8; i++) { | |
uint32_t frame = htonl(*((uint32_t *)(buf + i))); | |
if (frame == MARKER) { | |
printf("Found marker 0x%x at: %lu\n", MARKER, i); | |
inc_val(i + sizeof(int) + 3, file); | |
break; | |
} | |
} | |
puts("File patched successfully."); | |
// Replace poly with poly.tmp | |
if (rename("poly.tmp", "poly") < 0) { | |
perror("rename()"); | |
return 1; | |
} | |
// cleanup | |
free(buf); | |
fclose(file); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment