Advertisement
TiniVi

N3DS ARM9 Decryptor

Jul 12th, 2015
618
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.25 KB | None | 0 0
  1. //Credit to 3DBrew's contributors for documenting the ARM9 Loader's process (http://3dbrew.org/wiki/FIRM#New_3DS_FIRM)
  2.  
  3. int ARM9_decrypt(void *FIRM){ //Address of FIRM
  4.     if(strcmp((char*)FIRM, "FIRM", 4) != 0) return 3; //if not firm
  5.    
  6.     u8* arm9bin = FIRM + *((unsigned int*)(FIRM + 0xA0));
  7.    
  8.     if(arm9bin[0] != 0xA7 || arm9bin[1] != 0x38 || arm9bin[2] != 0x5F || arm9bin[3] != 0x46) return 2; //if o3ds firm
  9.     if(arm9bin[0x61] != 0xA9 && arm9bin[0x50] != 0xFF) return 1; //return ARM9_9_6_decrypt(FIRM);
  10.    
  11.     int size = atoi((char*)(arm9bin + 0x30)); //arm9bin encrypted data size
  12.     u8* ctr = arm9bin + 0x20;
  13.    
  14.     int keyslot = arm9bin[0x61] == 0xA9 ? 0x16 : 0x15; //keyslot changed on 9.5
  15.     int keyXAddr = arm9bin[0x61] == 0xA9 ? 0x60 : 0; //keyX Addr changed on 9.5
  16.    
  17.     u8* keyX = arm9bin + keyXAddr;
  18.    
  19.     use_aeskey(0x11);
  20.     aes_decrypt(&keyX, &keyX, NULL, 1, AES_ECB_DECRYPT_MODE); //keyX is encrypted with aes ecb
  21.    
  22.     setup_aeskeyX(keyslot, keyX);
  23.     setup_aeskey(keyslot, AES_BIG_INPUT|AES_NORMAL_INPUT, arm9bin + 0x10); //keyY must be set last
  24.    
  25.     use_aeskey(keyslot);
  26.     for(u32 i = 0; i < size; i += 16) {
  27.         set_ctr(AES_BIG_INPUT|AES_NORMAL_INPUT, ctr);
  28.         aes_decrypt(arm9bin+0x800+i, arm9bin+0x800+i, ctr, 1, AES_CTR_MODE);
  29.         add_ctr(ctr, 1);
  30.     }
  31.    
  32.     return 0;
  33. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement