Monday, 24 August 2015

Reversing sceLibCamera

Well, first thanks to all people involved in WebKit exploit. Without their tools i could't dump module and reverse it.

1) We need dump the module. Load libSceCamera.sprx its id is 31. So load it first.

2) Dump it. its index is 20 when it is loaded.

3) Idapro to the rescue. We need offset for all functions that can be called from other modules. Only a brief view and you can see that Sony is using printf("%s ...\n",__FUNCTION__,..) in his code (Thanks of this help Sony) so many function names are you waiting for you with the offset ready :P and plenty of them are the same names that we know from vita and ps3.

you can use getFunctionAddressByName sycall 591 with the names that you see in idapro so you can confirm all function names and the offsets.

The list is:

sceCameraAudioOpen Offset = 0x6d00
sceCameraClose Offset = 0x5550
sceCameraCloseByHandle Offset = 0x55b0
sceCameraGetAttribute Offset = 0x5a10
sceCameraGetAutoExposureGain Offset = 0x5ba0
sceCameraGetAutoWhiteBalance Offset = 0x5d00
sceCameraGetConfig Offset = 0x5710
sceCameraGetContrast Offset = 0x5e60
sceCameraGetDefectivePixelCancellation Offset = 0x5fc0
sceCameraGetDeviceConfig Offset = 0x6dc0
sceCameraGetDeviceInfo Offset = 0x5af0
sceCameraGetExposureGain Offset = 0x6120
sceCameraGetFrameData Offset = 0x5950
sceCameraGetGamma Offset = 0x62c0
sceCameraGetHue Offset = 0x6460
sceCameraGetLensCorrection Offset = 0x65c0
sceCameraGetSaturation Offset = 0x6720
sceCameraGetSharpness Offset = 0x6880
sceCameraGetWhiteBalance Offset = 0x69e0
sceCameraIsAttached Offset = 0x6bd0
sceCameraIsValidFrameData Offset = 0x59b0
sceCameraOpen Offset = 0x5430
sceCameraOpenByModuleId Offset = 0x54c0
sceCameraSetAttribute Offset = 0x5a80
sceCameraSetAutoExposureGain Offset = 0x5c50
sceCameraSetAutoWhiteBalance Offset = 0x5db0
sceCameraSetCalibData Offset = 0x6c70
sceCameraSetConfig Offset = 0x5610
sceCameraSetConfigInternal Offset = 0x5690
sceCameraSetContrast Offset = 0x5f10
sceCameraSetDefectivePixelCancellation Offset = 0x6070
sceCameraSetExposureGain Offset = 0x6200
sceCameraSetGamma Offset = 0x63a0
sceCameraSetHue Offset = 0x6510
sceCameraSetLensCorrection Offset = 0x6670
sceCameraSetSaturation Offset = 0x67d0
sceCameraSetSharpness Offset = 0x6930
sceCameraSetWhiteBalance Offset = 0x6ac0
sceCameraStart Offset = 0x5790
sceCameraStartByHandle Offset = 0x5810
sceCameraStop Offset = 0x5890
sceCameraStopByHandle Offset = 0x58f0

there are more but are internals and you can't use it outside the module.

4) Now fun job. Dissasemble each function that you can use from WebKit. You will see that Sony is using the same error Codes than in vita so this will help you to follow better the code. For example function sceCameraStop is at offset 0x5890 you can see its code in the next capture:



Remember:
"The first is placed in rdi, the second in rsi, the third in rdx, and then rcx, r8 and r9. Only the 7th argument and onwards are passed on the stack
For calls that may call functions that use varargs or stdargs (prototype-less
calls or calls to functions containing ellipsis (. . . ) in the declaration)
%al is used as hidden argument to specify the number of vector registers used."

so here we go:

edi contains parameter passed to the function. It is comparing with itself so basically if it is less or equal to 0 go to loc_58c7.

You will see that in loc_58c7 it is using something like:

printf("%s invalid handle:%d\n",__FUNCTION,arg1);

then you will see our old friend 802E0000h aka SCE_CAMERA_ERROR_PARAM well known in psp2sdk. So if you pass an arg1 less or equal than 0 to this function  you will get that.

So now what happen if you pass a valid handle greater than 0. When you open it will give you handle 1. If you are not open previously the camera what happen? Test and error and you will see.

if handle >0 it will call loc_58e3 with 2 parameter first is our handle and second you can see in the code. Result is saved on rsx and if it is not 0 (our old friend SCE_OK) it will return code error. For example try to call close before open and it will return  0x802e0004 aka SCE_CAMERA_ERROR_NOT_OPEN

Easy don't you?

int sceCameraClose(int handle) 0 on success error codes on fail

5) Follow reversing functions. Advice some function are using structures in their parameter so it check if these structures are not NULL and depend of the function check the first 32 bits in these structures it is harcoded on the code so it you can call with a valid chain.data from WebKit and set the correct values on that first 32 bits you can call all the functions described with success.

6) What do you wait to help to open sdk?

sample output from ps4:

https://gist.github.com/psxdev/0aec149948e0dbb3c382

The best is yet to come ;) (greets to Kojima san)





Sunday, 15 February 2015

Reversing PlayStation 4 Camera

I have been working with PlayStation 4 Camera since 2013. So i want to share with you all things learned since then.

First of all, if device has not a public/free driver , you need to make reverse engineering  and you need to look for information about its chipset and make a research about it. So you need to open the device and look for information about its different chips. After making some research we can show the next high level design diagram:


PlayStation 4 Camera is using a propietary connector called AUX, however it is a USB 3 cable so our first goal was to cut off the AUX connector and connect it to  an USB3 male connector, after this we can connect directly to Mac/PC with USB3 female ports.  Next step was to get an USB sniffer capture from PlayStation 4 with a beagle device in the middle, without this we could not have learnt about how to initialize the device and their different options.

Chips description:

  • OV580. It is an asic from Omnivision a typical custom USB bridge solution to manage all other chip. No information or datasheet about it without signing a NDA with Omnivision. Other companies using it are Mantis Vision and LeapMotion. I have worked with others Omnivision USB bridge solutions included in PlayStation EyeToy(OV519) and PlayStation Eye(OV534) so basically it is the same work i made with other drivers for Omnivision.

  • OV9713.  Two cmos sensors well documented with full datasheet available in google.

  • AK5703. An analogical to digital converter connected with an microphone array (4). Datasheet is available.  The datasheet was very helpfull to get audio properly from PlayStation 4 Camera.

  • 4g51A. An eeprom chip. It contains the initial configuration for PlayStation 4 Camera.

When you connect device to a Mac/PC  with  USB3 it  is in boot mode waiting for loading firmware. Analizing sniffer capture we got the firmware and steps needed  to load it  to device. So after loading firmware you have and special UVC Camera device and you can learn about their different streaming modes.

Interface 1 alt setting 0 describe all video modes with these possible options:

  •     mode 0 fps 60(default), 30, 15, 8 video left and video right frames 1280x800

  •     mode 1 fps 120(default), 60, 30, 15, 8 video left and video right frames 640x400

  •     mode 2 fps 240(default), 120, 60, 30 video left and video right frames 320x192

OV580 is delivering in each mode:

  •     mode 0 3448x2x808 bytes frame each row with:
        header 32 bytes
        audio 64 bytes
        video left 1280x2 bytes
        video right 1280x2 bytes
        video interleave 840x2 bytes

  •     mode 1 1748x2x408 bytes frame each row with:
        header 32 bytes
        audio 64 bytes
        video left 640x2 bytes
        video right 640x2 bytes
        video interleave 420x2 bytes
  •     mode 2 898x2x200 bytes frame each row with
        header 32 bytes
        audio 64 bytes
        video left 320x2 bytes
        video right 320x2 bytes
        video interleave 210x2 bytes

Part of Header is showed in the next screenshot:


Part of Audio is showed in the next screenshot:


Audio has 4 channel i use Audicity tool loading a 10 second capture a reproducing 4 audio channels with success.  AK5703 datasheet was very helpfull. An screenshot from audicity tool:

Videl Left and Right can be converted to RGB with CV_YUV2RGB_YUY2 conversion:

cv::Mat yuv(size_y,size_x,CV_8UC2 ,in);
cv::Mat rgb(size_y,size_x,CV_8UC3, out);
 cv::cvtColor(yuv, rgb, CV_YUV2RGB_YUY2);

Video interleave it is also the same video format but it is making a mix of two sensor

A sample application made using basic PS4EYECam driver showing a 640x400 mode for two PlayStation Cameras at the same time:






Low level usb stuff is implemented and available in my repository. EyeLab  is a  poc of multi camera   application using PS4EYECam driver and it is not in the repository,  you don't need to make changes  in the driver to support multi cameras you need to do it at application level.

So after this i can say that PlayStation 4 Camera is full documented and it can be supported on other platforms. All information needed is here and in my repository.

PlayStation 4 receives frames with format explained here. I suppose that secondary processor makes all the job to parse frames(video and audio) and connect with image/audio libraries from sdk(if someone want to share it with me you can contact with me :P).  PlayStation 4 only has 1 AUX port so a multicam solution would be hard to implement like i am doing now in Osx.