devkitPro / wut

Let's try to make a Wii U Toolchain / SDK for creating rpx/rpl.
zlib License
244 stars 52 forks source link

Figure out what signature is in SHT_RPL_IMPORT #2

Closed exjam closed 8 years ago

exjam commented 8 years ago

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

shinyquagsire23 commented 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> &sections, uint32_t index, Section &section)
{
   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.