From 340a321cbee6328e49171df0c2d68bc7b38c0d77 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Mon, 3 Aug 2026 21:22:07 +0300 Subject: [PATCH] fix(header): fix read section headers --- core/relinker/include/relinker/ElfReader.hpp | 1 + core/relinker/include/relinker/IElfReader.hpp | 1 + core/relinker/include/relinker/Types.hpp | 5 +++ core/relinker/src/ElfReader.cpp | 23 ++++++++++++ core/relinker/src/main.cpp | 36 ++++++++++++++----- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/core/relinker/include/relinker/ElfReader.hpp b/core/relinker/include/relinker/ElfReader.hpp index 5bffef3d6..a6b0e286c 100644 --- a/core/relinker/include/relinker/ElfReader.hpp +++ b/core/relinker/include/relinker/ElfReader.hpp @@ -14,6 +14,7 @@ public: ElfHeader ReadHeader() const override; std::vector ReadProgramHeaders() const override; std::vector ReadSectionHeaders() const override; + std::vector ReadDynamicTags(const ProgramHeader& dynamicHeader) const override; std::vector ReadSection(const SectionHeader& header) const override; std::vector ReadSegment(const ProgramHeader& header) const override; std::uint64_t GetFileSize() const override; diff --git a/core/relinker/include/relinker/IElfReader.hpp b/core/relinker/include/relinker/IElfReader.hpp index 0e99e1cd1..8bf55e5e1 100644 --- a/core/relinker/include/relinker/IElfReader.hpp +++ b/core/relinker/include/relinker/IElfReader.hpp @@ -14,6 +14,7 @@ public: [[nodiscard]] virtual ElfHeader ReadHeader() const = 0; [[nodiscard]] virtual std::vector ReadProgramHeaders() const = 0; [[nodiscard]] virtual std::vector ReadSectionHeaders() const = 0; + [[nodiscard]] virtual std::vector ReadDynamicTags(const ProgramHeader& dynamicHeader) const = 0; [[nodiscard]] virtual std::vector ReadSection(const SectionHeader& header) const = 0; [[nodiscard]] virtual std::vector ReadSegment(const ProgramHeader& header) const = 0; [[nodiscard]] virtual std::uint64_t GetFileSize() const = 0; diff --git a/core/relinker/include/relinker/Types.hpp b/core/relinker/include/relinker/Types.hpp index 104d0ef7a..686d016b4 100644 --- a/core/relinker/include/relinker/Types.hpp +++ b/core/relinker/include/relinker/Types.hpp @@ -73,6 +73,11 @@ struct SymbolExport { CallSiteInfo CallSites; }; +struct DynamicTag { + std::int64_t Tag; + std::uint64_t Value; +}; + struct RelinkerException : std::runtime_error { FileByteOffset FailureOffset; diff --git a/core/relinker/src/ElfReader.cpp b/core/relinker/src/ElfReader.cpp index ffc40582a..1db0b75e1 100644 --- a/core/relinker/src/ElfReader.cpp +++ b/core/relinker/src/ElfReader.cpp @@ -168,6 +168,29 @@ std::string ElfReader::_resolveShdrName(std::uint32_t nameOffset, const ElfHeade return name; } +std::vector ElfReader::ReadDynamicTags(const ProgramHeader& dynamicHeader) const { + _loadFileIntoBuffer(); + + std::vector tags; + FileByteOffset offset = dynamicHeader.Offset; + const FileByteOffset end = dynamicHeader.Offset + dynamicHeader.FileSize; + + while (offset + 16 <= end && offset + 16 <= _fileBuffer.size()) { + DynamicTag tag; + tag.Tag = static_cast(_readU64At(offset)); + tag.Value = _readU64At(offset + 0x08); + + if (tag.Tag == 0) { + break; + } + + tags.push_back(tag); + offset += 16; + } + + return tags; +} + std::vector ElfReader::ReadSection(const SectionHeader& header) const { _loadFileIntoBuffer(); diff --git a/core/relinker/src/main.cpp b/core/relinker/src/main.cpp index 432e2b970..435a20878 100644 --- a/core/relinker/src/main.cpp +++ b/core/relinker/src/main.cpp @@ -26,7 +26,12 @@ std::shared_ptr MakeCallRegistryWriter(); static constexpr std::uint32_t PT_LOAD = 1; static constexpr std::uint32_t PT_DYNAMIC = 2; static constexpr std::uint32_t PT_SCE_DYNLIBDATA = 0x61000000; -static constexpr std::uint32_t SHT_NULL = 0; +static constexpr std::uint32_t PF_X = 0x1; + +static constexpr std::int64_t DT_PLTGOT = 0x00000003; +static constexpr std::int64_t DT_OS_PLTGOT = 0x61000027; +static constexpr std::int64_t DT_PLTRELSZ = 0x00000002; +static constexpr std::int64_t DT_OS_PLTRELSZ = 0x6100002d; static std::string _relocationTypeName(const std::uint32_t type) { switch (type) { @@ -62,7 +67,6 @@ int main(int argc, char* argv[]) { auto header = elfReader->ReadHeader(); auto programHeaders = elfReader->ReadProgramHeaders(); - auto sectionHeaders = elfReader->ReadSectionHeaders(); std::vector sceDynlibData; std::vector textSection; @@ -75,16 +79,30 @@ int main(int argc, char* argv[]) { sceDynlibData = elfReader->ReadSegment(ph); } - for (const auto& sh : sectionHeaders) { - if (sh.Name == ".text") { - textSection = elfReader->ReadSection(sh); - textVAddr = sh.MappedAddress; - } else if (sh.Name == ".got" || sh.Name == ".got.plt") { - gotVAddr = sh.MappedAddress; - gotSize = sh.SectionSize; + for (const auto& ph : programHeaders) { + if (ph.Type == PT_LOAD && (ph.Flags & PF_X) != 0) { + textSection = elfReader->ReadSegment(ph); + textVAddr = ph.MappedAddress; + break; } } + for (const auto& ph : programHeaders) { + if (ph.Type != PT_DYNAMIC) + continue; + + auto dynTags = elfReader->ReadDynamicTags(ph); + + for (const auto& tag : dynTags) { + if (tag.Tag == DT_PLTGOT || tag.Tag == DT_OS_PLTGOT) + gotVAddr = tag.Value; + else if (tag.Tag == DT_PLTRELSZ || tag.Tag == DT_OS_PLTRELSZ) + gotSize = tag.Value; + } + + break; + } + if (sceDynlibData.empty()) throw Relinker::RelinkerException("SCE_DYNLIBDATA segment not found");