From 3971b78a2972ebbafc359efcb43e46b95ea43fb7 Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Fri, 28 Jan 2022 10:18:55 +0100 Subject: [PATCH] vxBoot - 1.1.1 : GOT patch @update <> CMakeList.txt : dump version + add new sources files <> include/vxBoot/loader : remove useless define and add Elf32_Sym @fix <> vxBoot/loader/got : relocalize the .got section to _GLOBAL_OFFSET_TABLE_ --- CMakeLists.txt | 2 +- include/vxBoot/loader.h | 47 +++++++++++------- src/loader/elf/got.c | 106 +++++++++++++++++++++++++++++++--------- 3 files changed, 113 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e1cbb6..85f7b5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(vxBoot VERSION 1.1.0 LANGUAGES C) +project(vxBoot VERSION 1.1.1 LANGUAGES C) include(GenerateG1A) include(GenerateG3A) diff --git a/include/vxBoot/loader.h b/include/vxBoot/loader.h index f1a4333..583f56e 100644 --- a/include/vxBoot/loader.h +++ b/include/vxBoot/loader.h @@ -94,24 +94,35 @@ typedef struct { /* Legal values for sh_type (section type). */ -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ -#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ +#define SHT_NUM 19 /* Number of defined types. */ + +/* Symbol table entry. */ + +typedef struct { + uint32_t st_name; /* Symbol name (string tbl index) */ + uint32_t st_value; /* Symbol value */ + uint32_t st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + uint16_t st_shndx; /* Section index */ +} Elf32_Sym; //--- // Loader API diff --git a/src/loader/elf/got.c b/src/loader/elf/got.c index 09858ac..1a765b1 100644 --- a/src/loader/elf/got.c +++ b/src/loader/elf/got.c @@ -4,15 +4,15 @@ #include -/* loader_got_patch() : Try to patch the GOT section */ -int loader_got_patch( + +/* loader_get_section() : Try to find section information using its name */ +static int loader_get_section( + Elf32_Shdr *shdr, + char const * const name, struct smemfs_inode const * restrict const inode, - struct kernel_info * const kernel, Elf32_Ehdr *hdr ) { - Elf32_Shdr shdr; - uintptr_t *got; - char name[5]; + char buff[16]; off_t stroff; off_t shoff; @@ -22,28 +22,88 @@ int loader_got_patch( /* find the section string table ".strtable" */ smemfs_pread( inode, - &shdr, sizeof(Elf32_Shdr), + shdr, sizeof(Elf32_Shdr), shoff + (sizeof(Elf32_Shdr) * hdr->e_shstrndx) ); - stroff = shdr.sh_offset; + stroff = shdr->sh_offset; /* walk throught each section and find the .got section */ for (int i = 0; i < hdr->e_shnum; ++i) { - smemfs_pread(inode, &shdr, sizeof(Elf32_Shdr), shoff); - smemfs_pread(inode, name, 5, shdr.sh_name + stroff); - if (strcmp(name, ".got") != 0) { - shoff += sizeof(Elf32_Shdr); - continue; - } - got = kernel->memory.program.start; - got = (void*)((uintptr_t)got + (uintptr_t)shdr.sh_addr); - terminal_write(" GOT section found at %p...\n", got); - for (uint32_t j = 0 ; j < shdr.sh_size >> 2 ; ++j) { - terminal_write(" path symbols %p...\n", got[j]); - got[j] += (uintptr_t)kernel->hardware.ram.physical.kernel_addr; - got[j] |= (uintptr_t)0x80000000; - } - return (0); + smemfs_pread(inode, shdr, sizeof(Elf32_Shdr), shoff); + smemfs_pread(inode, buff, 16, shdr->sh_name + stroff); + if (strcmp(buff, name) == 0) + return (0); + shoff += sizeof(Elf32_Shdr); } return (-1); } + + +/* loader_get_symbols() : get symbols information */ +static int loader_get_symbol( + Elf32_Sym *sym, + char const * const name, + struct smemfs_inode const * restrict const inode, + Elf32_Ehdr *hdr +){ + Elf32_Shdr symhdr; + Elf32_Shdr strhdr; + char buff[64]; + int off; + + /* frist, find the symtab section */ + loader_get_section(&symhdr, ".symtab", inode, hdr); + loader_get_section(&strhdr, ".strtab", inode, hdr); + + /* walk throut the table */ + off = symhdr.sh_offset; + for (uint32_t i = 0 ; i < symhdr.sh_size / sizeof(Elf32_Sym) ; ++i) { + smemfs_pread(inode, sym, sizeof(Elf32_Sym), off); + smemfs_pread(inode, buff, 64, sym->st_name + strhdr.sh_offset); + if (strcmp(buff, name) == 0) + return (0); + off += sizeof(Elf32_Sym); + } + return (-1); +} + + +/* loader_got_patch() : Try to patch the GOT/PLT section */ +int loader_got_patch( + struct smemfs_inode const * restrict const inode, + struct kernel_info * const kernel, + Elf32_Ehdr *hdr +) { + Elf32_Shdr shdr; + Elf32_Sym sym; + uintptr_t *__got__; + uintptr_t *got; + uintptr_t addr; + + /* first, try to find the __GLOBAL_OFFSET_TABLE__ symbol */ + if (loader_get_symbol(&sym, "_GLOBAL_OFFSET_TABLE_", inode, hdr)) { + terminal_write("_GLOBAL_OFFSET_TABLE_ not found...\n"); + return (0); + } + __got__ = kernel->memory.program.start; + __got__ = (void*)((uintptr_t)__got__ + (uintptr_t)sym.st_value); + terminal_write(" __GOT__ found at %p...\n", __got__); + + + /* and we need to relocalise the "real" GOT section and update the + hardcoded address in the same time */ + loader_get_section(&shdr, ".got", inode, hdr); + got = kernel->memory.program.start; + got = (void*)((uintptr_t)got + (uintptr_t)shdr.sh_addr); + terminal_write(" GOT found at %p...\n", got); + + /* perform transation */ + for (uint32_t i = 0 ; i < shdr.sh_size >> 2 ; ++i) { + terminal_write(" path symbols %p...\n", got[i]); + addr = got[i]; + addr += (uintptr_t)kernel->hardware.ram.physical.kernel_addr; + addr |= (uintptr_t)0x80000000; + __got__[i] = addr; + } + return (0); +}