arc.nsaをデコードしようとしてみる。

nscript.datをデコードして遊んだついでにarc.nsaをデコードしようとしてみる。NScripterをダウンロードしてきて、適当にちっさいarc.nsaを作っておいてそれを展開させてみる。ディレクトリの作り方とかからして調べないとわからないレベルなので、それなりに時間がかかってしまった。めちゃくちゃ適当。ソースコードの中にマジックコードだらけでわっしょいやし、ディレクトリに格納されてたら展開できないし、あとほとんどのarc.nsaを開けないし。自分で作ったarc.nsa展開できてわー思って、「歌月十夜」のarc.nsa展開してみよ思ったらできねーし。

わかったこと
sarとかnsaはファイル名とアドレスとかサイズとかがヘッダーにごちゃごちゃあって、その後に生データが連続して存在する

とかそんな感じ

ちゃんとしたsarとかnsaを展開するソフトとしては、
google:sartool とか http://elku.at.infoseek.co.jp/ とか。

#include 
#include 
#include 

#define NAME_SIZE 256

struct nsafile{
	char filename[NAME_SIZE];
	int size;
	int address;
};
struct nsarc{
	struct nsafile *file;
	int filenum;
};

int read_nshead(struct nsarc *, FILE *);
int decode_nsa(struct nsarc *, FILE *);

int main(){
	FILE *nsafile;
	struct nsarc *nsa;
	nsa = (struct nsarc *)malloc(sizeof(struct nsarc));
	nsa->file = NULL;
	if)((nsafile = fopen("arc.nsa", "rb"))( == NULL)
		puts("arc.nsa読み込み失敗"), exit(1);
	if(read_nshead(nsa, nsafile) == -1)
		puts("arc.nsaヘッダ読み込み失敗"), exit(1);

	decode_nsa(nsa, nsafile);

	fclose(nsafile);

	return 0;
}

int read_nshead(struct nsarc *nsa, FILE *nsafile){
	unsigned int size;
	long int base_address;
	int i, j, c;
	nsa->filenum = 0; base_address = 0;
	for(i=0;i<2;++i) nsa->filenum = nsa->filenum * 0x100 + fgetc(nsafile);
	nsa->file = (struct nsafile *)calloc(nsa->filenum, sizeof(struct nsafile));
	printf("arc.nsa内のファイル%u個\n", nsa->filenum);
	for(i=0;ifilenum;++i){
		size = 0;
		for(j=0;j<4;++j)
			size = size * 0x100 + fgetc(nsafile);
		base_address += size;
		nsa->file[i].address = base_address;
		j=0;
		while)((c=fgetc(nsafile))( != 0){
			nsa->file[i].filename[j] = (char)c;
			++j;
		}
		puts(nsa->file[i].filename);
		fseek(nsafile, 5, SEEK_CUR);
		size = 0;
		for(j=0;j<4;++j)
			size = size * 0x100 + fgetc(nsafile);
		nsa->file[i].size = size;
		printf("size: %d byte\n", size);
		printf("location: %08x\n", base_address);
	}
	return 1;
}
int decode_nsa(struct nsarc *nsa, FILE *nsafile){
	int i, j, c;
	FILE *decfile;
	_mkdir("nsa");
	if(_chdir("nsa") != 0) puts("cannot move nsa\\"), exit(1);
	for(i=0;ifilenum;++i){
		if)((decfile = fopen(nsa->file[i].filename, "wb"))( == NULL)
			printf("%sが開けない\n", nsa->file[i].filename), exit(1);
		fseek(nsafile, nsa->file[i].address, SEEK_SET);
		for(j=0;jfile[i].size;++j){
			c = fgetc(nsafile);
			fputc(c, decfile);
		}
		fclose(decfile);
	}
	return 1;
}

場当たりプログラミング万歳。プログラミングはおもしろいのかもしれないけど、めんどくさい。

test