RPF Explorer Edit mode

This commit is contained in:
dexyfex
2018-01-10 14:17:30 +11:00
Unverified
parent 81daf0c23e
commit 65c549840f
6 changed files with 1750 additions and 122 deletions
+178
View File
@@ -39,6 +39,10 @@ namespace CodeWalker.GameFiles
{
return DecryptAESData(data, GTA5Keys.PC_AES_KEY);
}
public static byte[] EncryptAES(byte[] data)
{
return EncryptAESData(data, GTA5Keys.PC_AES_KEY);
}
public static byte[] DecryptAESData(byte[] data, byte[] key, int rounds = 1)
{
@@ -247,5 +251,179 @@ namespace CodeWalker.GameFiles
public static byte[] EncryptNG(byte[] data, string name, uint length)
{
byte[] key = GetNGKey(name, length);
return EncryptNG(data, key);
}
public static byte[] EncryptNG(byte[] data, byte[] key)
{
if ((GTA5Keys.PC_NG_ENCRYPT_TABLES == null) || (GTA5Keys.PC_NG_ENCRYPT_LUTs == null))
{
throw new Exception("Unable to encrypt - tables not loaded.");
}
var encryptedData = new byte[data.Length];
var keyuints = new uint[key.Length / 4];
Buffer.BlockCopy(key, 0, keyuints, 0, key.Length);
for (int blockIndex = 0; blockIndex < data.Length / 16; blockIndex++)
{
byte[] decryptedBlock = new byte[16];
Array.Copy(data, 16 * blockIndex, decryptedBlock, 0, 16);
byte[] encryptedBlock = EncryptBlock(decryptedBlock, keyuints);
Array.Copy(encryptedBlock, 0, encryptedData, 16 * blockIndex, 16);
}
if (data.Length % 16 != 0)
{
var left = data.Length % 16;
Buffer.BlockCopy(data, data.Length - left, encryptedData, data.Length - left, left);
}
return encryptedData;
}
public static byte[] EncryptBlock(byte[] data, uint[] key)
{
var buffer = data;
// prepare key...
var subKeys = new uint[17][];
for (int i = 0; i < 17; i++)
{
subKeys[i] = new uint[4];
subKeys[i][0] = key[4 * i + 0];
subKeys[i][1] = key[4 * i + 1];
subKeys[i][2] = key[4 * i + 2];
subKeys[i][3] = key[4 * i + 3];
}
buffer = EncryptRoundA(buffer, subKeys[16], GTA5Keys.PC_NG_ENCRYPT_TABLES[16]);
for (int k = 15; k >= 2; k--)
buffer = EncryptRoundB_LUT(buffer, subKeys[k], GTA5Keys.PC_NG_ENCRYPT_LUTs[k]);
buffer = EncryptRoundA(buffer, subKeys[1], GTA5Keys.PC_NG_ENCRYPT_TABLES[1]);
buffer = EncryptRoundA(buffer, subKeys[0], GTA5Keys.PC_NG_ENCRYPT_TABLES[0]);
return buffer;
}
public static byte[] EncryptRoundA(byte[] data, uint[] key, uint[][] table)
{
// apply xor to data first...
var xorbuf = new byte[16];
Buffer.BlockCopy(key, 0, xorbuf, 0, 16);
var x1 =
table[0][data[0] ^ xorbuf[0]] ^
table[1][data[1] ^ xorbuf[1]] ^
table[2][data[2] ^ xorbuf[2]] ^
table[3][data[3] ^ xorbuf[3]];
var x2 =
table[4][data[4] ^ xorbuf[4]] ^
table[5][data[5] ^ xorbuf[5]] ^
table[6][data[6] ^ xorbuf[6]] ^
table[7][data[7] ^ xorbuf[7]];
var x3 =
table[8][data[8] ^ xorbuf[8]] ^
table[9][data[9] ^ xorbuf[9]] ^
table[10][data[10] ^ xorbuf[10]] ^
table[11][data[11] ^ xorbuf[11]];
var x4 =
table[12][data[12] ^ xorbuf[12]] ^
table[13][data[13] ^ xorbuf[13]] ^
table[14][data[14] ^ xorbuf[14]] ^
table[15][data[15] ^ xorbuf[15]];
var buf = new byte[16];
Array.Copy(BitConverter.GetBytes(x1), 0, buf, 0, 4);
Array.Copy(BitConverter.GetBytes(x2), 0, buf, 4, 4);
Array.Copy(BitConverter.GetBytes(x3), 0, buf, 8, 4);
Array.Copy(BitConverter.GetBytes(x4), 0, buf, 12, 4);
return buf;
}
public static byte[] EncryptRoundA_LUT(byte[] dataOld, uint[] key, GTA5NGLUT[] lut)
{
var data = (byte[])dataOld.Clone();
// apply xor to data first...
var xorbuf = new byte[16];
Buffer.BlockCopy(key, 0, xorbuf, 0, 16);
for (int y = 0; y < 16; y++)
{
data[y] ^= xorbuf[y];
}
return new byte[] {
lut[0].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[1].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[2].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[3].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[4].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[5].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[6].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[7].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[8].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[9].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[10].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[11].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[12].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[13].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[14].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[15].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0))
};
}
public static byte[] EncryptRoundB_LUT(byte[] dataOld, uint[] key, GTA5NGLUT[] lut)
{
var data = (byte[])dataOld.Clone();
// apply xor to data first...
var xorbuf = new byte[16];
Buffer.BlockCopy(key, 0, xorbuf, 0, 16);
for (int y = 0; y < 16; y++)
{
data[y] ^= xorbuf[y];
}
return new byte[] {
lut[0].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[1].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[2].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[3].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[4].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[5].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[6].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[7].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[8].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0)),
lut[9].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[10].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[11].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[12].LookUp(BitConverter.ToUInt32( new byte[] { data[12], data[13], data[14], data[15] }, 0)),
lut[13].LookUp(BitConverter.ToUInt32( new byte[] { data[0], data[1], data[2], data[3] }, 0)),
lut[14].LookUp(BitConverter.ToUInt32( new byte[] { data[4], data[5], data[6], data[7] }, 0)),
lut[15].LookUp(BitConverter.ToUInt32( new byte[] { data[8], data[9], data[10], data[11] }, 0))};
}
}
}