PolymorphicEngine
Barry Read ELF format for binary modification 85e847c (3 years, 3 months ago)
diff --git a/src/main.c b/src/main.c
index e0e84fb..4163afc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,10 +1,13 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
+#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
+#include <elf.h>
+#include <limits.h>
/* Config */
#define NAME_PREFIX "poly_" /* Copies' names start with */
@@ -12,12 +15,20 @@
#define NAME_AFFIX_LENGTH 6 /* Number of random chars after prefix */
#define KEY_SIZE 8 /* Size of encryption key */
-#define POLYMORPHIC __attribute__((noinline, section(".polymorphic")))
+#define POLYMORPHIC __attribute__((noinline, section(".polymorphic"), used))
+
+#if ( __WORDSIZE == 64 )
+# define EHDR Elf64_Ehdr
+# define SHDR Elf64_Shdr
+#else
+# define EHDR Elf32_Ehdr
+# define SHDR Elf32_Shdr
+#endif
/* Keys */
const uint8_t act[KEY_SIZE] = {}, /* Operators */
key[KEY_SIZE] = {}; /* Operands */
-extern uint8_t binaryStart[], polymorphicStart[], polymorphicEnd[];
+uintptr_t polymorphicStart, polymorphicEnd;
/* Copy a file */
POLYMORPHIC
@@ -62,6 +73,7 @@ polymorphic_main(int argc, char **argv)
*code = (uint8_t *) polymorphicStart;
FILE *child;
size_t i;
+ uint32_t rodata, polymorphic, vrodata;
/* Seed the random function */
srand(time(NULL));
@@ -70,26 +82,47 @@ polymorphic_main(int argc, char **argv)
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);
+ chmod(filename, 0755);
/* Open child file */
child = fopen(filename, "r+");
if (child == NULL)
exit(EXIT_FAILURE);
+ /* Parse ELF to find sections */
+ EHDR hdr;
+ SHDR shdr, nhdr;
+ char sectionName[16];
+ fread(&hdr, 1, sizeof(EHDR), child);
+ i = hdr.e_shstrndx;
+ fseek(child, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET);
+ fread(&nhdr, 1, sizeof(SHDR), child);
+ for (i = 0; i < hdr.e_shnum; i++) {
+ fseek(child, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET);
+ fread(&shdr, 1, sizeof(SHDR), child);
+ fseek(child, nhdr.sh_offset + shdr.sh_name, SEEK_SET);
+ fread(sectionName, 16, 1, child);
+ if (!strcmp(sectionName, ".rodata")) {
+ rodata = shdr.sh_offset;
+ vrodata = shdr.sh_addr;
+ }
+ if (!strcmp(sectionName, ".polymorphic"))
+ polymorphic = shdr.sh_offset;
+ }
+
/* 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);
+ fseek(child, rodata + ((uintptr_t) act - vrodata), SEEK_SET);
fwrite(dAct, 1, KEY_SIZE, child);
- fseek(child, (unsigned long int) (key - binaryStart), SEEK_SET);
+ fseek(child, rodata + ((uintptr_t) key - vrodata), SEEK_SET);
fwrite(dKey, 1, KEY_SIZE, child);
/* Encrypt our code */
- fseek(child, (uint64_t) (polymorphicStart - binaryStart), SEEK_SET);
+ fseek(child, polymorphic, SEEK_SET);
for (i = 0; i < (polymorphicEnd - polymorphicStart); i++) {
data = code[i];
switch (dAct[i % KEY_SIZE]) {
@@ -118,8 +151,31 @@ main(int argc, char **argv)
{
size_t i, mask;
void *aligned;
- uint8_t *code = (uint8_t *) polymorphicStart;
+ uint8_t *code;
long pageSize = sysconf(_SC_PAGESIZE);
+ FILE *parent = fopen(argv[0], "rb");
+
+ /* Parse ELF to find sections */
+ EHDR hdr;
+ SHDR shdr, nhdr;
+ char sectionName[16];
+ fread(&hdr, 1, sizeof(EHDR), parent);
+ i = hdr.e_shstrndx;
+ fseek(parent, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET);
+ fread(&nhdr, 1, sizeof(SHDR), parent);
+ for (i = 0; i < hdr.e_shnum; i++) {
+ fseek(parent, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET);
+ fread(&shdr, 1, sizeof(SHDR), parent);
+ fseek(parent, nhdr.sh_offset + shdr.sh_name, SEEK_SET);
+ fread(sectionName, 16, 1, parent);
+ if (!strcmp(sectionName, ".polymorphic")) {
+ polymorphicStart = shdr.sh_addr;
+ polymorphicEnd = shdr.sh_addr + shdr.sh_size;
+ }
+ }
+ fclose(parent);
+
+ code = (void *) polymorphicStart;
/* Make memory writable */
if (pageSize <= 0)