From 3daf4e071dbdc3cb09bdfeb072ae40fb15f72505 Mon Sep 17 00:00:00 2001 From: Allan Wirth Date: Sun, 9 Dec 2012 16:50:45 -0500 Subject: [PATCH] Sin a lot, add basic 64 bit support. --- Makefile | 1 - includes/ropgadget.h | 32 ++++++++++++++++++++---------- src/check_file_mode.c | 43 ----------------------------------------- src/display_header.c | 27 +++++++++++++------------- src/gadget.c | 2 +- src/main.c | 4 ---- src/maps.c | 23 ++++++++++++---------- src/parse_elf.c | 42 ++++++++++++++++++++++++++++++---------- src/save_section.c | 45 +++++++++++++++++++++++++------------------ src/search_gadgets.c | 7 +++++-- 10 files changed, 113 insertions(+), 113 deletions(-) delete mode 100644 src/check_file_mode.c diff --git a/Makefile b/Makefile index de16449..edc62cd 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,6 @@ SRC = $(SRC_DIR)/main.c \ $(SRC_DIR)/ropmaker.c \ $(SRC_DIR)/maps.c \ $(SRC_DIR)/real_string_stringmode.c \ - $(SRC_DIR)/check_file_mode.c \ $(SRC_DIR)/display_header.c \ $(SRC_DIR)/varop.c \ $(SRC_DIR)/filter.c \ diff --git a/includes/ropgadget.h b/includes/ropgadget.h index ed77d66..1fb15ca 100644 --- a/includes/ropgadget.h +++ b/includes/ropgadget.h @@ -47,11 +47,13 @@ #define TRUE 0 #define FALSE 1 -#define SYSV (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_SYSV) -#define LINUX (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_LINUX) -#define FREEBSD (pElf_Header->e_ident[EI_OSABI] == ELFOSABI_FREEBSD) -#define ELF_F (pElf_Header->e_ident[EI_CLASS] == ELFCLASS32) -#define PROC8632 (pElf_Header->e_machine == EM_386) +#define SYSV (filemode.data[EI_OSABI] == ELFOSABI_SYSV) +#define LINUX (filemode.data[EI_OSABI] == ELFOSABI_LINUX) +#define FREEBSD (filemode.data[EI_OSABI] == ELFOSABI_FREEBSD) +#define ELF_F (filemode.data[EI_CLASS] == ELFCLASS32) +#define ELF_F64 (filemode.data[EI_CLASS] == ELFCLASS64) +#define PROC8632 (pElf32_Header->e_machine == EM_386) +#define PROC8664 (pElf64_Header->e_machine == EM_X86_64) /* type definitions for easing transition */ typedef Elf64_Addr Address; @@ -60,6 +62,14 @@ typedef uint64_t Size; #define ADDR_FORMAT "0x%.16ld" #define SIZE_FORMAT "0x%.16ld" +/* Joshua 7:20 - Achan replied, "It is true! I have sinned against the LORD, the God of Israel." */ +#define PHDR(X, t) (containerType == CONTAINER_ELF32?((t)(pElf32_Phdr X)):((t)(pElf64_Phdr X))) + +typedef enum { + CONTAINER_ELF32, + CONTAINER_ELF64 +} e_container; + /* gadgets series */ typedef struct s_asm { @@ -218,9 +228,12 @@ typedef enum e_syntax } e_syntax; /* globals vars */ -Elf32_Ehdr *pElf_Header; -Elf32_Phdr *pElf32_Phdr; -Elf32_Shdr *pElf32_Shdr; +Elf32_Ehdr *pElf32_Header; +Elf64_Ehdr *pElf64_Header; + +Elf32_Phdr *pElf32_Phdr; +Elf64_Phdr *pElf64_Phdr; + Address Addr_sData; Address Addr_sGot; @@ -230,6 +243,7 @@ unsigned int NbTotalGadFound; t_list_inst *pVarop; t_list_section *list_section; t_list_symbols *list_symbols; +e_container containerType; /* flag options */ t_filemode filemode; /* -file */ @@ -260,8 +274,6 @@ void search_gadgets(unsigned char *, unsigned int); /* elf */ const char *get_flags(uint32_t); char *get_seg(Elf32_Word); -void check_elf_format(unsigned char *); -void check_arch_supported(void); void save_section(void); void save_symbols(unsigned char *); t_list_section *get_section(char *); diff --git a/src/check_file_mode.c b/src/check_file_mode.c deleted file mode 100644 index 4cd8c9c..0000000 --- a/src/check_file_mode.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -** RopGadget - Release v3.4.2 -** Jonathan Salwan - http://twitter.com/JonathanSalwan -** Allan Wirth - http://allanwirth.com/ -** http://shell-storm.org -** 2012-11-11 -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "ropgadget.h" - -void process_filemode(char *file) -{ - int fd; - unsigned char *data; - struct stat filestat; - - fd = xopen(file, O_RDONLY, 0644); - stat(file, &filestat); - filemode.size = filestat.st_size; - filemode.file = file; - data = xmalloc(filemode.size * sizeof(char)); - xread(fd, data, filemode.size); - pMapElf = xmmap(0, filemode.size, PROT_READ, MAP_SHARED, fd, 0); - filemode.data = data; - pElf_Header = (Elf32_Ehdr *)data; - pElf32_Shdr = (Elf32_Shdr *)((char *)data + pElf_Header->e_shoff); - pElf32_Phdr = (Elf32_Phdr *)((char *)data + pElf_Header->e_phoff); - close(fd); -} diff --git a/src/display_header.c b/src/display_header.c index 01033cf..546d555 100644 --- a/src/display_header.c +++ b/src/display_header.c @@ -26,16 +26,16 @@ void display_elf_header(void) { fprintf(stdout, "%sELF Header\n", YELLOW); fprintf(stdout, "============================================================%s\n\n", ENDC); - fprintf(stdout, "entry %s0x%.8x%s\n", RED, pElf_Header->e_entry, ENDC); - fprintf(stdout, "phoff %s0x%.8x%s\n", RED, pElf_Header->e_phoff, ENDC); - fprintf(stdout, "shoff %s0x%.8x%s\n", RED, pElf_Header->e_shoff, ENDC); - fprintf(stdout, "flags %s0x%.8x%s\n", RED, pElf_Header->e_flags, ENDC); - fprintf(stdout, "ehsize %s0x%.8x (%d)%s\n", RED, pElf_Header->e_ehsize, pElf_Header->e_ehsize, ENDC); - fprintf(stdout, "phentsize %s0x%.8x (%d)%s\n", RED, pElf_Header->e_phentsize, pElf_Header->e_phentsize, ENDC); - fprintf(stdout, "phnum %s0x%.8x (%d)%s\n", RED, pElf_Header->e_phnum, pElf_Header->e_phnum,ENDC); - fprintf(stdout, "shentsize %s0x%.8x (%d)%s\n", RED, pElf_Header->e_shentsize, pElf_Header->e_shentsize, ENDC); - fprintf(stdout, "shnum %s0x%.8x (%d)%s\n", RED, pElf_Header->e_shnum, pElf_Header->e_shnum,ENDC); - fprintf(stdout, "shstrndx %s0x%.8x (%d)%s\n\n\n", RED, pElf_Header->e_shstrndx, pElf_Header->e_shstrndx,ENDC); + fprintf(stdout, "entry %s0x%.8x%s\n", RED, pElf32_Header->e_entry, ENDC); + fprintf(stdout, "phoff %s0x%.8x%s\n", RED, pElf32_Header->e_phoff, ENDC); + fprintf(stdout, "shoff %s0x%.8x%s\n", RED, pElf32_Header->e_shoff, ENDC); + fprintf(stdout, "flags %s0x%.8x%s\n", RED, pElf32_Header->e_flags, ENDC); + fprintf(stdout, "ehsize %s0x%.8x (%d)%s\n", RED, pElf32_Header->e_ehsize, pElf32_Header->e_ehsize, ENDC); + fprintf(stdout, "phentsize %s0x%.8x (%d)%s\n", RED, pElf32_Header->e_phentsize, pElf32_Header->e_phentsize, ENDC); + fprintf(stdout, "phnum %s0x%.8x (%d)%s\n", RED, pElf32_Header->e_phnum, pElf32_Header->e_phnum,ENDC); + fprintf(stdout, "shentsize %s0x%.8x (%d)%s\n", RED, pElf32_Header->e_shentsize, pElf32_Header->e_shentsize, ENDC); + fprintf(stdout, "shnum %s0x%.8x (%d)%s\n", RED, pElf32_Header->e_shnum, pElf32_Header->e_shnum,ENDC); + fprintf(stdout, "shstrndx %s0x%.8x (%d)%s\n\n\n", RED, pElf32_Header->e_shstrndx, pElf32_Header->e_shstrndx,ENDC); } void display_symtab(void) @@ -71,7 +71,7 @@ void display_program_header() fprintf(stdout, "%sProgram Header\n", YELLOW); fprintf(stdout, "============================================================%s\n\n", ENDC); - while (x != pElf_Header->e_phnum) + while (x != pElf32_Header->e_phnum) { fprintf(stdout, "%s%s%s\n", YELLOW, get_seg(pElf32_Phdr->p_type), ENDC); fprintf(stdout, "\toffset %s0x%.8x%s ", RED, pElf32_Phdr->p_offset, ENDC); @@ -89,10 +89,11 @@ void display_program_header() void display_section_header(void) { + Elf32_Shdr *pElf32_Shdr = (Elf32_Shdr *)filemode.data + pElf32_Header->e_shoff; char *ptrNameSection = NULL; int x = 0; - while(x != pElf_Header->e_shnum) + while(x != pElf32_Header->e_shnum) { if (pElf32_Shdr->sh_type == SHT_STRTAB && pElf32_Shdr->sh_addr == 0) { @@ -108,7 +109,7 @@ void display_section_header(void) fprintf(stdout, "%sSection Header\n", YELLOW); fprintf(stdout, "============================================================%s\n\n", ENDC); fprintf(stdout, "%sidx\taddr\t\tsize\t\tsection%s\n", GREEN, ENDC); - while (x != pElf_Header->e_shnum) + while (x != pElf32_Header->e_shnum) { fprintf(stdout, "%s%.2d%s\t", GREEN, x, ENDC); fprintf(stdout, "%s0x%.8x\t", RED, pElf32_Shdr->sh_addr); diff --git a/src/gadget.c b/src/gadget.c index c5357a8..3d82b26 100644 --- a/src/gadget.c +++ b/src/gadget.c @@ -76,7 +76,7 @@ void find_all_gadgets(unsigned char *data, unsigned int size_data, t_map *maps_e pVarop = NULL; stringlen = 0; importsc_mode.poctet = NULL; - offset = (pElf32_Phdr->p_vaddr - pElf32_Phdr->p_offset); /* base addr */ + offset = (PHDR(->p_vaddr) - PHDR(->p_offset)); /* base addr */ cpt = set_cpt_if_mapmode(cpt); /* mapmode */ /* If we're in simple gadget mode, precompute which instructions to search */ diff --git a/src/main.c b/src/main.c index 34cd464..4924efa 100644 --- a/src/main.c +++ b/src/main.c @@ -221,8 +221,6 @@ int main(int argc, char **argv) { } process_filemode(file); - check_elf_format(filemode.data); - check_arch_supported(); save_section(); /* save all sections in list_sections */ save_symbols(filemode.data); /* save all symbols in list_symbols */ @@ -244,8 +242,6 @@ int main(int argc, char **argv) { search_gadgets(filemode.data, filemode.size); - free(filemode.data); - return 0; } #undef is_option diff --git a/src/maps.c b/src/maps.c index 4af94d9..ff75306 100644 --- a/src/maps.c +++ b/src/maps.c @@ -49,13 +49,13 @@ void free_add_map(t_map *element) } /* check if flag have a READ BIT */ -static int check_read_flag(Elf32_Word flag) +static int check_read_flag(Elf64_Word flag) { return (flag > 3); } /* check if flag have a EXEC BIT */ -static int check_exec_flag(Elf32_Word flag) +static int check_exec_flag(Elf64_Word flag) { return (flag%2 == 1); } @@ -65,13 +65,16 @@ t_map *return_map(int read) { int x; t_map *map; + Elf64_Half phnum; map = NULL; - for (x = 0; x != pElf_Header->e_phnum; x++, pElf32_Phdr++) - if (read?check_read_flag(pElf32_Phdr->p_flags):check_exec_flag(pElf32_Phdr->p_flags)) - map = add_map(map, pElf32_Phdr->p_vaddr, (Address)(pElf32_Phdr->p_vaddr + pElf32_Phdr->p_memsz)); + phnum = (containerType==CONTAINER_ELF32?pElf32_Header->e_phnum:pElf64_Header->e_phnum); - pElf32_Phdr -= x; + for (x = 0; x != phnum; x++, PHDR(++, void *)) + if (read?check_read_flag(PHDR(->p_flags, Elf64_Word)):check_exec_flag(PHDR(->p_flags, Elf64_Word))) + map = add_map(map, PHDR(->p_vaddr, Address), PHDR(->p_vaddr, Address) + PHDR(->p_memsz, Address)); + + PHDR( -= x, void *); return map; } @@ -92,13 +95,13 @@ unsigned int set_cpt_if_mapmode(unsigned int cpt) { Address base_addr; - base_addr = (pElf32_Phdr->p_vaddr - pElf32_Phdr->p_offset); + base_addr = (PHDR(->p_vaddr, Address) - PHDR(->p_offset, Address)); return (mapmode.flag == 0)?cpt:(mapmode.addr_start - base_addr); } unsigned int check_end_mapmode(unsigned int cpt) { - return (mapmode.flag && cpt + (pElf32_Phdr->p_vaddr - pElf32_Phdr->p_offset) > mapmode.addr_end); + return (mapmode.flag && cpt + (PHDR(->p_vaddr, Address) - PHDR(->p_offset, Offset)) > mapmode.addr_end); } void map_parse(char *str) @@ -106,8 +109,8 @@ void map_parse(char *str) Address base_addr; Address end_addr; - base_addr = (pElf32_Phdr->p_vaddr - pElf32_Phdr->p_offset); - end_addr = (pElf32_Phdr->p_vaddr - pElf32_Phdr->p_offset) + filemode.size; + base_addr = (PHDR(->p_vaddr, Address) - PHDR(->p_offset, Offset)); + end_addr = base_addr + filemode.size; mapmode.addr_start = (Address)strtol(str, NULL, 16); diff --git a/src/parse_elf.c b/src/parse_elf.c index 2bb82bf..6cf9b75 100644 --- a/src/parse_elf.c +++ b/src/parse_elf.c @@ -76,25 +76,47 @@ char *get_seg(Elf32_Word seg) return ("ERROR"); } -void check_elf_format(unsigned char *data) +void process_filemode(char *file) { - if (strncmp((const char *)data, MAGIC_ELF, 4)) + int fd; + unsigned char *data; + struct stat filestat; + + fd = xopen(file, O_RDONLY, 0644); + stat(file, &filestat); + filemode.size = filestat.st_size; + filemode.file = file; + + pMapElf = xmmap(0, filemode.size, PROT_READ, MAP_SHARED, fd, 0); + data = (unsigned char*)pMapElf; + filemode.data = data; + close(fd); + + if (strncmp((char *)data, MAGIC_ELF, 4)) { fprintf(stderr, "%sError%s: No elf format\n", RED, ENDC); exit(EXIT_FAILURE); } -} -void check_arch_supported(void) -{ /* supported: - Linux/x86-32bits */ /* supported: - FreeBSD/x86-32bits */ - if (ELF_F && (SYSV || LINUX || FREEBSD) && PROC8632) - return ; - else + if (ELF_F && (SYSV || LINUX || FREEBSD)) { - fprintf(stderr, "%sError%s: Architecture isn't supported\n", RED, ENDC); - exit(EXIT_FAILURE); + containerType = CONTAINER_ELF32; + pElf32_Header = (Elf32_Ehdr *)data; + pElf32_Phdr = (Elf32_Phdr *)(filemode.data + pElf32_Header->e_phoff); + if (PROC8632) + return; } + else if (ELF_F64 && (SYSV || LINUX || FREEBSD)) + { + containerType = CONTAINER_ELF64; + pElf64_Header = (Elf64_Ehdr *)data; + pElf64_Phdr = (Elf64_Phdr *)(filemode.data + pElf64_Header->e_phoff); + if (PROC8664) + return; + } + fprintf(stderr, "%sError%s: Architecture isn't supported\n", RED, ENDC); + exit(EXIT_FAILURE); } diff --git a/src/save_section.c b/src/save_section.c index 5d1699a..b2f3dfe 100644 --- a/src/save_section.c +++ b/src/save_section.c @@ -66,37 +66,44 @@ static void save_info_section_ropmaker(void) Addr_sGot++; } +#define SHDR(X, t) (containerType == CONTAINER_ELF32?((t)(a.pElf32_Shdr X)):((t)(a.pElf64_Shdr X))) void save_section(void) { - int x = 0; + Size x = 0; char *ptrNameSection = NULL; - list_section = NULL; + Size shnum; + union { + Elf32_Shdr *pElf32_Shdr; + Elf64_Shdr *pElf64_Shdr; + } a; - while(x != pElf_Header->e_shnum) + if (containerType == CONTAINER_ELF32) + a.pElf32_Shdr = (Elf32_Shdr *)(filemode.data + pElf32_Header->e_shoff); + else + a.pElf64_Shdr = (Elf64_Shdr *)(filemode.data + pElf64_Header->e_shoff); + + list_section = NULL; + shnum = (containerType == CONTAINER_ELF32?pElf32_Header->e_shnum:pElf64_Header->e_shnum); + + for (x = 0; x != shnum; x++, SHDR(++, void*)) { - if (pElf32_Shdr->sh_type == SHT_STRTAB && pElf32_Shdr->sh_addr == 0) + if (SHDR(->sh_type, Elf64_Word) == SHT_STRTAB && SHDR(->sh_addr, Address) == 0) { - ptrNameSection = (char *)pMapElf + pElf32_Shdr->sh_offset; + ptrNameSection = (char *)pMapElf + SHDR(->sh_offset, ssize_t); break; } - x++; - pElf32_Shdr++; } - pElf32_Shdr -= x; - x = 0; + SHDR( -= x, void *); - while (x != pElf_Header->e_shnum) + for ( x = 0; x != shnum; x++, SHDR(++, void *)) { list_section = add_section(list_section, - (ptrNameSection + pElf32_Shdr->sh_name), - pElf32_Shdr->sh_addr, - pElf32_Shdr->sh_offset, - pElf32_Shdr->sh_size, - pElf32_Shdr->sh_entsize); - x++; - pElf32_Shdr++; + (ptrNameSection + SHDR(->sh_name, size_t)), + SHDR(->sh_addr, Address), + SHDR(->sh_offset, Offset), + SHDR(->sh_size, size_t), + SHDR(->sh_entsize, int)); } save_info_section_ropmaker(); - pElf32_Shdr -= x; } - +#undef SHDR diff --git a/src/search_gadgets.c b/src/search_gadgets.c index 4ecb092..d986d4f 100644 --- a/src/search_gadgets.c +++ b/src/search_gadgets.c @@ -28,7 +28,8 @@ void search_gadgets(unsigned char *data, unsigned int size_data) t_map *maps_read; if (asm_mode.flag) - x8632_build_code(asm_mode.argument); + if (containerType == CONTAINER_ELF32) + x8632_build_code(asm_mode.argument); maps_exec = return_map(0); maps_read = return_map(1); @@ -36,8 +37,10 @@ void search_gadgets(unsigned char *data, unsigned int size_data) fprintf(stdout, "============================================================%s\n", ENDC); /* Linux/x86-32bits & FreeBSD/x86-32bits*/ - if (ELF_F && (SYSV || LINUX || FREEBSD) && PROC8632) + if (containerType == CONTAINER_ELF32) find_all_gadgets(data, size_data, maps_exec, maps_read, tab_x8632); + else if (containerType == CONTAINER_ELF64) + find_all_gadgets(data, size_data, maps_exec, maps_read, tab_x8664); if (opcode_mode.flag != 1 && stringmode.flag != 1) {