Merge pull request #184 from YossiYad/fix/self-input-diagnostic

fix(relinker): name the SELF container and the bytes read when the input is not an ELF
This commit is contained in:
boykopovar 2026-10-01 11:53:18 +03:00 committed by GitHub
commit 8cc16ec23a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 1 deletions

View File

@ -182,6 +182,8 @@ if(BUILD_TESTING)
${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_guest_tls.py $<TARGET_FILE:relinker>)
add_test(NAME elf_header COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_elf_header.py $<TARGET_FILE:relinker>)
add_test(NAME input_magic COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/relinker/tests/test_input_magic.py $<TARGET_FILE:relinker>)
else()
message(STATUS "Python3 interpreter not found; skipping Python relinker tests")
endif()

View File

@ -29,6 +29,7 @@ private:
std::uint16_t _readU16At(FileByteOffset offset) const;
std::uint8_t _readU8At(FileByteOffset offset) const;
std::string _resolveShdrName(std::uint32_t nameOffset, const ElfHeader& header) const;
std::string formatMagic() const;
};
}

View File

@ -21,6 +21,17 @@ const std::vector<std::uint8_t>& ElfReader::GetRawBytes() const {
return _fileBuffer;
}
std::string ElfReader::formatMagic() const {
static constexpr char digits[] = "0123456789abcdef";
std::string text;
for (std::size_t index = 0; index < 4; ++index) {
if (index != 0) text += ' ';
text += digits[_fileBuffer[index] >> 4];
text += digits[_fileBuffer[index] & 0x0f];
}
return text;
}
std::uint8_t ElfReader::_readU8At(FileByteOffset fileByteOffset) const {
if (fileByteOffset >= _fileBuffer.size()) {
throw RelinkerException("FileByteOffset out of bounds", fileByteOffset);
@ -60,9 +71,13 @@ ElfHeader ElfReader::ReadHeader() const {
throw RelinkerException("File too small for ELF header");
}
if (_fileBuffer[0] == 0x4f && _fileBuffer[1] == 0x15 && _fileBuffer[2] == 0x3d && _fileBuffer[3] == 0x1d) {
throw RelinkerException("The input is a SELF container, not an ELF");
}
if (_fileBuffer[0] != 0x7f || _fileBuffer[1] != 'E' ||
_fileBuffer[2] != 'L' || _fileBuffer[3] != 'F') {
throw RelinkerException("Invalid ELF magic number");
throw RelinkerException("Invalid ELF magic number: " + formatMagic());
}
ElfHeader header{};

View File

@ -0,0 +1,29 @@
"""Reject inputs that are not plain ELF files with a message that names what was read."""
from pathlib import Path
import subprocess
import sys
import tempfile
def main():
relinker = Path(sys.argv[1]).resolve()
with tempfile.TemporaryDirectory(prefix="anyps5-magic-") as directory:
work = Path(directory)
def convert(name, content, error):
source = work / name
source.write_bytes(content)
output = work / (name + ".out")
result = subprocess.run([str(relinker), "--skip-sce-module", str(source), str(output)],
capture_output=True, text=True, timeout=20)
assert result.returncode == 2 and error in result.stderr and not output.exists(), (name, result)
convert("eboot.self", b"\x4f\x15\x3d\x1d" + bytes(0x1000), "The input is a SELF container, not an ELF")
convert("eboot.pkg", b"\x7fCNT" + bytes(0x1000), "Invalid ELF magic number: 7f 43 4e 54")
convert("eboot.short", b"\x7fEL", "File too small for ELF header")
print("Input magic diagnostics tests passed")
if __name__ == "__main__":
main()