Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Plugin request] Decrypt/Encrypt Archive/Text.bin #522

Open
Liquid-S opened this issue Sep 26, 2018 · 6 comments
Open

[Plugin request] Decrypt/Encrypt Archive/Text.bin #522

Liquid-S opened this issue Sep 26, 2018 · 6 comments
Assignees
Labels

Comments

@Liquid-S
Copy link

Liquid-S commented Sep 26, 2018

Issue: Plugin request
Console: PC
Format extension(s): BIN
Filename: textdata.bin
Type: ARCHIVE (TEXT?)
Game Name: Taishou x Alice Episode I
STEAM: https://store.steampowered.com/app/1056570/TAISHO_x_ALICE_episode_1/

First 8 bytes of the file(s):
Extension: bin
Hex: 95 6B 3C 9D 63 CE B9 0F 95
ASCII: •k<�cι�•

More details:
The file seems encrypted.
In the ".7z" you'll find the same file from the japanese, english and spanish version of the game.

I used this https://github.com/jjolano/unpac/releases to unpack "archivee.dat" and obtain "textdata.bin"

Sample files (if possible):
https://www.mediafire.com/file/ndld88z69wwpxgy/Textdata.7z/file

@onepiecefreak3
Copy link
Collaborator

If it's rly encrypted the game binary is absolutely needed. So pls add that to your sample files.

@Liquid-S
Copy link
Author

Done! The link is the same as before.
English and spanish files use the same binary file.

@onepiecefreak3
Copy link
Collaborator

The file was encrypted by a sequential XOR. The initialization value is 0xC5 and with each position this value advances by 0x5C.
XOR each byte in the file by this logic and you're golden.
Kuriimu2 implements a "Sequential XOR" in its newest dev build and upcomgin Release 1.2.1 to use for this. Use "Key"=C5 and "Step"=5C to make it work.

@Megaflan
Copy link
Contributor

Megaflan commented May 18, 2021

Translation plan

To start translating this game, you need to take into account that you have to go through two layers.

PAC2 (*.DAT)

The first one is the archive, a format called PAC2 which I solved with the next algorithm:

List<FileObj> fileList = new List<FileObj>();
if (br.ReadInt32() != 0x454d4147 || br.ReadInt32() != 0x20544144 || br.ReadInt32() != 0x32434150) //GAMEDAT PAC2
{
	Console.WriteLine("Not supported file, must be a PAC2 format");
	Console.ReadLine();
	return;
}
int fileCount = br.ReadInt32();
br.BaseStream.Position = 0x10 + 0x20 * fileCount;
for (int i = 0; i < fileCount; i++)
{
	fileList.Add(new FileObj()
	{
		Position = br.ReadInt32() + (0x10 + 0x20 * fileCount) + 0x30,
		Size = br.ReadInt32()
	});
}
br.BaseStream.Position = 0x10;

for (int i = 0; i < fileCount; i++)
{
	fileList[i].FileName = Encoding.ASCII.GetString(br.ReadBytes(0x20)).Replace("\0", "");
}
if (fileList.Count > 0)
{
	Directory.CreateDirectory(Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path));
	for (int i = 0; i < fileList.Count; i++)
	{
		br.BaseStream.Position = fileList[i].Position;
		fileList[i].Stream = br.ReadBytes(fileList[i].Size);
		Console.WriteLine("Unpacking... " + fileList[i].FileName);
		File.WriteAllBytes(Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "\\" + fileList[i].FileName, fileList[i].Stream);
	}
	Console.WriteLine("Unpacked!");
}

This will dump the archive into a folder, inside, you will find the next files:

  • BGM.ini
  • filename.dat
  • GAME.ini
  • graphic.bin
  • scenario.dat
  • textdata.bin

TEXTDATA.BIN (PJADV_TF)

From all those files, you can find the text in textdata.bin, this file is encrypted using a Sequential XOR algorithm.
The Key is 0xC5 and the Step is 0x5C. This algorithm has been implemented in Kuriimu 2 a few days ago by @onepiecefreak3.
When you decrypt that, the format is a simple null-terminated SJIS string-poblated file format, just split by ("\0\0")
A quick dump would be done by using the next algorithm:

Encoding encoding = Encoding.GetEncoding(932);
List<string> strings = new List<string>();
var fileID = dr.ReadBytes(0x10);
for (int i = 0; i < 0x2cfe; i++)
{
	strings.Add(dr.ReadStringToToken("\0\0", encoding));
}

After that, encrypt using the same keys found ahead and pack the data.

Problems found in the process

While the text format is a simple null-terminated string format, the game has hidden pointers in the flow script format found in the file scenario.dat
You need to keep that in mind when you dump the text and when you insert the text since you have to change those pointers.
imagen
These are some differences between the Japanese archive and the English one...

@KidBuu1991
Copy link

KidBuu1991 commented Nov 16, 2023

Translation plan

To start translating this game, you need to take into account that you have to go through two layers.

PAC2 (*.DAT)

The first one is the archive, a format called PAC2 which I solved with the next algorithm:

List<FileObj> fileList = new List<FileObj>();
if (br.ReadInt32() != 0x454d4147 || br.ReadInt32() != 0x20544144 || br.ReadInt32() != 0x32434150) //GAMEDAT PAC2
{
	Console.WriteLine("Not supported file, must be a PAC2 format");
	Console.ReadLine();
	return;
}
int fileCount = br.ReadInt32();
br.BaseStream.Position = 0x10 + 0x20 * fileCount;
for (int i = 0; i < fileCount; i++)
{
	fileList.Add(new FileObj()
	{
		Position = br.ReadInt32() + (0x10 + 0x20 * fileCount) + 0x30,
		Size = br.ReadInt32()
	});
}
br.BaseStream.Position = 0x10;

for (int i = 0; i < fileCount; i++)
{
	fileList[i].FileName = Encoding.ASCII.GetString(br.ReadBytes(0x20)).Replace("\0", "");
}
if (fileList.Count > 0)
{
	Directory.CreateDirectory(Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path));
	for (int i = 0; i < fileList.Count; i++)
	{
		br.BaseStream.Position = fileList[i].Position;
		fileList[i].Stream = br.ReadBytes(fileList[i].Size);
		Console.WriteLine("Unpacking... " + fileList[i].FileName);
		File.WriteAllBytes(Path.GetDirectoryName(path) + "\\" + Path.GetFileNameWithoutExtension(path) + "\\" + fileList[i].FileName, fileList[i].Stream);
	}
	Console.WriteLine("Unpacked!");
}

This will dump the archive into a folder, inside, you will find the next files:

  • BGM.ini
  • filename.dat
  • GAME.ini
  • graphic.bin
  • scenario.dat
  • textdata.bin

TEXTDATA.BIN (PJADV_TF)

From all those files, you can find the text in textdata.bin, this file is encrypted using a Sequential XOR algorithm. The Key is 0xC5 and the Step is 0x5C. This algorithm has been implemented in Kuriimu 2 a few days ago by @onepiecefreak3. When you decrypt that, the format is a simple null-terminated SJIS string-poblated file format, just split by ("\0\0") A quick dump would be done by using the next algorithm:

Encoding encoding = Encoding.GetEncoding(932);
List<string> strings = new List<string>();
var fileID = dr.ReadBytes(0x10);
for (int i = 0; i < 0x2cfe; i++)
{
	strings.Add(dr.ReadStringToToken("\0\0", encoding));
}

After that, encrypt using the same keys found ahead and pack the data.

Problems found in the process

While the text format is a simple null-terminated string format, the game has hidden pointers in the flow script format found in the file scenario.dat You need to keep that in mind when you dump the text and when you insert the text since you have to change those pointers. imagen These are some differences between the Japanese archive and the English one...

Hello, sorry for reviving this topic again. I already got everything worked by following your guide but now I have problem with repacking the files into one archive.dat file again. Could you help me out? The game I'm working on has exactly same format with this one.

@prowaynes
Copy link

Напиши мне на почту

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants