C Program Crypto-Fixer Code

How to write a C Program Crypto-Fixer Code in C Programming Language ?


Solution:

  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);
  14.         fseek(cxi, 0, SEEK_SET);
  15.         if (cxi_size < 0x200){
  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){
  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)){
  32.                 printf("SEED CRYPTO NOT DETECTED\n");
  33.                 return -3;
  34.         }
  35.        
  36.         FILE * seeddb = fopen(seed_path, "r+b");
  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);
  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){
  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);
  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);
  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++){
  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 (== seedcount-1){
  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 };
  101.         memcpy(keyY_gen, cxi_keyY, 0x10);
  102.         memcpy(keyY_gen+0x10, seed, 0x10);
  103.        
  104.         unsigned char keyy[0x20] = { 0 };
  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);
  123.        
  124.         seed_flag = seed_flag & 0x0F;
  125.         fseek(cxi, 0x18F, SEEK_SET);
  126.         fwrite(&seed_flag, 1, 1, cxi);
  127.        
  128.         printf("DONE!");
  129.        
  130.         return 0;
  131. }
  132.  
  133. int main(int argc, char *argv[]){
  134.         if (argc < 3 || argc > 4){
  135.                 printf("Crypto-Fixer <CXI PATH> <SEEDDB PATH> (OPTIONAL OUTPUT)\n");
  136.                 return 1;
  137.                
  138.         } else if (argc == 3){
  139.                 return crypto_fix(argv[1], argv[2]);
  140.                
  141.         } else if (argc == 4){
  142.                 FILE * input = fopen(argv[1], "rb");
  143.                 if (input == NULL){
  144.                         printf("INPUT COULD NOT BE OPENED\n");
  145.                         return 2;
  146.                 }
  147.                
  148.                 fseek(input, 0, SEEK_END);
  149.                 int size = ftell(input);
  150.                 fseek(input, 0, SEEK_SET);
  151.                 if (size < 0x200){
  152.                         printf("INVALID CXI\n");
  153.                         return -2;
  154.                 }
  155.                
  156.                 unsigned char ncch[5] = { '\0' };
  157.                 fseek(input, 0x100, SEEK_SET);
  158.                 fread(&ncch, 4, 1, input);
  159.                 if (strcmp(ncch, "NCCH") != 0){
  160.                         printf("INVALID CXI\n");
  161.                         return -2;
  162.                 }
  163.                
  164.                 FILE * output = fopen(argv[3], "wb");
  165.                
  166.                 printf("Copying input CXI to output file...\n");
  167.                 unsigned char buf[0x100000];
  168.                 for (int i = 0; i < size; i+=0x100000){
  169.                         if (+ 0x100000 > size){
  170.                                 fread(&buf, size - i, 1, input);
  171.                                 fwrite(&buf, size - i, 1, output);
  172.                         } else {
  173.                                 fread(&buf, 0x100000, 1, input);
  174.                                 fwrite(&buf, 0x100000, 1, output);
  175.                         }
  176.                 }
  177.                
  178.                 return crypto_fix(argv[3], argv[2]);
  179.         }
  180. }


Learn More :