Luke No... I am PlayStation Camera, part 1

Introduction to PlayStation Camera


Note: This article will be part of PlayStation Camera article series in near future:

See also for historical purposes. All was done at that time in user land, and with usb traffic sniffer:


Brief History

Do you remember E3 presentations with Dr Richard Marks and Phill Harrison in 2003 and 2005 with the infamous ruber duck and EyeToy? It was amazing. It was the first time you saw AR stuff in a game console.

I made my first usb driver for PlayStation 2 platform. It was a full IOP module replacement for original Sony EyeToy driver, streaming ipu frames and full audio support reversing the original ov519.irx module in 2004. It was done using ps2dis, a pencil and notebook(no Ida then a piece of paper with a assembler list and my brain XD old school you know). I took a sabbatical year from my work for personal matters and I learnt a lot about usb specticification, and a deep knowledge about chips inside Sony PlayStation 2(ee,iop,dmac,ipu,gs,vu). It was a very fun year indeed.

It was my first contact with Omnivsion, usb bridge asics and cmos sensors, and since then i have made reverse engineering of all Omnivision chips that Sony have been using. Sony have been making incredible and very cheap camera devices since 2003 (EyeToy, PlayStation Eye and PlayStation Camera) and thanks to that i had a lot of fun reversing them. That feeling when you get the first frame from a camera device with no internal information about their chips is incredible. Without challenge there is not fun at all :P.

PlayStation Camera

There are 2 Playstation Camera models:

I began my research in december 2013 just after bought it. It was using a propietary connector called AUX, Erik Wilson figured out that AUX was only an usb3 connector made by Sony so we tryed to get, with man in the middle approach, with a beagle usb 3 sniffer the traffic between the PlayStation 4 and PlayStation Camera.

After that,we analyzed all usb 3 traffic and we figured out that device was in boot mode waiting for firmware. We extracted the firmware from the usb traffic and after that i got all initialization done under osx on March 2014.

I released later a PS4EYECam driver using libusb for MacOS. Some people and researcher have been working with it porting to linux but windows has not a good support for libusb and it is difficult to get it up and running in an easy way, that zadig thing is a pain in the ass. There is other option for windows using Windows Media Framework after loading the firmware to device but firmware used is from our usb sniffer capture from kernel lower than 1.76 and it is veeery old.

I know that some researchers have been testing and looking for PlayStation Camera integration with PlayStation VR on pc and someone ask me if i could come back and work again in a proper driver for PlayStation Camera for Windows. I will try to get it up and running but i can share all my research from these years about it at low level in kernel land just now.

So let's go!!!! Luke...



Luke aka PlayStation Camera kernel driver for Orbis

PlayStation 4 Operating System is based on Freebsd 9 and it is called Orbis. Like all operating systems it has drivers for many devices.

PlayStation Camera is an usb 3 camera device with a propietary connector called AUX. It is managed by a kernel driver called Luke. It is like all kernel drivers for devices that you can see in a vanilla Freebsd Kernel. User land applications or games are using a library called libSceCamera.sprx and that library speaks with Luke using ioctl calls.

Recommended lecture for newbies "FreeBSD Device Drivers: A Guide for the Intrepid" by Joseph Kong.

So do you want to have a lot of fun reversing code from PlayStation 4 Kernel? Always :P.


luke_probe

The first surprise, first versions of PlayStation Kernels let to use PlayStation Camera from AUX port and USB ports. Sony fixed that on firmware 1.75, i have not Kernel between 1.62 and 1.75 so only i can confirm that 1.62 still can use PlayStation Camera from front usb ports in the PlayStation 4. Initial Kernels only support first camera model.

Second surprise there are two firmwares embed on Kernel for PlayStation Camera, one of them it is the same in all Kernels it is for a special UAC mode, the other one the UVC mode has different revisions but we will speak about that later don't worry take it easy.

Code from Kernel 5.05:

int luke_probe(device_t dev)
{
	struct usb_attach_arg *uaa = device_get_ivars(dev);
	int result=ENXIO;//6
	usb_device_descriptor *device;
	if(uaa!=NULL)
	{
		if(uaa->usb_mode!=0)
		{
			device=usbd_get_device_descriptor(uaa->device);
			if(device->idVendor==0x05a9)
			{
				if(device->idProduct-0x580>0xb)
				{
					return result;
				}
				if(device->idProduct!=0x58a && device->idProduct!=0x58b && device->idProduct!=0x580)
				{
					return result;
				}
				//uacmoode is 0 you can set to 1 with ioctl 0xC0088E09 called from libSceCamera.sprx
				if(uacmode==1 && device->idProduct&0xFFFE==0x58A )
    			{
      				printf("camera driver return ENXIO in probe for UAC\n");
      				return ENXIO;
    			}
				result=0;
        		uint8_t index=usbd_get_bus_index(uaa->device);
        		if(index!=2)
        		{
          			printf("PlayStation(R)Camera is supporting only AUX Port. index:%x\n",index);
          			return ENXIO;
          		}
        		
			}
		}
	}
	return result;
}

				


luke_attach

This function has a place where the size of 2 kind of PlayStation Camera firmwares is hardcoded , you can easily find the place in each Kernel looking for "camera attach: UAC mode!\n"

For 5.05:
	
loc_67D801:                             
or      byte ptr cs:dword_27A80C0, 1
cmp     uacmode, 0
mov     cs:dword_27A8034, 140000h
jz      short loc_67D830
lea     rdi, aCameraAttachUa ; "camera attach: UAC mode!\n"
xor     eax, eax
call    printf
mov     eax, 64036
jmp     short loc_67D835
loc_67D830:                             
mov     eax, 67924
loc_67D835:                             
mov     firmwareSize, eax
				

So uacmode firmware size in 5.05 is 64036 bytes. We will see later that that mode have the same size and same content for all firmwares.

The other one have size of 67924 bytes in 5.05. This one change for each new PlayStation Camera firmware revision.

This function will check if device is in boot mode to prepare transfer that in usb callback will call finally to luke_fw_cb funtion that will load the firmware.


luke_fw_cb

This function have the information about where is each firmware. UAC firmware is the same for all kernels, UVC firmware has different revisions.

3.50 is the first firmware we have that it supports second PlayStation Camera model. You can confirm that in luke_probe function easily.

Table with retail firmware versions, offset in kernel, size in bytes of PlayStation Camera firmware, name if it is present on kernel, md5, and type of fimware UAC or UVC.

firmware offset size kernel name md5 type
0.915_010 7329A0 62952 4322f2c5541dfa67edec7dd3d33c2d60 UVC
0.915_010 741F90 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
0.915_020 7329A0 62952 4322f2c5541dfa67edec7dd3d33c2d60 UVC
0.915_020 741F90 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
0.915_040 7369A0 62952 4322f2c5541dfa67edec7dd3d33c2d60 UVC
0.915_040 745F90 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
0.920_030 7680D0 65384 155eb994ad3b95e2af99aac18b6a6fea UVC
0.920_030 778040 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.00_devkit 84C4C0 66576 luke_fw 3a6ff06e3ff57615c4019b0a5c2e47ca UVC
1.00_devkit 84C8E0 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.01 84C4C0 66576 3a6ff06e3ff57615c4019b0a5c2e47ca UVC
1.01 85C8E0 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.05 7204C0 66576 3a6ff06e3ff57615c4019b0a5c2e47ca UVC
1.05 7308E0 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.50b 738530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.50b 748970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.51 738530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.51 748970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.52 738530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.52 748970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.60 73C530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.60 74C970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.61 73C530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.61 74C970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.62 73C530 66608 e70ad69b3faab612e8115960f568a924 UVC
1.62 74C970 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.75 961990 66608 e70ad69b3faab612e8115960f568a924 UVC
1.75 971DD0 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
1.76 8489F0 66608 e70ad69b3faab612e8115960f568a924 UVC
1.76 858E30 64036 luke_rom_image 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
3.15 913F00 66608 e70ad69b3faab612e8115960f568a924 UVC
3.15 9244D0 64036 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
3.50 8FEB30 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
3.50 90F640 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
3.55 8FF3D0 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
3.55 90FEE0 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.00 936B20 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.00 948380 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.01 936A80 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.01 9482E0 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.05 936D20 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.05 948580 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.06 936E70 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.06 9486D0 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.07 936FB0 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
4.07 948810 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.55 A3E4E0 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
4.55 A4FFD0 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
5.00 A71350 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
5.00 A82D00 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
5.05 A71750 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
5.05 A83100 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
5.05_devkit C53980 64036 ov580_full_UAC_20120918_21307.bin 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
5.05_devkit C65330 67924 9e7ddcb8b891d7227ac0bdc998ddbfe7 UVC
6.00 B0A82F 68032 24afe3c941dc599aafd23ac5170a4d14 UVC
6.00 B1D8BE 64036 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
6.50 B0CFC0 68032 24afe3c941dc599aafd23ac5170a4d14 UVC
6.50 B1F6E1 64036 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
7.00 B1BA24 68032 24afe3c941dc599aafd23ac5170a4d14 UVC
7.00 B0C000 64036 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC
7.02 B1BA24 68032 24afe3c941dc599aafd23ac5170a4d14 UVC
7.02 B0C000 64036 99ca1e97ea2bb9edaf4c6f511292b4e2 UAC

I will use 5.05 UVC for a proper driver check luke_firmwares repository to find all firmwares if you have not access to a PlayStation Kernel yourself to extract using the offset and size published here.


luke_ioctl

This function receive ioctl commands and buffer with parameters

This table is for kernel and libSceCamera.sprx from 5.05

cmd libSceCamera.sprx caller
libSceCamera.sprx call from user or internal
0xC0188E16 sub_10A0 sceCameraSetConfig,sceCameraSetConfigInternal
0xC0188E18 sub_1670 sceCameraGetConnfig
0xC0188E1A sub_1960 sceCameraStop,sceCameraStopByHandle
0xC0208E19 sub_1740 sceCameraStart,sceCameraStartByHandle
0xC0148E1E sub_3E80 sceCameraIsAttached
0xC0108E26 sub_1A90 sceCameraSetVideoSync,sceCameraSetVideoSyncInternal
0xC0288E14 sub_AF0 sceCameraOpen,sceCameraOpenByModuleId
0xC0388E1B sub_39A0 sceCameraSet*
0xC0388E1C sub_3390 sceCameraGetAttribute
0xC0388E1C sub_3300 sceCameraGetAutoExposureGain,sceCameraGetAutoWhiteBalance
0xC0468E02 sub_5000 sceCameraGetRegister
0xC0468E03 sub_5210 sceCameraSetRegister
0xC0388E1D sub_1B80 sceCameraGetFrameData
0xC0048E23 sub_3250 sceCameraIsValidFrame
0x40408E22 sub_AF0
0x40308E24 sub_5930 hftC5A1C8OQ_F_A
0xC0088E08 sub_4180 sceCameraGetDeviceInfo
0xC0088E09 nnR7KAIDPv8_F_A_0 nnR7KAIDPv8_F_A
0xC0088E0A sub_5D10
0xC0088E17
0xC0088E20 sub_49C0 sceCameraSetCalibData
0xC0088E21 sub_4080 sceCameraSetForceActivate
0xC0088E28 sub_5FB0 sceCameraSetVrTrackerMode
0xC0048E27 sub_5EC0 sceCameraSetDebugStop
0xC0108E15 sub_EF0 sceCameraClose,sceCameraCloseByHandle

Thanks