Next Generation Emulation banner
1 - 6 of 6 Posts

·
Registered
Joined
·
3 Posts
Discussion Starter · #1 ·
Hello wizards, I am hoping one of you out there has had much success when cracking CRC32 checksums on game saves. I need a pointer or two as I have almost exhausted my options.

I have been making gaming tools/editors/trainers for a while now that I have found my programming skills are much better used for gaming needs and not my job! I recently have been playing an old PSX rpg that I love (Legend of Legaia). This game will freeze on a PS3 or emulator around 80% through the game. I know how to hex-edit the save so that they get past the scene but unfortunately, this game seems to use a 32 bit CRC checksum as the last 4 bytes of the file. This doesn't seem to be very common so is it possible this game uses a 16bit CRC and either writes two different checksums or two bytes for something else?

It's quite obvious that the last four bytes of the save are checksum since there's tons of 00 bytes before it.

I researched and kept finding references to people cracking the 16bit CRCs that popular games around that time would use, but nothing about a 32 bit CRC. I thought I was in luck when they found that the CRC-16 in games were using the standard variables (start value, polynomial, compare). So I tried all of the CRC-32 bit standards I could find on wikipedia and none of them have matched.

I even created an app to work through 0 - 0xFFFFFFFF on the polynomial because it looks like the starting value is always 0xFFFFFFFF.

Now I'm not even sure that it's CRC-32bit since FF8 and FF9 are CRC-16bit?

Does anyone have any additional ideas to try or think this might be CRC-16bit? Any help would be greatly appreciated!
 

·
Premium Member
Joined
·
5,155 Posts
I managed to crack CTR checksum by using pSX's debugger. It should work in your case too.

Run the game in pSX and open debugger. Use ingame save option.
Now search for the save in memory and write the offset of the checksum.
Make a memory write breakpoint on the checksum. Make another save.
Game will stop and depending on your assembler skills you should notice a loop which goes through all the bytes
and calculates checksum. Now all you need to do is simulate that code in some other programming language.

Here is my C# CTR checksum calculating code for reference:
Code:
private uint GetChecksumCTR(byte[] InputData)
{
    //Simulated PS1 registers
    uint r2 = 0;
    uint r3 = 0;
    uint r4 = 0;
    uint r5 = 0;
    uint r6 = 0;
    uint r7 = 0;

    //Checksum calculation
    for (uint i = 0; i < 5760; i++)
    {
        r5 = InputData[i + 0x180];
        r3 = 0x7;
        r7 = 0x10000;
        r6 = r7;
        r6 = r6 | 0x1021;

        //Erase old checksum
        InputData[0x17FE] = 0x00;
        InputData[0x17FF] = 0x00;

        while (r3 < 0xFFFF)
        {
            r4 = r4 << 0x1;
            r2 = r5 >> (int)r3;
            r2 = r2 & 0x1;
            r4 = r4 | r2;
            r2 = r4 & r7;

            if (r2 != 0) r4 = r4 ^ r6;

            r3 = (r3 + 0xFFFF) & 0xFFFF;
        }
    }

    return r4;
}
P.S. MGS uses CRC-32 with default polynomial so no wizardry was used for that game :p
 

·
Registered
Joined
·
3 Posts
Discussion Starter · #3 ·
Thank you for replying Shendo!

I was actually hoping someone would reply about using a debugger. I tried to get one to work previously for seeing the drop % chance on a game but the debugger didn't work. pSX huh? I have been using ePSXe so now I'm excited to start using debugger and looking at the assembly. I can't wait to fix this issue and provide a means for other gamers to get past the glitch on PS3.

Thanks for the C# code reference as well. I am using C# for all my trainers so it could be useful if I run into issues later.

Default polynomial? Do you mean 0, 0xebd85320 or some standardized one? I wrote an app to brute force Legaia's CRC but it used a constant start value of 0xFFFFFFFF and compare byte 0xFF. Didn't find it so I bet I will find something like you did with CRT.

Thanks so much!
 

·
Registered
Joined
·
3 Posts
Discussion Starter · #4 ·
Okay so I love this emulator, the debugger, assembly language, you Shendo, and this site :) I finally got it!!!

I had a lot of issues and red herrings though. I breakpointed on the first write to the CRC checksum and tried following from there. However, the debugger kept skipping during the loop and I would miss all the generation it would do. Spent way too long on that :mad:

So then I spent only a little time realizing the memory card save is loaded in memory, so I found that, and put a break on when the first byte of the save is read. Immediately I found it doing some odd adding of every byte for the length of the save 0x1FFC (minus 4 bytes for checksum). Bingo!

I am so upset that I thought it was CRC 32....even after I found three values loaded into memory that looked very suspicious for CRC (0xFFFFFF7F,0x1031,0x7560). It's not a CRC at all! In fact, it's the lamest checksum I've ever seen!! Okay so I haven't seen that many...

It simply just adds up 4 bytes at a time as unsigned ints, so no overflow. That's it. Here is my C# code converted from assembly:

Code:
private uint GetChecksum(byte[] data)
{
    uint c = 0;
    uint i = 0;

    for(int x = 0; x < 0x1FFC;x+=4)
    {
        i = BitConverter.ToUInt32(data,x);
        c = c+i;
    }

    return c;
}
Soooo simple but it took all that debugging and researching assembly code to figure out. Uggghhh haha. But a great lesson I learned and I always wanted to know how to debug PSX games so many many thanks to you Shendo! I hope this post will help other noobs like me :)
 

·
Registered
Joined
·
1 Posts
I just discovered this post!!! I know next to nothing about any of this checksum stuff, let alone CRC32 or 16, I'm trying to work at all of this, but I'm not quite sure were you get stuff like "0xedb88320" saying it uses default polynomials and no wizardry :X Is there a good resource I can check out to learn a bit more of this? Thanks in advance!!!
 
1 - 6 of 6 Posts
Top