From 3ef08457e3d0c0f57961849fe8a7428cf476f962 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 10 Dec 2022 06:03:32 +0200 Subject: [PATCH] Fixed Spawn() --- Execute/Spawn.cpp | 94 +++++++++++++++++++++++++++++++++++------------ include/elf.h | 45 +++++++++++++++++++++++ 2 files changed, 115 insertions(+), 24 deletions(-) diff --git a/Execute/Spawn.cpp b/Execute/Spawn.cpp index 17ffd42..562c8d0 100644 --- a/Execute/Spawn.cpp +++ b/Execute/Spawn.cpp @@ -73,12 +73,13 @@ namespace Execute #if defined(__amd64__) const char *BaseName; cwk_path_get_basename(Path, &BaseName, nullptr); - PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User); void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->Node->Length)); memcpy(BaseImage, (void *)ExFile->Node->Address, ExFile->Node->Length); debug("Image Size: %#lx - %#lx (length: %ld)", BaseImage, (uint64_t)BaseImage + ExFile->Node->Length, ExFile->Node->Length); + PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User, BaseImage); + Memory::Virtual pva = Memory::Virtual(Process->PageTable); for (uint64_t i = 0; i < TO_PAGES(ExFile->Node->Length); i++) pva.Remap((void *)((uint64_t)BaseImage + (i * PAGE_SIZE)), (void *)((uint64_t)BaseImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); @@ -121,53 +122,98 @@ namespace Execute if (ELFHeader->e_type == ET_EXEC) { trace("Executable"); - Elf64_Phdr *pheader = (Elf64_Phdr *)(((char *)BaseImage) + ELFHeader->e_phoff); - debug("p_paddr: %#lx | p_vaddr: %#lx | p_filesz: %#lx | p_memsz: %#lx | p_offset: %#lx", pheader->p_paddr, pheader->p_vaddr, pheader->p_filesz, pheader->p_memsz, pheader->p_offset); + Elf64_Phdr *ProgramHeader = (Elf64_Phdr *)(((char *)BaseImage) + ELFHeader->e_phoff); + debug("p_paddr: %#lx | p_vaddr: %#lx | p_filesz: %#lx | p_memsz: %#lx | p_offset: %#lx", ProgramHeader->p_paddr, ProgramHeader->p_vaddr, ProgramHeader->p_filesz, ProgramHeader->p_memsz, ProgramHeader->p_offset); - void *Address = nullptr; - for (int i = 0; i < ELFHeader->e_phnum; i++, pheader++) + uintptr_t BaseAddress = UINTPTR_MAX; + uint64_t ElfAppSize = 0; + + Elf64_Phdr ItrProgramHeader; + for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) { - if (pheader->p_type != PT_LOAD) - continue; - Address = (void *)((uint64_t)pheader->p_vaddr + pheader->p_memsz); + memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr)); + BaseAddress = MIN(BaseAddress, ItrProgramHeader.p_vaddr); } - void *Offset = KernelAllocator.RequestPages(TO_PAGES((uint64_t)Address)); + debug("BaseAddress %#lx", BaseAddress); - pheader = (Elf64_Phdr *)(((char *)BaseImage) + ELFHeader->e_phoff); - for (uint64_t i = 0; i < TO_PAGES((uint64_t)Address); i++) + for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) { - pva.Remap((void *)((uint64_t)pheader->p_vaddr + (i * PAGE_SIZE)), (void *)((uint64_t)Offset + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); - // debug("Mapping: %#lx -> %#lx", (uint64_t)pheader->p_vaddr + (i * PAGE_SIZE), (uint64_t)Offset + (i * PAGE_SIZE)); + memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr)); + uintptr_t SegmentEnd; + SegmentEnd = ItrProgramHeader.p_vaddr - BaseAddress + ItrProgramHeader.p_memsz; + ElfAppSize = MAX(ElfAppSize, SegmentEnd); + } + debug("ElfAppSize %ld", ElfAppSize); + + uint8_t *MemoryImage = nullptr; + + // check for TEXTREL + for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) + { + memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr)); + if (ItrProgramHeader.p_type == DT_TEXTREL) + { + warn("TEXTREL ELF is not fully tested yet!"); + MemoryImage = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(ElfAppSize)); + for (uint64_t i = 0; i < TO_PAGES(ElfAppSize); i++) + { + pva.Remap((void *)((uint64_t)MemoryImage + (i * PAGE_SIZE)), (void *)((uint64_t)MemoryImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); + debug("Mapping: %#lx -> %#lx", (uint64_t)MemoryImage + (i * PAGE_SIZE), (uint64_t)MemoryImage + (i * PAGE_SIZE)); + } + break; + } } - pheader = (Elf64_Phdr *)(((char *)BaseImage) + ELFHeader->e_phoff); - for (int i = 0; i < ELFHeader->e_phnum; i++, pheader++) + if (!MemoryImage) { - if (pheader->p_type != PT_LOAD) - continue; - void *dst = (void *)((uint64_t)pheader->p_vaddr + (uint64_t)Offset); - memset(dst, 0, pheader->p_memsz); - memcpy(dst, ((char *)BaseImage) + pheader->p_offset, pheader->p_filesz); + debug("Allocating %ld pages for image", TO_PAGES(ElfAppSize)); + MemoryImage = (uint8_t *)KernelAllocator.RequestPages(TO_PAGES(ElfAppSize)); + for (uint64_t i = 0; i < TO_PAGES(ElfAppSize); i++) + { + pva.Remap((void *)((uint64_t)ProgramHeader->p_vaddr + (i * PAGE_SIZE)), (void *)((uint64_t)MemoryImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); + debug("Mapping: %#lx -> %#lx", (uint64_t)ProgramHeader->p_vaddr + (i * PAGE_SIZE), (uint64_t)MemoryImage + (i * PAGE_SIZE)); + } + } + + debug("BaseAddress: %#lx | ElfAppSize: %#lx (%ld, %ld KB)", BaseAddress, ElfAppSize, ElfAppSize, TO_KB(ElfAppSize)); + + for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) + { + memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr)); + uintptr_t MAddr; + + if (ItrProgramHeader.p_type == PT_LOAD) + debug("PT_LOAD"); + else + debug("Not PT_LOAD"); + + MAddr = (ItrProgramHeader.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage; + + memset(MemoryImage, 0, ItrProgramHeader.p_memsz); + memcpy(MemoryImage, (uint8_t *)BaseImage + ItrProgramHeader.p_offset, ItrProgramHeader.p_filesz); + debug("MemoryImage: %#lx", MemoryImage); + debug("MAddr: %#lx", MAddr); + debug("memset operation: 0 to %#lx for length %ld", MemoryImage + MAddr, ItrProgramHeader.p_memsz); + debug("memcpy operation: %#lx to %#lx for length %ld", (uint8_t *)BaseImage + ItrProgramHeader.p_offset, MemoryImage + MAddr, ItrProgramHeader.p_filesz); } debug("Entry Point: %#lx", ELFHeader->e_entry); Vector auxv; - pheader = (Elf64_Phdr *)(((char *)BaseImage) + ELFHeader->e_phoff); auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}}); auxv.push_back({.archaux = {.a_type = AT_PHENT, .a_un = {.a_val = (uint64_t)ELFHeader->e_phentsize}}}); auxv.push_back({.archaux = {.a_type = AT_PHNUM, .a_un = {.a_val = (uint64_t)ELFHeader->e_phnum}}}); auxv.push_back({.archaux = {.a_type = AT_PAGESZ, .a_un = {.a_val = (uint64_t)PAGE_SIZE}}}); - auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)Offset}}}); - auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)ELFHeader->e_entry + (uint64_t)pheader->p_offset}}}); + auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage}}}); + auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)ELFHeader->e_entry + (uint64_t)ProgramHeader->p_offset}}}); auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t) "x86_64"}}}); auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)Path}}}); TCB *Thread = TaskManager->CreateThread(Process, (IP)ELFHeader->e_entry, argv, envp, auxv, - (IPOffset)pheader->p_offset, + (IPOffset)ProgramHeader->p_offset, Arch, Comp); ret.Process = Process; diff --git a/include/elf.h b/include/elf.h index 68d85be..428c271 100644 --- a/include/elf.h +++ b/include/elf.h @@ -247,6 +247,51 @@ enum SegmentTypes PT_HIPROC = 0x7fffffff }; +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ +#define DT_RELRSZ 35 /* Total size of RELR relative relocations */ +#define DT_RELR 36 /* Address of RELR relative relocations */ +#define DT_RELRENT 37 /* Size of one RELR relative relocaction */ +#define DT_NUM 38 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + // used for Elf64_Sym st_info #define ELF32_ST_BIND(info) ((info) >> 4) #define ELF32_ST_TYPE(info) ((info)&0xf)