How to write a C Program Crypto-Fixer Code in C Programming Language ?
Solution:
- #include <stdio.h>
- #include <string.h>
- #include "sha256.h"
- int crypto_fix(char* cxi_path, char* seed_path){
- FILE * cxi = fopen(cxi_path, "r+b");
- if (cxi == NULL){
- printf("CXI COULD NOT BE OPENED\n");
- return -1;
- }
- fseek(cxi, 0, SEEK_END);
- int cxi_size = ftell(cxi);
- fseek(cxi, 0, SEEK_SET);
- if (cxi_size < 0x200){
- printf("INVALID CXI\n");
- return -2;
- }
- unsigned char ncch[5] = { '\0' };
- fseek(cxi, 0x100, SEEK_SET);
- fread(&ncch, 4, 1, cxi);
- if (strcmp(ncch, "NCCH") != 0){
- printf("INVALID CXI\n");
- return -2;
- }
- unsigned char seed_flag = 0;
- fseek(cxi, 0x18F, SEEK_SET);
- fread(&seed_flag, 1, 1, cxi);
- if (!(seed_flag & 0x20)){
- printf("SEED CRYPTO NOT DETECTED\n");
- return -3;
- }
- FILE * seeddb = fopen(seed_path, "r+b");
- if (seeddb == NULL){
- printf("SEEDDB COULD NOT BE OPENED\n");
- return -4;
- }
- fseek(seeddb, 0, SEEK_END);
- int seeddb_size = ftell(seeddb);
- fseek(seeddb, 0, SEEK_SET);
- unsigned int seedcount = 0;
- if (seeddb_size < 0x10) fread(&seedcount, 4, 1, seeddb);
- if (0x10 + (seedcount * 0x20) != seeddb_size){
- printf("INVALID SEEDDB\n");
- return -5;
- }
- unsigned int unique_id = 0;
- fseek(cxi, 0x109, SEEK_SET);
- fread(&unique_id, 3, 1, cxi);
- printf("UNIQUE ID: 0x%X\n", unique_id);
- unsigned char cxi_keyY[0x10] = { 0 };
- fseek(cxi, 0, SEEK_SET);
- fread(&cxi_keyY, 0x10, 1, cxi);
- printf("KEYY: ");
- for (int i = 0; i < 0x10; i++){
- if (cxi_keyY[i] < 0x10){
- printf("0");
- printf("%X", cxi_keyY[i]);
- } else {
- printf("%X", cxi_keyY[i]);
- }
- }
- printf("\n");
- unsigned int uid_check = 0;
- unsigned char seed[0x10] = { 0 };
- for (int i = 0; i < seedcount; i++){
- fseek(seeddb, 0x11+(i*0x20), SEEK_SET);
- fread(&uid_check, 3, 1, seeddb);
- if (uid_check == unique_id){
- fseek(seeddb, 0x18+(i*0x20), SEEK_SET);
- fread(&seed, 0x10, 1, seeddb);
- break;
- } else if (i == seedcount-1){
- printf("SEED NOT FOUND");
- return -6;
- }
- }
- printf("SEED: ");
- for (int i = 0; i < 0x10; i++){
- if (seed[i] < 0x10){
- printf("0");
- printf("%X", seed[i]);
- } else {
- printf("%X", seed[i]);
- }
- }
- printf("\n");
- unsigned char keyY_gen[0x20] = { 0 };
- memcpy(keyY_gen, cxi_keyY, 0x10);
- memcpy(keyY_gen+0x10, seed, 0x10);
- unsigned char keyy[0x20] = { 0 };
- sha256_context keyy_ctx;
- sha256_starts(&keyy_ctx);
- sha256_update(&keyy_ctx, keyY_gen, 0x20);
- sha256_finish(&keyy_ctx, keyy);
- printf("NEW KEYY: ");
- for (int i = 0; i < 0x10; i++){
- if (keyy[i] < 0x10){
- printf("0");
- printf("%X", keyy[i]);
- } else {
- printf("%X", keyy[i]);
- }
- }
- printf("\n");
- fseek(cxi, 0, SEEK_SET);
- fwrite(&keyy, 0x10, 1, cxi);
- seed_flag = seed_flag & 0x0F;
- fseek(cxi, 0x18F, SEEK_SET);
- fwrite(&seed_flag, 1, 1, cxi);
- printf("DONE!");
- return 0;
- }
- int main(int argc, char *argv[]){
- if (argc < 3 || argc > 4){
- printf("Crypto-Fixer <CXI PATH> <SEEDDB PATH> (OPTIONAL OUTPUT)\n");
- return 1;
- } else if (argc == 3){
- return crypto_fix(argv[1], argv[2]);
- } else if (argc == 4){
- FILE * input = fopen(argv[1], "rb");
- if (input == NULL){
- printf("INPUT COULD NOT BE OPENED\n");
- return 2;
- }
- fseek(input, 0, SEEK_END);
- int size = ftell(input);
- fseek(input, 0, SEEK_SET);
- if (size < 0x200){
- printf("INVALID CXI\n");
- return -2;
- }
- unsigned char ncch[5] = { '\0' };
- fseek(input, 0x100, SEEK_SET);
- fread(&ncch, 4, 1, input);
- if (strcmp(ncch, "NCCH") != 0){
- printf("INVALID CXI\n");
- return -2;
- }
- FILE * output = fopen(argv[3], "wb");
- printf("Copying input CXI to output file...\n");
- unsigned char buf[0x100000];
- for (int i = 0; i < size; i+=0x100000){
- if (i + 0x100000 > size){
- fread(&buf, size - i, 1, input);
- fwrite(&buf, size - i, 1, output);
- } else {
- fread(&buf, 0x100000, 1, input);
- fwrite(&buf, 0x100000, 1, output);
- }
- }
- return crypto_fix(argv[3], argv[2]);
- }
- }