Fix crash that occurs when trying to read an ELF with truncated section headers.

Was the case with Psychonauts.
This commit is contained in:
Jean-Philip Desjardins 2023-08-26 20:37:38 -04:00
parent 89f5384876
commit b8f2362895
4 changed files with 26 additions and 13 deletions

View file

@ -42,10 +42,10 @@ public:
typedef typename ElfTraits::ELFSECTIONHEADER SECTIONHEADER;
typedef typename ElfTraits::ELFSYMBOL SYMBOL;
CELF(uint8* content)
CELF(uint8* content, uint64 contentSize = ~0ULL)
: m_content(content)
{
Framework::CPtrStream stream(m_content, -1);
Framework::CPtrStream stream(m_content, contentSize);
stream.Read(&m_header, sizeof(m_header));
@ -173,13 +173,19 @@ private:
{
SECTIONHEADER zeroSectionHeader = {};
stream.Seek(m_header.nSectHeaderStart, Framework::STREAM_SEEK_SET);
stream.Read(&zeroSectionHeader, sizeof(zeroSectionHeader));
if(m_header.nId[ELF::EI_DATA] == ELF::ELFDATA2MSB)
//Some ELF files have their section headers truncated (ex.: Psychonauts PS2)
//Make sure that we were able to read the zeroth section header
//properly before proceeding
auto amountRead = stream.Read(&zeroSectionHeader, sizeof(zeroSectionHeader));
if(amountRead == sizeof(zeroSectionHeader))
{
Framework::CEndian::FromMSBF(zeroSectionHeader.nSize);
if(m_header.nId[ELF::EI_DATA] == ELF::ELFDATA2MSB)
{
Framework::CEndian::FromMSBF(zeroSectionHeader.nSize);
}
assert(zeroSectionHeader.nSize != 0);
sectionHeaderCount = zeroSectionHeader.nSize;
}
assert(zeroSectionHeader.nSize != 0);
sectionHeaderCount = zeroSectionHeader.nSize;
}
else
{

View file

@ -2,9 +2,9 @@
CElfFileContainer::CElfFileContainer(Framework::CStream& input)
{
uint32 size = static_cast<uint32>(input.GetLength());
m_content = new uint8[size];
input.Read(m_content, size);
m_size = input.GetLength();
m_content = new uint8[m_size];
input.Read(m_content, m_size);
}
CElfFileContainer::~CElfFileContainer()
@ -16,3 +16,8 @@ uint8* CElfFileContainer::GetFileContent() const
{
return m_content;
}
uint64 CElfFileContainer::GetFileSize() const
{
return m_size;
}

View file

@ -10,9 +10,11 @@ public:
virtual ~CElfFileContainer();
uint8* GetFileContent() const;
uint64 GetFileSize() const;
private:
uint8* m_content;
uint8* m_content = nullptr;
uint64 m_size = 0;
};
template <typename ElfType>
@ -21,7 +23,7 @@ class CElfFile : protected CElfFileContainer, public ElfType
public:
CElfFile(Framework::CStream& stream)
: CElfFileContainer(stream)
, ElfType(GetFileContent())
, ElfType(GetFileContent(), GetFileSize())
{
}

2
deps/Framework vendored

@ -1 +1 @@
Subproject commit 0f5922ebc4bb9161f8d29884e6f44e4c019aeae8
Subproject commit 2dadb6dfcbc855c08a6f0bdea90e0572ac4ee0b8