-
Notifications
You must be signed in to change notification settings - Fork 9
V_CODEs
V_CODEs are two codes contained within the CatSystem2 Windows executable resources that are used as keys for decryption and encryption.
The Type, Name, (and optionally the Language), are used to obtain the resource from the executable using Windows API methods.
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);
}