TiniVi

Crypto-Fixer (main.c)

Nov 11th, 2015
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.51 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "sha256.h"
  4.  
  5. int crypto_fix(char* cxi_path, char* seed_path){
  6.     FILE * cxi = fopen(cxi_path, "r+b");
  7.     if (cxi == NULL){
  8.         printf("CXI COULD NOT BE OPENED\n");
  9.         return -1;
  10.     }
  11.    
  12.     fseek(cxi, 0, SEEK_END);
  13.     int cxi_size = ftell(cxi); //get cxi filesize
  14.     fseek(cxi, 0, SEEK_SET);
  15.     if (cxi_size < 0x200){ //if it's too small to be a cxi, return -2
  16.         printf("INVALID CXI\n");
  17.         return -2;
  18.     }
  19.    
  20.     unsigned char ncch[5] = { '\0' };
  21.     fseek(cxi, 0x100, SEEK_SET);
  22.     fread(&ncch, 4, 1, cxi);
  23.     if (strcmp(ncch, "NCCH") != 0){ //if not NCCH, return -2
  24.         printf("INVALID CXI\n");
  25.         return -2;
  26.     }
  27.    
  28.     unsigned char seed_flag = 0;
  29.     fseek(cxi, 0x18F, SEEK_SET);
  30.     fread(&seed_flag, 1, 1, cxi);
  31.     if (!(seed_flag & 0x20)){ //if seed crypto is not enabled
  32.         printf("SEED CRYPTO NOT DETECTED\n");
  33.         return -3;
  34.     }
  35.    
  36.     FILE * seeddb = fopen(seed_path, "rb");
  37.     if (seeddb == NULL){
  38.         printf("SEEDDB COULD NOT BE OPENED\n");
  39.         return -4;
  40.     }
  41.    
  42.     fseek(seeddb, 0, SEEK_END);
  43.     int seeddb_size = ftell(seeddb); //get seeddb filesize
  44.     fseek(seeddb, 0, SEEK_SET);
  45.    
  46.     unsigned int seedcount = 0;
  47.     if (seeddb_size < 0x10) fread(&seedcount, 4, 1, seeddb);
  48.     if (0x10 + (seedcount * 0x20) != seeddb_size){ //if the seeddb is too small, return -5
  49.         printf("INVALID SEEDDB\n");
  50.         return -5;
  51.     }
  52.    
  53.     unsigned int unique_id = 0;
  54.     fseek(cxi, 0x109, SEEK_SET);
  55.     fread(&unique_id, 3, 1, cxi); //retrieve the unique id from the cxi
  56.     printf("UNIQUE ID: 0x%X\n", unique_id);
  57.    
  58.     unsigned char cxi_keyY[0x10] = { 0 };
  59.     fseek(cxi, 0, SEEK_SET);
  60.     fread(&cxi_keyY, 0x10, 1, cxi); //read keyy from the cxi
  61.    
  62.     printf("KEYY: ");
  63.     for (int i = 0; i < 0x10; i++){
  64.         if (cxi_keyY[i] < 0x10){
  65.             printf("0");
  66.             printf("%X", cxi_keyY[i]);
  67.         } else {
  68.             printf("%X", cxi_keyY[i]);
  69.         }
  70.     }
  71.     printf("\n");
  72.    
  73.     unsigned int uid_check = 0;
  74.     unsigned char seed[0x10] = { 0 };
  75.     for (int i = 0; i < seedcount; i++){ //search the seeddb for the unique id
  76.         fseek(seeddb, 0x11+(i*0x20), SEEK_SET);
  77.         fread(&uid_check, 3, 1, seeddb);
  78.        
  79.         if (uid_check == unique_id){
  80.             fseek(seeddb, 0x18+(i*0x20), SEEK_SET);
  81.             fread(&seed, 0x10, 1, seeddb);
  82.             break;
  83.         } else if (i == seedcount-1){ //if seed could not be located, return -6
  84.             printf("SEED NOT FOUND");
  85.             return -6;
  86.         }
  87.     }
  88.    
  89.     printf("SEED: ");
  90.     for (int i = 0; i < 0x10; i++){
  91.         if (seed[i] < 0x10){
  92.             printf("0");
  93.             printf("%X", seed[i]);
  94.         } else {
  95.             printf("%X", seed[i]);
  96.         }
  97.     }
  98.     printf("\n");
  99.    
  100.     unsigned char keyY_gen[0x20] = { 0 }; //create array including data to be hashed
  101.     memcpy(keyY_gen, cxi_keyY, 0x10);
  102.     memcpy(keyY_gen+0x10, seed, 0x10);
  103.    
  104.     unsigned char keyy[0x20] = { 0 }; //create an sha256 over the new keyy data
  105.     sha256_context keyy_ctx;
  106.     sha256_starts(&keyy_ctx);
  107.     sha256_update(&keyy_ctx, keyY_gen, 0x20);
  108.     sha256_finish(&keyy_ctx, keyy);
  109.    
  110.     printf("NEW KEYY: ");
  111.     for (int i = 0; i < 0x10; i++){
  112.         if (keyy[i] < 0x10){
  113.             printf("0");
  114.             printf("%X", keyy[i]);
  115.         } else {
  116.             printf("%X", keyy[i]);
  117.         }
  118.     }
  119.     printf("\n");
  120.    
  121.     fseek(cxi, 0, SEEK_SET);
  122.     fwrite(&keyy, 0x10, 1, cxi); //write the new keyy to the cxi
  123.    
  124.     seed_flag = seed_flag & 0x0F;
  125.     fseek(cxi, 0x18F, SEEK_SET);
  126.     fwrite(&seed_flag, 1, 1, cxi);
  127.    
  128.     fclose(cxi);
  129.     fclose(seeddb);
  130.    
  131.     printf("DONE!\n");
  132.    
  133.     return 0;
  134. }
  135.  
  136. int main(int argc, char *argv[]){
  137.     if (argc < 3 || argc > 4){ //if invalid number of arguments, prompt user with arg' layout
  138.         printf("Crypto-Fixer <CXI PATH> <SEEDDB PATH> (OPTIONAL OUTPUT)\n");
  139.         return 1;
  140.        
  141.     } else if (argc == 3){
  142.         return crypto_fix(argv[1], argv[2]);
  143.        
  144.     } else if (argc == 4){
  145.         FILE * input = fopen(argv[1], "rb");
  146.         if (input == NULL){
  147.             printf("INPUT COULD NOT BE OPENED\n");
  148.             return 2;
  149.         }
  150.        
  151.         fseek(input, 0, SEEK_END);
  152.         int size = ftell(input);
  153.         fseek(input, 0, SEEK_SET);
  154.         if (size < 0x200){
  155.             printf("INVALID CXI\n");
  156.             return -2;
  157.         }
  158.        
  159.         unsigned char ncch[5] = { '\0' };
  160.         fseek(input, 0x100, SEEK_SET);
  161.         fread(&ncch, 4, 1, input);
  162.         if (strcmp(ncch, "NCCH") != 0){
  163.             printf("INVALID CXI\n");
  164.             return -2;
  165.         }
  166.        
  167.         FILE * output = fopen(argv[3], "wb");
  168.        
  169.         printf("Copying input CXI to output file...\n");
  170.         unsigned char buf[0x100000];
  171.         for (int i = 0; i < size; i+=0x100000){
  172.             if (i + 0x100000 > size){
  173.                 fread(&buf, size - i, 1, input);
  174.                 fwrite(&buf, size - i, 1, output);
  175.             } else {
  176.                 fread(&buf, 0x100000, 1, input);
  177.                 fwrite(&buf, 0x100000, 1, output);
  178.             }
  179.         }
  180.        
  181.         fclose(input);
  182.         fclose(output);
  183.        
  184.         return crypto_fix(argv[3], argv[2]);
  185.     }
  186. }
Advertisement
Add Comment
Please, Sign In to add comment