fxos/lib/os.cpp

121 lines
2.3 KiB
C++

#include <fxos/os.h>
#include <fxos/target.h>
#include <fxos/memory.h>
#include <cstring>
namespace FxOS {
OS::OS(Buffer &buffer): target()
{
/* OS files are all at least 1 MB large */
if(buffer.size() < 1000000)
throw std::runtime_error("OS files cannot be < 1MB");
/* Bind the given file to the internal analysis target */
this->target.bind_region(MemoryRegion::ROM, buffer);
this->target.bind_region(MemoryRegion::ROM_P2, buffer);
parse_header();
parse_syscall_table();
parse_footer();
}
void OS::parse_header()
{
Target &t = this->target;
/* Bootcode timestamp at 0xffb0 (the very end of the bootcode) */
this->bootcode_timestamp = t.read_str(0x8000ffb0, 14);
/* Bootcode checksum at 0xfffc */
this->bootcode_checksum = t.read_u32(0x8000fffc);
/* Version string at 0x10020 */
this->version = t.read_str(0x80010020, 10);
/* Serial numer at 0xffd0... sometimes? */
this->serial_number = t.read_str(0x8000ffd0, 8);
}
//---
// Syscall resolution
//---
int OS::syscall_count() const noexcept
{
return m_syscall_table.size();
}
uint32_t OS::syscall(int id) const
{
return m_syscall_table[id];
}
int OS::find_syscall(uint32_t entry) const noexcept
{
try {
return m_syscall_addresses.at(entry);
}
catch(std::out_of_range &e) {
return -1;
}
}
void OS::parse_syscall_table()
{
Target &t = this->target;
/* Traverse the syscall table */
uint32_t syscall_table = t.read_u32(0x8001007c);
int id = 0;
while(1)
{
uint32_t entry = t.read_u32(syscall_table + 4 * id);
MemoryRegion const *r = MemoryRegion::region_for(entry);
if(!r) break;
m_syscall_table.push_back(entry);
m_syscall_addresses[entry] = id;
id++;
}
}
//---
// Footer search
//---
void OS::parse_footer()
{
Target &t = this->target;
/* Find the footer address (occurrence of "CASIOABSLangdata") */
uint32_t start = MemoryRegion::ROM.start;
uint32_t end = MemoryRegion::ROM.end;
this->footer = t.search(start, end, "CASIOABSLangdata", 16);
if(this->footer == end)
{
this->footer = -1;
this->timestamp = std::string("");
this->bootcode_timestamp = std::string("");
this->langdata = 0;
return;
}
uint32_t addr = this->footer + 8;
this->langdata = 0;
while(!memcmp(t.translate(addr, 8), "Langdata", 8))
{
this->langdata++;
addr += 0x30;
}
this->timestamp = t.read_str(addr, 14);
this->checksum = t.read_u32(addr + 0x18);
}
} /* namespace FxOS */