360haven works best with JavaScript enabled
Thief 4
Loading
Register
Page 1 of 2 12 LastLast
Results 1 to 8 of 10

Thread: Thief 4

  1. #1
    Junior Member
    pedore is offline
    Join Date : Sep 2019
    Location : 360haven
    Posts : 5
    Array

    Thief 4

    /* Google Translate */
    Hello!
    I need help from experienced forum users, I'm trying to make a save editor for Thief 4. Decompilation and compilation are successful, but there was a problem understanding crc. Saving is divided into many blocks that are compressed using zlib, crc checking data between them. I was able to allocate 3 crc blocks, the last two of which contain checksums of the decompiled and compiled blocks. But when I try to generate a checksum (for an unchanged block to check), I get incorrect values. Question: can anyone help determine the method for generating checksums and tell what the first crc is ??
    Click image for larger version. 

Name:	1.jpg 
Views:	13 
Size:	59.2 KB 
ID:	17242

  2. #2
    Administrator

    feudalnate is offline
    Join Date : Nov 2010
    Location : Canada
    Age : 34
    Posts : 347
    Array

    Re: Thief 4

    Post a save and some information on the data you've discovered
    Downloads : 63 || Uploads : 11 || Rep Power : 5609 || Posts : 347 || Thanks : 62 || Thanked 939 Times in 190 Posts


    "If you can get 30 seconds of fun, you can pretty much stretch that out to be an entire game. So you can have all the great graphics, all the different characters,
    and lots of different weapons with amazing effects but if you don't nail that 30 seconds, you're not going to have a great game." ~Jamie Griesemer (Halo 2 Design Lead)

  3. #3
    Junior Member
    pedore is offline
    Join Date : Sep 2019
    Location : 360haven
    Posts : 5
    Array

    Re: Thief 4

    /* Google Translate */
    Sure. The save file is attached to the response. As for the information. The required data is in the third block (I want to change the dificalty of the game). The block is decompiled using the standard zlib library (Used python). To check, I compressed the original block. Almost everything coincided, except for the beginning and the end. At the end of the block, it is enough to add empty bytes, even though there was some information before (checked in the game, it works). From the beginning of the block a lot of problems arose. Highlighted three crc blocks.
    s - static bytes (can be copied).
    ? - not known bytes.
    n - not known byte not related to nearby crc


    ?? ?? ?? ?? ss ss ss ss 06 00 00 00 ?? ?? ?? ??
    ss 00 00 00 00 00 00 01 00 00 00 01 00 ?? ?? ?? ??
    nn ss 00 00 00 00 00 00


    The first checksum is not known where to come from. Having studied the code through ida, I can assume that the second crc is calculated over the entire compressed data block. The third checksum is calculated over the entire uncompressed data block. The last part of nn is not known.


    Data is compressed using zlib with the following parameters (level 1, windowsize +15).
    Attached Files Attached Files

  4. #4
    Administrator

    feudalnate is offline
    Join Date : Nov 2010
    Location : Canada
    Age : 34
    Posts : 347
    Array

    Re: Thief 4

    The data you posted is little endian, I assume this is for PC? If that's the case then why not use or create a trainer?

    Memory editing would be a simpler way of going about it because everything would be uncompressed and unsecured (presumably) in memory. If you would still like to edit the save data then could you upload the IDB somewhere and post it?

  5. #5
    Junior Member
    pedore is offline
    Join Date : Sep 2019
    Location : 360haven
    Posts : 5
    Array

    Re: Thief 4

    You are right, this is the PC version, but the work with blocks is identical with the version for xbox, so I decided to use the PC version for convenience.
    I found information from Mr. Vulnavia on your forum. He worked on this topic and left the following notes.
    / * ---------------------- * /
    "No Crypto only alot of CRC's of uncompressed and compressed Data at the beginning
    and end of each Block ...


    CRC1 (CustomEA with Seed = 0xDEADBEEF) at Blockstart-0x1C calculated for whole uncompressed Block
    CRC2 (CustomEA with Seed = 0xDEADBEEF) at Blockstart-0x0C calculated for whole compressed Block
    CRC3 (CustomEA with Seed = 0xDEADBEEF) at Blockstart-0x28 calculated for 0x20 Bytes from Blockstart-0x20
    CRC4 (Adler32 added by ZLIB) at BlockEnd calculated by ZLIB for uncompressed Block


    The Compression Parameters are Level 1, Windowsize 15 and HTTPC disabled, with
    this Parameters the Adler32 is also added automatically by ZLIB ...


    Also the Re / Compressed Block must be 8 byte aligned / padded before Insertion else
    the Game will throw a Save Corruption and can also potential Crash, because their
    Routine to locate the Blocks is a bit messy compared to mine which don't care about
    any Alignment to find it ... Also who knows, perhaps thats the Source of Save Corruption
    that occured on non-modded Savegames ... lol! "
    / * ---------------------- * /
    I tried to figure out what "seed" is and how to use it, but due to the language barrier, I couldn’t. Perhaps you can tell.

  6. #6
    Administrator

    feudalnate is offline
    Join Date : Nov 2010
    Location : Canada
    Age : 34
    Posts : 347
    Array

    Re: Thief 4

    What Vulnavia meant by seed was the initial value of the CRC result, instead of the CRC starting as 0 or 0xFFFFFFFF it starts as 0xDEADBEEF

    This is the 'CustomEA' CRC mentioned in the notes (sorry Vulnavia, I decompiled your tool I hope you don't mind)

    Code:
            uint CalcCRC(uint CRC, byte[] buffer, int index, int count, bool flag)
            {
                uint[] Table = 
                {
                    0x00000000, 0x4c11db7,  0x9823b6e,  0xd4326d9,  0x130476dc, 0x17c56b6b,
                    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
                    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
                    0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
                    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
                    0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
                    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
                    0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
                    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
                    0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
                    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
                    0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
                    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x18aeb13,  0x54bf6a4,
                    0x808d07d,  0xcc9cdca,  0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
                    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
                    0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
                    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
                    0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
                    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
                    0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
                    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
                    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
                    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
                    0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
                    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
                    0x3f9b762c, 0x3b5a6b9b,  0x315d626, 0x7d4cb91,  0xa97ed48,  0xe56f0ff,
                    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
                    0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
                    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
                    0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
                    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
                    0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
                    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
                    0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
                    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
                    0x18197087, 0x1cd86d30, 0x29f3d35,  0x65e2082,  0xb1d065b,  0xfdc1bec,
                    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
                    0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
                    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
                    0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
                    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
                    0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
                    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
                };
    
    
    
                if (flag) CRC = ~CRC;
    
                for (int i = index; i < count; i++)
                {
                    CRC = ((CRC << 8) ^ Table[(buffer[i] ^ (CRC >> 24))]);
                }
    
                if (flag) CRC = ~CRC;
    
                return CRC;
            }
    
            //for swapping the crc result to big endian
            uint bswap32(uint value)
            {
                unchecked
                {
                    return ((value & 0xff000000) >> 24) | ((value & 0x00ff0000) >> 8) | ((value & 0x0000ff00) << 8) | ((value & 0x000000ff) << 24);
                }
            }
    Code:
                string file = "C:\\file.bin"; //some file
                byte[] buffer = File.ReadAllBytes(file); //read the file into memory
    
    
                uint seed = 0xDEADBEEF;
                uint crc = CalcCRC(seed, buffer, 0, buffer.Length, true); //flag is true for xbox360 (so it seems)
                crc = bswap32(crc); //swap the crc result to big endian for xbox360
    I don't know the offsets of the CRC or the data they cover but that is the algorithm for computing the custom CRC
    Last edited by feudalnate; 09-26-2019 at 11:31 AM.

  7. #7
    Junior Member
    pedore is offline
    Join Date : Sep 2019
    Location : 360haven
    Posts : 5
    Array

    Re: Thief 4

    As far as I understand, the table is the standard crc32 polynomial "0x04C11DB7". The argument "buffer" is passed to the function, but it is not used anywhere. Any idea why? Also, when using the specified calculation algorithm, the system generates an "index out of range" error. The problem is that with a shift (CRC << 8) and further calculations, a value is obtained that goes beyond the scope of the table. Can you check this algorithm using the example of "123456789" and post the answer to the forum?

  8. #8
    Administrator

    feudalnate is offline
    Join Date : Nov 2010
    Location : Canada
    Age : 34
    Posts : 347
    Array

    Re: Thief 4

    Yes you are right about the code, it should be buffer[i] and not (i & 0xFF). That was my mistake, I have edited the code in my post. You are also right about the checksum, it is a standard CRC32 checksum - the table is initialized with a polynomial value of 0xEDB88320 and uses an initial CRC value of 0xDEADBEEF

    If you need a result example to verify:

    Code:
    byte[] bytes = new byte[] { 0x15, 0xCD, 0x5D, 0x07 }; //123456789
    uint CRC = bswap32(CalcCRC(0xDEADBEEF, bytes, 0, 4, true)); // calculate crc and reverse endian
    Console.Write("0x" + CRC.ToString("X2")); //print crc result in hexadecimal
    
    
    //output: 0xCEBD580C
    Last edited by feudalnate; 09-26-2019 at 12:01 PM.

 

 
Page 1 of 2 12 LastLast

Similar Threads

  1. [YouTube] UNCHARTED 4: A Thief's End
    By THUMBS in forum Youtube Famous
    Replies: 0
    Last Post: 02-24-2016, 09:18 PM
  2. [Trainer] Thief Tu1 RTE/Trainer
    By matthewjohn in forum Trainers
    Replies: 16
    Last Post: 04-17-2014, 01:38 PM
  3. Thief on ps4, was NOT impressed!
    By ShangTsung in forum General Discussion
    Replies: 8
    Last Post: 04-04-2014, 06:21 PM
  4. [YouTube] Thief Review
    By scorpionnet in forum Youtube Famous
    Replies: 1
    Last Post: 02-25-2014, 12:44 AM

Visitors found this page by searching for:

Nobody landed on this page from a search engine, yet!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

About 360haven

    360haven is an Forum Devoted To Game modding Fans from all over the world.

    An Awesome Community of Xbox 360 Gamers, Modders and Developers who Create & Share Tutorials, Applications, Gfx, Trainers and Gamesaves.

    A haven for the l33t.
    A scarce paradise for modders.

★★★★★¯\_(ツ)_/¯