Closed exjam closed 8 years ago
Figured this one out, the signature is a crc over each imported symbol for the section, except STT_SECTION symbols. Ran a test using this (somewhat hacked in) function within readrpl on Sm4sh's cross_f.rpx, and so far it seems pretty solid:
static void
formatRplImports(fmt::MemoryWriter &out, std::vector<Section> §ions, uint32_t index, Section §ion)
{
auto import = reinterpret_cast<elf::RplImport *>(section.data.data());
out.write(" name = {}\n", import->name);
out.write(" signature = 0x{:08X}\n", static_cast<uint32_t>(import->signature));
out.write(" count = {}\n", import->count);
auto crc = 0u;
crc = crc32(0, Z_NULL, 0);
if (import->count) {
for (auto &symSection : sections) {
if (symSection.header.type != elf::SHT_SYMTAB) {
continue;
}
auto symbols = reinterpret_cast<elf::Symbol *>(symSection.data.data());
auto count = symSection.data.size() / sizeof(elf::Symbol);
auto strTab = reinterpret_cast<const char*>(sections[symSection.header.link].data.data());
for (auto i = 0u; i < count; ++i) {
auto &symbol = symbols[i];
if (symbol.shndx == index) {
out.write(" {} 0x{:08X} 0x{:08X}\n", strTab + symbol.name, symbol.other.value(), symbol.info.value());
if((symbol.info.value() & 0xF) != elf::STT_SECTION)
{
crc = crc32(crc, reinterpret_cast<const Bytef *>(strTab + symbol.name), strlen(strTab + symbol.name)+1);
printf("%x %x %x\n", crc, strlen(strTab + symbol.name)+1, symbol.info.value());
}
}
}
}
}
char *nothing = reinterpret_cast<char*>(malloc(0x10));
memset(nothing, 0, 0x10);
crc = crc32(crc, reinterpret_cast<const Bytef *>(nothing), 0xE);
printf("Redicted signature: %x\n", crc);
}
Might see if I can't integrate this into elf2rpl later, I don't think it'll be too hard? My C++ is kinda meh at the moment.
No clue what this is or how it is calculated to be honest.
https://github.com/decaf-emu/wut/blob/83e6b4c0042b590e1bf361feaf0fff5e720446f9/tools/elf2rpl/main.cpp#L622