Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2014
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.63 KB | None | 0 0
  1. /*
  2.  * ctrKeyGen.c
  3.  * 8/28/2014
  4.  * Coded by Relys
  5.  * Based on makerom by 3dsguy (structs and ctr method ripped from there)
  6.  * Used for generating custom file format to be used with xor generator on 3ds coded by sbJFn5r.
  7.  * xor generator based off of base libraries provided by Kane49. Interaction with the AES engine based off of crypto libs coded by megazig.
  8.  * Special thanks to sm for providing file system libs.
  9.  * xor generator coded by sbJFn5r, Relys
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16.  
  17. #include <wchar.h>
  18.  
  19. typedef unsigned char   u8;
  20. typedef unsigned short  u16;
  21. typedef unsigned int    u32;
  22. typedef unsigned long long      u64;
  23.  
  24. typedef struct
  25. {
  26.         u8 signature[0x100];
  27.         u8 magic[4];
  28.         u8 ncchSize[4];
  29.         u8 titleId[8];
  30.         u8 makerCode[2];
  31.         u8 formatVersion[2];
  32.         u8 padding0[4];
  33.         u8 programId[8];
  34.         u8 padding1[0x10];
  35.         u8 logoHash[0x20]; // SHA-256 over the entire logo region
  36.         u8 productCode[0x10];
  37.         u8 exhdrHash[0x20]; // SHA-256 over exhdrSize of the ExHeader region
  38.         u8 exhdrSize[4];
  39.         u8 padding2[4];
  40.         u8 flags[8];
  41.         u8 plainRegionOffset[4];
  42.         u8 plainRegionSize[4];
  43.         u8 logoOffset[4];
  44.         u8 logoSize[4];
  45.         u8 exefsOffset[4];
  46.         u8 exefsSize[4];
  47.         u8 exefsHashSize[4];
  48.         u8 padding4[4];
  49.         u8 romfsOffset[4];
  50.         u8 romfsSize[4];
  51.         u8 romfsHashSize[4];
  52.         u8 padding5[4];
  53.         u8 exefsHash[0x20];
  54.         u8 romfsHash[0x20];
  55. } ncch_hdr;
  56.  
  57. typedef struct
  58. {
  59.         u16 formatVersion;
  60.         u32 exhdrOffset;
  61.         u32 exhdrSize;
  62.         u32 acexOffset;
  63.         u32 acexSize;
  64.         u64 logoOffset;
  65.         u64 logoSize;
  66.         u64 plainRegionOffset;
  67.         u64 plainRegionSize;
  68.         u64 exefsOffset;
  69.         u64 exefsSize;
  70.         u64 exefsHashDataSize;
  71.         u64 romfsOffset;
  72.         u64 romfsSize;
  73.         u64 romfsHashDataSize;
  74.         u8 titleId[8];
  75.         u8 programId[8];
  76. } ncch_info;
  77.  
  78. typedef enum
  79. {
  80.         BE = 0,
  81.         LE = 1
  82. } endianness_flag;
  83.  
  84. typedef enum
  85. {
  86.         ncch_exhdr = 1,
  87.         ncch_exefs,
  88.         ncch_romfs,
  89. } ncch_section;
  90.  
  91.  
  92. void endian_memcpy(u8 *destination, u8 *source, u32 size, int endianness)
  93. {
  94.         for (u32 i = 0; i < size; i++){
  95.                 switch (endianness){
  96.                 case(BE):
  97.                         destination[i] = source[i];
  98.                         break;
  99.                 case(LE):
  100.                         destination[i] = source[((size-1)-i)];
  101.                         break;
  102.                 }
  103.         }
  104. }
  105.  
  106. void GetNcchAesCounter(ncch_info *ctx, u8 counter[16], u8 type)
  107. {
  108.         u8 *titleId = ctx->titleId;
  109.         u32 i;
  110.         u32 x = 0;
  111.  
  112.         memset(counter, 0, 16);
  113.  
  114.         if (ctx->formatVersion == 2 || ctx->formatVersion == 0)
  115.         {
  116.                 endian_memcpy(counter,titleId,8,LE);
  117.                 counter[8] = type;
  118.         }
  119.         else if (ctx->formatVersion == 1)
  120.         {
  121.                 switch(type){
  122.                 case ncch_exhdr : x = ctx->exhdrOffset; break;
  123.                 case ncch_exefs : x = ctx->exefsOffset; break;
  124.                 case ncch_romfs : x = ctx->romfsOffset; break;
  125.                 }
  126.                 for(i=0; i<8; i++)
  127.                         counter[i] = titleId[i];
  128.                 for(i=0; i<4; i++)
  129.                         counter[12+i] = x>>((3-i)*8);
  130.         }
  131.  
  132.         //memdump(stdout,"CTR: ",counter,16);
  133. }
  134.  
  135. typedef struct
  136. {
  137.         u8 offset[4];
  138.         u8 size[4];
  139. } ncch_offsetsize;
  140.  
  141. typedef struct
  142. {
  143.         u8 signature[0x100];
  144.         u8 magic[4];
  145.         u8 mediaSize[4];
  146.         u8 titleId[8];
  147.         u8 padding0[0x10];
  148.         ncch_offsetsize offset_sizeTable[8];
  149.         u8 padding1[0x28];
  150.         u8 flags[8];
  151.         u8 ncchIdTable[8][8];
  152.         u8 padding2[0x30];
  153. } cci_hdr;
  154.  
  155. int roundUp(int numToRound, int multiple)
  156. {
  157.     if (multiple == 0)
  158.         return numToRound;
  159.  
  160.     int remainder = abs(numToRound) % multiple;
  161.     if (remainder == 0)
  162.         return numToRound;
  163.     if (numToRound < 0)
  164.         return -(abs(numToRound) - remainder);
  165.     return numToRound + multiple - remainder;
  166. }
  167.  
  168.  
  169. int main(int argc, char *argv[])
  170. {
  171.  
  172.         //Checks for input arguments
  173.         if(argc<2)
  174.         {
  175.                 printf("ctrKeyGen.exe <input.3ds>");
  176.                 return 0;
  177.         }
  178.  
  179.         //file setup;
  180.         FILE * pFile;
  181.         long lSize;
  182.  
  183.         //Opens file for reading
  184.         pFile = fopen ( argv[1] , "rb" );
  185.         if (pFile==NULL) { printf("Error: Couldn't open input file"); return 1;}
  186.  
  187.         // obtain file size for input file:
  188.         fseek (pFile , 0 , SEEK_END);
  189.         lSize = ftell (pFile);
  190.         rewind (pFile);
  191.        
  192.                 //file setup for output;
  193.         FILE * pFileOut;
  194.                 //Opens file for reading
  195.         pFileOut = fopen ( "ncchinfo.bin" , "wb" );
  196.         if (pFileOut==NULL) { printf("Error: Couldn't output file"); return 1;}
  197.        
  198.         //setup counter for entries (# of xor pads to be generated)
  199.         int entries=0;
  200.         fwrite(&entries,sizeof(int),1,pFileOut);
  201.        
  202.  
  203.         //setup NCSD header;
  204.         cci_hdr ncsd;
  205.         //fseek(pFile,0x0,SEEK_SET);
  206.         //fread(&ncsd, sizeof(cci_hdr), 1, pFile);
  207.  
  208.         //Go through lists of ncch header offsets found in the ncsd table
  209.         //for(int ii=0;ii<1;ii++)
  210.         //{
  211.        
  212.                 //grab the offset of the current ncch header for the current partition
  213.                 //ncch_offsetsize ncchOffset;
  214.                 //ncchOffset=ncsd.offset_sizeTable[ii];  
  215.  
  216.                 //checks if the header exists for the current partition.
  217.                 //if((*(u32*)ncchOffset.offset)!=0)
  218.                 //{
  219.                         //Prints out offset for NCCH header in the current partition
  220.                         //printf("\nNCCH Offset:\n");
  221.                         //printf(" %08X ",(*(u32*)ncchOffset.offset)*0x200);
  222.  
  223.                         //Time to read the ncch header into a struct. Seek position according to the ncch header table defined in the ncsd header
  224.                         fseek(pFile,0x0,SEEK_SET);
  225.                        
  226.                         //header to read into
  227.                         ncch_hdr hdr;
  228.  
  229.                         //read header
  230.                         fread(&hdr, sizeof(ncch_hdr), 1, pFile);
  231.  
  232.                         //print out product code
  233.                         printf("\nProduct Code:\n");
  234.                         printf("%.*s",0x10,hdr.productCode);
  235.                        
  236.                         //print out current partition
  237.                         //printf("\nPartition #:\n");
  238.                         //printf("%d",ii);
  239.                         //print out keyY which is first 16 bytes of the ncch RSA signature
  240.                         printf("\nKeyY:\n");
  241.                         for(int iii=0;iii<16;iii++)
  242.                         {
  243.                                 printf(" %02X ", hdr.signature[iii] );
  244.                         }
  245.  
  246.                         //Print out titleID
  247.                         printf("\nTitle ID:\n");
  248.                         for(int iii=0;iii<8;iii++)
  249.                         {
  250.                                 printf(" %02X ", hdr.titleId[iii] );
  251.                         }
  252.  
  253.                         //Print out Format version
  254.                         printf("\nFormat Version:\n");
  255.                         for(int iii=0;iii<2;iii++)
  256.                         {
  257.                                 printf(" %02X ", hdr.formatVersion[iii] );
  258.                         }
  259.                         //Define exhdrOffset. This is a constant variable from what I can tell in makerom
  260.                         //ctx->exhdrOffset=0x200;
  261.                         u64 exhdrOffset=0x200;
  262.                        
  263.                         //Print out exhdr offset
  264.                         if((*(u32*)hdr.exhdrSize))
  265.                         {
  266.                         printf("\nExHeader Offset:\n");
  267.                         printf(" %02X ", exhdrOffset);
  268.                         }
  269.                         //print of exefs offset
  270.                         printf("\nExeFS Offset:\n");
  271.                         for(int iii=0;iii<4;iii++)
  272.                         {
  273.                                 printf(" %02X ", hdr.exefsOffset[iii] );
  274.                         }
  275.  
  276.                         //printout romfs offset
  277.                         printf("\nRomFS Offset:\n");
  278.                         for(int iii=0;iii<4;iii++)
  279.                         {
  280.                                 printf(" %02X ", hdr.romfsOffset[iii] );
  281.                         }
  282.  
  283.                         //Put the ncch header into the ncch info struct to be used with the makerom functions.
  284.                         ncch_info ctx;
  285.                         memcpy(&ctx.titleId,&hdr.titleId,8);
  286.                         memcpy(&ctx.formatVersion,&hdr.formatVersion,2);
  287.                         memcpy(&ctx.exhdrOffset,&exhdrOffset,4);
  288.                         memcpy(&ctx.exefsOffset,&hdr.exefsOffset,4);
  289.                         memcpy(&ctx.romfsOffset,&hdr.romfsOffset,4);
  290.                        
  291.                         //declare ctr for exhdr
  292.                         u8 exhdr_ctr[16];
  293.                        
  294.                         //calculate ctr for exhdr
  295.                         GetNcchAesCounter(&ctx,exhdr_ctr,ncch_exhdr);
  296.  
  297.                         //Grab size of exhdr and grab megabytes for xor to generate
  298.                         u32 exhdrSize = (*(u32*)hdr.exhdrSize);
  299.                         u32 exhdrSizeMegabytes=roundUp(exhdrSize*0x200, 1024*1024) / (1024*1024);
  300.                        
  301.                         //Check if the exhdr exists in the current partition
  302.                         if(exhdrSize!=0)
  303.                         {
  304.                         entries++;
  305.                                 printf("\nExHeaderFS CTR:\n");
  306.                                 for(int iii=0;iii<16;iii++)
  307.                                 {
  308.                                         printf(" %02X ", exhdr_ctr[iii] );
  309.                                 }
  310.                                 printf("\nExHeader Megabytes (rounded up):\n");
  311.                                 printf("%d",exhdrSizeMegabytes);
  312.                                 fwrite(&exhdr_ctr,16,1,pFileOut);
  313.                                 fwrite(&hdr.signature,16,1,pFileOut);
  314.                                 fwrite(&exhdrSizeMegabytes,4,1,pFileOut);
  315.                                
  316.                                 wchar_t exhdrDirWide[32];
  317.                                 //Initialize exhdr
  318.                                 for(int jj=0;jj<32;jj++)
  319.                                 {
  320.                                 exhdrDirWide[jj]=0;
  321.                                 }
  322.                                
  323.                                 exhdrDirWide[0]='/';
  324.                                 for(int jj=0;jj<16;jj++)
  325.                                 {
  326.                                 exhdrDirWide[1+jj]=hdr.productCode[jj];
  327.                                 }
  328.                                 char exhdrBuff[1];
  329.                                 sprintf(exhdrBuff, "%d", 0);
  330.                                 exhdrDirWide[11]=exhdrBuff[0];
  331.                                 exhdrDirWide[12]='.';
  332.                                 exhdrDirWide[13]='e';
  333.                                 exhdrDirWide[14]='x';
  334.                                 exhdrDirWide[15]='h';
  335.                                 exhdrDirWide[16]='.';
  336.                                 exhdrDirWide[17]='x';
  337.                                 exhdrDirWide[18]='o';
  338.                                 exhdrDirWide[19]='r';
  339.                                 exhdrDirWide[20]='p';
  340.                                 exhdrDirWide[21]='a';
  341.                                 exhdrDirWide[22]='d';
  342.                                
  343.                                 //swprintf(exhdrDirWide, 32, L"%hs", "/TEST.BIN");
  344.                                 fwrite(&exhdrDirWide,32,2,pFileOut);
  345.                         }
  346.  
  347.                         //declare ctr for exefs
  348.                         u8 exefs_ctr[16];
  349.                        
  350.                         //calculate exefs for exhdr
  351.                         GetNcchAesCounter(&ctx,exefs_ctr,ncch_exefs);
  352.  
  353.                         //Grab size of exefs and grab megabytes for xor to generate
  354.                         u32 exefsSize = (*(u32*)hdr.exefsSize);
  355.                         u32 exefsSizeMegabytes=roundUp(exefsSize*0x200, 1024*1024) / (1024*1024);
  356.                        
  357.                         //Check if the exefs exists in the current partition
  358.                         if(exefsSize!=0)
  359.                         {
  360.                         entries++;
  361.                                 printf("\nExeFS CTR:\n");
  362.                                 for(int iii=0;iii<16;iii++)
  363.                                 {
  364.                                         printf(" %02X ", exefs_ctr[iii] );
  365.                                 }
  366.                                 printf("\nExeFS Megabytes (rounded up):\n");
  367.                                 printf("%d",exefsSizeMegabytes);
  368.                                 fwrite(&exefs_ctr,16,1,pFileOut);
  369.                                 fwrite(&hdr.signature,16,1,pFileOut);
  370.                                 fwrite(&exefsSizeMegabytes,4,1,pFileOut);
  371.                                
  372.                                 wchar_t exefsDirWide[32];
  373.                                 //Initialize exefs
  374.                                 for(int jj=0;jj<32;jj++)
  375.                                 {
  376.                                 exefsDirWide[jj]=0;
  377.                                 }
  378.                                
  379.                                 exefsDirWide[0]='/';
  380.                                 for(int jj=0;jj<16;jj++)
  381.                                 {
  382.                                 exefsDirWide[1+jj]=hdr.productCode[jj];
  383.                                 }
  384.                                 char exefsBuff[1];
  385.                                 sprintf(exefsBuff, "%d", 0);
  386.                                 exefsDirWide[11]=exefsBuff[0];
  387.                                 exefsDirWide[12]='.';
  388.                                 exefsDirWide[13]='e';
  389.                                 exefsDirWide[14]='x';
  390.                                 exefsDirWide[15]='e';
  391.                                 exefsDirWide[16]='f';
  392.                                 exefsDirWide[17]='s';
  393.                                 exefsDirWide[18]='.';
  394.                                 exefsDirWide[19]='x';
  395.                                 exefsDirWide[20]='o';
  396.                                 exefsDirWide[21]='r';
  397.                                 exefsDirWide[22]='p';
  398.                                 exefsDirWide[23]='a';
  399.                                 exefsDirWide[24]='d';
  400.                                
  401.                                 //swprintf(exefsDirWide, 32, L"%hs", "/TEST.BIN");
  402.                                 fwrite(&exefsDirWide,32,2,pFileOut);
  403.                         }
  404.  
  405.                         //declare ctr for romfs
  406.                         u8 romfs_ctr[16];
  407.                        
  408.                         //calculate romfs for exhdr
  409.                         GetNcchAesCounter(&ctx,romfs_ctr,ncch_romfs);
  410.  
  411.                         //Grab size of romfs and grab megabytes for xor to generate
  412.                         u32 romfsSize = (*(u32*)hdr.romfsSize);
  413.                         u32 romfsSizeMegabytes=roundUp(romfsSize*0x200, 1024*1024) / (1024*1024);
  414.                        
  415.                         //Check if the romfs exists in the current partition
  416.                         if(romfsSize!=0)
  417.                         {
  418.                         entries++;
  419.                                 printf("\nRomFS CTR:\n");
  420.                                 for(int iii=0;iii<16;iii++)
  421.                                 {
  422.                                         printf(" %02X ", romfs_ctr[iii] );
  423.                                 }
  424.                                 printf("\nRomFS Megabytes (rounded up):\n");
  425.                                 printf("%d",romfsSizeMegabytes);
  426.                                 fwrite(&romfs_ctr,16,1,pFileOut);
  427.                                 fwrite(&hdr.signature,16,1,pFileOut);
  428.                                 fwrite(&romfsSizeMegabytes,4,1,pFileOut);
  429.                                
  430.                                 wchar_t romfsDirWide[32];
  431.                                
  432.                                 //Initialize romfs
  433.                                 for(int jj=0;jj<32;jj++)
  434.                                 {
  435.                                 romfsDirWide[jj]=0;
  436.                                 }
  437.                                
  438.                                 romfsDirWide[0]='/';
  439.                                 for(int jj=0;jj<16;jj++)
  440.                                 {
  441.                                 romfsDirWide[1+jj]=hdr.productCode[jj];
  442.                                 }
  443.                                 char romfsBuff[1];
  444.                                 sprintf(romfsBuff, "%d", 0);
  445.                                 romfsDirWide[11]=romfsBuff[0];
  446.                                 romfsDirWide[12]='.';
  447.                                 romfsDirWide[13]='r';
  448.                                 romfsDirWide[14]='o';
  449.                                 romfsDirWide[15]='m';
  450.                                 romfsDirWide[16]='f';
  451.                                 romfsDirWide[17]='s';
  452.                                 romfsDirWide[18]='.';
  453.                                 romfsDirWide[19]='x';
  454.                                 romfsDirWide[20]='o';
  455.                                 romfsDirWide[21]='r';
  456.                                 romfsDirWide[22]='p';
  457.                                 romfsDirWide[23]='a';
  458.                                 romfsDirWide[24]='d';
  459.                                
  460.                                 //swprintf(romfsDirWide, 32, L"%hs", "/TEST.BIN");
  461.                                
  462.                                 fwrite(&romfsDirWide,32,2,pFileOut);
  463.                         }
  464.  
  465.                 printf("\n=======\n");
  466.                 //}
  467.  
  468.                
  469.         //}
  470.        
  471.         //print out total entries recorded.
  472.         printf("\nTotal Entries:\n");
  473.         printf("%d",entries);
  474.        
  475.         //Seek back to beginning of file and update the number of entries to the final value.
  476.         fseek(pFileOut,0x0,SEEK_SET);
  477.         fwrite(&entries,sizeof(int),1,pFileOut);
  478.        
  479.        
  480.         //Don't forget to close files kiddies. :p
  481.         fclose (pFile);
  482.         fclose (pFileOut);
  483.  
  484.  
  485.         return 0;
  486. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement