예제 #1
0
int main(int argc,char *argv[])
{
  printf("woodsec v0.90 - tool to manipulate secure area.\nproduced by yellow wood goblin.\n\n");
  if(argc<3)
  {
    printf("USAGE:\n\twoodsec e filename\t\tencrypt secure area.\n\twoodsec d filename\t\tdecrypt secure area.\n");
    return 1;
  }
  int result=0;
  fNDS=fopen(argv[2],"r+b");
  if(fNDS)
  {
    if(stricmp("e",argv[1])==0) //encrypt
    {
      printf("encrypting %s.\n",argv[2]);
      if(!EnDecryptSecureArea(true)) result=1;
    }
    else if(stricmp("d",argv[1])==0) //decrypt
    {
      printf("decrypting %s.\n",argv[2]);
      if(!EnDecryptSecureArea(false)) result=1;
    }
    else
    {
      printf("invalid option.\n");
      result=1;
    }
    fclose(fNDS);
  }
  else
  {
    printf("cant' open file %s.\n",argv[2]);
    result=1;
  }
  return result;
}
예제 #2
0
/*
 * main
 */
int main(int argc, char *argv[])
{
	#ifdef _NDSTOOL_P_H
		if (sizeof(Header) != 0x200) { fprintf(stderr, "Header size %d != %d\n", sizeof(Header), 0x200); return 1; }
	#endif

	if (argc < 2) { Help(); return 0; }
	
	int num_actions = 0;
	int actions[MAX_ACTIONS];

	/*
	 * parse parameters to actions
	 */

	for (int a=1; a<argc; a++)
	{
		if (argv[a][0] == '-')
		{
			switch (argv[a][1])
			{
				case 'i':	// show information
				{
					ADDACTION(ACTION_SHOWINFO);
					OPTIONAL(ndsfilename);
					break;
				}

				case 'f':	// fix header CRC
				{
					ADDACTION(ACTION_FIXHEADERCRC);
					OPTIONAL(ndsfilename);
					break;
				}

				case 's':	// en-/decrypt secure area
				{
					ADDACTION(ACTION_ENCRYPTSECUREAREA);
					endecrypt_option = argv[a][2];
					OPTIONAL(ndsfilename);
					break;
				}

				case 'l':	// list files
				{
					ADDACTION(ACTION_LISTFILES);
					OPTIONAL(ndsfilename);
					break;
				}

				case 'x':	// extract
				{
					ADDACTION(ACTION_EXTRACT);
					OPTIONAL(ndsfilename);
					break;
				}
				
				case 'w':	// wildcard filemasks
				{
					while (1)
					{
						char *filemask = 0;
						OPTIONAL(filemask);
						if (!(filemasks[filemask_num] = filemask)) break;
						if (++filemask_num >= MAX_FILEMASKS) return 1;
					}
					break;
				}

				case 'c':	// create
				{
					ADDACTION(ACTION_CREATE);
					OPTIONAL(ndsfilename);
					break;
				}

				// file root directory
				case 'd': REQUIRED(filerootdir); break;

				// ARM7 filename
				case '7': 
					if (argv[a][2] == 'i') {
						REQUIRED(arm7ifilename);
					} else {
						REQUIRED(arm7filename);
					}
					break;
				// ARM9 filename
				case '9':
					if (argv[a][2] == 'i') {
						REQUIRED(arm9ifilename);
					} else {
						REQUIRED(arm9filename);
					}
					break;

				// hook ARM7 executable
				case 'k':
				{
					ADDACTION(ACTION_HOOK);
					OPTIONAL(ndsfilename);
					break;
				}

				case 't':
					REQUIRED(bannerfilename);
					bannertype = BANNER_BINARY;
					break;

				case 'b':
					bannertype = BANNER_IMAGE;
					REQUIRED(bannerfilename);
					REQUIRED(bannertext);
					break;

				case 'o':
					REQUIRED(logofilename);
					break;

				case 'h':	// load header or header size
					REQUIRED(headerfilename_or_size);
					break;

				/*case 'u':	// unique ID file
					REQUIRED(uniquefilename);
					break;*/

				case 'u': // DSi title ID high word
					if (argc > a)
						titleidHigh = strtoul(argv[++a], 0, 16);
					break;

				case 'z': // SCFG access flags
					if (argc > a)
						scfgExtMask = strtoul(argv[++a], 0, 16);
					break;

				case 'a': // DSi access control flags
					if (argc > a)
						accessControl = strtoul(argv[++a], 0, 16);
					break;

				case 'p': // DSi application flags
					if (argc > a)
						appFlags = strtoul(argv[++a], 0, 16) & 0xFF;
					break;

				case 'v':	// verbose
					for (char *p=argv[a]; *p; p++) if (*p == 'v') verbose++;
					OPTIONAL(romlistfilename);
					break;

				case 'n':	// latency
					//compatibility = true;
					OPTIONAL_INT(latency1);
					OPTIONAL_INT(latency2);
					break;

				case 'r':	// RAM address
					switch (argv[a][2])
					{
						case '7': arm7RamAddress = (argc > a) ? strtoul(argv[++a], 0, 0) : 0; break;
						case '9': arm9RamAddress = (argc > a) ? strtoul(argv[++a], 0, 0) : 0; break;
						default: Help(argv[a]); return 1;
					}
					break;

				case 'e':	// entry point
					switch (argv[a][2])
					{
						case '7': arm7Entry = (argc > a) ? strtoul(argv[++a], 0, 0) : 0; break;
						case '9': arm9Entry = (argc > a) ? strtoul(argv[++a], 0, 0) : 0; break;
						default: Help(argv[a]); return 1;
					}
					break;

				case 'm':	// maker code
					REQUIRED(makercode);
					break;

				case 'g':	// game code
					REQUIRED(gamecode);
					OPTIONAL(makercode);
					OPTIONAL(title);
					OPTIONAL_INT(romversion);
					break;

				case 'y':	// overlay table file / directory
					switch (argv[a][2])
					{
						case '7': REQUIRED(arm7ovltablefilename); break;
						case '9': REQUIRED(arm9ovltablefilename); break;
						case 0: REQUIRED(overlaydir); break;
						default: Help(argv[a]); return 1;
					}
					break;
				
				case '?':	// global or specific help
				{
					Help(argv[a][2] ? argv[a]+2 : 0);	// 0=global help
					return 0;	// do not perform any other actions
				}

				default:
				{
					Help(argv[a]);
					return 1;
				}
			}
		}
		else
		{
			//Help();
			if (ndsfilename)
			{
				fprintf(stderr, "NDS filename is already given!\n");
				return 1;
			}
			ndsfilename = argv[a];
			break;
		}
	}

	Title();

	/*
	 * sanity checks
	 */

	if (gamecode)
	{
		if (strlen(gamecode) != 4)
		{
			fprintf(stderr, "Game code must be 4 characters!\n");
			return 1;
		}
		for (int i=0; i<4; i++) if ((gamecode[i] >= 'a') && (gamecode[i] <= 'z'))
		{
			fprintf(stderr, "Warning: Gamecode contains lowercase characters.\n");
			break;
		}
		if (gamecode[0] == 'A')
		{
			fprintf(stderr, "Warning: Gamecode starts with 'A', which might be used for another commercial product.\n");
		}
	}
	if (makercode && (strlen(makercode) != 2))
	{
		fprintf(stderr, "Maker code must be 2 characters!\n");
		return 1;
	}
	if (title && (strlen(title) > 12))
	{
		fprintf(stderr, "Title can be no more than 12 characters!\n");
		return 1;
	}
	if (romversion > 255) {
		fprintf(stderr, "romversion can only be 0 - 255!\n");
		return 1;
	}

	/*
	 * perform actions
	 */

	int status = 0;
	for (int i=0; i<num_actions; i++)
	{
//printf("action %d\n", actions[i]);
		switch (actions[i])
		{
			case ACTION_SHOWINFO:
				ShowInfo(ndsfilename);
				break;

			case ACTION_FIXHEADERCRC:
				FixHeaderCRC(ndsfilename);
				break;

			case ACTION_EXTRACT:
				fNDS = fopen(ndsfilename, "rb");
				if (!fNDS) { fprintf(stderr, "Cannot open file '%s'.\n", ndsfilename); exit(1); }
				fread(&header, 512, 1, fNDS);
				fclose(fNDS);

			printf("9i %s, 7i %s, unitcode %x\n",arm9ifilename,arm7ifilename, header.unitcode);
				if (arm9filename) Extract(arm9filename, true, 0x20, true, 0x2C, true);
				if (arm7filename) Extract(arm7filename, true, 0x30, true, 0x3C);
				if (header.unitcode & 2) {
					if (arm9ifilename) Extract(arm9ifilename, true, 0x1C0, true, 0x1CC, true);
					if (arm7ifilename) Extract(arm7ifilename, true, 0x1D0, true, 0x1DC);
				}
				if (bannerfilename) Extract(bannerfilename, true, 0x68, false, 0x840);
				if (headerfilename_or_size) Extract(headerfilename_or_size, false, 0x0, false, 0x200);
				if (logofilename) Extract(logofilename, false, 0xC0, false, 156);	// *** bin only
				if (arm9ovltablefilename) Extract(arm9ovltablefilename, true, 0x50, true, 0x54);
				if (arm7ovltablefilename) Extract(arm7ovltablefilename, true, 0x58, true, 0x5C);
				if (overlaydir) ExtractOverlayFiles();
				if (filerootdir) ExtractFiles(ndsfilename);
				break;

			case ACTION_CREATE:
				Create();
				break;

			case ACTION_LISTFILES:
				filerootdir = 0;
				/*status =*/ ExtractFiles(ndsfilename);
				break;
			
			case ACTION_HOOK:
			{
				Hook(ndsfilename, arm7filename);
				break;
			}

			case ACTION_ENCRYPTSECUREAREA:
			{
				/*status =*/ EnDecryptSecureArea(ndsfilename, endecrypt_option);
				break;
			}
		}
	}

	return (status < 0) ? 1 : 0;
}