├── .gitignore ├── CRCFix ├── Makefile └── main.c ├── flawEU.sav ├── flawUS.sav ├── README.md ├── inject_payload.py ├── makefile └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | CRCFix/CRCFix.exe -------------------------------------------------------------------------------- /CRCFix/Makefile: -------------------------------------------------------------------------------- 1 | CRCFix: main.c 2 | gcc $< -O2 -Wall -o $@ -------------------------------------------------------------------------------- /flawEU.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/st4rk/The-Biggest-Loser/HEAD/flawEU.sav -------------------------------------------------------------------------------- /flawUS.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/st4rk/The-Biggest-Loser/HEAD/flawUS.sav -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The-Biggest-Loser 2 | ================= 3 | 4 | Exploit for The Biggest Loser. 5 | 6 | Runs in DSi mode if you use a real cartridge on a DSi or 3DS system, otherwise, it runs in DS mode. 7 | 8 | Both US and EU regions are supported. 9 | 10 | Read more [here](http://st4rk.net/hacking/the-biggest-loser-exploit/). 11 | -------------------------------------------------------------------------------- /inject_payload.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | binfileUS = "payloadUS.bin" 4 | binfileEU = "payloadEU.bin" 5 | savfileUS = "flawUS.sav" 6 | savfileEU = "flawEU.sav" 7 | 8 | binUS = open(binfileUS, "r+b") 9 | binEU = open(binfileEU, "r+b") 10 | savUS = open(savfileUS, "r+b") 11 | savEU = open(savfileEU, "r+b") 12 | 13 | bincontentUS = binUS.read() 14 | bincontentEU = binEU.read() 15 | 16 | savUS.seek(0x8C) 17 | savUS.write(bincontentUS) 18 | 19 | savEU.seek(0x8C) 20 | savEU.write(bincontentEU) 21 | 22 | binUS.close() 23 | binEU.close() 24 | savUS.close() 25 | savEU.close() -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | include $(DEVKITARM)/ds_rules 2 | 3 | OBJDUMP := $(PREFIX)objdump 4 | 5 | all: flawUS.sav flawEU.sav 6 | 7 | flawUS.sav flawEU.sav: payloadUS.bin payloadEU.bin 8 | python inject_payload.py 9 | 10 | @# Since CRC length is 1 byte, there is no need to CRCFix it 11 | @#CRCFix/CRCFix flawUS.sav 12 | @#CRCFix/CRCFix flawEU.sav 13 | 14 | @rm -f payloadUS.bin 15 | @rm -f payloadEU.bin 16 | 17 | payloadUS.bin: *.c 18 | $(CC) -nostartfiles -nostdlib -DARM9 -I$(LIBNDS)/include *.c -o payload.elf -O2 -Wall -Ttext=0x0211E364 19 | $(OBJCOPY) -O binary payload.elf payloadUS.bin 20 | @rm -f payload.elf 21 | 22 | payloadEU.bin: *.c 23 | $(CC) -nostartfiles -nostdlib -DARM9 -I$(LIBNDS)/include *.c -o payload.elf -O2 -Wall -Ttext=0x0211E604 24 | $(OBJCOPY) -O binary payload.elf payloadEU.bin 25 | @rm -f payload.elf 26 | -------------------------------------------------------------------------------- /CRCFix/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | unsigned int crc32(unsigned char *data, size_t length) { 6 | unsigned int byte, crc = 0xFFFFFFFF, mask; 7 | 8 | int i; 9 | for(i = 0; i < length; i++) { 10 | byte = data[i]; // Get next byte. 11 | crc = crc ^ byte; 12 | 13 | int j; 14 | for(j = 7; j >= 0; j--) { // Do eight times. 15 | mask = -(crc & 1); 16 | crc = (crc >> 1) ^ (0xEDB88320 & mask); 17 | } 18 | } 19 | 20 | return ~crc; 21 | } 22 | 23 | int main(int argc, char **argv) { 24 | if(argc < 2) { 25 | printf("The Biggest Loser DS save CRC fixer\n"); 26 | printf("Usage:\n"); 27 | printf("%s save.sav\n", argv[0]); 28 | return 1; 29 | } 30 | 31 | FILE *f = fopen(argv[1], "rwb+"); 32 | 33 | if(!f) { 34 | printf("Couldn't open %s!\n", argv[1]); 35 | return 1; 36 | } 37 | 38 | fseek(f, 0, SEEK_END); 39 | size_t length = ftell(f); 40 | unsigned char *save = malloc(length); 41 | rewind(f); 42 | fread(save, length, 1, f); 43 | 44 | unsigned char crcLength; 45 | memcpy(&crcLength, save + 8, 1); 46 | 47 | unsigned int oldCRC; 48 | memcpy(&oldCRC, save + 4, 4); 49 | 50 | unsigned int CRC = crc32(save + 8, crcLength); 51 | free(save); 52 | 53 | if(oldCRC != CRC) { 54 | fseek(f, 4, SEEK_SET); 55 | fwrite(&CRC, 1, 4, f); 56 | 57 | printf("Fixed!\n"); 58 | } 59 | 60 | fclose(f); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | asm(".global _start"); 5 | asm("_start:"); 6 | asm("mov r0, #0x0"); 7 | asm("mov r1, #0x0"); 8 | asm("mov r2, #0x0"); 9 | asm("mov r3, #0x0"); 10 | asm("mov r4, #0x0"); 11 | asm("mov r5, #0x0"); 12 | asm("mov r6, #0x0"); 13 | asm("mov r7, #0x0"); 14 | asm("mov r8, #0x0"); 15 | asm("mov r9, #0x0"); 16 | asm("mov r10, #0x0"); 17 | asm("mov r11, #0x0"); 18 | asm("ldr pc, =main"); 19 | 20 | const char fonts[] = { //Fonte 8x8 1BPP 21 | 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 //tile:0 22 | , 0x18, 0x18, 0x18, 0x18, 0x18, 0x0, 0x18, 0x0 //tile:1 23 | , 0x6c, 0x6c, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0 //tile:2 24 | , 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x0 //tile:3 25 | , 0x18, 0x7e, 0xc0, 0x7c, 0x6, 0xfc, 0x18, 0x0 //tile:4 26 | , 0x0, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x0 //tile:5 27 | , 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x0 //tile:6 28 | , 0x30, 0x30, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0 //tile:7 29 | , 0xc, 0x18, 0x30, 0x30, 0x30, 0x18, 0xc, 0x0 //tile:8 30 | , 0x30, 0x18, 0xc, 0xc, 0xc, 0x18, 0x30, 0x0 //tile:9 31 | , 0x0, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x0, 0x0 //tile:10 32 | , 0x0, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x0, 0x0 //tile:11 33 | , 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x30 //tile:12 34 | , 0x0, 0x0, 0x0, 0x7e, 0x0, 0x0, 0x0, 0x0 //tile:13 35 | , 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x0 //tile:14 36 | , 0x6, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x0 //tile:15 37 | , 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0x7c, 0x0 //tile:16 38 | , 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x0 //tile:17 39 | , 0x7c, 0xc6, 0x6, 0x7c, 0xc0, 0xc0, 0xfe, 0x0 //tile:18 40 | , 0xfc, 0x6, 0x6, 0x3c, 0x6, 0x6, 0xfc, 0x0 //tile:19 41 | , 0xc, 0xcc, 0xcc, 0xcc, 0xfe, 0xc, 0xc, 0x0 //tile:20 42 | , 0xfe, 0xc0, 0xfc, 0x6, 0x6, 0xc6, 0x7c, 0x0 //tile:21 43 | , 0x7c, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x0 //tile:22 44 | , 0xfe, 0x6, 0x6, 0xc, 0x18, 0x30, 0x30, 0x0 //tile:23 45 | , 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x0 //tile:24 46 | , 0x7c, 0xc6, 0xc6, 0x7e, 0x6, 0x6, 0x7c, 0x0 //tile:25 47 | , 0x0, 0x18, 0x18, 0x0, 0x0, 0x18, 0x18, 0x0 //tile:26 48 | , 0x0, 0x18, 0x18, 0x0, 0x0, 0x18, 0x18, 0x30 //tile:27 49 | , 0xc, 0x18, 0x30, 0x60, 0x30, 0x18, 0xc, 0x0 //tile:28 50 | , 0x0, 0x0, 0x7e, 0x0, 0x7e, 0x0, 0x0, 0x0 //tile:29 51 | , 0x30, 0x18, 0xc, 0x6, 0xc, 0x18, 0x30, 0x0 //tile:30 52 | , 0x3c, 0x66, 0xc, 0x18, 0x18, 0x0, 0x18, 0x0 //tile:31 53 | , 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x7e, 0x0 //tile:32 54 | , 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x0 //tile:33 55 | , 0xfc, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0x0 //tile:34 56 | , 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x0 //tile:35 57 | , 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x0 //tile:36 58 | , 0xfe, 0xc0, 0xc0, 0xf8, 0xc0, 0xc0, 0xfe, 0x0 //tile:37 59 | , 0xfe, 0xc0, 0xc0, 0xf8, 0xc0, 0xc0, 0xc0, 0x0 //tile:38 60 | , 0x7c, 0xc6, 0xc0, 0xc0, 0xce, 0xc6, 0x7c, 0x0 //tile:39 61 | , 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x0 //tile:40 62 | , 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x0 //tile:41 63 | , 0x6, 0x6, 0x6, 0x6, 0x6, 0xc6, 0x7c, 0x0 //tile:42 64 | , 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x0 //tile:43 65 | , 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x0 //tile:44 66 | , 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x0 //tile:45 67 | , 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x0 //tile:46 68 | , 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x0 //tile:47 69 | , 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x0 //tile:48 70 | , 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x6 //tile:49 71 | , 0xfc, 0xc6, 0xc6, 0xfc, 0xd8, 0xcc, 0xc6, 0x0 //tile:50 72 | , 0x7c, 0xc6, 0xc0, 0x7c, 0x6, 0xc6, 0x7c, 0x0 //tile:51 73 | , 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0 //tile:52 74 | , 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x0 //tile:53 75 | , 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x38, 0x0 //tile:54 76 | , 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x0 //tile:55 77 | , 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x0 //tile:56 78 | , 0xc6, 0xc6, 0xc6, 0x7c, 0x18, 0x30, 0xe0, 0x0 //tile:57 79 | , 0xfe, 0x6, 0xc, 0x18, 0x30, 0x60, 0xfe, 0x0 //tile:58 80 | , 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x0 //tile:59 81 | , 0xc0, 0x60, 0x30, 0x18, 0xc, 0x6, 0x2, 0x0 //tile:60 82 | , 0x3c, 0xc, 0xc, 0xc, 0xc, 0xc, 0x3c, 0x0 //tile:61 83 | , 0x10, 0x38, 0x6c, 0xc6, 0x0, 0x0, 0x0, 0x0 //tile:62 84 | , 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff //tile:63 85 | , 0x18, 0x18, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0 //tile:64 86 | , 0x0, 0x0, 0x7c, 0x6, 0x7e, 0xc6, 0x7e, 0x0 //tile:65 87 | , 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xfc, 0x0 //tile:66 88 | , 0x0, 0x0, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x0 //tile:67 89 | , 0x6, 0x6, 0x6, 0x7e, 0xc6, 0xc6, 0x7e, 0x0 //tile:68 90 | , 0x0, 0x0, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x0 //tile:69 91 | , 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x0 //tile:70 92 | , 0x0, 0x0, 0x7e, 0xc6, 0xc6, 0x7e, 0x6, 0xfc //tile:71 93 | , 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x0 //tile:72 94 | , 0x18, 0x0, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x0 //tile:73 95 | , 0x6, 0x0, 0x6, 0x6, 0x6, 0x6, 0xc6, 0x7c //tile:74 96 | , 0xc0, 0xc0, 0xcc, 0xd8, 0xf8, 0xcc, 0xc6, 0x0 //tile:75 97 | , 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0 //tile:76 98 | , 0x0, 0x0, 0xcc, 0xfe, 0xfe, 0xd6, 0xd6, 0x0 //tile:77 99 | , 0x0, 0x0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x0 //tile:78 100 | , 0x0, 0x0, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x0 //tile:79 101 | , 0x0, 0x0, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0 //tile:80 102 | , 0x0, 0x0, 0x7e, 0xc6, 0xc6, 0x7e, 0x6, 0x6 //tile:81 103 | , 0x0, 0x0, 0xfc, 0xc6, 0xc0, 0xc0, 0xc0, 0x0 //tile:82 104 | , 0x0, 0x0, 0x7e, 0xc0, 0x7c, 0x6, 0xfc, 0x0 //tile:83 105 | , 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0xe, 0x0 //tile:84 106 | , 0x0, 0x0, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x0 //tile:85 107 | , 0x0, 0x0, 0xc6, 0xc6, 0xc6, 0x7c, 0x38, 0x0 //tile:86 108 | , 0x0, 0x0, 0xc6, 0xc6, 0xd6, 0xfe, 0x6c, 0x0 //tile:87 109 | , 0x0, 0x0, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x0 //tile:88 110 | , 0x0, 0x0, 0xc6, 0xc6, 0xc6, 0x7e, 0x6, 0xfc //tile:89 111 | , 0x0, 0x0, 0xfe, 0xc, 0x38, 0x60, 0xfe, 0x0 //tile:90 112 | , 0xe, 0x18, 0x18, 0x70, 0x18, 0x18, 0xe, 0x0 //tile:91 113 | , 0x18, 0x18, 0x18, 0x0, 0x18, 0x18, 0x18, 0x0 //tile:92 114 | , 0x70, 0x18, 0x18, 0xe, 0x18, 0x18, 0x70, 0x0 //tile:93 115 | , 0x76, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 //tile:94 116 | , 0x0, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x0 //tile:95 117 | }; 118 | 119 | 120 | void draw_pixel_rgb(int x, int y, u8 r, u8 g, u8 b) { 121 | u32 v = 256 * y + x; 122 | *(VRAM_A + v) = RGB15(r, g, b); 123 | } 124 | 125 | 126 | void draw_string(u16 *fb, int sx, int sy, char *str) { 127 | int i; 128 | for(i = 0; str[i]; i++) { 129 | int fntnum = (str[i] - 32) & 0xFF; 130 | int y; 131 | for (y = 0; y < 8; y++) { 132 | int currbyte = fonts[(fntnum * 8) + y]; 133 | 134 | //Desenha sprite de 1BPP 135 | int x; 136 | int mult = 0x80; 137 | for(x = 0; x < 8; x++) { 138 | if ((currbyte & mult) == mult) { 139 | draw_pixel_rgb(sx + x, sy + y, 0xFF, 0xFF, 0xFF); 140 | draw_pixel_rgb(sx + x, sy + y + 1, 0, 0, 0); //Sombra 141 | } 142 | mult /= 2; 143 | } 144 | } 145 | sx += 8; 146 | } 147 | } 148 | 149 | int main(void) { 150 | /* Enable Both Screen, and FrameBuffer mode */ 151 | 152 | REG_DISPCNT = MODE_FB0; 153 | VRAM_A_CR = VRAM_ENABLE | VRAM_A_LCD; 154 | 155 | int i = 0; 156 | u8 r = 0, g = 31, b = 0; 157 | u8 random = 1; 158 | 159 | while (1) { 160 | i = 0; 161 | 162 | switch (random) { 163 | case 1: 164 | if (r != 31) { 165 | r++; 166 | g--; 167 | } else { 168 | random = 2; 169 | } 170 | break; 171 | 172 | case 2: 173 | if (b != 31) { 174 | b++; 175 | g++; 176 | r--; 177 | } else { 178 | random = 3; 179 | } 180 | break; 181 | 182 | case 3: 183 | if (b != 0) { 184 | b--; 185 | } else { 186 | random = 1; 187 | } 188 | break; 189 | 190 | default: 191 | 192 | break; 193 | } 194 | 195 | while(i < 0x18000) { 196 | VRAM_A[i] = RGB15(r, g, b); 197 | i++; 198 | } 199 | 200 | draw_string(VRAM_A, 85, 85, "Flawwwww"); 201 | asm("swi 0x050000"); 202 | } 203 | 204 | return 0; 205 | } 206 | --------------------------------------------------------------------------------