Exemplo n.º 1
0
void DrawMenu(MenuInfo* currMenu, u32 index, bool fullDraw, bool subMenu)
{
    u32 emunand_state = CheckEmuNand();
    bool top_screen = true;
    u32 menublock_x0 = (((top_screen) ? SCREEN_WIDTH_TOP : SCREEN_WIDTH_BOT) - 50 * FONT_WIDTH_EXT) / 2;
    u32 menublock_x1 = menublock_x0 - FONT_WIDTH_EXT;
    u32 menublock_y0 = 40;
    u32 menublock_y1 = menublock_y0 + currMenu->n_entries * 10;
    
    if (fullDraw) { // draw full menu
        ClearScreenFull(true, !top_screen);
		FileGetData("lima/border.bin", TOP_SCREEN0, 400 * 240 * 3, 0);
        DrawStringF(menublock_x0 - 25, menublock_y0 - 30, top_screen, "%s", currMenu->name);
        DrawStringF(menublock_x0, menublock_y1 + 95, top_screen, (subMenu) ? "A: Choose  B: Return" : "A: Choose");
        DrawStringF(menublock_x0, menublock_y1 + 105, top_screen, "SELECT: Unmount SD Card");
        DrawStringF(menublock_x0, menublock_y1 + 115, top_screen, "START:  Reboot / [+\x1B] Poweroff");
		}
    
    if (!top_screen)
        DrawStringF(10, 10, true, "Selected: %-*.*s", 32, 32, currMenu->entries[index].name);
        
    for (u32 i = 0; i < currMenu->n_entries; i++) { // draw menu entries / selection []
        char* name = currMenu->entries[i].name;
        DrawStringF(menublock_x0, menublock_y0 + (i*10), top_screen, (i == index) ? "[%s]" : " %s ", name);
    }
}
Exemplo n.º 2
0
u32 ScrollOutput()
{
    u32 log_start = LogWrite(NULL);

    // careful, these areas are used by other functions in Decrypt9
    char** logptr = (char**) 0x21100000;
    char* logtext = (char*)  0x21200000;
    u32 log_size = FileGetData(LOG_FILE, logtext, 1024 * 1024, log_start); // log size
    u32 l_total = 0; // total lines
    u32 l_curr = 0; // current line

    // read log file (second time)
    log_size = FileGetData(LOG_FILE, logtext, 1024 * 1024, log_start);

    // allow 1MB of text max
    if ((log_size == 0) || (log_size >= 1024 * 1024))
        return 0;

    // organize lines
    logtext[log_size - 1] = '\0';
    logptr[l_total++] = logtext;
    for (char* line = strchr(logtext, '\n'); line != NULL && l_total < 4000; line = strchr(line, '\n')) {
        *line = '\0';
        logptr[l_total++] = ++line;
    }
    if (l_total >= 4000) // allow 4000 lines of text max
        return 0;
    for (; l_total < DBG_N_CHARS_Y; logptr[l_total++] = logtext + log_size - 1); // fill up with empty lines
    // here, the actual output starts
    l_curr = l_total - DBG_N_CHARS_Y;
    if (l_curr > 0) l_curr--; // start at the line before the last
    while (true) {
        DebugSet((const char**) logptr + l_curr);
        u32 pad_state = InputWait();
        if (pad_state & BUTTON_X) {
            Screenshot(NULL);
        } else if ((pad_state & BUTTON_UP) && (l_curr > 0)) {
            l_curr--;
        } else if ((pad_state & BUTTON_DOWN) && (l_curr < l_total - DBG_N_CHARS_Y)) {
            l_curr++;
        } else if (pad_state & (BUTTON_B | BUTTON_START)) {
            return pad_state;
        }
    }

    return 0;
}
Exemplo n.º 3
0
u32 InitializeD9()
{
    u32 errorlevel = 0; // 0 -> none, 1 -> autopause, 2 -> critical
    
    ClearScreenFull(true, true);
    DebugClear();
    #ifndef BUILD_NAME
    Debug("-- Decrypt9 --");
    #else
    Debug("-- %s --", BUILD_NAME);
    #endif
    
    // a little bit of information about the current menu
    if (sizeof(menu)) {
        u32 n_submenus = 0;
        u32 n_features = 0;
        for (u32 m = 0; menu[m].n_entries; m++) {
            n_submenus = m;
            for (u32 e = 0; e < menu[m].n_entries; e++)
                n_features += (menu[m].entries[e].function) ? 1 : 0;
        }
        Debug("Counting %u submenus and %u features", n_submenus, n_features);
    }
    
    Debug("Initializing, hold L+R to pause");
    Debug("");    
    
    if (InitFS()) {
        Debug("Initializing SD card... success");
        FileGetData("d9logo.bin", BOT_SCREEN0, 320 * 240 * 3, 0);
        memcpy(BOT_SCREEN1, BOT_SCREEN0, 320 * 240 * 3);
        if (SetupTwlKey0x03() != 0) // TWL KeyX / KeyY
            errorlevel = 2;
        if ((GetUnitPlatform() == PLATFORM_N3DS) && (LoadKeyFromFile(0x05, 'Y', NULL) != 0))
            errorlevel = (((*(vu32*) 0x101401C0) == 0) || (errorlevel > 1)) ? 2 : 1; // N3DS CTRNAND KeyY
        if (LoadKeyFromFile(0x25, 'X', NULL)) // NCCH 7x KeyX
            errorlevel = (errorlevel < 1) ? 1 : errorlevel;
        if (LoadKeyFromFile(0x18, 'X', NULL)) // NCCH Secure3 KeyX
            errorlevel = (errorlevel < 1) ? 1 : errorlevel;
        if (LoadKeyFromFile(0x1B, 'X', NULL)) // NCCH Secure4 KeyX
            errorlevel = (errorlevel < 1) ? 1 : errorlevel;
        Debug("Finalizing Initialization...");
        RemainingStorageSpace();
    } else {
        Debug("Initializing SD card... failed");
            errorlevel = 2;
    }
    Debug("");
    Debug("Initialization: %s", (errorlevel == 0) ? "success!" : (errorlevel == 1) ? "partially failed" : "failed!");
    
    if (((~HID_STATE & BUTTON_L1) && (~HID_STATE & BUTTON_R1)) || (errorlevel > 1)) {
        Debug("(A to %s)", (errorlevel > 1) ? "exit" : "continue");
        while (!(InputWait() & BUTTON_A));
    }
    
    return errorlevel;
}
Exemplo n.º 4
0
//==================================================================
bool FileManagerAndroid::GrabFile(const char* pFileName, DVec<U8> &out_data, const char* pMode)
{
    DFUNCTION();
    DLOG("File: %s", pFileName);

#if defined(ANDROID)
	bool prefs = isPrefsMode( pMode );

    if (prefs)
    {
        // Read from the prefs storage

        DLOG("Grabbing file (prefs): %s", pFileName);
        char *contents = ::DoReadPrefs(pFileName);
        if (0 == contents)
        {
            DLOG("Failed to open the file");
            return false;
        }

        // Decode into binary

        size_t binLength = 0;
        void *binData = FromBase64(contents, &binLength);
        free(contents);
        if (binData == 0)
        {
            DPRINT("!! File '%s' was not base64 format.  Rejecting.", pFileName);
            return false;
        }

        // Copy into output array and free original

        // TODO: Could be sped up by pre-calculating length and not
        // copying.

        out_data.resize(binLength);
        memcpy(&out_data[0], binData, binLength);
        free(binData);

        DLOG("copied %d bytes", binLength);
        return true;
    }

    ::FileLoad(pFileName);
    int datasize;
    void *data;
    if (!FileGetData(pFileName, &data, &datasize))
    {
        //DASSTHROW(0, ("failed loading file '%s'", pFileName));
        return false;
    }

    out_data.resize(datasize);

    DVERBOSE("GrabFile: memcpy-ing '%s', %d bytes", pFileName, datasize);
    memcpy(&out_data[0], data, datasize);

    FileRemove(pFileName);
    DVERBOSE("GrabFile: released");
#endif

	return true;
}
Exemplo n.º 5
0
u32 SdPadgen(u32 param)
{
    (void) (param); // param is unused here
    SdInfo *info = (SdInfo*) 0x20316000;

    // setup AES key from SD
    SetupSdKeyY0x34(false, NULL);
    
    if (!DebugFileOpen("SDinfo.bin"))
        return 1;
    if (!DebugFileRead(info, 4, 0)) {
        FileClose();
        return 1;
    }
    if (!info->n_entries || info->n_entries > MAX_ENTRIES) {
        FileClose();
        Debug("Bad number of entries!");
        return 1;
    }
    if (!DebugFileRead(info->entries, info->n_entries * sizeof(SdInfoEntry), 4)) {
        FileClose();
        return 1;
    }
    FileClose();
    
    Debug("Number of entries: %i", info->n_entries);
    for(u32 i = 0; i < info->n_entries; i++) {
        PadInfo padInfo = {.keyslot = 0x34, .setKeyY = 0, .size_mb = info->entries[i].size_mb, .mode = AES_CNT_CTRNAND_MODE};
        memcpy(padInfo.ctr, info->entries[i].ctr, 16);
        memcpy(padInfo.filename, info->entries[i].filename, 180);
        Debug ("%2i: %s (%iMB)", i, info->entries[i].filename, info->entries[i].size_mb);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 SdPadgenDirect(u32 param)
{
    (void) (param); // param is unused here
    SdInfo *info = (SdInfo*) 0x20316000;
    char basepath[256];
    u8 movable_keyY[16];
    
    if (SetupSdKeyY0x34(true, movable_keyY) != 0)
        return 1; // movable.sed has to be present in NAND
    
    Debug("");
    if (SdFolderSelector(basepath, movable_keyY) != 0)
        return 1;
    Debug("");
    if (SdInfoGen(info, basepath) != 0)
        return 1;
    if (!info->n_entries) {
        Debug("Nothing found in folder");
        return 1;
    }
    
    Debug("Number of entries: %i", info->n_entries);
    for(u32 i = 0; i < info->n_entries; i++) {
        PadInfo padInfo = {.keyslot = 0x34, .setKeyY = 0, .size_mb = info->entries[i].size_mb, .mode = AES_CNT_CTRNAND_MODE};
        memcpy(padInfo.ctr, info->entries[i].ctr, 16);
        memcpy(padInfo.filename, info->entries[i].filename, 180);
        Debug ("%2i: %s (%iMB)", i, info->entries[i].filename, info->entries[i].size_mb);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 AnyPadgen(u32 param)
{
    (void) (param); // param is unused here
    AnyPadInfo *info = (AnyPadInfo*) 0x20316000;
    
    // get header
    if ((FileGetData("anypad.bin", info, 16, 0) != 16) || !info->n_entries || info->n_entries > MAX_ENTRIES) {
        Debug("Corrupt or not existing: anypad.bin");
        return 1;
    }
    
    // get data
    u32 data_size = info->n_entries * sizeof(AnyPadInfoEntry);
    if (FileGetData("anypad.bin", (u8*) info + 16, data_size, 16) != data_size) {
        Debug("File is missing data: anypad.bin");
        return 1;
    }
    
    Debug("Processing anypad.bin...");
    Debug("Number of entries: %i", info->n_entries);
    for (u32 i = 0; i < info->n_entries; i++) { // this translates all entries to a standard padInfo struct
        AnyPadInfoEntry* entry = &(info->entries[i]);
        PadInfo padInfo = {.keyslot = entry->keyslot, .setKeyY = 0, .size_mb = 0, .size_b = entry->size_b, .mode = entry->mode};
        memcpy(padInfo.filename, entry->filename, 80);
        memcpy(padInfo.ctr, entry->ctr, 16);
        // process keys
        if (entry->setNormalKey)
            setup_aeskey(entry->keyslot, entry->normalKey);
        if (entry->setKeyX)
            setup_aeskeyX(entry->keyslot, entry->keyX);
        if (entry->setKeyY)
            setup_aeskeyY(entry->keyslot, entry->keyY);
        use_aeskey(entry->keyslot);
        // process flags
        if (entry->flags & (AP_USE_NAND_CTR|AP_USE_SD_CTR)) {
            u32 ctr_add = getbe32(padInfo.ctr + 12);
            u8 shasum[32];
            u8 cid[16];
            sdmmc_get_cid((entry->flags & AP_USE_NAND_CTR) ? 1 : 0, (uint32_t*) cid);
            if (entry->mode == AES_CNT_TWLNAND_MODE) {
                sha_quick(shasum, cid, 16, SHA1_MODE);
                for (u32 i = 0; i < 16; i++)
                    padInfo.ctr[i] = shasum[15-i];
            } else {
                sha_quick(shasum, cid, 16, SHA256_MODE);
                memcpy(padInfo.ctr, shasum, 16);
            }
            add_ctr(padInfo.ctr, ctr_add);
        }
        // create the pad
        Debug ("%2i: %s (%ikB)", i, entry->filename, entry->size_b / 1024);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 CtrNandPadgen(u32 param)
{
    char* filename = (param & PG_FORCESLOT4) ? "nand.fat16.slot0x04.xorpad" : "nand.fat16.xorpad";
    u32 keyslot;
    u32 nand_size;

    // legacy sizes & offset, to work with Python 3DSFAT16Tool
    if (GetUnitPlatform() == PLATFORM_3DS) {
        if (param & PG_FORCESLOT4) {
            Debug("This is a N3DS only feature");
            return 1;
        }
        keyslot = 0x4;
        nand_size = 758;
    } else {
        keyslot = (param & PG_FORCESLOT4) ? 0x4 : 0x5;
        nand_size = 1055;
    }

    Debug("Creating NAND FAT16 xorpad. Size (MB): %u", nand_size);
    Debug("Filename: %s", filename);

    PadInfo padInfo = {
        .keyslot = keyslot,
        .setKeyY = 0,
        .size_mb = nand_size,
        .mode = AES_CNT_CTRNAND_MODE
    };
    strncpy(padInfo.filename, filename, 64);
    if(GetNandCtr(padInfo.ctr, 0xB930000) != 0)
        return 1;

    return CreatePad(&padInfo);
}

u32 TwlNandPadgen(u32 param)
{
    (void) (param); // param is unused here
    PartitionInfo* twln_info = GetPartitionInfo(P_TWLN);
    u32 size_mb = (twln_info->size + (1024 * 1024) - 1) / (1024 * 1024);
    Debug("Creating TWLN FAT16 xorpad. Size (MB): %u", size_mb);
    Debug("Filename: twlnand.fat16.xorpad");

    PadInfo padInfo = {
        .keyslot = twln_info->keyslot,
        .setKeyY = 0,
        .size_mb = size_mb,
        .filename = "twlnand.fat16.xorpad",
        .mode = AES_CNT_TWLNAND_MODE
    };
    if(GetNandCtr(padInfo.ctr, twln_info->offset) != 0)
        return 1;

    return CreatePad(&padInfo);
}

u32 Firm0Firm1Padgen(u32 param)
{
    (void) (param); // param is unused here
    PartitionInfo* firm0_info = GetPartitionInfo(P_FIRM0);
    PartitionInfo* firm1_info = GetPartitionInfo(P_FIRM1);
    u32 size_mb = (firm0_info->size + firm1_info->size + (1024 * 1024) - 1) / (1024 * 1024);
    Debug("Creating FIRM0FIRM1 xorpad. Size (MB): %u", size_mb);
    Debug("Filename: firm0firm1.xorpad");

    PadInfo padInfo = {
        .keyslot = firm0_info->keyslot,
        .setKeyY = 0,
        .size_mb = size_mb,
        .filename = "firm0firm1.xorpad",
        .mode = AES_CNT_CTRNAND_MODE
    };
    if(GetNandCtr(padInfo.ctr, firm0_info->offset) != 0)
        return 1;

    return CreatePad(&padInfo);
}