SHOW:
|
|
- or go back to the newest paste.
| 1 | // Read/write from DS serial SPI | |
| 2 | // Write firmware sends a spew of unknown firmware commands. Worth looking into. | |
| 3 | extern void read_firmware(void *dest, uint32_t start, size_t size); | |
| 4 | extern void write_firmware(void *src, uint32_t start, size_t size); | |
| 5 | ||
| 6 | // CRC16 and related hash functions | |
| 7 | extern uint16_t do_hash1(const char *firm, size_t size); | |
| 8 | extern uint16_t do_hash2(const char *firm, size_t size); | |
| 9 | extern uint32_t do_hash3(const char *firm, size_t size); | |
| 10 | extern uint16_t do_hash4(const char *firm, size_t size); | |
| 11 | ||
| 12 | const char patch1[] = {0xB9, 0xF2, 0x10, 0x00, 0xAE, 0x2B, 0x27, 0x00, 0xED, 0x0D, 0xDC, 0xBA, 0x9C, 0xF1, 0x18, 0x00, 0x90, 0xB6, 0x10, 0x00, 0x00, 0xB0, 0xFA, 0x00, 0x00, 0x02, 0x20, 0x00, 0xB9, 0xF2, 0x10, 0x00, 0x00, 0x90, 0x27, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE1, 0x49, 0x15, 0x00, 0x38, 0x6F, 0x27, 0x00, 0xAC, 0x82, 0x1B, 0x00, 0xDC, 0xD5, 0x18, 0x00, 0x40, 0x83, 0x27, 0x00, 0x00, 0x02, 0x10, 0x00, 0xCC, 0x48, 0x00, 0x00, 0x60, 0x3D, 0x14, 0x00, 0xB9, 0xF2, 0x10, 0x00, 0x00, 0x90, 0x27, 0x00, 0x00, 0x00, 0x2B, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xF9, 0x02, 0x10, 0x00, 0xE1, 0x49, 0x15, 0x00, 0x51, 0x00, 0xCD, 0xC2, 0xE1, 0x49, 0x15, 0x00, 0x20, 0x90, 0x27, 0x00, 0x8C, 0x53, 0x10, 0x00, 0x00, 0x90, 0x00, 0x00, 0x58, 0x39, 0x1B, 0x00, 0xE5, 0x04, 0x21, 0x00, 0x00, 0xDA, 0x19, 0x00, 0x00, 0x75, 0x01, 0x00, 0x86, 0xDF, 0x21, 0x00, 0x00, 0xC1, 0x1A, 0x00, 0x22, 0xDA, 0x1D, 0x00, 0x91, 0xFE, 0x16, 0x00, 0x00, 0x01, 0x10, 0x00, 0xBC, 0x4C, 0x14, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x90, 0x00, 0x00, 0xE1, 0x49, 0x15, 0x00, 0xAC, 0xEF, 0x22, 0x00, 0x88, 0x5C, 0x10, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x90, 0x03, 0x25, 0x00, 0xC0, 0xFA, 0x1E, 0x00, 0x91, 0xFE, 0x16, 0x00, 0x8C, 0x53, 0x10, 0x00, 0x24, 0x6B, 0x03, 0x00, 0x60, 0x3D, 0x14, 0x00};
| |
| 13 | ||
| 14 | const char patch2[] = {0xB9, 0xF2, 0x10, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE1, 0x49, 0x15, 0x00, 0x00, 0x94, 0x27, 0x00, 0xFC, 0x34, 0x13, 0x00, 0xD0, 0x8C, 0x1E, 0x00, 0x8C, 0x53, 0x10, 0x00, 0x9C, 0x94, 0x27, 0xF0, 0x60, 0x3D, 0x14, 0x00};
| |
| 15 | ||
| 16 | void do_patches(char *firm) | |
| 17 | {
| |
| 18 | memcpy(firm+0x1FE00, patch1, sizeof(patch1)); | |
| 19 | memcpy(firm+0x1FFB4, patch2, sizeof(patch2)); | |
| 20 | *(uint16_t)(firm+0x1FEFE) = do_hash1(firm, 0x1FFFF); | |
| 21 | *(uint16_t)(firm+0x1FF50) = do_hash2(firm, 0x1FFFF); | |
| 22 | *(uint32_t)(firm+0x1FF70) = do_hash3(firm, 0x1FFFF); | |
| 23 | *(uint16_t)(firm+0x1FFFE) = do_hash4(firm, 0x1FFFF); | |
| 24 | } | |
| 25 | ||
| 26 | void program() | |
| 27 | {
| |
| 28 | char *firm = malloc(0x1FFFF); | |
| 29 | - | uint16_t unk1; |
| 29 | + | |
| 30 | uint16_t unk1, unk2; | |
| 31 | ||
| 32 | // Read first 0x0001FFFF bytes of firmware | |
| 33 | read_firmware(firm, 0x0, 0x1FFFF); | |
| 34 | do_patches(firm); | |
| 35 | ||
| 36 | // Writes first 0x300 bytes back (same data) | |
| 37 | write_firmware(firm, 0x0, 0x300); | |
| 38 | ||
| 39 | // Gets a pointer of uint16_t at 0x300 | |
| 40 | unk1 = *(uint16_t*)(firm+0x300); | |
| 41 | ||
| 42 | // Read 0x1D bytes at that location | |
| 43 | read_firmware(data, unk1, 0x1D); | |
| 44 | ||
| 45 | // Writes 0x300 - 0x9FF bytes back (same data) | |
| 46 | write_firmware(firm+0x300, 0x300, 0x6FF); | |
| 47 | ||
| 48 | - | write_firmware(data, unk1, 0x1D); |
| 48 | + | // gets value to write data to |
| 49 | unk2 = *(uint16_t*)(firm+0xA00); | |
| 50 | ||
| 51 | // Writes the 0x1D bytes of data from 0xA00 at #3's location | |
| 52 | write_firmware(data, unk2, 0x1D); | |
| 53 | ||
| 54 | // Writes 0xA00 - 0x1FFF, mostly same data except 6 patches | |
| 55 | write_firmware(firm+0xA00, 0xA00, 0x15FF); | |
| 56 | } | |
| 57 | ||
| 58 | void verify() | |
| 59 | {
| |
| 60 | // not much, just read back all 0x1FFFF bytes again and compare it with patched data | |
| 61 | } |