#include #include #include #include #include #include #include "mtgcompat.h" #include #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) struct FIRM_sect { uint32_t offset; uint32_t physical; uint32_t size; uint32_t arm11; uint8_t SHA256[0x20]; //Implement later. }__attribute__((packed)); struct FIRM_header { char magic[4]; int reserved1; uint32_t arm11Entry; uint32_t arm9Entry; uint8_t reserved2[0x30]; FIRM_sect sections[4]; uint8_t RSA2048[0x100]; //I'd need to find out big N's private key to do that! }__attribute__((packed)); int main(int argc, char** argv) { std::vector infiles; std::vector offsets; std::string outfile="firm.bin"; FIRM_header header; //Populate header char * tmp="FIRM"; memset(&header,0,sizeof(header)); memcpy(header.magic,tmp,4); header.reserved1=0; header.arm11Entry=0x1FF80000; header.arm9Entry=0x08000000; char opt = (char)getopt(argc, argv, "O:o:e:E:"); //O = load point of segment; o= output file; e=ARM9 entry; E=ARM11 entry while (opt!=-1) { switch(opt) { case 'O': { std::stringstream tmp; tmp<> entry; offsets.push_back(entry); break; } case 'o': { outfile=optarg; break; } case 'e': { std::stringstream tmp; tmp<> entry; header.arm9Entry=entry; break; } case 'E': { std::stringstream tmp; tmp<> entry; header.arm11Entry=entry; break;} case '?': { std::cerr << "Usage: " <(&header),sizeof header); for(int i=0;i