diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c index fc1dc29..0d0fc11 100644 --- a/source/gfx/gfx.c +++ b/source/gfx/gfx.c @@ -514,10 +514,10 @@ void gfx_set_rect_grey(const u8 *buf, u32 size_x, u32 size_y, u32 pos_x, u32 pos } void gfx_box(int x0, int y0, int x1, int y1, u32 color){ - int i = y0; - while(y1 >= i){ - gfx_line(x0, i, x1, i, color); - i++; + for (int x = x0; x < x1 + 1; x++){ + for (int y = y0; y < y1 + 1; y++){ + gfx_set_pixel(x, y, color); + } } } diff --git a/source/tegraexplorer/emmc.c b/source/tegraexplorer/emmc.c index 2af520c..be8e41b 100644 --- a/source/tegraexplorer/emmc.c +++ b/source/tegraexplorer/emmc.c @@ -61,11 +61,8 @@ pkg1_info returnpkg1info(){ return pkg1inf; } -int mount_mmc(const char *partition, const int biskeynumb){ - f_unmount("emmc:"); - - se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10); - se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10); +int connect_part(const char *partition){ + sdmmc_storage_set_mmc_partition(&storage, 0); system_part = nx_emmc_part_find(&gpt, partition); if (!system_part) { @@ -73,6 +70,18 @@ int mount_mmc(const char *partition, const int biskeynumb){ return -1; } + return 0; +} + +int mount_mmc(const char *partition, const int biskeynumb){ + f_unmount("emmc:"); + + se_aes_key_set(8, bis_key[biskeynumb] + 0x00, 0x10); + se_aes_key_set(9, bis_key[biskeynumb] + 0x10, 0x10); + + if (connect_part(partition)) + return -1; + if (f_mount(&emmc, "emmc:", 1)) { gfx_printf("Mount failed of %s.", partition); return -1; diff --git a/source/tegraexplorer/emmc.h b/source/tegraexplorer/emmc.h index cf5f855..3f7bb78 100644 --- a/source/tegraexplorer/emmc.h +++ b/source/tegraexplorer/emmc.h @@ -13,7 +13,7 @@ pkg1_info returnpkg1info(); int mount_mmc(const char *partition, const int biskeynumb); void connect_mmc(short mmctype); void disconnect_mmc(); - +int connect_part(const char *partition); static const u8 zeros[0x10] = {0}; diff --git a/source/tegraexplorer/io.c b/source/tegraexplorer/io.c index 56e4b0e..d9add65 100644 --- a/source/tegraexplorer/io.c +++ b/source/tegraexplorer/io.c @@ -9,6 +9,13 @@ #include "../gfx/gfx.h" #include "../utils/util.h" #include "io.h" +#include "emmc.h" +#include "../storage/sdmmc.h" +#include "../storage/nx_emmc.h" +#include "../utils/types.h" + +extern sdmmc_storage_t storage; +extern emmc_part_t *system_part; bool checkfile(char* path){ FRESULT fr; @@ -251,5 +258,100 @@ int copy_recursive(char *path, char *dstpath){ free(destpath); free(destfoldername); + return 0; +} + +int dump_emmc_part(char *path, sdmmc_storage_t *storage, emmc_part_t *part){ + FIL fp; + u8 *buf; + u32 lba_curr = part->lba_start; + u32 bytesWritten = 0; + u32 totalSectors = part->lba_end - part->lba_start + 1; + u64 totalSize = (u64)((u64)totalSectors << 9); + u32 num = 0; + u32 pct = 0; + int res; + + buf = calloc(16384, sizeof(u8)); + + if ((res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE))){ + message(COLOR_RED, "f_open() failed! err: %d", res); + return -1; + } + + f_lseek(&fp, totalSize); + f_lseek(&fp, 0); + + while (totalSectors > 0){ + num = MIN(totalSectors, 32); + if (!sdmmc_storage_read(storage, lba_curr, num, buf)){ + message(COLOR_RED, "eMMC read failed!"); + return -1; + } + if ((res = f_write(&fp, buf, num * NX_EMMC_BLOCKSIZE, NULL))){ + message(COLOR_RED, "f_write() failed! err: %d", res); + return -1; + } + pct = (u64)((u64)(lba_curr - part->lba_start) * 100u) / (u64)(part->lba_end - part->lba_start); + gfx_printf("Progress: %d%%\r", pct); + + lba_curr += num; + totalSectors -= num; + bytesWritten += num * NX_EMMC_BLOCKSIZE; + } + gfx_printf(" \r"); + f_close(&fp); + free(buf); + return 0; +} + +int dump_emmc_parts(u16 parts, u8 mmctype){ + char *path; + char basepath[] = "sd:/tegraexplorer/dumps"; + f_mkdir("sd:/tegraexplorer"); + f_mkdir("sd:/tegraexplorer/dumps"); + + connect_mmc(mmctype); + clearscreen(); + + if (parts & PART_BOOT){ + emmc_part_t bootPart; + const u32 BOOT_PART_SIZE = storage.ext_csd.boot_mult << 17; + memset(&bootPart, 0, sizeof(bootPart)); + + bootPart.lba_start = 0; + bootPart.lba_end = (BOOT_PART_SIZE / NX_EMMC_BLOCKSIZE) - 1; + + for (int i = 0; i < 2; i++){ + strcpy(bootPart.name, "BOOT"); + bootPart.name[4] = (u8)('0' + i); + bootPart.name[5] = 0; + + sdmmc_storage_set_mmc_partition(&storage, i + 1); + makestring(getnextloc(basepath, bootPart.name), &path); + gfx_printf("Dumping %s\n", bootPart.name); + + dump_emmc_part(path, &storage, &bootPart); + free(path); + } + } + + if (parts & PART_PKG2){ + for (int i = 0; i < 6; i++){ + if (connect_part(pkg2names[i])){ + message(COLOR_RED, "Find of partition failed!\nPart: %s", pkg2names[i]); + return -1; + } + + makestring(getnextloc(basepath, system_part->name), &path); + gfx_printf("Dumping %s\n", system_part->name); + + dump_emmc_part(path, &storage, system_part); + free(path); + } + } + + gfx_printf("\nDone!"); + btn_wait(); return 0; } \ No newline at end of file diff --git a/source/tegraexplorer/io.h b/source/tegraexplorer/io.h index 6b112e0..539fd52 100644 --- a/source/tegraexplorer/io.h +++ b/source/tegraexplorer/io.h @@ -7,4 +7,17 @@ u64 getfilesize(char *path); int getfolderentryamount(const char *path); void makestring(char *in, char **out); int del_recursive(char *path); -int copy_recursive(char *path, char *dstpath); \ No newline at end of file +int copy_recursive(char *path, char *dstpath); +int dump_emmc_parts(u16 parts, u8 mmctype); + +#define PART_BOOT 0x1 +#define PART_PKG2 0x2 + +static const char *pkg2names[] = { + "BCPKG2-1-Normal-Main", + "BCPKG2-2-Normal-Sub", + "BCPKG2-3-SafeMode-Main", + "BCPKG2-4-SafeMode-Sub", + "BCPKG2-5-Repair-Main", + "BCPKG2-6-Repair-Sub" +}; \ No newline at end of file diff --git a/source/tegraexplorer/te.c b/source/tegraexplorer/te.c index 3df0c7d..4620313 100644 --- a/source/tegraexplorer/te.c +++ b/source/tegraexplorer/te.c @@ -41,13 +41,14 @@ menu_item shutdownmenu[7] = { {"Reboot to Atmosphere", COLOR_GREEN, AMS, -1} }; -menu_item toolsmenu[6] = { +menu_item toolsmenu[7] = { {"-- TOOLS --\n", COLOR_VIOLET, -1, 0}, {"Back", COLOR_WHITE, -1, 1}, {"\nDisplay Console Info", COLOR_GREEN, DISPLAY_INFO, 1}, {"Display GPIO pins", COLOR_VIOLET, DISPLAY_GPIO, 1}, {"Dump Firmware", COLOR_BLUE, DUMPFIRMWARE, 1}, - {"Dump User Saves", COLOR_YELLOW, DUMPUSERSAVE, 1} + {"Dump User Saves", COLOR_YELLOW, DUMPUSERSAVE, 1}, + {"[DEBUG] Dump bis", COLOR_RED, DUMP_BOOT, 1} }; menu_item formatmenu[4] = { @@ -103,7 +104,7 @@ void MainMenu_MountSD(){ } void MainMenu_Tools(){ - res = makemenu(toolsmenu, 6); + res = makemenu(toolsmenu, 7); switch(res){ case DISPLAY_INFO: @@ -124,6 +125,9 @@ void MainMenu_Tools(){ dumpusersaves(SYSMMC); break; + case DUMP_BOOT: + dump_emmc_parts(PART_BOOT | PART_PKG2, SYSMMC); + break; } } diff --git a/source/tegraexplorer/te.h b/source/tegraexplorer/te.h index 83b2cef..92c972d 100644 --- a/source/tegraexplorer/te.h +++ b/source/tegraexplorer/te.h @@ -38,7 +38,8 @@ enum toolsmenu_return { DISPLAY_INFO = 1, DISPLAY_GPIO, DUMPFIRMWARE, - DUMPUSERSAVE + DUMPUSERSAVE, + DUMP_BOOT }; enum formatmenu_return {