Monday, January 17, 2011

Reading the PlayStation 3 registry with PHP

Sony Brasil took way too long to release the PS3 console on my country (something around august 2010). A long time before that happened, many foreign versions of the console (mostly of them american) were already available all around the country. So when I bought mine, I had no choice but a DVD region 1 PS3.

Brazil and United States shares the same Blu-ray region, so I am fine on that matter. DVD playback wasn't an issue for me either as I used to play them on my MacBook. But I have recently replaced it with the new MacBook Air 11" which has no DVD drive built-in, and now I am left with only the PS3 to watch my DVD movies.

Even though Brazil is DVD region 4 and my console is region 1, most recent DVDs play fine on it - it seems that region lock has been removed from those discs on factory. But a recent purchase showed an exception: my 40 DVDs box of the complete series of "Friends" (from Warner) just won't play on my PS3. Now that is bothering me.

I have been searching for weeks on how to watch my original, and expensive, DVDs region 4 on my console region 1, bought on a region 4 country at a time when only region 1 console was available. I couldn't overcome that limitation, I couldn't even find a way to opt for a region change (like my old MacBook let me do). But still, I found out about a really interesting stuff: the PS3 has a registry file with all of its settings - including the DVD region.

The registry file is called xRegistry.sys and can not be obtained by normal ways - you have to jailbreak your console to have access to it. It is a binary file, but a few guys managed to reverse engineer it here and here.

A GUI editor is available at the last link above, but it is target on a platform I have no access to. So I wrote a small piece of PHP code to help me with the task of manually editing the registry file - based on the specifications on the PS3 wiki and also on the code by stoker25.



A sample output is:

Array
(
...
[3933] => Array
(
[0] => /setting/bddvd/mnrForDvdRom
[1] => Array
(
[flags] => 0
[xxx] => 27415
[length] => 4
[type] => 01
[data] => 0x00000000
)

)

[3966] => Array
(
[0] => /setting/bddvd/dvdRegionCode
[1] => Array
(
[flags] => 0
[xxx] => 35494
[length] => 4
[type] => 01
[data] => 0x00000001
)

)
...


Which tells me, for instance, that at the decimal offset 3966 (0xF7E) I have the setting /setting/bddvd/dvdRegionCode which holds a value of 0x1. With that information in hand I can open xRegistry.sys with my favorite HEX editor and change that value to 0x4, for instance, and then upload the file back to my PS3.

Note that the registry file is divided in two sections: settings and data. The outer array keys on the output above are offsets to the settings. The data section is located below the settings, and points directly (with a delta of 0x10) to its parent setting. So in the example above I would search for 0x0000076E (which is 0x7E - 0x10) and hopefully I would end up on the value of the dvdRegionCode setting. To make sure you are on the right place, check the other fields as well - flags, length, type and the unknown field "xxx".

For more information on the structure of the registry file, please check the PS3 wiki.

Note that I have successfully changed my dvdRegionCode setting from 0x1 to 0x4 using the method above, but it had no real effect. I still can not play region 4 DVDs. But other people reported it worked for them - perhaps my american console is doing hardware checks while other versions don't.