PS3 4.88.2 Evilnat Cobra (8.3) Custom FirmWare (CFW-CEX) Released

UPDATE 4.88.2: PS3 Developer @Evilnat has updated and released 4.88.2 Evilnat (Cobra 8.3) CFW , there is a number of new options like an added File manager, Option to toggle Cobra version, and various other new options detailed in the changlog provided below. Also the developer has provided a number of fixes and improvements, View all the details of 4.88.2 release of this latest CFW by @Evilnat

.Original release (4.88.1) Developer @Evilnat (creator of releases like SEN Enabler and PAUD Unpacker) has created and released 4.88 EVILNAT's COBRA CFW, following the success of 4.87 Evilnat's CFW, the developer provides another trusted CFW release that provides the Cobra Payload and all the features it brings (note: MAMBA is an alternative to the Cobra Payload, Cobra is included in firmware's where as MAMBA is typically injected in a Standard CEX CFW via a homebrew app. See all the details of this CFW Release below

Also Included are: noBD / noBT / noBD & noBT CFW Builds (for damaged console's to make them usable again)
-STLcardsWS​



CFW Evilnat.png

  • 4.88.2 EVILNAT (COBRA 8.3)

    Changelog
    • Fixed memory leak in LV2 kernel while Cobra is enabled
    • Added option to dump ERK (eid_root_key) through xai_plugin (from flatz's EID root key dumper)
    • Added option to dump LV2 through xai_plugin
    • Added option to dump LV1 through xai_plugin
    • Added File Manager in xai_plugin (by DeViL303)
    • Added option to toggle Cobra version, release (default in CFW) and debug (get debug logs through socat)
    • Manual FAN speed now works with Cobra disabled too
    • Added system to block login in on PSN/SEN while CFW syscalls are enabled (by DeViL303)
    • Added sort games by name and date options (by aldostools)
    • xai_plugin translated to Brazilian (thanks to jcorrea and LuanTeles)
    • xai_plugin translated to Polish (thanks to KcrPLo and Agrippa)
    • xai_plugin translated to Italian (thanks to Sheireen)
    • xai_plugin translated to Chinese Traditional/Simplified (thanks to xiaoyang)
    • xai_plugin translated to Spanish

    Features
    • Made out of 4.88 OFW
    • Made manually without automatic tools
    • SEN/PSN enabled
    • Disabled deletion of unsigned act.dat and .rif files
    • Allowed unsigned act.dat and .rif files
    • Allowed running of unsigned applications
    • Compatibility with FSELF
    • C00 demo unlocker
    • Disabled LIC.EDAT license check
    • Can be installed over 3.55 OFW
    • Can be installed over +3.56 OFW (bguerville Toolset)
    • Can be installed over any CFW CEX
    • COBRA 8.3 added and enabled as default
    • Full PS2 Games Compatibility
    • Possibility of Downgrade from any CFW with active QA Flags
    • QA Flags active if previously enabled
    • Disabled Epilepsy Message on Boot
    • Compatibility with PSX games in ISO
    • Compatibility with PSP games in ISO
    • Compatibility with PS2 games in ISO
    • Compatibility with PS3 games in ISO/JB folder format
    • Compatibility with ReactPSN
    • Display of Temperatures in XMB In-Game on PS2 Games
    • RSOD Screen Bypass
    • BSOD Screen Bypass
    • PS3_GAME/app_home
    • XMB In-Game Screenshot
    • Added Package Manager
    • CoreOS Hash Check patched to prevent Brick on non-dehashed Downgradate consoles
    • Patched to remove LV2 Protection
    • Peek and Poke (LV2)
    • Peek and Poke (LV1)
    • CINAVIA protection disabled
    • Option to sort games by name and date

    Cobra 8.3
    • Failsafe Cobra stage2 (by bguerville/aldo)
    • Restore CFW Syscalls without reboot just entering to 'Settings > System Update' on XMB (by aldo)
    • Integrated Dynamic Control FAN (to control fan when webMAN is unloaded) (by aldo/Evilnat)
    • Support Photo GUI integration with webMAN MOD (mount games from 'Photo' column) (by aldo/DeViL303)
    • Get/Set FAN speed (by aldo)
    • Enable/disable features: Photo GUI, Restore Syscalls (by aldo)
    • Opcode to create CFW Syscalls (6, 7, 8, 9, 10, 11, 15, 35) (by aldo)
    • Opcode to set fake accountID (by Evilnat)
    • Opcode to activate account (act.dat) (by Evilnat)
    • Opcode to create license (RIF) (by Evilnat)
    • Updated ps3mapi_load_process_modules to load custom modules and system modules (by haxxxen)
    • Added ps3mapi_get_process_module_info
    • Increased from 24 to 32 the max number of map paths (by aldo)
    • Added sm_get_temperature patch in kernel (by Evilnat)
    • Added sm_get_fan_policy patch in kernel (by Evilnat)
    • Added sm_set_fan_policy patch in kernel (by Evilnat)
    • Fixed Control FAN payload, avoids loading previous mode (by Evilnat)
    • Disable stage2.bin while Recovery Menu is loaded (by haxxxen)
    • Fixed max FAN speed after shutdown (by Evilnat)
    • Improved Habib's QA flags code imported by aldostools (by Evilnat)
    • Fixed black screen in CFW2OFW converted games (by Evilnat)
    • Added sm_ring_buzzer with single_beep, double_beep and triple_beep (by Evilnat)
    • Skip license creation (rif) if it already exists (by aldo)
    • Added cellFsMkdir symbol (by Evilnat)
    • Added constant FAN Speed while a PS2 ISO is launched (by Evilnat)
    • Check/Disable/Enable QA Flags (by Evilnat)
    • Creation of act.dat while launching a PSN game (by Evilnat)
    • Convert someones's else savedata to your own savedata (by Evilnat)
    • Block Log In on PSN/SEN when CFW syscalls are enabled (by DeViL303)

    Tested in:
    • CECH-2000A
    • CECH-2000B
    • CECH-2001A
    • CECH-2002B
    • CECH-2004A
    • CECH-2012A
    • CECH-2104B
    • CECH-2500A
    • CECH-2501A
    • CECH-2504A
    • CECH-2511A
    • CECH-2511B
    • CECH-L04
    • CECHA01
    • CECHE01
    • CECHB01
    • CECHC04
    • CECHG01
    • CECHP01

    Improvements xai plugin


    These options are in Network tab under [★ Custom Firmware Tools] option:

    Power Options
    • Turn Off: Turns off the PS3
    • Hard Reboot: Reboots the PS3 completely
    • Soft Reboot: Reboots the PS3 softly
    • Reboot LV2: Reboots the LV2

    File Manager
    • Internal Hard Disk Drive 0: Manage PS3 files in /dev_hdd0
    • Internal Hard Disk Drive 1: Manage PS3 cached files in /dev_hdd1
    • USB Mass Storage Devices: Manage files on your USB devices
    • Internal Flash Memory: Manage PS3 internal flash files
    • Optical Disc: Manage optical discs
    • Memory Cards: Manage memory cards

    Basic Tools
    • FAN Speed: Shows current FAN speed
    • PS3 Temperature: Shows current CPU and RSX temperature
    • Show IDPS: Shows current IDPS
    • Show PSID: Shows current PSID
    • Toggle Coldboot: Toggles between custom/original coldboot.raf
    • Toggle System Version: Toggles between custom/original system version in "System Information"

    Basic Tools > xRegistry Tools

    • Backup xRegistry.sys: Creates a backup of xRegistry.sys to /dev_usb or /dev_hdd0
    • Button Assignment: Switches O and X buttons

    Cobra Tools
    • Cobra Information: Shows current Cobra information
    • Check Syscall 8: Checks Cobra's Syscall 8 status
    • Create Syscalls: Create syscalls 6, 7, 8, 9, 10, 11, 15 and 35
    • Allow Restore Syscalls: Allows restoring syscalls through "System Update"
    • Skip license creation: Skips overwriting license file (RIF) if it already exists
    • Toggle Cobra Version: Toggles between release and debug versions (reboot is required)
    • Toggle Cobra: Enables or disables Cobra (reboot is required)

    Cobra Tools > FAN Tools
    • Control FAN Mode: DISABLED: Disables Cobra's Control FAN
    • Control FAN Mode: SYSCON: Allows the PS3's SYSCON to control FAN speed
    • Control FAN Mode: MAX: Set Cobra FAN speed to 0xFF

    Cobra Tools > QA Tools
    • Check QA Flags: Check if QA flags are enabled or disabled
    • Enable QA Flags: Enables QA Flags
    • Disable QA Flags: Disables QA Flags

    Cobra Tools > FAN Tools > Dynamic FAN Control
    • Maximum temperature: 60°C: Sets the fan speed dynamically to keep the system at a maximum temperature of 60°C
    • Maximum Temperature: 65°C: Sets the fan speed dynamically to keep the system at a maximum temperature of 65°C
    • Maximum Temperature: 70°C: Sets the fan speed dynamically to keep the system at a maximum temperature of 70°C
    • Maximum Temperature: 75°C: Sets the fan speed dynamically to keep the system at a maximum temperature of 75°C

    WARNING: Some PS3 cannot reach/stay some option temperatures, use with caution

    Cobra Tools > FAN Tools > Manual Speed
    • Manual Speed: 40%: Sets the fan speed statically at 40% (0x67)
    • Manual Speed: 45%: Sets the fan speed statically at 45% (0x75)
    • Manual Speed: 50%: Sets the fan speed statically at 50% (0x80)
    • Manual Speed: 55%: Sets the fan speed statically at 55% (0x8E)
    • Manual Speed: 60%: Sets the fan speed statically at 60% (0x9B)
    • Manual Speed: 65%: Sets the fan speed statically at 65% (0xA8)
    • Manual Speed: 70%: Sets the fan speed statically at 70% (0xB5)
    • Manual Speed: 75%: Sets the fan speed statically at 75% (0xC0)
    • Manual Speed: 80%: Sets the fan speed statically at 80% (0xCE)
    • Manual Speed: 85%: Sets the fan speed statically at 85% (0xDA)
    • Manual Speed: 90%: Sets the fan speed statically at 90% (0xE7)
    • Manual Speed: 95%: Sets the fan speed statically at 95% (0xF4)

    WARNING: The chosen speed will be static, it will not be changed at any time automatically

    Cobra Tools > FAN Tools > PS2 FAN

    • PS2 Fan Mode: DISABLED: Disables Control FAN on PS2 game
    • PS2 Fan Mode: SYSCON: Allows the PS3's SYSCON to control FAN speed on PS2 game
    • PS2 Fan Mode: 40%: Sets FAN speed to 0x66 on PS2 game
    • PS2 Fan Mode: 50%: Sets FAN speed to 0x80 on PS2 game
    • PS2 Fan Mode: 60%: Sets FAN speed to 0x9A on PS2 game
    • PS2 Fan Mode: 70%: Sets FAN speed to 0xB4 on PS2 game
    • PS2 Fan Mode: 80%: Sets FAN speed to 0xCE on PS2 game
    • PS2 Fan Mode: 90%: Sets FAN speed to 0xE8 on PS2 game

    WARNING: There is no Control FAN in a PS2 game, select with caution

    PSN Tools
    • Disable Syscalls: Disables syscalls and remove history files
    • Show accountID: Shows current user's accountID
    • Create accountID: Creates a fake accountID for current user's in xRegistry
    • Overwrite accountID: Overwrites current user's accountID with a fake one in xRegistry
    • Activate account: Creates act.dat file in the current local account
    • Create license: Creates RIF licenses from RAP files from "x:\exdata"
    • Backup activation file: Creates a backup of act.dat to /dev_usb or /dev_hdd0
    • Disable account: Deletes current user's activation file act.dat permanently
    • Convert savedata: Converts savedata from "/dev_usbXXX/PS3/SAVEDATA" to your own savedata

    Dump Tools
    • View Log: http://localhost/dev_hdd0/tmp/cfw_settings.log (webMAN MOD is required for this function)
    • Clean Log File: Resets /dev_hdd0/tmp/cfw_settings.log file
    • Dump IDPS: Saves IDPS to log file
    • Dump PSID: Saves PSID to log file
    • Dump LV2: Dumps LV2 to /dev_usb or /dev_hdd0/tmp
    • Dump LV1: Dumps LV1 to /dev_usb or /dev_hdd0/tmp
    • Dump ERK: Dumps eid_root_key to /dev_usb or /dev_hdd0/tmp
    • Log KLicense usage: Saves filename and klicensee to log file
    • Log Secure File ID usage: Writes save data name and file ID key to log file
    • Dump Disc Hash Key: Retrieves disc hash key from an ORIGINAL game disc

    Service Tools
    • Display Applicable Version: Displays minimum downgrade version
    • Check File System: Reboots and allows you to check and repair filesystem
    • Rebuild Database: Reboots with Database rebuilding flag set
    • Toggle Recovery Mode: Reboot to Recovery Mode (Not supported on NAND models!)

    Service Tools > Advanced Service Tools
    • RSOD fix: Re-initialize VTRM-Region to attempt to fix RSOD
    • Toggle Factory Service Mode: Enter/Exit Factory Service Mode (DON'T INSTALL CFW ON FSM)
    • Remarry Bluray Drive: Requires: Enter to FSM and copy "eid_root_key" to /dev_usb
    • Load LV2 kernel: Loads lv2_kernel.self file from /dev_usb000 or /dev_flash


    Savegames conversion tutorial

    WARNING: This option will overwrite your current savedata in dev_usbXXX, use it with caution

    • Download someone else's savegame for your game of your choice
    • Put the savedata in your pendrive in "X:\PS3\SAVEDATA" (pendrive must be in FAT32)
    • Put in the pendrive in the PS3
    • Select Network Tab > [★ Custom Firmware Tools] > PSN Tools > Convert Savedata
    • Wait until the conversion finishes
    • Once finished, copy your converted savedata throught XMB "Saved Data Utility (PS3)"
    • Launch your game and load your new savedata


    Creation of act.dat tutorial

    WARNING: The accountID is linked to savedata and trophies, so, if your current user already have a valid accountID and you overwrite it, you will be unable to use your trophies and savedata on that account until you restore the original accountID in xRegistry.sys.


    I recommend to use an empty account without trophies and savedata or an account without accountID.


    To create a fake act.dat, Cobra 8.3 must be enabled, and your PS3 must have at least one account with a valid accountID and launch a game that requires a RIF/RAP license file.

    Cobra will search a valid accountID in all existing accounts and create act.dat while the game is launched through the XMB. If no accountID is found, act.dat will not be created.

    You can create a fake accountID (like reactPSN), to do this go to Network > ★ Custom Firmware Tools > PSN Tools and choose between "Create accountID" or "Overwrite accountID" (Be careful about the last option because if you already have a fake/real accountID it will be overwritten). It is recommended to use these options in an account that does not have an ID. The PS3 will restart if everything went well.

    The tutorial would be the following:
    • Download your purchased PSN game from PS Store
    • Put game RAP file in "X:\exdata" or "/dev_hdd0/exdata"
    • Launch your purchased PSN game
    • Cobra will check if any of your PS3 accounts have accountID
    • Faked act.dat will be created while the game is launching

    If none of your accounts have a valid accountID you will need to create it. To do this log into the local PS3 account where you want to create the accountID. You can see if your current local account has an accountID choosing Network Tab > [★ Custom Firmware Tools] > PSN Tools > Show accountID.

    To create a faked act.dat do the following:
    • Make sure Cobra 8.3 is enabled
    • Select Network Tab > [★ Custom Firmware Tools] > PSN Tools > Create accountID
    • Select Network Tab > [★ Custom Firmware Tools] > PSN Tools > Activate account
    • Launch your purchased PSN game
    • Faked act.dat will be created while the game is launching

    Now you have a faked act.dat and your local account is activated. The act.dat file works for every local account, you only need one file for all accounts.


    Block PSN log in

    This method is developed by @DeViL303, it will only work with Cobra enabled, Cobra will block log in on PSN/SEN while the CFW syscalls are enabled, to enable it again you need to disable CFW syscalls completely (you can do it with webMAN MOD, psnpatch, SEN Enabler, etc…).

    If you want to disable this feature, simply delete /dev_flash/vsh/resource/npsignin_plugin.lck


    Translations


    Final Words

    I hope that the CFW is working fine and without issues for everyone, but if you see any issue, please let me know in my twitter and I will try to fix it as soon as possible: @xXEvilnatXx

    Cobra 8.3 and xai_plugin source code can be found in my Github repository:


    Credits and Acknowledgment

    Credits to Team Rebug, Team Cobra, @mysis, @Joonie, @habib, @aldostools, @haxxxen, @DeViL303, @zecoxao, @3141card, @Berion, @kakaroto, @KW, @naehrwert, @flatz, @Dean, @Rogero, @Estwald and anyone who has contributed to the PS3 scene.

    Thanks to @DeViL303, @Berion, @Brandon Stump, @jcorrea, @nhie07, @NSC-Modz, @LuanTeles, @thejavigames, @raidriar, @xiaoyang, @Zwei, @haxxxen, @RetroFan_90, @SpyroMancer, @patricksouza472, @MrYadro, @CFW-Us3r, @Andrio, @KcrPLo, Nur Rakhmadi Rajab, @Lwiz, @Sheireen, @TheWizWiki and all who helped me testing the CFW 4.88.

    If I forgot someone, I apologize, there are many people in the PS3 scene and you are many people who
    have helped me to test the CFW.



Download: MEGA FOLDER WITH ALL CFW VERSION

Download: CFW EVILNAT 4.88.2 COBRA 8.3 [CEX]
MD5: 3202971E05140F24E52B36D5C443AD35

Download: CFW EVILNAT 4.88.2 COBRA 8.3 [CEX] [noBD]

MD5: 80029DC0FBD238DAF8ED45BCDFD04CD6

Download:CFW EVILNAT 4.88.2 COBRA 8.3 [CEX] [noBT]
MD5: 360569FE808B1815BD05258C8496003F

Download: CFW EVILNAT 4.88.2 COBRA 8.3 [CEX] [noBD] [noBT]
MD5: D8BB1F47B77F1737F974308B935F81B6
 
Last edited by a moderator:
@aldostools Fix for max FAN speed after shutdown, i'm hooking syscall 379 (sys_sm_shutdown) and check if we are calling it with parameter 0x0100 or 0x1100 (I don't check if it restarts, is not needed), then i let the SYSCON have control over FAN before the PS3 shutdowns completely.

This way is working fine, tested in my PS3

https://github.com/Evilnat/Cobra-PS...e4b12da536b67b0bcc8b23f5d0af6b9891a225b5b55cc

fan_control.c

Code:
#define SYS_SHUTDOWN               0x0100
#define SYS_SHUTDOWN2              0x1100

LV2_HOOKED_FUNCTION_COND_POSTCALL_3(int, sys_shutdown, (uint16_t op, const void *buf, uint64_t size))
{
    // Avoids max FAN speed after a shutdown by Evilnat
    if(op == SYS_SHUTDOWN || op == SYS_SHUTDOWN2)
    { 
        DPRINTF("Shutdown executed, resetting FAN policy\n");
        sm_set_fan_policy(0, 1, 0);
    }

    return DO_POSTCALL;
}

void fan_patches(void)
{
    hook_function_with_cond_postcall(get_syscall_address(SYS_SM_SET_FAN_POLICY), sm_set_fan_policy_sc, 3);
    hook_function_with_cond_postcall(get_syscall_address(SYS_SM_SHUTDOWN), sys_shutdown, 3);
}

void unhook_all_fan_patches(void)
{
    suspend_intr();
    unhook_function_with_precall(get_syscall_address(SYS_SM_SET_FAN_POLICY), sm_set_fan_policy_sc, 3);
    unhook_function_with_precall(get_syscall_address(SYS_SM_SHUTDOWN), sys_shutdown, 3);
    resume_intr();
}


Added options to disable/enable and check QA Flags, whole code was modified using Habib's QA code as a base.

I'm retrieving IDPS from EID5 instead LV2 (PS3MAPI_IDPS_2).

qa.c
Code:
//---------------------------------------------------
// Advanced QA Flag & Debug Settings Enabler by habib
//---------------------------------------------------

// Improved by Evilnat

#include <stdlib.h>
#include <string.h>
#include <lv1/lv1.h>
#include <lv2/io.h>
#include <lv2/security.h>
#include <lv2/thread.h>
#include <lv2/patch.h>
#include <lv1/patch.h>
#include <lv1/mm.h>
#include "ps3mapi_core.h"
#include "common.h"
#include "storage_ext.h"
#include "qa.h"

uint64_t *idps;
uint64_t IDPS_1, IDPS_2;
uint32_t UM_ori_patch, DM_ori_patch1, DM_ori_patch2, DM_ori_patch3, DM_ori_patch4;

static u8 erk[0x20] =
{
    0x34, 0x18, 0x12, 0x37, 0x62, 0x91, 0x37, 0x1c,
    0x8b, 0xc7, 0x56, 0xff, 0xfc, 0x61, 0x15, 0x25,
    0x40, 0x3f, 0x95, 0xa8, 0xef, 0x9d, 0x0c, 0x99,
    0x64, 0x82, 0xee, 0xc2, 0x16, 0xb5, 0x62, 0xed
};

static u8 hmac[0x40] =
{
    0xcc, 0x30, 0xc4, 0x22, 0x91, 0x13, 0xdb, 0x25,
    0x73, 0x35, 0x53, 0xaf, 0xd0, 0x6e, 0x87, 0x62,
    0xb3, 0x72, 0x9d, 0x9e, 0xfa, 0xa6, 0xd5, 0xf3,
    0x5a, 0x6f, 0x58, 0xbf, 0x38, 0xff, 0x8b, 0x5f,
    0x58, 0xa2, 0x5b, 0xd9, 0xc9, 0xb5, 0x0b, 0x01,
    0xd1, 0xab, 0x40, 0x28, 0x67, 0x69, 0x68, 0xea,
    0xc7, 0xf8, 0x88, 0x33, 0xb6, 0x62, 0x93, 0x5d,
    0x75, 0x06, 0xa6, 0xb5, 0xe0, 0xf9, 0xd9, 0x7a
};

static u8 iv_qa[0x10] =
{
    0xe8, 0x66, 0x3a, 0x69, 0xcd, 0x1a, 0x5c, 0x45,
    0x4a, 0x76, 0x1e, 0x72, 0x8c, 0x7c, 0x25, 0x4e
};

/**
* Function to compute the digest
*
* @param k   Secret key
* @param lk  Length of the key in bytes
* @param d   Data
* @param ld  Length of data in bytes
* @param out Digest output
* @param t   Size of digest output
*/

static void hmac_sha1(const u8 *k, u8 lk, const u8 *d, size_t ld, u8 *out)
{
    SHACtx *ictx = malloc(0x100);

    if(!ictx)
        return;

    SHACtx *octx = malloc(0x100);

    if(!octx)
    {
        free(ictx);
        return;
    }

    u8 isha[SHA_DIGEST_LENGTH];
    u8 key[SHA_DIGEST_LENGTH];
    u8 buf[SHA_BLOCKSIZE];
    u8 i;

    if (lk > SHA_BLOCKSIZE)
    {
        SHACtx *tctx = malloc(0x100);
        sha1_init(tctx);
        sha1_update(tctx, k, lk);
        sha1_final(key, tctx);
        free(tctx);

        k = key;
        lk = SHA_DIGEST_LENGTH;
    }

    // Inner Digest
    sha1_init(ictx);

    // Pad the key for inner digest
    for (i = 0; i < lk; ++i)
        buf[i] = k[i] ^ 0x36;
    for (i = lk; i < SHA_BLOCKSIZE; ++i)
        buf[i] = 0x36;

    sha1_update(ictx, buf, SHA_BLOCKSIZE);
    sha1_update(ictx, d, ld);

    sha1_final(isha, ictx);

    // Outer Digest
    sha1_init(octx);

    // Pad the key for outter digest

    for (i = 0; i < lk; ++i)
        buf[i] = k[i] ^ 0x5c;
    for (i = lk; i < SHA_BLOCKSIZE; ++i)
        buf[i] = 0x5c;

    sha1_update(octx, buf, SHA_BLOCKSIZE);
    sha1_update(octx, isha, SHA_DIGEST_LENGTH);

    sha1_final(out, octx);

    free(ictx);
    free(octx);
}

static void lv1_patches()
{
    UM_ori_patch = lv1_peekw(UM_PATCH_OFFSET);
    DM_ori_patch1 = lv1_peekw(DM_PATCH1_OFFSET);
    DM_ori_patch2 = lv1_peekw(DM_PATCH2_OFFSET);
    DM_ori_patch3 = lv1_peekw(DM_PATCH3_OFFSET);
    DM_ori_patch4 = lv1_peekw(DM_PATCH4_OFFSET);

    lv1_pokew(UM_PATCH_OFFSET, LI(R0, 0));
    lv1_pokew(DM_PATCH1_OFFSET, NOP);
    lv1_pokew(DM_PATCH2_OFFSET, LI(R3, 1));
    lv1_pokew(DM_PATCH3_OFFSET, LI(R31, 1));
    lv1_pokew(DM_PATCH4_OFFSET, LI(R3, 0));
}

static void restore_patches()
{
    lv1_pokew(UM_PATCH_OFFSET, UM_ori_patch);
    lv1_pokew(DM_PATCH1_OFFSET, DM_ori_patch1);
    lv1_pokew(DM_PATCH2_OFFSET, DM_ori_patch2);
    lv1_pokew(DM_PATCH3_OFFSET, DM_ori_patch3);
    lv1_pokew(DM_PATCH4_OFFSET, DM_ori_patch4);
}

static int get_idps()
{
    uint32_t nread;
    uint64_t device;
    uint64_t start_flash_sector = 0x181;
    device_handle_t handle;

    page_allocate_auto(NULL, 4096, 0x2F, (void **)&idps);

    device = storage_get_flash_device();

    if(!device)
        start_flash_sector = 0x20D;

    DPRINTF("Flash Device: %016lX\n", device);

    if(storage_open(device, 0, &handle, 0))
        return 1;
 
    if(storage_map_io_memory(device, idps, 4096))
        return 1;

    if(call_hooked_function_7(emu_storage_read, (uint64_t)handle, 0, start_flash_sector, 1, (uint64_t)idps, (uint64_t)&nread, 0))
        return 1;

    memcpy(&IDPS_1, (void *)&idps[0x3A], 8);
    memcpy(&IDPS_2, (void *)&idps[0x3B], 8);

    DPRINTF("IDPS from EID5: %016lX%016lX\n", IDPS_1, IDPS_2);
       
    storage_close(handle);
    storage_unmap_io_memory(device, idps);
    page_free(NULL, idps, 0x2F);

    return 0;
}

uint8_t read_qa_flag()
{
    uint8_t value = 0;
    update_mgr_read_eeprom(QA_FLAG_OFFSET, &value, LV2_AUTH_ID);
    return (value == 0x00);
}

int set_qa_flag(uint8_t value)
{
    uint8_t seed[TOKEN_SIZE];
    uint8_t token[TOKEN_SIZE];

    if(get_idps())
        return 2;

    memset(seed, 0, TOKEN_SIZE);
    memcpy(seed + 4, (void *)&IDPS_1, 8);
    memcpy(seed + 12, (void *)&IDPS_2, 8);

    if(seed[0x07] != 0x01)
    {
        DPRINTF("QA Flag: IDPS is not valid!!\n");
        return 1;
    }

    seed[3] = 1;

    if(value)
    {
        seed[39] |= 0x1; // QA_FLAG_EXAM_API_ENABLE
        seed[39] |= 0x2; // QA_FLAG_QA_MODE_ENABLE

        seed[47] |= 0x2; // checked by lv2_kernel.self and sys_init_osd.self
        seed[47] |= 0x4; // can run sys_init_osd.self from /app_home ?

        seed[51] |= 0x1; // QA_FLAG_ALLOW_NON_QA
        seed[51] |= 0x2; // QA_FLAG_FORCE_UPDATE
    }

    hmac_sha1(hmac, 0x40, seed, 60, seed + 60);
    aescbccfb_enc(token, seed, 0x50, erk, 0x100, iv_qa);

    DPRINTF("QA Flag: %s...\n", (value) ? "Enabling" : "Disabling");

    lv1_patches();

    struct ps3dm_scm_write_eeprom write_eeprom;
    int len;
    u8 *p = (u8*)&write_eeprom;
    u64 laid, paid, vuart_lpar_addr, muid, nwritten;

    if(lv1_allocate_memory(4096, 0x0C, 0, 0, &vuart_lpar_addr, &muid) != 0)
    {
        restore_patches();
        return 2;
    }

    if(mm_map_lpar_memory_region(vuart_lpar_addr, HV_BASE, HV_SIZE2, HV_PAGE_SIZE, 0) != 0)
    {
        restore_patches();
        return 2;
    }

    laid = 0x1070000002000001ULL;
    paid = 0x1070000033000001ULL;

    memset(&write_eeprom, 0, sizeof(write_eeprom));

    ps3dm_init_header(&write_eeprom.dm_hdr, 1, PS3DM_FID_SCM,
        sizeof(write_eeprom)    -    sizeof(struct ps3dm_header),
        sizeof(write_eeprom)    -    sizeof(struct ps3dm_header));

    ps3dm_init_ss_header(&write_eeprom.ss_hdr, PS3DM_PID_SCM_WRITE_EEPROM, laid, paid);
    write_eeprom.offset = 0x48D3E;
    write_eeprom.nwrite = 0x50;
    write_eeprom.buf_size = 0x50;
    memset(write_eeprom.buf, 0, sizeof(write_eeprom.buf));
    memcpy(write_eeprom.buf, token, 0x50);
    len = sizeof(write_eeprom);

    for(u16 n = 0; n < len ; n += 8)
    {
        static u64 value;
        memcpy(&value, &p[n], 8);
        lv1_poked2((u64) n, value);
        __asm__("sync");
        memcpy(&value, (void *)0x8000000000000000ULL, 8);
    }

    if(lv1_write_virtual_uart(10, vuart_lpar_addr, len, &nwritten) != 0)
    {
        restore_patches();
        return 2;
    }

    nwritten = len;

    update_mgr_write_eeprom(QA_FLAG_OFFSET, (value) ? 0x00 : 0xFF, LV2_AUTH_ID);

    DPRINTF("QA Flag: %s\n", (value) ? "Enabled (Value: 0x00)" : "Disabled (Value: 0xFF)");
 
    restore_patches();

    return 0;
}


qa.h
Code:
#ifndef _QA_H
#define _QA_H

#define SHA_BLOCKSIZE        (64)
#define SHA_DIGEST_LENGTH    (20)

#define PS3DM_PID(fid, id)    ((fid) | (id))
#define PS3DM_FID(pid)        ((pid) & ~0xffful)

#define UM_PATCH_OFFSET     0x80000000000FEBD4ULL
#define DM_PATCH1_OFFSET    0x800000000016FA64ULL
#define DM_PATCH2_OFFSET    0x800000000016FA88ULL
#define DM_PATCH3_OFFSET    0x800000000016FB00ULL
#define DM_PATCH4_OFFSET    0x800000000016FB08ULL

#define HV_SIZE2            0x001000
#define HV_PAGE_SIZE        0x0C

#define TOKEN_SIZE          0x50
#define IDPS_SIZE           0x10

#define QA_FLAG_OFFSET      0x48C0A

enum ps3dm_function_packet
{
    /* SC manager */
    PS3DM_FID_SCM                    = 0x00009000,
    PS3DM_PID_SCM_GET_REGION_DATA    = PS3DM_PID(PS3DM_FID_SCM, 6),
    PS3DM_PID_SCM_READ_EEPROM        = PS3DM_PID(PS3DM_FID_SCM, 0xB),
    PS3DM_PID_SCM_WRITE_EEPROM       = PS3DM_PID(PS3DM_FID_SCM, 0xC),
};

struct ps3dm_header
{
    uint32_t tag;
    uint32_t fid;            /* enum ps3dm_function_packet */
    uint32_t payload_length;
    uint32_t reply_length;
};

struct ps3dm_ss_header
{
    uint64_t pid;            /* enum ps3dm_function_packet */
    uint64_t fid;            /* enum ps3dm_function_packet */
    uint32_t status;
    uint8_t res[4];
    uint64_t laid;
    uint64_t paid;
};

struct ps3dm_scm_write_eeprom
{
    struct ps3dm_header dm_hdr;
    struct ps3dm_ss_header ss_hdr;
    u32 offset;
    u8 res1[4];
    u32 nwrite;
    u8 res2[4];
    u64 buf_size;
    u8 buf[0x50];
};

static inline void ps3dm_init_header(struct ps3dm_header *hdr, uint32_t tag, uint32_t fid, uint32_t payload_length, uint32_t reply_length)
{
    hdr->tag = tag;
    hdr->fid = fid;
    hdr->payload_length = payload_length;
    hdr->reply_length = reply_length;
}

static inline void ps3dm_init_ss_header( struct ps3dm_ss_header *hdr, uint64_t pid, uint64_t laid, uint64_t paid)
{
    hdr->pid = pid;
    hdr->fid = PS3DM_FID(pid);
    hdr->laid = laid;
    hdr->paid = paid;
}

static inline u64 lv1_peekd2(u64 addr)
{
    return *(u64 *)(HV_BASE + addr);
}

static inline void lv1_poked2(u64 addr, u64 value)
{
    *(u64 *)(HV_BASE + addr) = value;
}

uint8_t read_qa_flag();
int set_qa_flag(uint8_t value);

#endif /* _QA_H */


main.c
Code:
//----------
//QA
//----------
case PS3MAPI_OPCODE_CHECK_QA:
    return read_qa_flag();
break;
case PS3MAPI_OPCODE_ENABLE_QA:
    return set_qa_flag(1);
break;
case PS3MAPI_OPCODE_DISABLE_QA:
    return set_qa_flag(0);
break;
 
Last edited:
Awesome job, dear Nathan @Evilnat !!

Now that you're making great improvements to Cobra, could you check also a bug related with CFW2OFW games?

The issue reported is that these kind of games fail to launch if there is another game mounted in /dev_bdvd.
If the user unmounts the game, the CFW2OFW converted game works.

It's looks like a conflict between the content in /dev_bdvd and the files of the CFW2OFW game stored in /dev_hdd0/game.

These type of games can detected because they contain the file /dev_hdd0/game/*********/LICDIR/LIC.EDAT

The issue cannot be fixed by webMAN MOD, because the CFW2OFW game is launched directly from XMB.

I think a hook must be created (or maybe use open_path_hook) to detect /LICDIR/LIC.EDAT and call sys_storage_ext_umount_discfile();

I tried doing this but I failed to make it work. I'm sure you can fix it.
 
Awesome job, dear Nathan @Evilnat !!

Now that you're making great improvements to Cobra, could you check also a bug related with CFW2OFW games?

The issue reported is that these kind of games fail to launch if there is another game mounted in /dev_bdvd.
If the user unmounts the game, the CFW2OFW converted game works.

It's looks like a conflict between the content in /dev_bdvd and the files of the CFW2OFW game stored in /dev_hdd0/game.

These type of games can detected because they contain the file /dev_hdd0/game/*********/LICDIR/LIC.EDAT

The issue cannot be fixed by webMAN MOD, because the CFW2OFW game is launched directly from XMB.

I think a hook must be created (or maybe use open_path_hook) to detect /LICDIR/LIC.EDAT and call sys_storage_ext_umount_discfile();

I tried doing this but I failed to make it work. I'm sure you can fix it.
Sure I'll take a look and hope I can fix it. Can i try to reproduce the issue on CFW? Didn't use CFW2OFW games before.
 
Sure I'll take a look and hope I can fix it. Can i try to reproduce the issue on CFW? Didn't use CFW2OFW games before.

I think it should be possible to reproduce on CFW, but you'll have to build your own CFW2OFW game first. Most disc games with updates can be converted, so I think you probably can find one of those games in your collection.
Just check the compatibility list so you don't waste time: https://www.psdevwiki.com/ps3/CFW2OFW_Compatibility_List
 
Thank you, still no luck I'm afraid
Ok this problem is also fixed sometimes by 1st Uninstalling webman from your ps3, then boot your PS3 into safe mode but this time select option 4 to Rebuild Database. Once done before you reinstall webman again try your BD drive and see if it works.
 
@Evilnat FYI I have been updating COBRA with your latest changes, in case that you want ot try it again.
https://downgit.github.io/#/home?url=https://github.com/aldostools/COBRA/tree/master/487/REX

One of the features in Cobra 8.3 that I don't see in your implementation is the "partial" map path.
This feature let you redirect one path to another containing only the files that need to be replaced. It's like a "patch" or "addition" folder.
For instance, if I redirect "/dev_hdd0/tmp/wm_icons" to "//dev_hdd0/more_icons", I can download from "wm_icons" the files in "more_icons", in addition to the ones in "wm_icons". The "//" in the redirected path indicates that it is a "partial map path" folder.

https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/mappath.c#L424-L438
Code:
if(map_table[i].newpath[1] == '/') // double //
{
    CellFsStat stat;
    if(cellFsStat(map_table[i].newpath, &stat) != CELL_FS_SUCCEEDED)
    {
        #ifdef DEBUG
        DPRINTF("open_path %s\n", path0);
        #endif
        avoid_recursive_calls = 0;
        return; // Do not remap / Use the original file when redirected file does not exist
    }
}

BTW CELL_FS_SUCCEEDED is a new define declared in io.h
https://github.com/aldostools/COBRA/blob/master/487/REX/lv2/include/lv2/io.h#L9
 
Last edited:
@Evilnat: These are 4 additional features found in my fork:

1- Protect map path from deletion if redirected path starts with /./
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/mappath.c#L59-L63

Backup managers clean the map paths when they start. This is useful to prevent accidental deletion of important map paths.
I use /./ (and // for partial map path) to maintain the original function interface and keep backward compatibility.

2- Another feature (maybe you don't want to add it) is support for spoof ISO as PNG.
The code involves the addition of the variable base_offset. The change is found in various lines of these 2 modules:
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/storage_ext.c
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/psp.c

In summary, it allows an ISO to start at offset 0x10000. So the first 64KB can be used to stored the cover, CONFIG, PARAM.SFO, etc.

The spoof ISO can be mounted using the PhotoGUI feature and has the advantage that the files can be copied from USB to HDD (and viceversa) using the standard copy function of XMB. The GameOS treats the ISO as Photo because the headers are a valid picture.

3- Auto mount dev_blind allows to use the lmn7's make custom packages to install patches directly in /dev_blind without forcing the user to enable /dev_blind. The feature can be disabled if the user doesn't want it.
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/homebrew_blocker.h#L180-L191

4- make_rif only creates new rif files from rap. Original implementation recreate the rif every time the game is launched.
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/make_rif.h#L180

If the user needs to re-create a rif (which is rarely needed), just need to go to system update, go back and launch the game again.
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/homebrew_blocker.h#L202

BTW These features are implemented and tested in MAMBA 8.4
 
Last edited:
@Evilnat These issues are not very important, but I think they should be fixed at some point:

1- Opcodes SYSCALL8_OPCODE_RUN_PAYLOAD and SYSCALL8_OPCODE_RUN_PAYLOAD_DYNAMIC return inconsistent results. In your fork:
SYSCALL8_OPCODE_RUN_PAYLOAD returns 0 (SUCCEEDED) if the payload is loaded and -1 or -2 if failed.
SYSCALL8_OPCODE_RUN_PAYLOAD_DYNAMIC returns 1 if the payload is loaded and 0, -1 or -2 if failed.

I changed SYSCALL8_OPCODE_RUN_PAYLOAD_DYNAMIC to return 0 (SUCCEEDED) instead of 1. If not loaded returns -1.
https://github.com/aldostools/COBRA/blob/master/487/REX/stage2/kernel_payload.h#L49

2- Opcode SYSCALL8_OPCODE_UNLOAD_PAYLOAD_DYNAMIC does not check for NULL. It may freeze if not called properly.

3- The modules drm.c, permissions.c, laboratory.c & cobra.c can be removed or moved to another place. They are useless.
  • drm.c was used to generate a random code for the USB dongle.
  • permissions.c was used to make the Cobra process invisible to other processes.
  • cobra.c was used for the USB dongle.
  • laboratory.c was experimental code used by devs of Cobra Team. Not used.
I moved them to an "unused" folder. MAMBA already have these modules removed.

4- What do you think if we add Fan Control also to nonCobra payload?
It would use the Cobra settings. So it can be enabled/disabled. See attachment.
 

Attachments

If we are brainstorming here, would it be possible to redirect /dev_hdd0/home/0000000x/savedata to /dev_usb000/home/0000000x/savedata ? So you can have all your save files to a usb stick?

I have two ps3 consoles, my first was banned, so i use the same idps on both consoles and i may be playing a game on my living room and the other day on my bedroom.

Just an idea and an example, not really rushing for.
 
If we are brainstorming here, would it be possible to redirect /dev_hdd0/home/0000000x/savedata to /dev_usb000/home/0000000x/savedata ? So you can have all your save files to a usb stick?

I have two ps3 consoles, my first was banned, so i use the same idps on both consoles and i may be playing a game on my living room and the other day on my bedroom.

Just an idea and an example, not really rushing for.
I think with map_path it's possible. My hope is @Evilnat can patch the CEX VSH to support Fake Save Data Owner, so we can use "save data" for all PS3 (users) like PS2.
 
@aldostools I fixed CFW2OFW games, but there is a minor issue (but it is not important).

As i could see, if there is a JB folder game mounted and you try to launch a CFW2OFW game, the result is black screen. This doesn't happen with ISOs (at least it has not given me problems).

I have used a backup of my games:
  • Disgaea D2: Brighter Darkness (BLES01939) converted to CFW2OFW game
  • Disgaea 3: Absence of Justice (BLES00452) used only to cause black screen
  • Disgaea 4: A Promise Unforgotten (DISC GAME)
Yes i know, i love Disgaea games :D

The piece of code i used is very small, after my second attempt it looks like this (sys_storage_ext_umount_discfile() didn't work):

mappath.c
Code:
int CEX2OFW_game = 0; (extern in mappath.h)

LV2_HOOKED_FUNCTION_POSTCALL_2(void, open_path_hook, (char *path0, int mode))
{
    int path_len = strlen(path0);

    if(!strncmp(path, "/dev_hdd0/game/", 15) && !strcmp(path + path_len - 8, "LIC.EDAT"))
        CEX2OFW_game = 1;

.........

storage_ext.c
Code:
LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, post_cellFsUtilMount, (const char *block_dev, const char *filesystem, const char *mount_point, int unk, int read_only, int unk2, char *argv[], int argc))
{
    #ifdef DEBUG
        DPRINTF("cellFsUtilMount: %s\n", mount_point);
    #endif

    if(!strcmp(mount_point, "/dev_bdvd/PS3_GAME") && CEX2OFW_game)
    {
        DPRINTF("Detected CEX2OFW game\n");

        map_path("/dev_bdvd/PS3_GAME", NULL, 0);
        map_path("/app_home/PS3_GAME", NULL, 0);
        map_path("/dev_bdvd", NULL, 0);
        map_path("//dev_bdvd", NULL, 0);
        map_path("/app_home", NULL, 0);
        map_path("//app_home", NULL, 0);

        CEX2OFW_game =  0;
    }

........

The code works and i can launch Disgaea D2 with Disgaea 3 mounted, but there is an inconvenient.

After returning to the XMB the previous game mounted with webMAN MOD (and maybe with ManaGunZ too, i have not tried it) is unmounted but the game title and maybe mapped path remains, it can't be launched giving error. To "fix" this you need to eject the disc and insert again or mount another game as usual.

This is not really an issue but maybe there is more methods to fix it.

This doesn't happen with multiMAN, is working perfect with it, the mounted game disappears completely and it let me launch Disgaea 4 from disc after returning to the XMB.

I don't know if this must be imported in Cobra 8.3 yet, what do you think @aldostools?
 
Last edited:
Also call sys_storage_ext_umount_discfile();
that is the same function called by the opcode SYSCALL8_OPCODE_UMOUNT_DISCFILE


@aldostools I fixed CFW2OFW games, but there is a minor issue (but it is not important).

The code works and i can launch Disgaea D2 with Disgaea 3 mounted, but there is an inconvenient.

After returning to the XMB the previous game mounted with webMAN MOD (and maybe with ManaGunZ too, i have not tried it) is unmounted but the game title and maybe mapped path remains, it can't be launched giving error. To "fix" this you need to eject the disc and insert again or mount another game as usual.

This is not really an issue but maybe there is more methods to fix it.

This doesn't happen with multiMAN, is working perfect with it, the mounted game disappears completely and it let me launch Disgaea 4 from disc after returning to the XMB.

I don't know if this must be imported in Cobra 8.3 yet, what do you think @aldostools?

IMO this fix could be included in Cobra 8.3 even if the unmount methods suggested above don't work.
 
Last edited:
this is just an idea I don't know if it will fix you issue, try to eject and insert virtually after unmaping /dev_bdvd
for example :
sys_fs_unmount("/dev_bdvd");
sys_fs_mount("CELL_FS_IOS:PATA0_BDVD_DRIVE", "CELL_FS_ISO9660", "/dev_bdvd", 1);
That's what i tried the first attempt, crashes LV2.

After some research i finally fixed it completely @aldotsools but first of all, we can't remove permissions.c because multiMAN is calling sys_permissions_get_access through SYSCALL8_OPCODE_GET_ACCESS, or we can move it to another file and remove permissions.c.

Let's start with the explanation and code:

We need to check if the game we are launching is a CFW2OFW game, like @aldostools said, this games have a file called LIC.EDAT, i'm checking if the hooked path is in /dev_hdd0/game/ and if it have the file LIC.EDAT. After that i set the variable CFW2OFW_game as 1 if the game is CFW2OFW.

mappath.c
Code:
int CFW2OFW_game = 0; // Extern in mappath.h

LV2_HOOKED_FUNCTION_POSTCALL_2(void, open_path_hook, (char *path0, int mode))
{
    // CFW2OFW fix by Evilnat
    int path_len = strlen(path0);
    if(!strncmp(path0, "/dev_hdd0/game/", 15) && !strcmp(path0 + path_len - 8, "LIC.EDAT"))
        CFW2OFW_game = 1;

..........
}

We need to hook cellFsUtilMount and catch /dev_bdvd/PS3_GAME mount event and check if CFW2OFW value is 1, after that we call sys_storage_ext_umount_discfile(); and unmap the following paths:
  • /dev_bdvd/PS3_GAME
  • /app_home/PS3_GAME
  • /dev_bdvd
  • //dev_bdvd
  • /app_home
  • //app_home
This will fix black screen while CFW2OFW game is booting. I'm disabling unhook of post_cellFsUtilMount, we need it (or hook a new cellFsUtilMount).

storage_ext.c
Code:
LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, post_cellFsUtilMount, (const char *block_dev, const char *filesystem, const char *mount_point, int unk, int read_only, int unk2, char *argv[], int argc))
{
    #ifdef DEBUG
        DPRINTF("cellFsUtilMount: %s\n", mount_point);
    #endif

    if(!strcmp(mount_point, "/dev_bdvd/PS3_GAME") && CFW2OFW_game)
    {
        // CFW2OFW fix by Evilnat
        // Fixes black screen while a CFW2OFW game is loaded with a mounted JB folder game
        #ifdef DEBUG
            DPRINTF("Detected CFW2OFW game\n");
        #endif

        sys_storage_ext_umount_discfile();
        map_path("/dev_bdvd/PS3_GAME", NULL, 0);
        map_path("/app_home/PS3_GAME", NULL, 0);
        map_path("/dev_bdvd", NULL, 0);
        map_path("//dev_bdvd", NULL, 0);
        map_path("/app_home", NULL, 0);
        map_path("//app_home", NULL, 0);
    }

    if (!hdd0_mounted && strcmp(mount_point, "/dev_hdd0") == 0 && strcmp(filesystem, "CELL_FS_UFS") == 0)
    {
        ......... 
 
        /*#ifndef DEBUG
            unhook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8); // Hook no more needed
        #endif*/
    }
}


By last, once we quit the game we need to catch process mcore.self (as i could see this is one of the first files the PS3 load while the XMB is loading) and check if CFW2OFW is 1, and if all is true the last step is reset the disc in BD Drive (If there were any) with restore_BD(); (defined in storage_ext.c), and set the variable CFW2OFW to 0. I'm disabling unhook of load_process_hooked, we need it (or hook a new load_process_hooked).

modulespatch.c
Code:
void restore_BD()
{
    mutex_lock(mutex, 0);
    unsigned int disctype = get_disc_type();
    fake_reinsert(disctype);
    mutex_unlock(mutex);
}

LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, load_process_hooked, (process_t process, int fd, char *path, int r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t sp_70))
{
    #ifdef DEBUG
        DPRINTF("PROCESS %s (%08X) loaded\n", path, process->pid);
    #endif
 
    if (!vsh_process)
    {
        ........
    }

    // CFW2OFW fix by Evilnat
    // Restores disc in BD drive, this fixes leftovers of previous game mounted
    if (!strcmp(path, "/dev_flash/vsh/module/mcore.self") && CFW2OFW_game)
    {
        #ifdef DEBUG
            DPRINTF("Resetting BD Drive after CFW2OFW game...\n");
        #endif

        restore_BD();
        CFW2OFW_game =  0;
    }

    /*#ifndef DEBUG
    if (vsh_process)
        unhook_function_on_precall_success(load_process_symbol, load_process_hooked, 9); // Hook no more needed
    #endif*/

    return 0;
}

And finally we are in the XMB with the previous game unmounted and with our disc in BD Drive.

I tested it on my PS3 with discs of PSX, PS2, PS3, BD Movie and mounted ISO and JB format folder and it worked fine, it is not tested with noBD patches or broken BD.

Here it is my Cobra repo with all the changes: https://github.com/Evilnat/Cobra-PS...43a33edfd80ab3bd26b0d6d99a381d9637152e2625daa
 
Last edited:
That's what i tried the first attempt, crashes LV2.

After some research i finally fixed it completely @aldotsools but first of all, we can't remove permissions.c because multiMAN is calling sys_permissions_get_access through SYSCALL8_OPCODE_GET_ACCESS, or we can move it to another file and remove permissions.c.

Let's start with the explanation and code:

We need to check if the game we are launching is a CFW2OFW game, like @aldostools said, this games have a file called LIC.EDAT, i'm checking if the hooked path is in /dev_hdd0/game/ and if it have the file LIC.EDAT. After that i set the variable CFW2OFW_game as 1 if the game is CFW2OFW.

mappath.c
Code:
int CFW2OFW_game = 0; // Extern in mappath.h

LV2_HOOKED_FUNCTION_POSTCALL_2(void, open_path_hook, (char *path0, int mode))
{
    // CFW2OFW fix by Evilnat
    int path_len = strlen(path0);
    if(!strncmp(path0, "/dev_hdd0/game/", 15) && !strcmp(path0 + path_len - 8, "LIC.EDAT"))
        CFW2OFW_game = 1;

..........
}

We need to hook cellFsUtilMount and catch /dev_bdvd/PS3_GAME mount event and check if CFW2OFW value is 1, after that we call sys_storage_ext_umount_discfile(); and unmap the following paths:
  • /dev_bdvd/PS3_GAME
  • /app_home/PS3_GAME
  • /dev_bdvd
  • //dev_bdvd
  • /app_home
  • //app_home
This will fix black screen while CFW2OFW game is booting. I'm disabling unhook of post_cellFsUtilMount, we need it (or hook a new cellFsUtilMount).

storage_ext.c
Code:
LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, post_cellFsUtilMount, (const char *block_dev, const char *filesystem, const char *mount_point, int unk, int read_only, int unk2, char *argv[], int argc))
{
    #ifdef DEBUG
        DPRINTF("cellFsUtilMount: %s\n", mount_point);
    #endif

    if(!strcmp(mount_point, "/dev_bdvd/PS3_GAME") && CFW2OFW_game)
    {
        // CFW2OFW fix by Evilnat
        // Fixes black screen while a CFW2OFW game is loaded with a mounted JB folder game
        #ifdef DEBUG
            DPRINTF("Detected CFW2OFW game\n");
        #endif

        sys_storage_ext_umount_discfile();
        map_path("/dev_bdvd/PS3_GAME", NULL, 0);
        map_path("/app_home/PS3_GAME", NULL, 0);
        map_path("/dev_bdvd", NULL, 0);
        map_path("//dev_bdvd", NULL, 0);
        map_path("/app_home", NULL, 0);
        map_path("//app_home", NULL, 0);
    }

    if (!hdd0_mounted && strcmp(mount_point, "/dev_hdd0") == 0 && strcmp(filesystem, "CELL_FS_UFS") == 0)
    {
        .........
 
        /*#ifndef DEBUG
            unhook_function_on_precall_success(cellFsUtilMount_symbol, post_cellFsUtilMount, 8); // Hook no more needed
        #endif*/
    }
}


By last, once we quit the game we need to catch process mcore.self (as i could see this is one of the first files the PS3 load while the XMB is loading) and check if CFW2OFW is 1, and if all is true the last step is reset the disc in BD Drive (If there were any) with restore_BD(); (defined in storage_ext.c), and set the variable CFW2OFW to 0. I'm disabling unhook of load_process_hooked, we need it (or hook a new load_process_hooked).

modulespatch.c
Code:
void resto++re_BD()
{
    mutex_lock(mutex, 0);
    unsigned int disctype = get_disc_type();
    fake_reinsert(disctype);
    mutex_unlock(mutex);
}

LV2_HOOKED_FUNCTION_PRECALL_SUCCESS_8(int, load_process_hooked, (process_t process, int fd, char *path, int r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t sp_70))
{
    #ifdef DEBUG
        DPRINTF("PROCESS %s (%08X) loaded\n", path, process->pid);
    #endif
 
    if (!vsh_process)
    {
        ........
    }

    // CFW2OFW fix by Evilnat
    // Restores disc in BD drive, this fixes leftovers of previous game mounted
    if (!strcmp(path, "/dev_flash/vsh/module/mcore.self") && CFW2OFW_game)
    {
        #ifdef DEBUG
            DPRINTF("Resetting BD Drive after CFW2OFW game...\n");
        #endif

        restore_BD();
        CFW2OFW_game =  0;
    }

    /*#ifndef DEBUG
    if (vsh_process)
        unhook_function_on_precall_success(load_process_symbol, load_process_hooked, 9); // Hook no more needed
    #endif*/

    return 0;
}

And finally we are in the XMB with the previous game unmounted and with our disc in BD Drive.

I tested it on my PS3 with discs of PSX, PS2, PS3, BD Movie and mounted ISO and JB format folder and it worked fine, it is not tested with noBD patches or broken BD.

Here it is my Cobra repo with all the changes: https://github.com/Evilnat/Cobra-PS...43a33edfd80ab3bd26b0d6d99a381d9637152e2625daa

Excellent job Nathan!
Just a minor suggestion: C uses short circuit evaluation. If you first check CFW2OFW_game is more efficient:

post_cellFsUtilMount:

if(CFW2OFW_game && !strcmp(mount_point, "/dev_bdvd/PS3_GAME"))

load_process_hooked:
if (CFW2OFW_game && !strcmp(path, "/dev_flash/vsh/module/mcore.self"))

In regards to permissions.c, multiMAN is calling sys_permissions_get_access (aka SYSCALL8_OPCODE_GET_ACCESS) when it calls cobra_lib_init(). It basically checks that it returns 0.

multiman.cpp:
upload_2021-2-11_8-2-42.png


cobra_lib calls stage2 through sys_permission_get_access() using SYSCALL8_OPCODE_GET_ACCESS:
upload_2021-2-11_8-15-37.png


upload_2021-2-11_8-14-0.png


In permissions.c the function sys_permissions_get_access() sets the variable access_pid with the process id of stage2.

That variable *was* used in the hook permissions_func_hook to restrict the access to cobra process. That hook is commented out.
upload_2021-2-11_8-28-45.png


The variable access_pid is also used in get_pid_patched() to spoof cobra process id returning vsh_process->pid;

IMO The following opcodes can be simplified like this (instead of call their original functions):
Code:
case SYSCALL8_OPCODE_GET_ACCESS:
case SYSCALL8_OPCODE_REMOVE_ACCESS:
case SYSCALL8_OPCODE_COBRA_USB_COMMAND:
    return 0; // deprecated opcodes
break;

case SYSCALL8_OPCODE_DRM_GET_DATA:
case SYSCALL8_OPCODE_VSH_SPOOF_VERSION:
    return ENOSYS; // deprecated opcodes
 

Featured content

Trending content

Back
Top