예제 #1
1
        public static void Generate(byte[] exeData)
        {
            var exeStr = new MemoryStream(exeData);

            PC_AES_KEY = HashSearch.SearchHash(exeStr, GTA5HashConstants.PC_AES_KEY_HASH, 0x20);
            Console.WriteLine("aes key found");
            PC_NG_KEYS = HashSearch.SearchHashes(exeStr, GTA5HashConstants.PC_NG_KEY_HASHES, 0x110);
            Console.WriteLine("ng keys found");
            var tabs = HashSearch.SearchHashes(exeStr, GTA5HashConstants.PC_NG_DECRYPT_TABLE_HASHES, 0x400);
            Console.WriteLine("ng decrypt tables found");

            // 17 rounds
            PC_NG_DECRYPT_TABLES = new uint[17][][];
            for (int i = 0; i < 17; i++)
            {
                // 
                PC_NG_DECRYPT_TABLES[i] = new uint[16][];
                for (int j = 0; j < 16; j++)
                {
                    var buf = tabs[j + 16 * i];
                    PC_NG_DECRYPT_TABLES[i][j] = new uint[256];
                    Buffer.BlockCopy(buf, 0, PC_NG_DECRYPT_TABLES[i][j], 0, 1024);
                }
            }

            PC_LUT = HashSearch.SearchHash(exeStr, GTA5HashConstants.PC_LUT_HASH, 0x100);
            Console.WriteLine("ng hash LUTs found");



            PC_NG_ENCRYPT_TABLES = new uint[17][][];
            for (int i = 0; i < 17; i++)
            {
                PC_NG_ENCRYPT_TABLES[i] = new uint[16][];
                for (int j = 0; j < 16; j++)
                {
                    PC_NG_ENCRYPT_TABLES[i][j] = new uint[256];
                    for (int k = 0; k < 256; k++)
                    {
                        PC_NG_ENCRYPT_TABLES[i][j][k] = 0;
                    }
                }
            }

            PC_NG_ENCRYPT_LUTs = new GTA5NGLUT[17][];
            for (int i = 0; i < 17; i++)
            {
                PC_NG_ENCRYPT_LUTs[i] = new GTA5NGLUT[16];
                for (int j = 0; j < 16; j++)
                    PC_NG_ENCRYPT_LUTs[i][j] = new GTA5NGLUT();
            }




            PC_NG_ENCRYPT_TABLES[0] = RandomGauss.Solve(PC_NG_DECRYPT_TABLES[0]);
            Console.WriteLine("ng encrypt table 1 of 17 calculated");
            PC_NG_ENCRYPT_TABLES[1] = RandomGauss.Solve(PC_NG_DECRYPT_TABLES[1]);
            Console.WriteLine("ng encrypt table 2 of 17 calculated");

            for (int k = 2; k <= 15; k++)
            {
                PC_NG_ENCRYPT_LUTs[k] = LookUpTableGenerator.BuildLUTs2(PC_NG_DECRYPT_TABLES[k]);
                Console.WriteLine("ng encrypt table " + (k + 1).ToString() + " of 17 calculated");
            }

            PC_NG_ENCRYPT_TABLES[16] = RandomGauss.Solve(PC_NG_DECRYPT_TABLES[16]);
            Console.WriteLine("ng encrypt table 17 of 17 calculated");

        }
예제 #2
0
        public static GTA5NGLUT[][] ReadNgLuts(string fileName)
        {
            var fileStream = new FileStream(fileName, FileMode.Open);
            var dataReader = new DataReader(fileStream);
            var array      = new GTA5NGLUT[17][];

            for (var i = 0; i < 17; i++)
            {
                array[i] = new GTA5NGLUT[16];
                for (var j = 0; j < 16; j++)
                {
                    array[i][j]      = new GTA5NGLUT();
                    array[i][j].LUT0 = new byte[256][];
                    for (var k = 0; k < 256; k++)
                    {
                        array[i][j].LUT0[k] = dataReader.ReadBytes(256);
                    }

                    array[i][j].LUT1 = new byte[256][];
                    for (var l = 0; l < 256; l++)
                    {
                        array[i][j].LUT1[l] = dataReader.ReadBytes(256);
                    }

                    array[i][j].Indices = dataReader.ReadBytes(65536);
                }
            }

            fileStream.Close();

            return(array);
        }
예제 #3
0
        public static void WriteLuts(string fileName, GTA5NGLUT[][] lutData)
        {
            FileStream fileStream = new FileStream(fileName, FileMode.Create);
            DataWriter dataWriter = new DataWriter(fileStream, Endianess.LittleEndian);

            for (int i = 0; i < 17; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    GTA5NGLUT gta5NGLUT = lutData[i][j];
                    for (int k = 0; k < 256; k++)
                    {
                        for (int l = 0; l < 256; l++)
                        {
                            dataWriter.Write(gta5NGLUT.LUT0[k][l]);
                        }
                    }
                    for (int m = 0; m < 256; m++)
                    {
                        for (int n = 0; n < 256; n++)
                        {
                            dataWriter.Write(gta5NGLUT.LUT1[m][n]);
                        }
                    }
                    for (int num = 0; num < 65536; num++)
                    {
                        dataWriter.Write(gta5NGLUT.Indices[num]);
                    }
                }
            }
            fileStream.Close();
        }
예제 #4
0
        public static GTA5NGLUT[][] ReadNgLuts(byte[] data)
        {
            var ms = new MemoryStream(data);
            var rd = new DataReader(ms);

            GTA5NGLUT[][] array = new GTA5NGLUT[17][];
            for (int i = 0; i < 17; i++)
            {
                array[i] = new GTA5NGLUT[16];
                for (int j = 0; j < 16; j++)
                {
                    array[i][j]      = new GTA5NGLUT();
                    array[i][j].LUT0 = new byte[256][];
                    for (int k = 0; k < 256; k++)
                    {
                        array[i][j].LUT0[k] = rd.ReadBytes(256);
                    }
                    array[i][j].LUT1 = new byte[256][];
                    for (int l = 0; l < 256; l++)
                    {
                        array[i][j].LUT1[l] = rd.ReadBytes(256);
                    }
                    array[i][j].Indices = rd.ReadBytes(65536);
                }
            }
            ms.Close();
            return(array);
        }
예제 #5
0
        public static GTA5NGLUT[][] ReadNgLuts(string fileName)
        {
            GTA5NGLUT[][] result;

            var fs = new FileStream(fileName, FileMode.Open);
            var rd = new DataReader(fs);

            // 17 rounds...
            result = new GTA5NGLUT[17][];
            for (int i = 0; i < 17; i++)
            {
                // 16 bytes...
                result[i] = new GTA5NGLUT[16];
                for (int j = 0; j < 16; j++)
                {
                    result[i][j] = new GTA5NGLUT();

                    // first compression step (2^32 -> 2^24)
                    result[i][j].LUT0 = new byte[256][];
                    for (int k = 0; k < 256; k++)
                    {
                        //result[i][j].LUT0[k] = new byte[256];
                        //for (int l = 0; l < 256; l++)
                        //    result[i][j].LUT0[k][l] = rd.ReadByte();
                        result[i][j].LUT0[k] = rd.ReadBytes(256);
                    }

                    // second compression step (2^24 -> 2^16)
                    result[i][j].LUT1 = new byte[256][];
                    for (int k = 0; k < 256; k++)
                    {
                        //result[i][j].LUT1[k] = new byte[256];
                        //for (int l = 0; l < 256; l++)
                        //    result[i][j].LUT1[k][l] = rd.ReadByte();
                        result[i][j].LUT1[k] = rd.ReadBytes(256);
                    }

                    // indices
                    //result[i][j].Indices = new byte[65536];
                    //for (int k = 0; k < 65536; k++)
                    //    result[i][j].Indices[k] = rd.ReadByte();
                    result[i][j].Indices = rd.ReadBytes(65536);
                }
            }


            fs.Dispose();

            return(result);
        }
예제 #6
0
        public static void WriteLuts(string fileName, GTA5NGLUT[][] lutData)
        {
            var fs = new FileStream(fileName, FileMode.Create);
            var wr = new DataWriter(fs);

            // 17 rounds...
            for (int i = 0; i < 17; i++)
            {
                // 16 bytes...
                for (int j = 0; j < 16; j++)
                {
                    GTA5NGLUT lut = lutData[i][j];

                    // first compression step (2^32 -> 2^24)
                    for (int k = 0; k < 256; k++)
                    {
                        for (int l = 0; l < 256; l++)
                        {
                            wr.Write(lut.LUT0[k][l]);
                        }
                    }

                    // second compression step (2^24 -> 2^16)
                    for (int k = 0; k < 256; k++)
                    {
                        for (int l = 0; l < 256; l++)
                        {
                            wr.Write(lut.LUT1[k][l]);
                        }
                    }

                    // indices
                    for (int k = 0; k < 65536; k++)
                    {
                        wr.Write(lut.Indices[k]);
                    }
                }
            }

            fs.Dispose();
        }
예제 #7
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))};
        }
예제 #8
0
        public static GTA5NGLUT[] BuildLUTs2(uint[][] tables)
        {
            var temp = new byte[16][];
            for (int i = 0; i < 16; i++)
                temp[i] = new byte[65536];

            var result = new GTA5NGLUT[16];
            for (int i = 0; i < 16; i++)
            {
                result[i] = new GTA5NGLUT();
                //result[i].Tables = new byte[256][];
                //result[i].LUT = new byte[16777216];
            }

            var tempLUTS = new byte[16][];
            for (int i = 0; i < 16; i++)
                tempLUTS[i] = new byte[16777216];

            var t0 = tables[0];
            var t1 = tables[1];
            var t2 = tables[2];
            var t3 = tables[3];
            var t4 = tables[4];
            var t5 = tables[5];
            var t6 = tables[6];
            var t7 = tables[7];
            var t8 = tables[8];
            var t9 = tables[9];
            var t10 = tables[10];
            var t11 = tables[11];
            var t12 = tables[12];
            var t13 = tables[13];
            var t14 = tables[14];
            var t15 = tables[15];

            Parallel.For(0, 0x100, (long k1) =>
            {
                for (long k2 = 0; k2 < 0x1000000; k2++)
                {
                    long i = k1 * 0x1000000 + k2;

                    byte b0 = (byte)((i >> 0) & 0xFF);
                    byte b1 = (byte)((i >> 8) & 0xFF);
                    byte b2 = (byte)((i >> 16) & 0xFF);
                    byte b3 = (byte)((i >> 24) & 0xFF);

                    var x1 =
                         t0[b0] ^
                         t7[b1] ^
                         t10[b2] ^
                         t13[b3];
                    var x2 =
                        t1[b0] ^
                        t4[b1] ^
                        t11[b2] ^
                        t14[b3];
                    var x3 =
                        t2[b0] ^
                        t5[b1] ^
                        t8[b2] ^
                        t15[b3];
                    var x4 =
                        t3[b0] ^
                        t6[b1] ^
                        t9[b2] ^
                        t12[b3];

                    // the first LUT-compression step is built-it
                    // because it would take 4GB ram per data byte (and there are 16)

                    if (x1 < 65536)
                    {
                        temp[0][x1] = b0;
                        temp[7][x1] = b1;
                        temp[10][x1] = b2;
                        temp[13][x1] = b3;
                    }

                    if (x2 < 65536)
                    {
                        temp[1][x2] = b0;
                        temp[4][x2] = b1;
                        temp[11][x2] = b2;
                        temp[14][x2] = b3;
                    }

                    if (x3 < 65536)
                    {
                        temp[2][x3] = b0;
                        temp[5][x3] = b1;
                        temp[8][x3] = b2;
                        temp[15][x3] = b3;
                    }

                    if (x4 < 65536)
                    {
                        temp[3][x4] = b0;
                        temp[6][x4] = b1;
                        temp[9][x4] = b2;
                        temp[12][x4] = b3;
                    }

                    if ((x1 & 0x000000FF) == 0)
                    {
                        tempLUTS[0][x1 >> 8] = b0;
                        tempLUTS[7][x1 >> 8] = b1;
                        tempLUTS[10][x1 >> 8] = b2;
                        tempLUTS[13][x1 >> 8] = b3;
                    }

                    if ((x2 & 0x000000FF) == 0)
                    {
                        tempLUTS[1][x2 >> 8] = b0;
                        tempLUTS[4][x2 >> 8] = b1;
                        tempLUTS[11][x2 >> 8] = b2;
                        tempLUTS[14][x2 >> 8] = b3;
                    }

                    if ((x3 & 0x000000FF) == 0)
                    {
                        tempLUTS[2][x3 >> 8] = b0;
                        tempLUTS[5][x3 >> 8] = b1;
                        tempLUTS[8][x3 >> 8] = b2;
                        tempLUTS[15][x3 >> 8] = b3;
                    }

                    if ((x4 & 0x000000FF) == 0)
                    {
                        tempLUTS[3][x4 >> 8] = b0;
                        tempLUTS[6][x4 >> 8] = b1;
                        tempLUTS[9][x4 >> 8] = b2;
                        tempLUTS[12][x4 >> 8] = b3;
                    }
                }
            });

            for (int i = 0; i < 16; i++)
            {
                result[i].LUT0 = new byte[256][];
                for (int blockIdx = 0; blockIdx < 256; blockIdx++)
                {

                    var xl = new byte[256];
                    for (int k = 0; k < 256; k++)
                    {
                        xl[k] = temp[i][256 * blockIdx + k];
                    }

                    result[i].LUT0[xl[0]] = xl;
                }
            }

            // compress tables...
            // length from 2^24 -> 2^16
            for (int i = 0; i < 16; i++)
            {
                GTA5NGLUT lut = result[i];
                lut.LUT1 = new byte[256][];
                lut.Indices = new byte[65536];    
                
                for (int blockIdx = 0; blockIdx < 256; blockIdx++)
                {
                    var xl = new byte[256];
                    for (int k = 0; k < 256; k++)
                    {
                        xl[k] = tempLUTS[i][256 * blockIdx + k];
                    }

                    lut.LUT1[xl[0]] = xl;
                }
                for (int blockIdx = 0; blockIdx < 65536; blockIdx++)
                {
                    lut.Indices[blockIdx] = tempLUTS[i][256 * blockIdx];
                }                
            }

            return result;
        }
예제 #9
0
        public static void WriteLuts(string fileName, GTA5NGLUT[][] lutData)
        {
            var fs = new FileStream(fileName, FileMode.Create);
            var wr = new DataWriter(fs);

            // 17 rounds...
            for (int i = 0; i < 17; i++)
            {
                // 16 bytes...
                for (int j = 0; j < 16; j++)
                {
                    GTA5NGLUT lut = lutData[i][j];

                    // first compression step (2^32 -> 2^24)
                    for (int k = 0; k < 256; k++)
                        for (int l = 0; l < 256; l++)
                            wr.Write(lut.LUT0[k][l]);

                    // second compression step (2^24 -> 2^16)
                    for (int k = 0; k < 256; k++)
                        for (int l = 0; l < 256; l++)
                            wr.Write(lut.LUT1[k][l]);

                    // indices
                    for (int k = 0; k < 65536; k++)
                        wr.Write(lut.Indices[k]);
                }
            }

            fs.Close();
        }
예제 #10
0
        public static GTA5NGLUT[][] ReadNgLuts(string fileName)
        {
            GTA5NGLUT[][] result;

            var fs = new FileStream(fileName, FileMode.Open);
            var rd = new DataReader(fs);

            // 17 rounds...
            result = new GTA5NGLUT[17][];
            for (int i = 0; i < 17; i++)
            {
                // 16 bytes...
                result[i] = new GTA5NGLUT[16];
                for (int j = 0; j < 16; j++)
                {
                    result[i][j] = new GTA5NGLUT();

                    // first compression step (2^32 -> 2^24)
                    result[i][j].LUT0 = new byte[256][];
                    for (int k = 0; k < 256; k++)
                    {
                        //result[i][j].LUT0[k] = new byte[256];
                        //for (int l = 0; l < 256; l++)
                        //    result[i][j].LUT0[k][l] = rd.ReadByte();
                        result[i][j].LUT0[k] = rd.ReadBytes(256);
                    }

                    // second compression step (2^24 -> 2^16)
                    result[i][j].LUT1 = new byte[256][];
                    for (int k = 0; k < 256; k++)
                    {
                        //result[i][j].LUT1[k] = new byte[256];
                        //for (int l = 0; l < 256; l++)
                        //    result[i][j].LUT1[k][l] = rd.ReadByte();
                        result[i][j].LUT1[k] = rd.ReadBytes(256);
                    }

                    // indices
                    //result[i][j].Indices = new byte[65536];
                    //for (int k = 0; k < 65536; k++)
                    //    result[i][j].Indices[k] = rd.ReadByte();
                    result[i][j].Indices = rd.ReadBytes(65536);
                }
            }


            fs.Close();

            return result;
        }