Skip to content

Instantly share code, notes, and snippets.

@rw-r-r-0644
Created March 31, 2021 13:18
Show Gist options
  • Save rw-r-r-0644/c53803f6f6d03e26d23cb6220d678552 to your computer and use it in GitHub Desktop.
Save rw-r-r-0644/c53803f6f6d03e26d23cb6220d678552 to your computer and use it in GitHub Desktop.
int write_payload(uint8_t *ptr)
{
/* instructions placed at 0x0C+(0x20*k)
* will be corrupted if the 2 least
* significant bits are set */
/* clean the area overwritten by the stack overflow
* memset( 0x0D40E240, 0, 0xB70 ) */
write32(ptr+0x000, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x004, 0xe59f00f8); // ldr r0, [pc, #0xF8]
write32(ptr+0x008, 0xe3a01000); // mov r1, #0
write32(ptr+0x010, 0xe3a02eb7); // mov r2, #0xB70
write32(ptr+0x014, 0xe12fff33); // blx r3
write32(ptr+0x100, 0x0d409c78); // memset addr
write32(ptr+0x104, 0x0d40e240); // stack overflow end
/* fix boot_info pointer
* write32( 0x0d40eda4, 0x10008000 ) */
write32(ptr+0x018, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x01C, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x020, 0xe5832000); // str r2, [r3]
write32(ptr+0x118, 0x0d40eda4); // boot_info_ptr addr
write32(ptr+0x11C, 0x10008000); // boot_info addr
/* skip decryption and signature verification
* write16( 0x0d400786, 0x46c0 ) */
write32(ptr+0x024, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x028, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x030, 0xe1c320b0); // strh r2, [r3]
write32(ptr+0x124, 0x0d400786);
write32(ptr+0x128, 0x000046c0); // (beq LAB_0d40078e) -> (nop)
/* stub out FLADevice_Write and ISFS_WriteSuperblock
* write32( 0x0d401474, 0x20004770 )
* write32( 0x0d40231c, 0x20004770 ) */
write32(ptr+0x034, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x038, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x03C, 0xe5832000); // str r2, [r3]
write32(ptr+0x040, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x044, 0xe5832000); // str r2, [r3]
write32(ptr+0x134, 0x20004770); // (mov r0, #0 ; bx lr)
write32(ptr+0x138, 0x0d401474);
write32(ptr+0x140, 0x0d40231c);
/* set first invalid generation number to 0xfffffffe
* to prevent the modified superblock from being reused
* write16( 0x0d402728, 0x2402 ) */
write32(ptr+0x048, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x050, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x054, 0xe1c320b0); // strh r2, [r3]
write32(ptr+0x148, 0x0d402728);
write32(ptr+0x150, 0x00002402); // (mov r4, #2)
/* patch fw.img path "/title" -> "/cboot"
* write32( 0x0d40cc8c+4, 0x2f63626f )
* write32( 0x0d40cc8c+8, 0x6f742f25 ) */
write32(ptr+0x058, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x05C, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x060, 0xe5832004); // str r2, [r3, #4]
write32(ptr+0x064, 0xe59f20f8); // ldr r2, [pc, #0xF8]
write32(ptr+0x068, 0xe5832008); // str r2, [r3, #8]
write32(ptr+0x158, 0x0d40cc8c);
write32(ptr+0x15C, 0x2f63626f); // "/cbo"
write32(ptr+0x164, 0x6f742f25); // "ot/%"
/* prepare for jump to LoadFirmware at 0x0d4017b2 */
write32(ptr+0x070, 0xe59f30f8); // ldr r3, [pc, #0xF8]
write32(ptr+0x170, 0x0d4017b2 | 1);
/* restore r11 saved in ISFS_ReadCluster */
write32(ptr+0x07C, 0xe59db160); // ldr r11, [sp, #0x160]
/* restore LoadFirmware stack at 0x0d4017b2 */
write32(ptr+0x074, 0xe28ddfdd); // add sp, sp, #0x374
/* set useCrypto arg to 0 */
write32(ptr+0x078, 0xe3a00000); // mov r0, #0
/* return to LoadFirmware at 0x0d4017b2 */
write32(ptr+0x080, 0xe12fff13); // bx r3
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment