PolymorphicEngine
Barry Read ELF format for binary modification 85e847c (2 years, 10 months ago)diff --git a/.gitignore b/.gitignore
index 75b1567..b8ebcdc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
*.swp
*.o
+poly_*
diff --git a/Makefile b/Makefile
index 0a208ee..3c61d47 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ PRODUCT = poly_original
CC=gcc
CFLAGS=
-LFLAGS=-T script.ld
+LFLAGS=-T script.ld -static -s
C_SOURCES := $(shell find src -name '*.c')
OBJS = $(sort $(subst src/,build/,$(subst .c,.o,$(C_SOURCES))))
@@ -10,10 +10,11 @@ OBJS = $(sort $(subst src/,build/,$(subst .c,.o,$(C_SOURCES))))
$(PRODUCT): $(OBJS)
@echo "LINKING $(PRODUCT)..."
@$(CC) -o $@ $^ $(LFLAGS)
+ @strip --strip-all $(PRODUCT)
clean:
@echo "REMOVING OBJECT FILES..."
- @touch build/main.o
+ @touch $(OBJS)
@rm $(OBJS)
build/%.o: src/%.c
diff --git a/script.ld b/script.ld
index 2b41fdb..841f4f3 100644
--- a/script.ld
+++ b/script.ld
@@ -1,7 +1,18 @@
SECTIONS {
- binaryStart = 0x00000000;
- polymorphicStart = .;
.polymorphic : { *(.polymorphic); }
- polymorphicEnd = .;
+
+ /DISCARD/ :
+ {
+ *(.comment)
+ *(.debug_aranges)
+ *(.debug_info)
+ *(.debug_abbrev)
+ *(.debug_line)
+ *(.debug_str)
+ *(.debug_line_str)
+ *(.debug_rnglists)
+ *(.debug_loclists)
+ *(.note.*)
+ }
}
INSERT AFTER .text;
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)