Code Monkey home page Code Monkey logo

Comments (9)

hozuki avatar hozuki commented on July 20, 2024

Thank you for the report.
Actually there is no yet working loop support. I wrote some code to handle HCAs with loops (or just check and throw an exception), but I was confused about how to deal with repetitions. In most of the games, looped audios are used as background music, which requires infinite loop. However wave audio doesn't support partial looping (e.g. 00:13.20-00:40.35), so if you want to write generated data into a file you should set a finite number.
Anyway, I'll write a new audio stream class dedicated for the loops. I think that should fully enable the looping feature.
Cheers.

from deretore.

FZFalzar avatar FZFalzar commented on July 20, 2024

I'm just guessing, but could the AWB container hold the loop start/end times for the contained hca loop? I also remember seeing mention of loop start/end in the source code of "HCA Decoder 1.12", when you run it with option "i" (info)

from deretore.

hozuki avatar hozuki commented on July 20, 2024

FYI, the loop range info is stored in HCA header. You can refer to HcaInfo.cs and HcaReader.cs and see how it works.
I've almost completed simulated looping (by outputting looped section for multiple times). However there are still some blank periods whose causes are to be figured out. Right now I'm in the exam weeks so the progress will be somewhat slow.
I checked the wave format this morning and found a good explanation for the LOOP section in (standard type) wave header. I'm not sure how would audio players (e.g. foobar2000, WMP) support this section, and the wave format has many sub-types. Anyway I'll test it.

from deretore.

hozuki avatar hozuki commented on July 20, 2024

I finished simulated looping and tried to use your sample file as an input. However there is an IndexOutOfRangeException (in Channel.Decode1) thrown when I tried to decode it. Magic and checksum are all correct.
I checked the cipher type property, both HcaReader class and hcainfo report that it is "not encrypted" (type 0).
Then, to ensure that it is not a fault of arithmetic overflow, I tried to use hca2wav to decode it. Since hca2wav is written in C++ and it works as long as there is no invalid memory access, it gave me an decoded wave audio file. I was not surprised when I found the wave file is filled with noise. 😞
So could you please confirm your sample please?

from deretore.

FZFalzar avatar FZFalzar commented on July 20, 2024

Hmm if my fears are true, it could be that what I posted is still encrypted, not as one of the HCA ciphers but by the CriWare plugin itself (usage of authenticationFile and enableAtomDecryption when initializing the CriWare system) which could have possibly encrypted the block data but keeping the header data in tact. Furthermore some RE indicates this is done within the native lib, so deriving the actual algo just became harder OTL

Recently alot of other games using CriWare (JPN mobages esp) also give rise to the same problem where the HCA extracted gives just noise when played although the headers look correct

I think it could be possible to create a system to "piggyback" the loading algorithm and dump the PCM data into its own file through IL injection, bypassing the encryption altogether.

Alternatively, create a Unity Project that uses the same method for decryption
But that'll be for experimentation and future work

If I can get this working, I'll be sure to use DereTore/libcgss for conversion

Thanks for your time! And if you have any insight regarding RE of CriWare please do drop a PM :)

from deretore.

hozuki avatar hozuki commented on July 20, 2024

Thank you for the reply.

As far as I know, a second encryption/decryption is possible using the authenticationFile. I tried to RE it last year but I thought it was too time-costing. The CRI plugin has its own file system abstraction (FS), audio output abstraction (Atom) and player (AtomEx). The plugin only exposes AtomEx APIs in CGSS's case so I can't study its audio output functions.

If we consider the plugin as a black box, we can intercept calls to it (initialization) and from it (audio output). By constructing a dummy shell we may be able to reuse the plugin to get waveform without cracking it. However there are pitfalls with this method:

  1. Hooking system's audio APIs is hard.
  2. CRI plugin is mainly used on platforms other than PC (iPhone, Android, consoles), making it harder to do the hooking.
  3. We can only operate limited APIs exposed by the plugin. We can't control the inner processes.

If we consider the plugin as a open system, say, being REed, then everything will be fine, except... fighting with plugin's standalone (maybe complicated) IO API. A benefit is we can get what we want, especially by low level access of waveform generation.

I think I will try the first method to prove the possibility, and then the second. Either way will cost huge amount of time, and I won't have plenty of time until summer vacation. I mean, trying it will be exciting, as if holding the master key to most of the game audio files, but I have to put it later in my schedule.

It has been nice to discuss this problem with you and I hope to hear from you if there is any progress. 😃

from deretore.

FZFalzar avatar FZFalzar commented on July 20, 2024

Hi, the other day I passed a key for the HCA file I uploaded, it turns out that the order of the hex that I posted was wrong; I swapped the positions of the first 8 and last 8 bytes and HCA Decoder v1.12 seemed to decode it properly, after some coaxing. Also what I've found out from some experimentation is that the authenticationFile seems to be unused for the entirety of Atom but has its part to play in Mana (by use of enableManaDecryption flag, mostly for video assets)

The authenticationFile is generated from one of the sdk apps that uses the key as a seed value of sorts, and the output is always 256 bytes long. I tested and confirmed this for a few games, by generating each file with its corresponding key and comparing it to each game's authenticationFile. Both the authenticationFile and key is then specified in the Unity Project Scene where the CriWare GameObject exists, then CriwareInitializer is called with these params, starting up the abstraction layers. I guess this partly makes up the reason why the key itself is rather difficult to extract, since it doesn't exist compiled into the code but rather, inside the scene that requires it.

from deretore.

hozuki avatar hozuki commented on July 20, 2024

Thank you FZFalzar for exploration and such a detailed explanation. I've learned a lot from your words. :)

By the way did you try the new version of hca2wav (if you compiled it, since there are no new binaries released yet)? It should support finite times looping the looping range in an HCA file. I tested that with "holding" sound effect in CGSS and it works well.

from deretore.

FZFalzar avatar FZFalzar commented on July 20, 2024

Hi, I have just built and tested it and it is working fine 👍 Maybe a suggestion would be to catch invalid key errors causing the program to throw "Index out of bounds" exception

Anyway I will close this issue now, all the best with your work and I would like to hear from you if you ever get down to doing the system-level stuff

from deretore.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.