I did not write a single line of this code. Welcome, to the era of using ChatGPT to exploit a video game. This took almost 4 hours of debugging with ChatGPT to get right, but I got it. This is the source code for Decrypting and Encrypting CA: Classic's Attributes txt files.
What's needed:
- Combat Arms: classic (obviously)
- Visual Studio 2022 with C# WinForms
- .NET 6.0 installed
- A few text boxes and buttons (see image below of how I set it up)
- RezXtract and RezInject and Rez Bypass if you'd like to use a modded rez file (in the rez section)
- BouncyCastle (get this with NuGet Manager in your project)
Shout out to @SoNoS and @qqshutup for their shared info on the Text Decrypter thread. I wanted to make a free to use version, and big shout out to ChatGPT on this.
Video explaining it and showing it working
Attributes TwoFish Key (hex) and IV
Code:
Key: 620C724A2FF22C975B5A2B9C21430820227B3D2800193AAA4C F3128803AC3ABD
IV: 56B83E3F68B60F0F29357BED335E5642
My WinForm
Code:
Needed
Code:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
Decryption
Code:
public static void DecryptFile(string encryptedFilePath, string decryptedFilePath, string keyHex, string ivHex)
{
byte[] encryptedBytes = File.ReadAllBytes(encryptedFilePath);
byte[] key = ConvertHexStringToByteArray(keyHex);
byte[] iv = ConvertHexStringToByteArray(ivHex);
byte[] decryptedBytes;
Decrypt(encryptedBytes, out decryptedBytes, key, iv);
string decryptedText = Encoding.UTF8.GetString(decryptedBytes);
SaveDecryptedTextToFile(decryptedText, decryptedFilePath);
}
public static void Decrypt(byte[] cipherText, out byte[] plainText, byte[] key, byte[] iv)
{
var engine = new TwofishEngine();
var cipher = new CbcBlockCipher(engine);
var parameters = new ParametersWithIV(new KeyParameter(key), iv);
cipher.Init(false, parameters);
int blockSize = cipher.GetBlockSize();
int numChunks = cipherText.Length / blockSize;
var plainTextList = new List<byte>(cipherText.Length);
for (int i = 0; i < numChunks; i++)
{
byte[] inputBlock = new byte[blockSize];
byte[] outputBlock = new byte[blockSize];
Array.Copy(cipherText, i * blockSize, inputBlock, 0, blockSize);
int processedBytes = cipher.ProcessBlock(inputBlock, 0, outputBlock, 0);
plainTextList.AddRange(outputBlock);
}
plainText = plainTextList.ToArray();
}
Encrypt
Code:
public static void EncryptFile(string filePath, string encryptedFilePath, string keyHex, string ivHex)
{
byte[] plainText = File.ReadAllBytes(filePath);
byte[] key = ConvertHexStringToByteArray(keyHex);
byte[] iv = ConvertHexStringToByteArray(ivHex);
byte[] encryptedBytes;
Encrypt(plainText, out encryptedBytes, key, iv);
File.WriteAllBytes(encryptedFilePath, encryptedBytes);
MessageBox.Show("File encrypted and saved successfully.");
}
public static void Encrypt(byte[] plainText, out byte[] encryptedBytes, byte[] key, byte[] iv)
{
var engine = new TwofishEngine();
var cipher = new CbcBlockCipher(engine);
var parameters = new ParametersWithIV(new KeyParameter(key), iv);
cipher.Init(true, parameters);
int blockSize = cipher.GetBlockSize();
int numChunks = (int)Math.Ceiling((double)plainText.Length / blockSize);
var encryptedData = new List<byte>(plainText.Length);
for (int i = 0; i < numChunks; i++)
{
byte[] inputBlock = new byte[blockSize];
byte[] outputBlock = new byte[blockSize];
int length = Math.Min(blockSize, plainText.Length - i * blockSize);
Array.Copy(plainText, i * blockSize, inputBlock, 0, length);
int processedBytes = cipher.ProcessBlock(inputBlock, 0, outputBlock, 0);
encryptedData.AddRange(outputBlock);
}
encryptedBytes = encryptedData.ToArray();
}
Save File and ConvertoHex
Code:
private static byte[] ConvertHexStringToByteArray(string hexString)
{
float numberChars = hexString.Length;
MessageBox.Show(hexString.Length.ToString());
byte[] bytes = new byte[Convert.ToInt16(numberChars / 2)];
for (long i = 0; i < numberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hexString.Substring((int)i, 2), 16);
}
return bytes;
}
private static void SaveDecryptedTextToFile(string decryptedText, string decryptedFilePath)
{
File.WriteAllText(decryptedFilePath, decryptedText);
}
Do not expect this to work perfectly, there's ONE ISSUE ChatGPT couldn't solve and I'm too stupid
No matter what you Decrypt, the decryption stops when the new decrypted text file matches the same file size as the encrypted text file.
For Example: If Encrypted.txt is 19,242bytes in file size, decrypted.txt will never be larger than that, when it should be.
I figured this is still worth posting because the only public way to do this is with a tool that requires a 300 dollar license key (not blaming someone else for using this). If someone fixes the code to do the full decryption of a file, I'll edit the post and make a few videos on what you can do with Attributes editing.
@Flengo @killingspree888 @meme ... welcome to the new age of hacking CA lol