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

Saving decrypted HCA #71

Open
wh665o opened this issue Dec 24, 2022 · 4 comments
Open

Saving decrypted HCA #71

wh665o opened this issue Dec 24, 2022 · 4 comments

Comments

@wh665o
Copy link

wh665o commented Dec 24, 2022

Hi I was trying to output the unconverted decrypted HCA. I see there is a part in HCA.cs about saving decrypted HCA to the disk but I've had no luck getting this segment to work.

@ToaHartor
Copy link
Owner

So if I understood well, you want to only decrypt the HCA file without converting it into a wav file right ?
For the method, the Mask() function does the decryption on a data block, then the block checksum has to be made since the block content changed. Of course the decrypted header has to be written before the data. To know if it's decrypted, you can see the header fields (fmt, comp written in raw if you open the file in a HEX viewer/editor.)
If I recall correctly, the Decrypt() function you might have seen has some missing parts, and I don't think it actually writes the decrypted header to the file as well.

@wh665o
Copy link
Author

wh665o commented Dec 28, 2022

Yes, I was wanting to only decrypt the HCA file without converting it into a wav file. What I had tried was this:

//FileStream filePointer = File.OpenRead(_filename);
string decryptedFile = Path.Combine(outputDir, _filename[..^4] + "_decrypted.hca");

byte[] content = new byte[_hcaHeader.blockSize * _hcaHeader.blockCount];
byte[] buf = new byte[_hcaHeader.blockSize];
if (_hcaHeader.ciphType != 0)
{
    for (uint i = 0, offset = 0; i < _hcaHeader.blockCount; i++, offset += _hcaHeader.blockSize)
    {
        Array.Copy(_data, offset, buf, 0, _hcaHeader.blockSize);
        //filePointer.Seek(offset, SeekOrigin.Begin);
        //filePointer.Read(buf, 0, _hcaHeader.blockSize);
        Mask(ref buf, _hcaHeader.blockSize);
        //DecodeBlock(ref buf);
        BitConverter.GetBytes(Tools.Bswap(CheckSum(buf, _hcaHeader.blockSize - 2))).CopyTo(buf, _hcaHeader.blockSize - 2);
        Array.Copy(buf, 0, content, offset, _hcaHeader.blockSize);
    }
}

File.WriteAllBytes(decryptedFile, this._header.Concat(content).ToArray());
Console.WriteLine("File written : " + decryptedFile);
return Task.CompletedTask;

And although the header does get decrypted, the audio is still not playable. Any ideas what I'm missing/have done wrong?

@ToaHartor
Copy link
Owner

Sorry, I'm replying a bit late, but with which player are you trying to play the file ?

@wh665o
Copy link
Author

wh665o commented Feb 7, 2023

I'm using foobar2000 and can play unencrypted HCA files from other games and also some encrypted ones included in vgmstream.

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

No branches or pull requests

2 participants