February 21, 20251 yr I'm having an issue with trying to hack a PS1 memory card save checksum. The game is Chrono Cross and the format is .MCS from the pSX emulator. I have provided two files to illustrate the issue. The only difference between them is address 0x13E7 and the last four bytes which are probably the checksum. It isn't a Checksum-32 or any other common checksum that I know of. I ran it through a web-based checksum fixer but I would rather just write my own editor program than use that one. Chrono Cross.7z
February 21, 20251 yr Localization In Silent Hill 1 on PS1 checksum is just a simple XOR operation on all bytes. Maybe this is the same
February 21, 20251 yr Author I wrote some code to check this but it doesn't seem to work for (int aa = 0; aa < byteFile.Length - 4; aa++) { fileSum ^= byteFile[aa]; }
February 21, 20251 yr Localization No, not the whole memory card. Try only on the save block, or more realistically only on one of the structures inside the save block. It is not for the whole memory card. Edited February 22, 20251 yr by Sparagas
February 21, 20251 yr Author That code wasn't meant for the whole memory card but I can see how it could be construed that way.
October 18Oct 18 Hi spamzilla,I had a look at your two samples and I think the checksum is solved.**Algorithm:** it's a plain unsigned byte sum, stored as a little-endian uint32.- Sum every byte of the 8 KiB save block from block offset `0x0000` to `0x1FF7` (inclusive).- Store the result as little-endian uint32 at block offset `0x1FFC`.- In your `.mcs` files the block starts after the 128-byte header, so that's file range `0x0080`–`0x2077`, with the checksum at file offset `0x207C`.- The 4 bytes at `0x2078`–`0x207B` (`06 01 00 00` in both files) are **not** included.**Why I'm fairly confident:**- Original checksum `0x0004DFF0`, modified `0x0004E074`. The difference is `0x84` = 132 = 192 − 60, exactly the change you made at `0x13E7`. That rules out XOR/CRC.- Searching all contiguous ranges containing `0x13E7`, `[0x80, 0x2078)` is the only one whose sum matches.- Taking your original file, setting `0x13E7` to 192 and recomputing gives a file byte-identical to your "(Modified)" file.That's also why the whole-file XOR didn't work.**Tool:** I wrote a small Python script, `cc_checksum.py`, with no dependencies:```python3 cc_checksum.py verify save.mcspython3 cc_checksum.py fix save.mcs # in placepython3 cc_checksum.py fix save.mcs -o out.mcs```It accepts single-block `.mcs` (8320 bytes) or a raw 8192-byte save block.**Caveats:**- I only had one pair of files, and haven't test-loaded an edited save in an emulator yet. Please confirm it loads on your side.- If you have saves from other slots or later in the game, they'd help confirm the `0x1FF8` field never matters.Hope this helps with your editor! cc_checksum.py
Create an account or sign in to comment