BarryServer : Git

All the code for all my projects
// BarryServer : Git / PolymorphicEngine / blob / 8a21c42a2835df392c10329a034cc360e02d44ba / src / main.c

// Related

PolymorphicEngine

Barry Changing default config 8a21c42 (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  6       /* 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 function */
ENCRYPTED
int
encrypted_main(int argc, char **argv)
{
	char filename[NAME_PREFIX_LENGTH + NAME_AFFIX_LENGTH + 1] = NAME_PREFIX,
	     /* Possible characters in filename */
	     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)-1)];
	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;
}