示例#1
0
文件: patcher.c 项目: God-Sec/Luma3DS
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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
0
static void loadCustomVerString(u16 *out, u32 *verStringSize, u32 currentNand)
{
    static const char *paths[] = { "/puma/customversion_sys.txt",
                                   "/puma/customversion_emu.txt",
                                   "/puma/customversion_emu2.txt",
                                   "/puma/customversion_emu3.txt",
                                   "/puma/customversion_emu4.txt" };

    IFile file;

    if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, paths[currentNand], FS_OPEN_READ)))
    {
        u64 fileSize;

        if(R_SUCCEEDED(IFile_GetSize(&file, &fileSize)) && fileSize <= 62)
        {
            u8 buf[fileSize];
            u64 total;

            if(R_SUCCEEDED(IFile_Read(&file, &total, buf, fileSize)))
            {
                static const u8 bom[] = {0xEF, 0xBB, 0xBF};
                u32 finalSize = 0;

                //Convert from UTF-8 to UTF-16 (Nintendo doesn't support 4-byte UTF-16, so 4-byte UTF-8 is unsupported)
                for(u32 increase, fileSizeTmp = (u32)fileSize, i = (fileSizeTmp > 2 && memcmp(buf, bom, 3) == 0) ? 3 : 0;
                    i < fileSizeTmp && finalSize < 19; i += increase, finalSize++)
                {
                    if((buf[i] & 0x80) == 0 && !(buf[i] == 0xA || buf[i] == 0xD))
                    {
                        increase = 1;
                        out[finalSize] = (u16)buf[i];
                    }
                    else if((buf[i] & 0xE0) == 0xC0 && i + 1 < fileSizeTmp && (buf[i + 1] & 0xC0) == 0x80)
                    {
                        increase = 2;
                        out[finalSize] = (u16)(((buf[i] & 0x1F) << 6) | (buf[i + 1] & 0x3F));
                    }
                    else if((buf[i] & 0xF0) == 0xE0 && i + 2 < fileSizeTmp && (buf[i + 1] & 0xC0) == 0x80 && (buf[i + 2] & 0xC0) == 0x80)
                    {
                        increase = 3;
                        out[finalSize] = (u16)(((buf[i] & 0xF) << 12) | ((buf[i + 1] & 0x3F) << 6) | (buf[i + 2] & 0x3F));
                    }
                    else break;
                }

                if(finalSize > 0)
                {
                    if(finalSize > 5 && finalSize < 19) out[finalSize++] = 0;
                    *verStringSize = finalSize * 2;
                }
            }
        }

        IFile_Close(&file);
    }
}
示例#5
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;
}
示例#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";

    u32 i = 29;

    while(progId)
    {
        static const char hexDigits[] = "0123456789ABCDEF";
        path[i--] = hexDigits[(u32)(progId & 0xF)];
        progId >>= 4;
    }

    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;
}
示例#7
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);
    }
}
示例#8
0
static u32 loadConfig(void)
{
    static u32 config = 0;

    if(!config)
    {
        IFile file;
        if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/luma/config.bin", FS_OPEN_READ)))
        {
            u64 total;
            if(R_SUCCEEDED(IFile_Read(&file, &total, &config, 4))) config |= 1 << 4;
            IFile_Close(&file);
        }
    }

    return config;
}
示例#9
0
static int loadCountryConfig(char *countryString)
{
    /* Here we look for "/puma/locales/country.txt"
       If it exists it should contain, for example, "GB" */
    char path[] = "/puma/locales/country.txt";

    IFile file;
    Result ret = fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ);
    if(R_SUCCEEDED(ret))
    {
        u64 total;

        ret = IFile_Read(&file, &total, countryString, 2);
        IFile_Close(&file);

        if(!R_SUCCEEDED(ret) || total < 2) return -1;
		return 0;
	}
    return ret;
}
示例#10
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);
    }
}
示例#11
0
文件: main.11.c 项目: b1l1s/2xrsa
int __attribute__ ((section (".text.a11.entry"))) _main()
{
	svc_sleepThread(0x10000000);
	
	// Get framebuffer addresses
	uint32_t regs[10];
	
	regs[0] = 0xDEADBABE;
	regs[1] = 0xBABEDADA;

	//FIXME where do these reg addresses come from?
	_GSPGPU_ReadHWRegs(gspHandle, 0x400468, &regs[0+2], 8); // framebuffer 1 top left & framebuffer 2 top left
	_GSPGPU_ReadHWRegs(gspHandle, 0x400494, &regs[2+2], 8); // framebuffer 1 top right & framebuffer 2 top right
	_GSPGPU_ReadHWRegs(gspHandle, 0x400568, &regs[4+2], 8); // framebuffer 1 bottom & framebuffer 2 bottom
	_GSPGPU_ReadHWRegs(gspHandle, 0x400478, &regs[6+2], 4); // framebuffer select top
	_GSPGPU_ReadHWRegs(gspHandle, 0x400578, &regs[7+2], 4); // framebuffer select bottom
	
	//patch gsp event handler addr to kill gsp thread ASAP, PA 0x267CF418
	*((u32*)(0x003F8418+0x10+4*0x4))=0x002CA520; //svc 0x9 addr
	flashScreen();
	svc_sleepThread(0x10000000);

	// Read the main payload to 0x17F00000(0x23F00000 pa)
	u32* buffer = (work_buffer + 0x10000/sizeof(u32));

	IFILE file;
	unsigned int readBytes;
	_memset(&file, 0, sizeof(file));
	IFile_Open(&file, L"dmc:/arm9.bin", 1);
	
	const uint32_t block_size = 0x10000;
	for(u32 i = 0; i < 0x20000u; i += block_size)
	{
		IFile_Read(&file, &readBytes, (void*)buffer, block_size);
		GSPGPU_FlushDataCache(buffer, block_size);
		GX_SetTextureCopy(buffer, (void *)(0x17F00000 + i), block_size, 0, 0, 0, 0, 8);
		if(readBytes != block_size)
			break;
	}

	// Copy the magic to 0x18410000
	// Copy it twice to make it easier to find and avoid catching the wrong one
	buffer[0] = MAGIC_WORD;
	buffer[1] = MAGIC_WORD;
	
	if(regs[6+2])
	{
		buffer[2] = regs[0+2];
		buffer[3] = regs[2+2];
	}
	else
	{
		buffer[2] = regs[1+2];
		buffer[3] = regs[3+2];
	}
	
	if(regs[7+2])
		buffer[4] = regs[4+2];
	else
		buffer[4] = regs[5+2];

	// Grab access to PS
	Handle port;
	svc_connectToPort(&port, "srv:pm");
	
	srv_RegisterClient(&port);
	
	u32 proc = 0;
	svc_getProcessId(&proc, 0xFFFF8001);
	
	srvUnregisterProcess(&port, proc);
	
	srvRegisterProcess(&port, proc, 0x18, (const void*)&access_bin[0]);
	
	Handle ps_handle = 0;
	srv_getServiceHandle(&port, &ps_handle, "ps:ps");
	
	svc_sleepThread(0x10000000);

	// Perform the exploit
	Result res = PS_VerifyRsaSha256(&ps_handle);

	// We do not expect reaching here
	return 0;
}