From 45cd4bb13c54ca2aa901f584625a477375d8d98b Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 20 Mar 2023 05:17:35 +0200 Subject: [PATCH] Fix wrong MemoryImage address given to the elf interpreter --- Execute/Elf/BaseLoad.cpp | 26 +++++++++++++------------- Execute/Elf/Exec.cpp | 12 +++++++----- Execute/Elf/Parse.cpp | 18 +++++++++--------- Execute/Elf/SharedObjects.cpp | 2 +- include/exec.hpp | 11 +++++++++-- 5 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Execute/Elf/BaseLoad.cpp b/Execute/Elf/BaseLoad.cpp index 7debccc..355b1f2 100644 --- a/Execute/Elf/BaseLoad.cpp +++ b/Execute/Elf/BaseLoad.cpp @@ -26,7 +26,7 @@ namespace Execute { char Path[256]; void *MemoryImage; - struct InterpreterIPCDataLibrary Libraries[256]; + struct InterpreterIPCDataLibrary Libraries[64]; } InterpreterIPCData; /* Passing arguments as a sanity check and debugging. */ @@ -42,7 +42,7 @@ namespace Execute Handle = Process->IPC->SearchByToken(UniqueToken); if (Handle == nullptr) debug("Failed"); - TaskManager->Sleep(100); + TaskManager->Sleep(200); if (Handle == nullptr) debug("Retrying..."); } @@ -56,6 +56,16 @@ namespace Execute { strcpy(TmpBuffer->Libraries[i].Name, NeededLibraries[i].c_str()); } + +#ifdef DEBUG + debug("Path: %s", TmpBuffer->Path); + debug("MemoryImage: %p", TmpBuffer->MemoryImage); + for (size_t i = 0; i < NeededLibraries.size(); i++) + { + debug("Library: %s", TmpBuffer->Libraries[i].Name); + } +#endif + int NotFoundRetry = 0; RetryIPCWrite: InterProcessCommunication::IPCErrorCode ret = Process->IPC->Write(Handle->ID, TmpBuffer, sizeof(InterpreterIPCData)); @@ -66,16 +76,6 @@ namespace Execute TaskManager->Sleep(100); goto RetryIPCWrite; } - else if (ret == InterProcessCommunication::IPCErrorCode::IPCIDNotFound) - { - if (NotFoundRetry < 100) - { - debug("IPC not found, retrying..."); - TaskManager->Sleep(1000); - NotFoundRetry++; - goto RetryIPCWrite; - } - } delete TmpBuffer; CPU::Halt(true); } @@ -216,7 +216,7 @@ namespace Execute { InterpreterTargetProcess = Process; InterpreterTargetPath = new String(Path); /* We store in a String because Path may get changed while outside ELFLoad(). */ - InterpreterMemoryImage = bl.MemoryImage; + InterpreterMemoryImage = bl.VirtualMemoryImage; InterpreterNeededLibraries = bl.NeededLibraries; __sync; TCB *InterpreterIPCThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ELFInterpreterThreadWrapper); diff --git a/Execute/Elf/Exec.cpp b/Execute/Elf/Exec.cpp index 53ddf67..834dfb2 100644 --- a/Execute/Elf/Exec.cpp +++ b/Execute/Elf/Exec.cpp @@ -29,6 +29,7 @@ namespace Execute uintptr_t BaseAddress = UINTPTR_MAX; uint64_t ElfAppSize = 0; uintptr_t EntryPoint = ELFHeader->e_entry; + debug("%s's entry point is %#lx", ExFile->Name, EntryPoint); Elf64_Phdr ItrPhdr; @@ -58,7 +59,7 @@ namespace Execute /* If required, MemoryImage will be at virtual address. (unless has PIE) * * tl;dr this is where the code is stored. */ - void *MemoryImage = ELFCreateMemoryImage(ELFBase.TmpMem, pV, ElfFile, ElfAppSize); + MmImage MemoryImage = ELFCreateMemoryImage(ELFBase.TmpMem, pV, ElfFile, ElfAppSize); debug("Solving symbols for address: %#llx", (uintptr_t)ElfFile); Elf64_Shdr *ElfSections = (Elf64_Shdr *)((uintptr_t)ElfFile + ELFHeader->e_shoff); @@ -87,7 +88,7 @@ namespace Execute /* Calculate entry point */ memcpy(&ItrPhdr, (uint8_t *)ElfFile + ELFHeader->e_phoff, sizeof(Elf64_Phdr)); if (ItrPhdr.p_vaddr == 0) - EntryPoint += (uintptr_t)MemoryImage; + EntryPoint += (uintptr_t)MemoryImage.Virtual; char InterpreterPath[256]; @@ -107,7 +108,7 @@ namespace Execute debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); - uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage; + uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal; fixme("Address: %#lx %s%s%s", MAddr, (ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "", @@ -191,14 +192,15 @@ namespace Execute ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile->node).Get()}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}}); - ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage}}}); + ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PAGESZ, .a_un = {.a_val = (uint64_t)PAGE_SIZE}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHNUM, .a_un = {.a_val = (uint64_t)ELFHeader->e_phnum}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHENT, .a_un = {.a_val = (uint64_t)ELFHeader->e_phentsize}}}); ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}}); ELFBase.InstructionPointer = EntryPoint; - ELFBase.MemoryImage = MemoryImage; + ELFBase.MemoryImage = MemoryImage.Phyiscal; + ELFBase.VirtualMemoryImage = MemoryImage.Virtual; ELFBase.Success = true; return ELFBase; diff --git a/Execute/Elf/Parse.cpp b/Execute/Elf/Parse.cpp index 9fed28c..a7dca44 100644 --- a/Execute/Elf/Parse.cpp +++ b/Execute/Elf/Parse.cpp @@ -140,7 +140,7 @@ namespace Execute return nullptr; } - void *ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length) + MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length) { void *MemoryImage = nullptr; Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile; @@ -153,7 +153,7 @@ namespace Execute fixme("Text relocation is not(?) tested yet!"); MemoryImage = (uint8_t *)mem->RequestPages(TO_PAGES(Length), true); memset(MemoryImage, 0, Length); - return MemoryImage; + return {MemoryImage, 0x0}; } Elf64_Phdr ItrPhdr; @@ -177,7 +177,7 @@ namespace Execute debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length)); MemoryImage = mem->RequestPages(TO_PAGES(Length), true); memset(MemoryImage, 0, Length); - return MemoryImage; + return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress}; } } @@ -195,7 +195,7 @@ namespace Execute pV.Remap((void *)((uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE)), (void *)((uintptr_t)MemoryImage + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); debug("Remapped: %#lx -> %#lx", (uintptr_t)FirstProgramHeaderVirtualAddress + (i * PAGE_SIZE), (uintptr_t)MemoryImage + (i * PAGE_SIZE)); } - return MemoryImage; + return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress}; } uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter) @@ -252,7 +252,7 @@ namespace Execute ElfAppSize = MAX(ElfAppSize, SegmentEnd); } - void *MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize); + MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize); for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) { @@ -265,7 +265,7 @@ namespace Execute debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx", ItrPhdr.p_offset, ItrPhdr.p_vaddr, ItrPhdr.p_filesz, ItrPhdr.p_memsz, ItrPhdr.p_align); - uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage; + uintptr_t MAddr = (ItrPhdr.p_vaddr - BaseAddress) + (uintptr_t)MemoryImage.Phyiscal; fixme("Address: %#lx %s%s%s", MAddr, (ItrPhdr.p_flags & PF_R) ? "R" : "", (ItrPhdr.p_flags & PF_W) ? "W" : "", @@ -277,8 +277,8 @@ namespace Execute } vfs->Close(File); - debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage + ELFHeader->e_entry, - (uintptr_t)MemoryImage, ELFHeader->e_entry); - return (uintptr_t)MemoryImage + ELFHeader->e_entry; + debug("Interpreter entry point: %#lx (%#lx + %#lx)", (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry, + (uintptr_t)MemoryImage.Phyiscal, ELFHeader->e_entry); + return (uintptr_t)MemoryImage.Phyiscal + ELFHeader->e_entry; } } diff --git a/Execute/Elf/SharedObjects.cpp b/Execute/Elf/SharedObjects.cpp index cb3d620..e167ba3 100644 --- a/Execute/Elf/SharedObjects.cpp +++ b/Execute/Elf/SharedObjects.cpp @@ -66,7 +66,7 @@ namespace Execute memcpy(LibFile, (void *)ElfImage, Length); Memory::Virtual ncpV = pV; - sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length); + sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal; { uintptr_t BaseAddress = UINTPTR_MAX; diff --git a/include/exec.hpp b/include/exec.hpp index 3b7338a..656ce93 100644 --- a/include/exec.hpp +++ b/include/exec.hpp @@ -62,6 +62,7 @@ namespace Execute Vector NeededLibraries; void *MemoryImage; + void *VirtualMemoryImage; /* This should be deleted after copying the allocated pages to the thread Intended to be used only inside BaseLoad.cpp */ @@ -71,6 +72,12 @@ namespace Execute Vector auxv; }; + struct MmImage + { + void *Phyiscal; + void *Virtual; + }; + BinaryType GetBinaryType(void *Image); BinaryType GetBinaryType(char *Path); @@ -94,9 +101,9 @@ namespace Execute * @param pV Memory::Virtual object to use * @param ElfFile ELF file loaded in memory (FULL FILE) * @param Length Length of @p ElfFile - * @return void* The Memory Image + * @return The Memory Image (Physical and Virtual) */ - void *ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length); + MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length); uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);