Beispiel #1
0
static int loadTitleCodeSection(u64 progId, u8 *code, u32 size)
{
    /* Here we look for "/luma/code_sections/[u64 titleID in hex, uppercase].bin"
       If it exists it should be a decompressed binary code file */
    
    char path[] = "/luma/code_sections/0000000000000000.bin";
    progIdToStr(path + 35, progId);

    IFile file;
    Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ);
    
    if(R_SUCCEEDED(ret))
    {
        u64 fileSize, total;
        
        ret = IFile_GetSize(&file, &fileSize);
        if(!R_SUCCEEDED(ret) || fileSize > size) return -1;
        
        ret = IFile_Read(&file, &total, code, fileSize);
        IFile_Close(&file);
        if(!R_SUCCEEDED(ret)) return -1;
        else if(total < fileSize) return -2; //Shouldn't happen
    }
    
    return ret;
}
Beispiel #2
0
static inline bool patchRomfsRedirection(u64 progId, u8* code, u32 size)
{
    /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/romfs"
       If it exists it should be a decrypted raw RomFS */

    char path[] = "/luma/titles/0000000000000000/romfs";
    progIdToStr(path + 28, progId);

    IFile file;
    u32 archive = openLumaFile(&file, path);

    if(!archive) return true;

    bool ret = false;
    u64 romfsSize;

    if(R_FAILED(IFile_GetSize(&file, &romfsSize))) goto exit;

    u64 total;
    u32 magic;

    if(R_FAILED(IFile_Read(&file, &total, &magic, 4)) || total != 4 || magic != 0x43465649) goto exit;

    u32 fsOpenFileDirectly = findFunctionCommand(code, size, 0x08030204),
        throwFatalError = findThrowFatalError(code, size);

    if(fsOpenFileDirectly == 0xFFFFFFFF || throwFatalError == 0xFFFFFFFF) goto exit;

    //Setup the payload
    u8 *payload = code + throwFatalError;
    memcpy(payload, romfsredir_bin, romfsredir_bin_size);
    memcpy(payload + romfsredir_bin_size, path, sizeof(path));
    *(u32 *)(payload + 0xC) = *(u32 *)(code + fsOpenFileDirectly);

    u32 *payloadSymbols = (u32 *)(payload + romfsredir_bin_size - 0x24);
    payloadSymbols[0] = 0x100000 + fsOpenFileDirectly + 4;
    *(u64 *)(payloadSymbols + 2) = 0x1000ULL;
    *(u64 *)(payloadSymbols + 4) = romfsSize - 0x1000ULL;
    payloadSymbols[6] = archive;
    payloadSymbols[7] = sizeof(path);
    payloadSymbols[8] = 0x100000 + throwFatalError + romfsredir_bin_size; //String pointer

    //Place the hooks
    *(u32 *)(code + fsOpenFileDirectly) = MAKE_BRANCH(fsOpenFileDirectly, throwFatalError);

    u32 fsOpenLinkFile = findFunctionCommand(code, size, 0x80C0000);

    if(fsOpenLinkFile != 0xFFFFFFFF)
    {
        *(u32 *)(code + fsOpenLinkFile) = 0xE3A03003; //mov r3, #3
        *(u32 *)(code + fsOpenLinkFile + 4) = MAKE_BRANCH(fsOpenLinkFile + 4, throwFatalError);
    }

    ret = true;

exit:
    IFile_Close(&file);

    return ret;
}
Beispiel #3
0
static inline bool loadTitleCodeSection(u64 progId, u8 *code, u32 size)
{
    /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/code.bin"
       If it exists it should be a decrypted and decompressed binary code file */

    char path[] = "/luma/titles/0000000000000000/code.bin";
    progIdToStr(path + 28, progId);

    IFile file;

    if(!openLumaFile(&file, path)) return true;

    bool ret;
    u64 fileSize;

    if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize > size) ret = false;
    else
    {
        u64 total;

        ret = R_SUCCEEDED(IFile_Read(&file, &total, code, fileSize)) && total == fileSize;
    }

    IFile_Close(&file);

    return ret;
}
Beispiel #4
0
static inline bool loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
{
    /* Here we look for "/luma/titles/[u64 titleID in hex, uppercase]/locale.txt"
       If it exists it should contain, for example, "EUR IT" */

    char path[] = "/luma/titles/0000000000000000/locale.txt";
    progIdToStr(path + 28, progId);

    IFile file;

    if(!openLumaFile(&file, path)) return true;

    bool ret = false;
    u64 fileSize;

    if(R_FAILED(IFile_GetSize(&file, &fileSize)) || fileSize < 6 || fileSize > 8) goto exit;

    char buf[8];
    u64 total;

    if(R_FAILED(IFile_Read(&file, &total, buf, fileSize))) goto exit;

    u32 i,
        j;

    for(i = 0; i < 7; i++)
    {
        static const char *regions[] = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"};

        if(memcmp(buf, regions[i], 3) == 0)
        {
            *regionId = (u8)i;
            break;
        }
    }

    for(j = 0; j < 12; j++)
    {
        static const char *languages[] = {"JP", "EN", "FR", "DE", "IT", "ES", "ZH", "KO", "NL", "PT", "RU", "TW"};

        if(memcmp(buf + 4, languages[j], 2) == 0)
        {
            *languageId = (u8)j;
            break;
        }
    }

    ret = i != 7 && j != 12;

exit:
    IFile_Close(&file);

    return ret;
}
Beispiel #5
0
static void loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
{
    /* Here we look for "/puma/locales/[u64 titleID in hex, uppercase].txt"
       If it exists it should contain, for example, "EUR IT" */

    char path[] = "/puma/locales/0000000000000000.txt";
    progIdToStr(path + 29, progId);

    IFile file;

    if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
    {
        u64 fileSize;

        if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize > 5 && fileSize < 9)
        {
            char buf[fileSize];
            u64 total;

            if(R_SUCCEEDED(IFile_Read(&file, &total, buf, fileSize)))
            {
                for(u32 i = 0; i < 7; i++)
                {
                    static const char *regions[] = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"};

                    if(memcmp(buf, regions[i], 3) == 0)
                    {
                        *regionId = (u8)i;
                        break;
                    }
                }

                for(u32 i = 0; i < 12; i++)
                {
                    static const char *languages[] = {"JP", "EN", "FR", "DE", "IT", "ES", "ZH", "KO", "NL", "PT", "RU", "TW"};

                    if(memcmp(buf + 4, languages[i], 2) == 0)
                    {
                        *languageId = (u8)i;
                        break;
                    }
                }
            }
        }

        IFile_Close(&file);
    }
}
Beispiel #6
0
static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
{
    /* Here we look for "/luma/locales/[u64 titleID in hex, uppercase].txt"
       If it exists it should contain, for example, "EUR IT" */

    char path[] = "/luma/locales/0000000000000000.txt";
    progIdToStr(path + 29, progId);

    IFile file;
    Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ);
    if(R_SUCCEEDED(ret))
    {
        char buf[6];
        u64 total;

        ret = IFile_Read(&file, &total, buf, 6);
        IFile_Close(&file);

        if(!R_SUCCEEDED(ret) || total < 6) return -1;

        for(u32 i = 0; i < 7; ++i)
        {
            static const char *regions[] = {"JPN", "USA", "EUR", "AUS", "CHN", "KOR", "TWN"};

            if(memcmp(buf, regions[i], 3) == 0)
            {
                *regionId = (u8)i;
                break;
            }
        }
        
        for(u32 i = 0; i < 12; ++i)
        {
            static const char *languages[] = {"JP", "EN", "FR", "DE", "IT", "ES", "ZH", "KO", "NL", "PT", "RU", "TW"};

            if(memcmp(buf + 4, languages[i], 2) == 0)
            {
                *languageId = (u8)i;
                break;
            }
        }
    }

    return ret;
}
Beispiel #7
0
static void loadTitleCodeSection(u64 progId, u8 *code, u32 size)
{
    /* Here we look for "/puma/code_sections/[u64 titleID in hex, uppercase].bin"
       If it exists it should be a decompressed binary code file */

    char path[] = "/puma/code_sections/0000000000000000.bin";
    progIdToStr(path + 35, progId);

    IFile file;

    if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
    {
        u64 fileSize;

        if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize <= size)
        {
            u64 total;
            IFile_Read(&file, &total, code, fileSize);
        }

        IFile_Close(&file);
    }
}