-
Notifications
You must be signed in to change notification settings - Fork 9
V_CODEs
V_CODEs are two codes contained within the CatSystem2 executable resources that are used as keys for decryption and encryption.
Type | Name | Language | Description |
---|---|---|---|
KEY_CODE | KEY | 0x0411 |
Key to decrypt V_CODEs |
V_CODE | DATA | 0x0411 |
Unknown usage. Often present in config/startup.xml
|
V_CODE2 | DATA | 0x0411 |
Used to decrypt KifintArchives |
V_CODEs can be extracted from the CatSystem2 executable using Windows API methods such as LoadLibraryEx
, FindResource
, LoadResource
, LockResource
, SizeofResource
, and FreeLibrary
. (These will not be linked to because Microsoft will change up their URLs and break these within a year's time)
Important Note: The executable used to launch the game may not be the CatSystem2 executable. Grisaia games often have a .bin
file with the same name that is actually launched when running the executable. In this situation, the .bin
file is the CatSystem2 executable with the V_CODE resource.
V_CODEs are decrypted using the KEY_CODE and a Blowfish cipher. First, take the KEY_CODE byte array, and XOR each byte by 0xCD
. Then pass the modified KEY_CODE to the Blowfish cipher as the key. Because Blowfish requires buffers to be a multiple of 8 bytes, make sure your V_CODE byte array is a multiple of 8 bytes rounded up.
string DecryptVCode(byte[] vcode, byte[] keyCode) {
// This assumes the keyCode buffer passed in will not be used after this.
// If you want to reuse the keyCode buffer, either perform the XOR once
// beforehand outside of the method, or perform the same XOR again at
// the end of the method before returning.
for (int i = 0; i < keyCode.Length; i++)
keyCode[i] ^= 0xCD;
// Key does not need to be a multiple of 8.
Blowfish blowfish = new Blowfish(keyCode);
// Decryption buffer needs to be rounded up to the next multiple of 8.
// & ~7 is equivalent to `(int) / 8 * 8`.
byte[] vcodeBuffer = new byte[(vcode.Length + 7) & ~7];
Array.Copy(vcodeData, vcodeBuffer, vcode.Length);
blowfish.Decrypt(vcodeBuffer);
// Shorten the string if there is a null-character.
int index = Array.IndexOf(vcodeBuffer, 0);
int length = (index != -1 ? index : vcodeBuffer.Length);
return Encoding.ASCII.GetString(vcodeBuffer, 0, length);
}