Skip to content

Commit

Permalink
Handle out of bounds IOP exports.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Jul 22, 2024
1 parent aa1bc3e commit 6a9b2d0
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Source/iop/IopBios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void CIopBios::SaveState(Framework::CZipArchiveWriter& archive)
{
CRegisterState moduleState;
{
uint32 importTableAddress = reinterpret_cast<uint8*>(dynamicModule->GetExportTable()) - m_ram;
uint32 importTableAddress = reinterpret_cast<const uint8*>(dynamicModule->GetExportTable()) - m_ram;
moduleState.SetRegister32(STATE_MODULE_IMPORT_TABLE_ADDRESS, importTableAddress);
}
modulesFile->InsertRegisterState(dynamicModule->GetId().c_str(), std::move(moduleState));
Expand Down
45 changes: 38 additions & 7 deletions Source/iop/Iop_Dynamic.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
#include <cstring>
#include "Iop_Dynamic.h"
#include "Log.h"

#define LOG_NAME ("iop_dynamic")

using namespace Iop;

CDynamic::CDynamic(uint32* exportTable)
static constexpr uint32 g_exportModuleNameOffset = 3;
static constexpr uint32 g_exportFctTableOffset = 5;

CDynamic::CDynamic(const uint32* exportTable)
: m_exportTable(exportTable)
{
m_name = GetDynamicModuleName(exportTable);
m_functionCount = GetDynamicModuleExportCount(exportTable);
}

std::string CDynamic::GetDynamicModuleName(uint32* exportTable)
std::string CDynamic::GetDynamicModuleName(const uint32* exportTable)
{
//Name is 8 bytes long without zero, so we need to make sure it's properly null-terminated
const unsigned int nameLength = 8;
char name[nameLength + 1];
memset(name, 0, nameLength + 1);
memcpy(name, reinterpret_cast<const char*>(exportTable) + 12, nameLength);
memcpy(name, reinterpret_cast<const char*>(exportTable + g_exportModuleNameOffset), nameLength);
return name;
}

uint32 CDynamic::GetDynamicModuleExportCount(const uint32* exportTable)
{
//Export tables are supposed to finish with a 0 value.
uint32 functionCount = 0;
while(exportTable[g_exportFctTableOffset + functionCount] != 0)
{
functionCount++;
if(functionCount >= 1000)
{
CLog::GetInstance().Warn(LOG_NAME, "Export count exceeded threshold of %d functions. Bailing.\r\n", functionCount);
break;
}
}
return functionCount;
}

std::string CDynamic::GetId() const
{
return m_name;
Expand All @@ -33,12 +56,20 @@ std::string CDynamic::GetFunctionName(unsigned int functionId) const

void CDynamic::Invoke(CMIPS& context, unsigned int functionId)
{
uint32 functionAddress = m_exportTable[5 + functionId];
context.m_State.nGPR[CMIPS::RA].nD0 = context.m_State.nPC;
context.m_State.nPC = functionAddress;
if(functionId < m_functionCount)
{
uint32 functionAddress = m_exportTable[g_exportFctTableOffset + functionId];
context.m_State.nGPR[CMIPS::RA].nD0 = context.m_State.nPC;
context.m_State.nPC = functionAddress;
}
else
{
CLog::GetInstance().Warn(LOG_NAME, "Failed to find export %d for module '%s'.\r\n",
functionId, m_name.c_str());
}
}

uint32* CDynamic::GetExportTable() const
const uint32* CDynamic::GetExportTable() const
{
return m_exportTable;
}
10 changes: 6 additions & 4 deletions Source/iop/Iop_Dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ namespace Iop
class CDynamic : public CModule
{
public:
CDynamic(uint32*);
CDynamic(const uint32*);
virtual ~CDynamic() = default;

static std::string GetDynamicModuleName(uint32*);
static std::string GetDynamicModuleName(const uint32*);
static uint32 GetDynamicModuleExportCount(const uint32*);

std::string GetId() const override;
std::string GetFunctionName(unsigned int) const override;
void Invoke(CMIPS&, unsigned int) override;

uint32* GetExportTable() const;
const uint32* GetExportTable() const;

private:
uint32* m_exportTable;
const uint32* m_exportTable;
std::string m_name;
uint32 m_functionCount = 0;
};

typedef std::shared_ptr<CDynamic> DynamicPtr;
Expand Down

0 comments on commit 6a9b2d0

Please sign in to comment.