forked from Lephenixnoir/fxos
111 lines
2.0 KiB
C++
111 lines
2.0 KiB
C++
#include <fxos/os.h>
|
|
#include <fxos/target.h>
|
|
#include <fxos/memory.h>
|
|
|
|
#include <cstring>
|
|
|
|
namespace FxOS {
|
|
|
|
OS::OS(File &file): m_target()
|
|
{
|
|
/* OS files are all at least 1 MB large */
|
|
if(file.size() < 1000000)
|
|
throw std::runtime_error("OS files cannot be < 1MB");
|
|
|
|
/* Bind the given file to the internal analysis target */
|
|
m_target.bind_region(MemoryRegion::ROM, file);
|
|
m_target.bind_region(MemoryRegion::ROM_P2, file);
|
|
|
|
parse_version();
|
|
parse_syscall_table();
|
|
// parse_footer();
|
|
}
|
|
|
|
void OS::parse_version()
|
|
{
|
|
/* Extract the version string at 0x10020 */
|
|
Target &t = m_target;
|
|
|
|
char *version = (char *)t.translate(0x80010020, 10);
|
|
m_version = std::string(version, 10);
|
|
}
|
|
|
|
//---
|
|
// Syscalle 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 = m_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
|
|
//---
|
|
|
|
uint32_t OS::footer() const noexcept
|
|
{
|
|
return m_footer;
|
|
}
|
|
|
|
void OS::parse_footer()
|
|
{
|
|
/* Find the footer address (last occurrence of "CASIOABSLangdata") */
|
|
uint32_t start = MemoryRegion::ROM.start;
|
|
uint32_t end = MemoryRegion::ROM.end;
|
|
|
|
m_target.search(start, end, "CASIOABSLangdata", 16);
|
|
#if 0
|
|
char const *signature = "CASIOABSLangdata";
|
|
void *occ = NULL, *next = memmem(os->data, os->len, signature, 16);
|
|
void *end = os->data + os->len;
|
|
|
|
while(next)
|
|
{
|
|
occ = next;
|
|
next = memmem(next + 1, end - (next + 1), signature, 16);
|
|
}
|
|
|
|
os->footer = (occ) ? (occ - os->data) : (uint32_t)-1;
|
|
#endif
|
|
}
|
|
|
|
} /* namespace FxOS */
|