PS3 PS1 libcrypt support on PS3 official emus - research thread

I just edited my previous post, compare it with this screenshot of the SBI file from redump
http://redump.org/disc/592/
Untitled-1-copy.jpg


As you can see the official format (of the config extracted from ps1_netemu.self) includes all the sector numbers of the SBI file in redump... divided in 2 groups of 8 sectors each

I don't know. In a way, it is not surprising that the binary will contain these sector numbers. At the end of the day, the binary, the libcrypt code, will need to know "these are the sectors I need to read to check if the disk is genuine".

EDIT: what is surprising to me is that it only contains the 8 sectors that have corrupted crc and not the full list of 16 sectors (excluding the duplicates up at lba >44000)
Is (this version of) libcrypt only checking the sectors that have "known bad crc"?
 
Last edited:
Anyway... some of the "garbage data" inside the official "PSOne classics" could be usign this same format... or a format derivated from it

I did some more digging and might have found something in the EBOOT's. I followed your hint and looked at the EBOOT's of the 3 games you mentioned. In Vagrant Story I found an encrypted PGD file just before the STARTDAT, so I decrypted it (with PSNPKGD&E) and found out it was the "JUNK" data that psxtract also would decrypt...but much more complete. So I started looking for comparable data in the .SUB/.SBI/.LSD files and it seems that the EBOOTS do contain some subchannel data:

upload_2021-12-27_5-40-14.png


A couple of things:
- It doesn't only contain the LibCrypted sectors but much more compared to .SBI/.LSD files, however it isn't as extensive as a .SUB file. I only displayed the first 4 and first Libcrypted entries here, but the file contains much more entries.
- 8 bytes match the .SUB format, doesn't use the 00 byte as seperator, last 2 bytes do not match.
- CTR and MediEvil do not contain this embedded file. They were released in 2007 as one of the early ps1 titles on PSN, Vagrant Story in 2009 so somewhere in between or around that time they changed their work method.

It seems that Soul Reaver also contains a similar file like this, will take a look tomorrow if I can find some more.
 
That is an interesting discovery actually. Could you look into the CTR and Vagrant Story data?
Is long, i wrote it at bottom of this page, MediEvil (SCES-00311), Vagrant Story (SLES-02754), and Crash Team Racing (SCES-02105)
https://www.psdevwiki.com/ps3/Talk:PS1_Emulation#Commands_Info

Im doing all the conversions manually, to short the time required i used the inverse process
I mean... instead of converting all the values from the official format (hex) to decimal and then searching for the decimal value in the SBI file displayed in redump pages... what i did was to convert the sector numbers of the SBI file (decimal) to hexadecimal and then i searched for them in the official format

Is a lot of text for wiki, but by now is worthy because those are the only 3 samples that exists about how to use netemu 4.88 command 0x02

I don't know. In a way, it is not surprising that the binary will contain these sector numbers. At the end of the day, the binary, the libcrypt code, will need to know "these are the sectors I need to read to check if the disk is genuine".

EDIT: what is surprising to me is that it only contains the 8 sectors that have corrupted crc and not the full list of 16 sectors (excluding the duplicates up at lba >44000)
Is (this version of) libcrypt only checking the sectors that have "known bad crc"?
Im wondering if the emulator have some function intended to add a hook to that sectors... so everytime that sectors are accessed the functions returns an "is ok, everything is good" so the libcrypt protection is not triggered
I dont really know how the libcrypt protection works technically, but i dont get what you mean with only 8 sectors... medievil have 16 in both, the SBI and the official format

I did some more digging and might have found something in the EBOOT's. I followed your hint and looked at the EBOOT's of the 3 games you mentioned. In Vagrant Story I found an encrypted PGD file just before the STARTDAT, so I decrypted it (with PSNPKGD&E) and found out it was the "JUNK" data that psxtract also would decrypt...but much more complete. So I started looking for comparable data in the .SUB/.SBI/.LSD files and it seems that the EBOOTS do contain some subchannel data:

View attachment 35602

A couple of things:
- It doesn't only contain the LibCrypted sectors but much more compared to .SBI/.LSD files, however it isn't as extensive as a .SUB file. I only displayed the first 4 and first Libcrypted entries here, but the file contains much more entries.
- 8 bytes match the .SUB format, doesn't use the 00 byte as seperator, last 2 bytes do not match.
- CTR and MediEvil do not contain this embedded file. They were released in 2007 as one of the early ps1 titles on PSN, Vagrant Story in 2009 so somewhere in between or around that time they changed their work method.

It seems that Soul Reaver also contains a similar file like this, will take a look tomorrow if I can find some more.
Very interesting, i dont understand your explanation to the point to say that is a full confirmation that data is related with the libcrypt protected sectors, but it looks like
Try to compare with the full list i just posted in wiki for vagrant story, we dont really know why they was adding so much sectors to the list for vagrant story (are sectors that doesnt seems to be related with librypt, or at least redump.org is not considering that are related), but there must be a reason for it, and probably they kept doing the same later for vagrant story

Btw, when looking at SBI files remember what i mentioned here:
https://www.psx-place.com/threads/p...mus-research-thread.35836/page-10#post-317262
// UCHAR ControlAndADR; (eg 0x41)
// UCHAR TrackNumber; (eg 0x01)
// UCHAR IndexNumber; (eg 0x01)
// UCHAR TrackRelativeAddress[3]; (bcd)
// UCHAR Filler; (always 0)
// UCHAR AbsoluteAddress[3]; (bcd)
The 410101 (used at the start of every line of the SBI files) doesnt matters much, as far i saw in redump in most of the games this values are always 410101, also maybe sony did something different with them
I mean... maybe they decided to not include this info about "ControlAndADR", "TrackNumber", "IndexNumber", or they included it but in a different format, dunno
But the others named "TrackRelativeAddress" and "AbsoluteAddress" (3 bytes each in the SBI file) are the most important
 
If that config does contain a sector list indeed, I do not understand why there are so many of them. The pool of modified sectors is the same for all the games. Not to mention only these around the third second are checked.

Assuming it is a sector list indeed, altering one pair of the LC sectors in that config would make the game fail to get a correct key.

If the method is working as it seems, then the emulator could be patched on the fly to get the LC sectors data from the external file. In theory.
 
If that config does contain a sector list indeed, I do not understand why there are so many of them. The pool of modified sectors is the same for all the games. Not to mention only these around the third second are checked.

Assuming it is a sector list indeed, altering one pair of the LC sectors in that config would make the game fail to get a correct key.

If the method is working as it seems, then the emulator could be patched on the fly to get the LC sectors data from the external file. In theory.
There are 3 or 4 experiments that "should" work

The easyer way to "nuke" that data is by using the terminator (value 0x00000000) for the first sector of the list, this way the emulator is going to do:
1) Read the ID from the game
2) Search for it in the config table (both, the ID... and the checksum of the ID)
3) Read the command counter (1)
4) Read the command data (an offset to the sector list)
5) Starts reading the sector list... it finds the terminator... and end of the story

The result is like deleting the sector list, but we are allowing everything else to work normally... lets say this is the less invasive way to do it

The other way is by "breaking" the ID/checksum from the header of the config table (are very easy to locate because are unique identifyers, and are posted in wiki)
By doing this we would be stopping the sequence at the step 2 of what i explained above... lets say... the emulator is not going to find any config compatible with the game, so nothing is loaded from the config table

And there are another couple of experiments that can be made by reorganizing the sectors info, as example... the config for medievil contains the 16 sectors mentioned in redump.org + a looot more sectors with unknown purpose
So we could take the 16 sectors, move them up to the first positions of the list, and continue with the terminator in position 17 (value 0x00000000)
This way the config will be composed only by 17 values (16 valid sectors + the terminator)... in other words... we can remove the unkown sectors from the list this way
Maybe the other way around could be interesting too (keeping only the unkowns)

And something a bit more tricky... we can change the ID/checksum to other of the libcrypt protected games, take the sector list from the SBI in redump, convert them to hex, add them to the sector list, and end the sequence with the terminator
This is pretty much like doing a config 100% custom for a different game, but trying to use the same rules of what sony did (except the unknown sectors)
 
Last edited:
There are two steps to test that config without reverse engineering the emulator. We have to operate with the data we know what they are for, at least hypothetically. We are assuming all the data present there, are the sectors themselves in ascending order.

1. Intentionally corrupt known sectors as little as possible. Let's take Vagrant Story config:
Code:
000038F3 --- to decimal ---> 14579 (mentioned in the redump SBI file)
000038F8 --- to decimal ---> 14584 (mentioned in the redump SBI file)
00003939 --- to decimal ---> 14649 (mentioned in the redump SBI file)
0000393E --- to decimal ---> 14654 (mentioned in the redump SBI file)
00003A33 --- to decimal ---> 14899 (mentioned in the redump SBI file)
00003A38 --- to decimal ---> 14904 (mentioned in the redump SBI file)
00003AD0 --- to decimal ---> 15056 (mentioned in the redump SBI file)
00003AD5 --- to decimal ---> 15061 (mentioned in the redump SBI file)
00003B1A --- to decimal ---> 15130 (mentioned in the redump SBI file)
00003B1F --- to decimal ---> 15135 (mentioned in the redump SBI file)
00003B8A --- to decimal ---> 15242 (mentioned in the redump SBI file)
00003B8F --- to decimal ---> 15247 (mentioned in the redump SBI file)
00003BD0 --- to decimal ---> 15312 (mentioned in the redump SBI file)
00003BD5 --- to decimal ---> 15317 (mentioned in the redump SBI file)
00003F27 --- to decimal ---> 16167 (mentioned in the redump SBI file)
00003F2C --- to decimal ---> 16172 (mentioned in the redump SBI file)

We have to corrupt the first pair of sectors for example. So instead of 0x38F3 and 0x38F8, they need to be changed to 0x3903 and 0x3908. Expected result: hang on the now loading screen.

2. Intentionally corrupt the data not related to the LC at first sight. We have to corrupt the sectors not mentioned in the redump database:
Code:
000014B5
00003FAA
00009084
0000BDD6
0000BEB1
0000BFAC
0000C9BC
0000E511
00010706
00010C80
000118E0
00011E36
00014146
000155E7
000171BF
0001D2F5
0001D8B5
0001E45A
0001E629
0001F1FD
0001FEB9
0002405D
0002599A
000259ED
00025A2F
00028BF6
00028CA0
00028CC2
0002A062
0002DD59
0002FDF1
00030BFC
00030C26
00039AB1
0003A9E1
0003BC7F
0003E1B9
0003E208
0003F88F
00040172
00040591
0004138F
00043ED8
000440DC
00044894
000467FB
0004782C
00048ACE
0004B4A0
0004B960
0004BE93
0004C30C
0004CB0E
0004CBC9
0004D5C8

Expected result: game should work without problems as with an uncorrupted config.
 
Very interesting, i dont understand your explanation to the point to say that is a full confirmation that data is related with the libcrypt protected sectors, but it looks like
Try to compare with the full list i just posted in wiki for vagrant story, we dont really know why they was adding so much sectors to the list for vagrant story (are sectors that doesnt seems to be related with librypt, or at least redump.org is not considering that are related), but there must be a reason for it, and probably they kept doing the same later for vagrant story

Btw, when looking at SBI files remember what i mentioned here:
https://www.psx-place.com/threads/p...mus-research-thread.35836/page-10#post-317262

The 410101 (used at the start of every line of the SBI files) doesnt matters much, as far i saw in redump in most of the games this values are always 410101, also maybe sony did something different with them
I mean... maybe they decided to not include this info about "ControlAndADR", "TrackNumber", "IndexNumber", or they included it but in a different format, dunno
But the others named "TrackRelativeAddress" and "AbsoluteAddress" (3 bytes each in the SBI file) are the most important

I can't say that it is related to libcrypt for sure, but can certainly say now it is subchannel data. Made a quick python script and extracted all the sector entries for Vagrant Story and Soul Reaver from the encrypted PGD files:

upload_2021-12-28_0-42-41.png


It seems that they don't use Control/ADR (41) and Zero (the filler byte between the Relative and Absolute addresses), but Track Number, Index, Pmin, Psec, Pframe, Amin, Asec, Aframe for sure. However I really don't understand yet how they calculate the CRC value here, normally it is calculated with "G(x) = x^{16}+x^{12}+x^5+1" (see here). So one might say that it should match the sector CRC values found in a .SUB file since the image data (in case of Soul Reaver) is identical as the one found in the EBOOT...but they don't match.

Some other findings:
- The file header is FF FF FF FF 00 00 00 00 FF FF FF FF
- The file footer is FF FF FF FF FF FF FF FF FF FF FF FF
- After the header the first 2 bytes seem to contain a CRC value
- The last sector entry has no CRC value

You can see the data for yourself, it's in the attachment. I'm looking the Final Fantasy VIII EBOOT atm, it seems there are 4 of these files in the EBOOT (matching the amount of discs).
 

Attachments

I can't say that it is related to libcrypt for sure, but can certainly say now it is subchannel data. Made a quick python script and extracted all the sector entries for Vagrant Story and Soul Reaver from the encrypted PGD files:

View attachment 35617

It seems that they don't use Control/ADR (41) and Zero (the filler byte between the Relative and Absolute addresses), but Track Number, Index, Pmin, Psec, Pframe, Amin, Asec, Aframe for sure. However I really don't understand yet how they calculate the CRC value here, normally it is calculated with "G(x) = x^{16}+x^{12}+x^5+1" (see here). So one might say that it should match the sector CRC values found in a .SUB file since the image data (in case of Soul Reaver) is identical as the one found in the EBOOT...but they don't match.

Some other findings:
- The file header is FF FF FF FF 00 00 00 00 FF FF FF FF
- The file footer is FF FF FF FF FF FF FF FF FF FF FF FF
- After the header the first 2 bytes seem to contain a CRC value
- The last sector entry has no CRC value

You can see the data for yourself, it's in the attachment. I'm looking the Final Fantasy VIII EBOOT atm, it seems there are 4 of these files in the EBOOT (matching the amount of discs).

I will try to attach a python program that has working subq crc calculation if you like to experiment. The crc is for the initial 10 bytes of data.
 

Attachments

There are two steps to test that config without reverse engineering the emulator. We have to operate with the data we know what they are for, at least hypothetically. We are assuming all the data present there, are the sectors themselves in ascending order.

1. Intentionally corrupt known sectors as little as possible. Let's take Vagrant Story config:
Code:
000038F3 --- to decimal ---> 14579 (mentioned in the redump SBI file)
000038F8 --- to decimal ---> 14584 (mentioned in the redump SBI file)
00003939 --- to decimal ---> 14649 (mentioned in the redump SBI file)
0000393E --- to decimal ---> 14654 (mentioned in the redump SBI file)
00003A33 --- to decimal ---> 14899 (mentioned in the redump SBI file)
00003A38 --- to decimal ---> 14904 (mentioned in the redump SBI file)
00003AD0 --- to decimal ---> 15056 (mentioned in the redump SBI file)
00003AD5 --- to decimal ---> 15061 (mentioned in the redump SBI file)
00003B1A --- to decimal ---> 15130 (mentioned in the redump SBI file)
00003B1F --- to decimal ---> 15135 (mentioned in the redump SBI file)
00003B8A --- to decimal ---> 15242 (mentioned in the redump SBI file)
00003B8F --- to decimal ---> 15247 (mentioned in the redump SBI file)
00003BD0 --- to decimal ---> 15312 (mentioned in the redump SBI file)
00003BD5 --- to decimal ---> 15317 (mentioned in the redump SBI file)
00003F27 --- to decimal ---> 16167 (mentioned in the redump SBI file)
00003F2C --- to decimal ---> 16172 (mentioned in the redump SBI file)

We have to corrupt the first pair of sectors for example. So instead of 0x38F3 and 0x38F8, they need to be changed to 0x3903 and 0x3908. Expected result: hang on the now loading screen.

2. Intentionally corrupt the data not related to the LC at first sight. We have to corrupt the sectors not mentioned in the redump database:
Code:
000014B5
00003FAA
00009084
0000BDD6
0000BEB1
0000BFAC
0000C9BC
0000E511
00010706
00010C80
000118E0
00011E36
00014146
000155E7
000171BF
0001D2F5
0001D8B5
0001E45A
0001E629
0001F1FD
0001FEB9
0002405D
0002599A
000259ED
00025A2F
00028BF6
00028CA0
00028CC2
0002A062
0002DD59
0002FDF1
00030BFC
00030C26
00039AB1
0003A9E1
0003BC7F
0003E1B9
0003E208
0003F88F
00040172
00040591
0004138F
00043ED8
000440DC
00044894
000467FB
0004782C
00048ACE
0004B4A0
0004B960
0004BE93
0004C30C
0004CB0E
0004CBC9
0004D5C8

Expected result: game should work without problems as with an uncorrupted config.

Ok. I performed these two simple tests. The results matched my predictions. It seems that only the LC sectors are critical for the emulator to pass the verification. Modifying them caused the Vagrant Story to crash at the loading screen after starting the new game. Modifying the rest of them does not change anything at all. I suspect the way of working is similar to what @Ronnie Sahlberg suggested somewhere in this thread - emulator is presenting these sectors to the GetlocP as corrupted ones. And it is enough for the game to obtain the key.

Now the question is how the emulator is calculating the game hash in order to replace the stored data with our sectors (or just the Magic Word using the different command).
 
Ok. I performed these two simple tests. The results matched my predictions. It seems that only the LC sectors are critical for the emulator to pass the verification. Modifying them caused the Vagrant Story to crash at the loading screen after starting the new game. Modifying the rest of them does not change anything at all. I suspect the way of working is similar to what @Ronnie Sahlberg suggested somewhere in this thread - emulator is presenting these sectors to the GetlocP as corrupted ones. And it is enough for the game to obtain the key.

Now the question is how the emulator is calculating the game hash in order to replace the stored data with our sectors (or just the Magic Word using the different command).

Very interesting result.
Now the question is "is it sufficient that the sector is corrupted or does it matter HOW it is corrupted"
(I suspect the former)
Background for this question is how I see the difference between the magic word and the content of the SBI file.
The magic word contains a list of all the sectors that should be corrupted, but not how they are corrupted.
While the SBI file contains both the list of corrupted sectors as well as exactly how they are corrupted.

Can you test that?
I.e. modify the two sectors 0x38F3 and 0x38F8 even further, so they are still corrupted but they are corrupted DIFFERENTLY from how they are corrupted in the sbi file.


I think that would be valuable to know if it is:
1, These sectors should be corrupted but it does not matter how, just that the crc is wrong
versus
2, These sectors should be corrupted and the corruption MUST be exactly like in the sbi file.

If 1, that would mean that the only information we would need are in the magic word. It would even mean that IF we have the magic word, then we could generate an SBI file that would work just from the magic word. I.e. "when creating sbi file, just insert random garbage for the sectors that the magic word indicates should be corrupted". I.e. we would technically never need the sbi file, we could just create one that works on-demand just from the magic word.
 
I explained how the LC sectors are modified few pages back with all three different schemes applied through the years. But for the game to work, all it comes down to the CRC-16 of the subchannel Q. If it is wrong, then the CD-ROM controller will report the subchannel Q data from the previous sector. The .SBI format is broken by design because the CRC is what the protection relies on. But yes, the exact subchannel Q M:S:F data is not important for the key to retrieve.

The Magic Word as a data does contain the list of corrupted sectors indeed (because all the games does use the same sector list for validation, a noticeable flaw in the protection itself).
 
I've made some progress in understanding the subchannel files in the EBOOT's. I couldn't understand why the last sector was missing a CRC value, turns out I was looking at the file wrong...once I understood the correct format of the file I found out that I wasn't looking at CRC values but at sector offsets.

upload_2021-12-31_4-42-11.png


So if we take the first sector value of the file which is AF000000 and convert it to Little Endian we get 000000AF. If we convert that to decimals we get 175 which means this is sector 175.
The next entry is 560C0000, again we take the steps described above and end up with a decimal value of 3158. To verify if the sector entry is correct we can calculate the difference in MSF values between the two entries by converting them to frames and calculate the difference between the two values:

(conversion to frames done here, set the frame rate to 75)
first entry: 00:04:24 to frames -> 324 frames
second entry: 00:44:07 to frames -> 3307 frames

3307 - 324 = 2983 frames

Then we calculate the difference between the two entries in hex:

first entry: 000000AF
second entry: 00000C56

00000C56 - 000000AF = BA7 which converted to decimal is 2983.

value of first sector entry (175) + difference between the two entries (2983) = value of second sector entry (3158).

What if we look at a sector with Libcrypt protection? If we take a look here we see that the first entry is sector 14579 with M:S:F value 03:14:29. Taking a look at the subchannel file in the EBOOT we can't find that M:S:F value, but we do find one on row 8 that is close to it (03:14:28 in the absolute columns). If we convert the sector value of that row (385D) to decimal we get 14429. The start sector of the data on a PS1 disc is 150, so if we add that to the converted sector value we get 14579 which does match the Libcrypt sector!

First 8 Libcrypt sectors comparison:
upload_2021-12-31_5-9-18.png


However, here we see something odd: The sector values match, but the MSF values dont. The difference is 1 frame. Also there is no mention of CRC values or Magic Word in these files.

I've added the extracted EBOOT subchannel data in an excel file, maybe you guys can find more.
 

Attachments

Last edited:
The hash is calculated using the 0x800 bytes of sectors, starting at the 0x9318 offset in the RAW/2352 image. I have not figured out the code, because I have not learned the PPC assembler yet, but it does look very simple. I just replaced the memory of RPCS3 before the code was executed to get a proper hash. It begins at 0x13758, so you can set a breakpoint there and replace the memory starting from 0x300296674 in the Cheat Engine. It is worth noting that RPCS3 does use the ps1_newemu emulator by default instead.

I have successfully replaced the Soul Reaver entries in the ps1_netemu emulator patch table with the Sydney 2000 FR. Data to replace:
0x162360 - 0x00003E1A (Magic Word for Sydney 2000 FR)
0x1A2E78 - 0x80877143 (sectors checksum of Sydney 2000 FR)
0x163BF8 - SLES_028.58 (title ID of Sydney 2000 FR)

The game successfully passed the LC check at the first loading screen. I do not remember if there are more of them throughout the game. The Javelin event was loaded without problems.

Next time I will replace the Vagrant Story sectors with Sydney 2000 ones. Meanwhile, @bguerville, @aldostools, @Evilnat, is there any way to patch the emulator on the fly in order to replace the values with ours? It could be implemented in the Cobra, am I right?
 
is there any way to patch the emulator on the fly in order to replace the values with ours? It could be implemented in the Cobra, am I right?
In theory, I suppose it could be implemented in Cobra stage2 using a hook on the kernel sub that loads user application (self) data into memory (after the signature check, decompression/decryption routines).
Cobra already does this kind of dynamic text segment patching routinely with vsh sprx modules, but I dunno if it already patches self apps starting their own processes (other than vsh.self which is somewhat of a special case), it might I am not sure, I would need to look at the source to confirm. If it already does, adding a dynamic patch to ps1_netemu will be trivial, if not, one may have to work out the appropriate hook to implement such a feature.
 
Last edited:
I replaced the Vagrant Story sector data with the Sydney 2000 FR. It does work too.
0x163C88 - SLES_028.58 (title ID of Sydney 2000 FR)
0x1A2F08 - 0x80877143 (sector checksum)
0x162A90 (LC sectors start at this offset) - 00 00 38 95 00 00 38 9A 00 00 38 F3 00 00 38 F8 00 00 39 39 00 00 39 3E 00 00 3A 33 00 00 3A 38 00 00 3A D0 00 00 3A D5 00 00 3D 0C 00 00 3D 11 00 00 3E 2F 00 00 3E 34 00 00 3E E5 00 00 3E EA (numbers of LC sectors converted to hexadecimal)

So there are two ways to patch. ps1_emu does not support the LC sectors command present in the netemu and (?) newemu. It supports only the Magic Word command. I think this command will not work with games loading the Magic Word into the different register than cop0r3 (MediEvil), as I suppose this command replaces the value in that register directly.
Anyway, Cobra needs to read the data from the .SBI/.LSD file with the sectors and calculate the checksum from the disc image. Then there are two ways:
1. If the ps1_emu is used, the Magic Word needs to be calculated from the list of sectors and the 0x17 command patched in the emulator table with calculated Magic Word.
2. If the ps1_netemu is used, the sectors need to be converted to the hexadecimal form. We could replace the Vagrant Story patch data, because all the LC sectors are following each other starting at the 0x162A90 (CTR LC sector list is interrupted by one sector not belonging to the protection). MediEvil game does not use paired sectors, so we could replace the MediEvil data in the emulator memory when the SBI file is loaded for this game (the game was released with different language versions separately).
 
Nice tests @Agrippa so both commands works with other games, we dont know if could work with all the others, but at least we know it works with some games
Command 0x17 (ps1_netemu.self 4.83~4.88)... to feed the emulator with the libcrypt magic word
Command 0x02 (ps1_netemu.self 4.83~4.88)... to feed the emulator with a list of the libcrypt protected sectors

Also, this is a proof that both commands are still availables and working in the newest emu revisions (there was another wiki editor doubting about it), and also the final proof of my speculations when i said the command data of 0x17 is an offset to an area with a list of libcrypt protected sectors

--------
Btw, what you did to calculate the checksum of sydney 2000 France ? (SLES_028.58), as far i knew the only public code related with that cheksums is this script published my @mysis (intended to work in PS2 games only but probably working with PS1 games too because ps2_netemu.self have some features "ported" from ps1_netemu.self)
https://www.psdevwiki.com/ps3/PS2_Emulation#ps2_title_brute_code

But... in my book i always considered that code as "black magic", i can see is doing bitswaping like there is no tomorrow but thats not the problem, the problems are:
-It have some functions commented out (and seems to be important)
-It have the "Title ID" = SLUS_200.73 hardcoded at several places, at top, but also inside the function gen_sum(title) when it does specific checks for the characters "S", "L", "U", "S" (but nothing for SCUS, SLES, SCES, SLPS, etc... ?)
-It doesnt have either any "user friendly" interface... you know... when running the script i would expect a prompt asking for something like "Type the code and press enter to calculate it"
- At top it have a list of "patches"... this is a clear indication that the algorythm is not failproof (seems to be very close to it, but is not perfect, because is not exactly what sony is doing)

All and all... the script is nice, im not complaining about it because was a great discovery, but is not usable (doesnt works in the actual state), it needs to be updated
I noticed your edit in wiki today where you published the RE of the algorythm from inside the emu, and i guess this is how you calculated the checksum for sidney 2000 :rolleyes:
Anyway... someone have a usable (and user friendly) code to deal with this checksums ?
It would be nice to join together the PS1 and PS2 support in the same script
 
I wrote in the previous message how I obtained the hash. I think there is a second way to get it - prepare a PS1 package with disc image, install it in the RPCS3 and after booting the game, look at the offset 0x002965e0 in the Memory Viewer. The hash will be there.

I am sure the 0x02 command (imported sectors) will work with every LibCrypt game. The 0x17 command will work with ~90% of games. If it does replace the cop0r3 register with the MW value then it may be not compatible with:
a) MediEvil which does use GPR register instead of COP one.
b) LC3 games which use the disc retrieved Magic Word as a parameter only, to calculate the final Magic Word later. Spyro 3 does work like that but I have not looked into the different games using that version of LibCrypt. Maybe @krHACKen would add more about this, because he used literary the same way of patching in his POPStarter project.

Anyway, my job on this is over. I have posted the code on wiki with very amateurish explanation of inner workings about that hash calculation, as it was my first experience with PPC assembler. Now it is up to the developers to think about it and implement the best way of patching in any homebrew app or the Cobra itself.

And no, that @mysis script does not apply to the PS1 hash calculation. The PS1 hash is generated from the whole disc sector 16, the PS2 hash from the title ID solely.
 
Last edited:
The other day i realized about a weird detail that was driving me a bit crazy... to make the long story short... the point is the complete list of checksums inside ps1_netemu.self could be equal or longer than the complete list of "Title IDs"

What i was doing was to extract both lists in a hexeditor, and using notepad++ to align them side by side, together with the offsets, and command counters (in other words... the first 2 levels of the hierarchy)
This is when i realized the list of checksums was 1 unit bigger, i dont remember which emulator revision i was looking at, but lets say... the total number of game configs is around 334 (so there are 344 "Title IDs") but the list of checksums was 335
After reviewing it several times i realized there was 2 different cheksums that belongs to the same "Title ID"

At that point i could not figure why it was happening that... i had in mind the code made by mysis that associates a checksum to the "Title ID" and it made no sense to have 2 different checksums for the same "Title ID"... but now that you are mentioning is a cheksum of a disc sector it makes more sense :encouragement:

In other words... the 2 cheksums for the same "Title ID" means that is the same game re-released 2 times and containing different data inside sector 16, but both are loading the same config data

----------
And this concept could be used for another hack, we can simply replace the sector 16 and the title ID to force it to load a config from a different game
Except the commands related with libcrypt most of the command data used by the other commands looks generic, i bet there are going to be a lot of game configs compatibles with different games


Edit:
I mean... when the backup managers "mounts" the virtual disc image we can change the data of sector 16, and the Title ID of the disc
This way we can load any config from the list by "faking" the disc (instead of tampering with ps1_netemu.self)
 
Last edited:
@krHACKen, it seems some of your patches do not work properly.
- Spyro 2: Gateway to Glimmer - error about no patch data to apply,
- Sydney 2000 - same error.

How do your Spyro 3 patches are meant to work? I mean, the MW calculation code does start at the 0x80067AD4 offset. But it does look like no patches are applied before the code is executed. I am not sure you can apply the code later on, because the disc obtained MW is added to the timer (?) value obtained from the 0x1F801120. I see the Spyro 2 does the same thing, I am not sure if it is an Insomniac specific code, or the LC3 one in general.

I think I figured out why the Babydock patch is triggering the protection. It seems the 0x80067AD4 range is not verified by the crack protection (at least until the LC routine is executed). But the 0x80036E2C range, which does contain the anti-debug protection is verified by the crack protection instead. Since he injected a jump to his overlay code at 0x80036EBC, this modification is detected, I think. And that is why the crack is not working properly.
 

Similar threads

Back
Top