Skip to content

Instantly share code, notes, and snippets.

@michaelfm1211
Last active September 26, 2022 14:12
Show Gist options
  • Save michaelfm1211/1037faceaa7860ef41aa9955917fa01d to your computer and use it in GitHub Desktop.
Save michaelfm1211/1037faceaa7860ef41aa9955917fa01d to your computer and use it in GitHub Desktop.
simply polymorphic C program that changes it's own binary
// 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