From 11bbe38aa450d4034ae3801ba5e5f5950d575ddc Mon Sep 17 00:00:00 2001 From: pbonilla Date: Tue, 19 Mar 2024 17:20:11 +0100 Subject: [PATCH] create codecave added --- .vscode/settings.json | 3 +- includes/woody.h | 24 ++++---- srcs/woody.c | 137 ++++++++++++++++++++++++++++-------------- 3 files changed, 105 insertions(+), 59 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 258e317..983d135 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "files.associations": { "stdio.h": "c", "mman.h": "c", - "stdint.h": "c" + "stdint.h": "c", + "compare": "c" } } \ No newline at end of file diff --git a/includes/woody.h b/includes/woody.h index 794a1d3..f136809 100644 --- a/includes/woody.h +++ b/includes/woody.h @@ -1,8 +1,8 @@ #ifndef WOODY_H -# define WOODY_H +#define WOODY_H #include "../ft_printf/includes/ft_printf.h" -#include +#include #include #include #include @@ -20,22 +20,22 @@ typedef struct efl_content { long unsigned int file_size; - char *file_path; - char *file; - Elf64_Ehdr *Ehdr; - Elf64_Phdr *Phdr; - char *extra_data; -} t_efl_content; - + char *file_path; + char *file; + Elf64_Ehdr *Ehdr; + Elf64_Phdr *Phdr; + Elf64_Shdr *Shdr; + char *extra_data; +} t_efl_content; // utils.c -void *fetch(char *file, unsigned long file_size, unsigned long offset_to_data, unsigned long supposed_data_size); -int ft_put_error(char *str); +void *fetch(char *file, unsigned long file_size, unsigned long offset_to_data, unsigned long supposed_data_size); +int ft_put_error(char *str); // woody.c int prepare_injection(t_efl_content *woody); // encrypt.c -void encrypt(char *file, unsigned long int offset, unsigned long int size); +void encrypt(char *file, unsigned long int offset, unsigned long int size); #endif \ No newline at end of file diff --git a/srcs/woody.c b/srcs/woody.c index 8aad51a..0748f6b 100644 --- a/srcs/woody.c +++ b/srcs/woody.c @@ -45,47 +45,89 @@ int get_load_segment(t_efl_content *woody, int start, bool executable) return -1; } -int32_t find_jmp(char *code, size_t len) +void offset_sections(t_efl_content *woody, unsigned int from, unsigned int offset_ammount) { - char *jump = JUMP; - char *ptr = ft_strnstr_nullterminated(code, jump, len); + for (int i = 0; i < woody->Ehdr->e_phnum; i++) + { + if (woody->Phdr[i].p_offset > from) + woody->Phdr[i].p_offset += offset_ammount; + } + for (int i = 0; i < woody->Ehdr->e_shnum; i++) + { + if (woody->Shdr[i].sh_offset > from) + woody->Shdr[i].sh_offset += offset_ammount; + } +} + +size_t create_codecave(t_efl_content *woody, Elf64_Phdr *load_segment) +{ + const unsigned int page_size = 4096;// getpagesize(); not authorized + unsigned int padding_size = ((sizeof(PAYLOAD) / page_size) + 1) * page_size; + unsigned int codecave_start = load_segment->p_offset + load_segment->p_filesz; + offset_sections(woody, codecave_start, padding_size); + char *new_woody = malloc(woody->file_size + padding_size); + if (!new_woody) + return 0; + ft_memcpy(new_woody, woody->file, codecave_start); + ft_bzero(new_woody + codecave_start, padding_size); + ft_memcpy(new_woody + codecave_start + padding_size, woody->file + codecave_start, woody->file_size - codecave_start); + munmap(woody->file, woody->file_size); + woody->file = new_woody; + woody->file_size += padding_size; + return codecave_start; +} + + +int insert_payload(t_efl_content *woody, size_t payload_position) +{ + char payload[] = PAYLOAD; + size_t len_payload = sizeof(PAYLOAD) - 1; + char *ptr = ft_strnstr_nullterminated(payload, JUMP, len_payload); + if (ptr) { - return ptr - code; + int32_t jmp_index = ptr - payload; + int32_t jump_value = ((payload_position + len_payload) - woody->Ehdr->e_entry) * -1; + ft_memcpy(&payload[jmp_index + 1], &jump_value, sizeof(jump_value)); + ft_memcpy(woody->file + payload_position, payload, len_payload); + + printf("Old entry : %ld (%lx)\n", woody->Ehdr->e_entry, woody->Ehdr->e_entry); + printf("Code_cave_start = %ld (%lx)\n", payload_position, payload_position); + printf("Payload size = %ld (%lx)\n", len_payload, len_payload); + printf("Backward offset = %d (%x)\n", jump_value, jump_value); + + return EXIT_SUCCESS; } - return 0; + return EXIT_FAILURE; } void inject(t_efl_content *woody) { - char payload[] = PAYLOAD; size_t len_payload = sizeof(PAYLOAD) - 1; - woody->Phdr = (Elf64_Phdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_phoff, sizeof(Elf64_Phdr)); int i = get_load_segment(woody, 0, true); int j = get_load_segment(woody, i + 1, false); + size_t code_cave_size = woody->Phdr[j].p_offset - (woody->Phdr[i].p_offset + woody->Phdr[i].p_filesz); - size_t payload_off = woody->Phdr[i].p_offset + woody->Phdr[i].p_memsz; - - printf("Old entry : %ld\n", woody->Ehdr->e_entry); - printf("Code_cave_start = %ld\n", payload_off); - printf("Code_cave_size = %ld\n", code_cave_size); - printf("Payload size = %ld\n", len_payload); - - int32_t jmp_index = find_jmp(payload, len_payload); - int32_t backward_len = ((payload_off + len_payload) - woody->Ehdr->e_entry) * -1; + size_t payload_position; - ft_memcpy(&payload[jmp_index + 1], &backward_len, sizeof(backward_len)); - ft_memcpy(woody->file + payload_off, payload, len_payload); - - printf("Backward offset = %d (%x)\n", backward_len, backward_len); + if (code_cave_size > len_payload) + { + payload_position = woody->Phdr[i].p_offset + woody->Phdr[i].p_memsz; + printf("Code_cave_size = %ld (%lx)\n", code_cave_size, code_cave_size); + } + else + { + payload_position = create_codecave(woody, &woody->Phdr[i]); + } + insert_payload(woody, payload_position); - woody->Ehdr->e_entry = payload_off; + woody->Ehdr->e_entry = payload_position; woody->Phdr[i].p_filesz += len_payload; woody->Phdr[i].p_memsz += len_payload; - printf("New entry = %ld\n", woody->Ehdr->e_entry); + printf("New entry = %ld (%lx)\n", woody->Ehdr->e_entry, woody->Ehdr->e_entry); } int get_elf_sections(t_efl_content *woody) @@ -96,39 +138,42 @@ int get_elf_sections(t_efl_content *woody) ft_printf("Error: \'%s\' is not a valid 64-bit ELF file\n", woody->file_path); return EXIT_FAILURE; } + woody->Phdr = (Elf64_Phdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_phoff, sizeof(Elf64_Phdr)); - Elf64_Shdr *Shdr = (Elf64_Shdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff, sizeof(Elf64_Shdr)); - if (Shdr == NULL || !fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff, woody->Ehdr->e_shnum * sizeof(Elf64_Shdr))) + woody->Shdr = (Elf64_Shdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff, sizeof(Elf64_Shdr)); + if (woody->Shdr == NULL || !fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff, woody->Ehdr->e_shnum * sizeof(Elf64_Shdr))) { return ft_put_error("Corrupted file"); } - Elf64_Shdr *symbols_table = NULL; - for (int i = 0; i < woody->Ehdr->e_shnum; i++) { - if (Shdr[i].sh_type == SHT_SYMTAB) { - symbols_table = fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (i * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr)); - } - } - if (symbols_table == NULL) - return ft_put_error("No symbols"); - if (!fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (woody->Ehdr->e_shstrndx * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr))) - return ft_put_error("Corrupted file"); - char *Sshstrtab = (char *)fetch(woody->file, woody->file_size, Shdr[woody->Ehdr->e_shstrndx].sh_offset, 0); - if (Sshstrtab == NULL) - return ft_put_error("Corrupted file"); + // Elf64_Shdr *symbols_table = NULL; + // for (int i = 0; i < woody->Ehdr->e_shnum; i++) { + // if (Shdr[i].sh_type == SHT_SYMTAB) { + // symbols_table = fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (i * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr)); + // } + // } + // if (symbols_table == NULL) + // return ft_put_error("No symbols"); - Elf64_Shdr *strtab_header = (Elf64_Shdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (symbols_table->sh_link * woody->Ehdr->e_shentsize), sizeof(Elf64_Shdr)); - if (!strtab_header) - return ft_put_error("Corrupted file"); + // if (!fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (woody->Ehdr->e_shstrndx * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr))) + // return ft_put_error("Corrupted file"); - char *strtab = fetch(woody->file, woody->file_size, strtab_header->sh_offset, 0); - if (strtab == NULL) - return ft_put_error("Corrupted file"); - Elf64_Sym *symbols = (Elf64_Sym *)fetch(woody->file, woody->file_size, symbols_table->sh_offset, sizeof(Elf64_Sym)); - if (symbols == NULL) - return ft_put_error("Corrupted file"); + // char *Sshstrtab = (char *)fetch(woody->file, woody->file_size, Shdr[woody->Ehdr->e_shstrndx].sh_offset, 0); + // if (Sshstrtab == NULL) + // return ft_put_error("Corrupted file"); + + // Elf64_Shdr *strtab_header = (Elf64_Shdr *)fetch(woody->file, woody->file_size, woody->Ehdr->e_shoff + (symbols_table->sh_link * woody->Ehdr->e_shentsize), sizeof(Elf64_Shdr)); + // if (!strtab_header) + // return ft_put_error("Corrupted file"); + + // char *strtab = fetch(woody->file, woody->file_size, strtab_header->sh_offset, 0); + // if (strtab == NULL) + // return ft_put_error("Corrupted file"); + // Elf64_Sym *symbols = (Elf64_Sym *)fetch(woody->file, woody->file_size, symbols_table->sh_offset, sizeof(Elf64_Sym)); + // if (symbols == NULL) + // return ft_put_error("Corrupted file"); return EXIT_SUCCESS; }