7/06/2006

use ipl_update to make FW 1.5 -> 1.0 (proof of concept)


CAUTION :
 人柱版。实验用。超危险。无保证,责任自负。
 任何事也会发生。最好避免使用。
 安全出口 → http://www.playstation.jp/psp/

 人柱版。実験用。超危険。無保証自己責任。
 なにが起きても知りません。避けて通るのが吉。
 非常出口 → http://www.playstation.jp/psp/

 To sacrifice yourself. Experimental. Extremely dangerous.
 No warranty. Use on your own risk and responsibility.
 Anything may happen. We recommend you to avoid seeing/downloading/using this.
 Emergency exit -> http://www.playstation.jp/psp/
 * this CAUTION copy from SEC(nem) :p


if you dont know exactly what it does and what you could use it for by looking at the posted code, forget it. you dont need it at all.

Don't use "IPL Data" from "ridge racers's kbooti.bin", it will brick your PSP !!!


// -------------------------------------------
// most of code from moonlight & PspPet
//
// * FW1.00 DownDate *
// Written by 0okm
// -------------------------------------------
#include <pspkernel.h>
#include <pspsdk.h>
#include <psptypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pspdebug.h>
#include <pspctrl.h>

PSP_MODULE_INFO("FW100_DownDate", 0x1000, 1, 1);

PSP_MAIN_THREAD_ATTR(0);

PSP_HEAP_SIZE_KB(0);

#define printf pspDebugScreenPrintf

int (* sceIplUpdateClearIpl)(void);
int (* sceIplUpdateSetIpl)(void);

/*** This function from PspPet PSARDUMPER ***/
static u32 FindProc(const char* szMod, const char* szLib, u32 nid)
{
    SceModule* modP = sceKernelFindModuleByName(szMod);
    if (modP == NULL)
    {
//        printf("Failed to find mod '%s'\n", szMod);
        return 0;
    }
    SceLibraryEntryTable* entP = (SceLibraryEntryTable*)modP->ent_top;
    while ((u32)entP < ((u32)modP->ent_top + modP->ent_size))
    {
        if (entP->libname != NULL && strcmp(entP->libname, szLib) == 0)
        {
            // found lib
            int i;
            int count = entP->stubcount + entP->vstubcount;
            u32* nidtable = (u32*)entP->entrytable;
            for (i = 0; i < count; i++)
            {
                if (nidtable[i] == nid)
                {
                    u32 procAddr = nidtable[count+i];
//                    printf("entry found: '%s' '%s' = $%x\n", szMod, szLib, (int)procAddr);
                    return procAddr;
                }
            }
//            printf("Found mod '%s' and lib '%s' but not nid=$%x\n", szMod, szLib, nid);
            return 0;
        }
        entP++;
    }
//    printf("Found mod '%s' but not lib '%s'\n", szMod, szLib);
    return 0;
}

void ErrorExit(char *error)
{
    printf("%s\n", error);
    sceKernelDelayThread(15 * 1000 * 1000);
    sceKernelExitGame();
}

char inputlist[12*1024], outputlist[12*1024];
char buffer[8192];

void downdate()
{
    SceUID inp = sceIoOpen("ms0:/FW100DOWNDATE/inputfl.bin", PSP_O_RDONLY, 0777);
    SceUID outp = sceIoOpen("ms0:/FW100DOWNDATE/outputfl.bin", PSP_O_RDONLY, 0777);

    if (inp < 0 || outp < 0)
        ErrorExit("Error Open file.\n");

    if (sceIoRead(inp, inputlist, 12*1024) <= 0)
    {
        sceIoClose(inp);
        ErrorExit("Error Read inputfl.bin file.\n");
    }

    if (sceIoRead(outp, outputlist, 12*1024) <= 0)
    {
        sceIoClose(outp);
        ErrorExit("Error Read outputfl.bin file.\n");
    }

    sceIoClose(inp);
    sceIoClose(outp);

    char *p = inputlist;
    while (*p != 0)
    {
        SceUID fd = sceIoOpen(p, PSP_O_RDONLY, 0777);
        if (fd < 0)
            ErrorExit("Error Read Flash file.\n");
        sceIoClose(fd);
        p += strlen(p)+1;
    }

    if(sceIoUnassign("flash0:") < 0)
    {
        ErrorExit("Error sceIoUnassign flash0\n");
    }
    if(sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", 0, IOASSIGN_RDWR , 0) < 0)
    {
        ErrorExit("Error sceIoAssign flash0\n");
    }

    char *src = inputlist;
    char *dst = outputlist;
    SceUID infd, outfd;
    int bytesread, totalwritten = 0;

    while (*src != 0)
    {
        infd = sceIoOpen(src, PSP_O_RDONLY, 0777);
        outfd = sceIoOpen(dst, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
        if (infd < 0)
        {
            ErrorExit("Error in file.\n");
        }
        if (outfd < 0)
        {
            ErrorExit("Error out file.\n");
        }
        while ((bytesread = sceIoRead(infd, buffer, 8192)) > 0)
        {
            totalwritten += sceIoWrite(outfd, buffer, bytesread);
        }
        sceIoClose(infd);
        sceIoClose(outfd);

        src += strlen(src)+1;
        dst += strlen(dst)+1;
    }
}

int main()
{
    pspDebugScreenInit();

    printf("FW100 DownDate V1.05\n");
    printf("most of code from moonlight & PspPet :)\n\n");

    SceKernelModuleInfo modinfo;
    u32 base;
    SceUID fd;
    SceUID mod;

    mod = sceKernelLoadModule("ms0:/FW100DOWNDATE/FW150_ipl_update.prx", 0, NULL);
    if (mod < 0)
        ErrorExit("Error loading module.\n");

    if(sceKernelDevkitVersion() == 0x01000300)
    {
        if (pspSdkQueryModuleInfoV1(mod, &modinfo) < 0)
            ErrorExit("Cannot query module info.\n");
    }
    else if(sceKernelDevkitVersion() == 0x01050001)
    {
        if (sceKernelQueryModuleInfo(mod, &modinfo) < 0)
            ErrorExit("Cannot query module info.\n");
    }
    else
    {
            ErrorExit("Cannot query module info.\n");
    }

    base = modinfo.text_addr;
//    printf("modinfo.text_addr : %.8X\n", modinfo.text_addr);

        fd = sceIoOpen("ms0:/FW100DOWNDATE/FW100_ipl.bin", PSP_O_RDONLY, 0777);
        if (fd < 0)
            ErrorExit("Cannot read IPL Data\n");
        printf("Reading IPL Data...\n\n");
        sceIoRead(fd, (void *)(base+0x900), 0x37000);
        sceIoClose(fd);

    mod = sceKernelStartModule(mod, 0, NULL, NULL, NULL);
    if (mod < 0)
        ErrorExit("Error Start module.\n");
    sceIplUpdateClearIpl = (void *)FindProc("IplUpdater", "sceIplUpdate_driver", 0x26093B04); //FW1.50 0x8822753c
    sceIplUpdateSetIpl = (void *)FindProc("IplUpdater", "sceIplUpdate_driver", 0xEE7EB563); //FW1.50 0x88227500

    printf("Pass [CIRCLE] to start DownDate, Pass [CROSS] to EXIT\n");
    SceCtrlData pad;
    sceCtrlSetSamplingCycle(0);
    sceCtrlSetSamplingMode(0);
    while(1)
    {
        sceCtrlReadBufferPositive(&pad, 1);
        if (pad.Buttons & PSP_CTRL_CIRCLE)
        {
            printf("start FW1.00 Ipl DownDate\n");
            sceIplUpdateClearIpl();
            sceIplUpdateSetIpl();

            printf("start FW1.00 Flash0 DownDate\n");
            downdate();

            ErrorExit("Finished. Exiting in 15 seconds\n");
        }
        if (pad.Buttons & PSP_CTRL_CROSS)
        {
            sceKernelExitGame();
        }
    }

    return 0;
}

i tested it on PSP FW1.50
and make FW1.50 -> FW1.00 :P

more information
FW100_ipl_update
http://forums.ps2dev.org/viewtopic.php?t=6153

About the 1.00 downgrade idea
http://mphwebsite.tuxfamily.org/punBB/viewtopic.php?pid=12110

sceLflashFatfmtStartFatfmt
http://forums.ps2dev.org/viewtopic.php?p=41886&highlight=iplupdate#41886

0 Comments:

Post a Comment

<< Home