diff --git a/readme.txt b/readme.txt index b878a45..0ccbe7f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,11 +1,20 @@ Chronoswitch Downgrader -http://lolhax.org +https://lolhax.org + +[VERSION 7.0] + -> Added support for Infinity + +[VERSION 6.1] + -> Added support for 11g units to 6.60 + +[VERSION 6] + -> Added support for 6.61 [VERSION 5] - -> Added support for 09g units to 6.20 + -> Added support for 09g units to 6.20 [What does it do?] -Allows users who are incontent with their firmware to downgrade to 6.20 using the Sony Updater. +Allows users to downgrade their PSP using the Sony Updater. [How do I use it?] Copy the "PSP" folder to your PSP. The downgrader is "signed" and can be launched from OFW XMB. You need to copy the 6.20 update to PSP/GAME/UPDATE/EBOOT.PBP and for PSPgo it must be the eflash it is placed on. After setup run the downgrader and follow the onscreen instructions. @@ -14,9 +23,7 @@ Copy the "PSP" folder to your PSP. The downgrader is "signed" and can be launche 6.20-6.35: It uses the utility/power exploit to gain kernel access and reboots into the updater with a special PRX running. This PRX uses the pspdecrypt functionality to decrypt the updater PRX when needed. This allows the updater to boot in the newer firmwares. 6.38/6.39: It uses my http_storage exploit to gain kernel access. Basically, http_storage has a vulnerability in it, where I can write -1 to anywhere in memory. 6.60: Uses sceNetMPulldown to gain kernel access. - -[I'm a dev, sup?] -Source code included in package. +6.61: same as 6.60 (only certloader kexploit is patched in 6.61) [Credits] Davee - legend. Originally made 6.35/6.31 downgrader @@ -26,6 +33,13 @@ coyotebean - legend. Coninuted updates to psardumper (pspdecrypt) and large infl kgsws - legend. First application signed and method released. Silverspring - legend. Lots and lots of info on KIRK where we'd still be in the dark without. Bubbletune - BTCNF injection code and bits and bobs here ;D +qwikrazor87 - 6.61/11g support. [READ] -You run the application at your OWN risk. I am not help accountable if you PSP fucks up. \ No newline at end of file +You run the application at your OWN risk. This software is free and has no warranty. + +[Open Source] +Chronoswitch is open source! Get the source here: https://bitbucket.org/DaveeFTW/ + +[Twitter] +Follow me on twitter: @DaveeFTW \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 458b3d0..a7b1c3e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,38 +1,38 @@ -all: clean clean_prx signed - -clean: clean_prx - make -f Makefile.signed clean - -clean_prx: - make -C downgrade_ctrl -f Makefile clean - make -C downgrade660_ctrl -f Makefile clean - -signed: clean_prx mk_downgrade_ctrl - make -f Makefile.signed - -hbl: clean_prx mk_downgrade_ctrl - make -f Makefile.hbl - -remove_dir: - -rmdir /S /Q RELEASE - -create_dir: - -mkdir RELEASE - -mkdir RELEASE\PSP - -mkdir RELEASE\PSP\GAME - -mkdir RELEASE\PSP\GAME\Downgrader - -mkdir RELEASE\SRC - -copy_src: - cp -dpR downgrade_ctrl\.. RELEASE\SRC - rmdir /S /Q RELEASE\SRC\RELEASE - -mk_downgrade_ctrl: - make -C downgrade_ctrl -f Makefile - make -C downgrade660_ctrl -f Makefile - -signed_release: clean clean_prx remove_dir create_dir copy_src signed - cp EBOOT.PBP RELEASE\PSP\GAME\Downgrader\EBOOT.PBP - -hbl_release: clean clean_prx remove_dir create_dir copy_src hbl +all: clean clean_prx signed + +clean: clean_prx + make -f Makefile.signed clean + +clean_prx: + make -C downgrade_ctrl -f Makefile clean + make -C downgrade660_ctrl -f Makefile clean + +signed: clean_prx mk_downgrade_ctrl + make -f Makefile.signed + +hbl: clean_prx mk_downgrade_ctrl + make -f Makefile.hbl + +remove_dir: + -rmdir /S /Q RELEASE + +create_dir: + -mkdir RELEASE + -mkdir RELEASE\PSP + -mkdir RELEASE\PSP\GAME + -mkdir RELEASE\PSP\GAME\Downgrader + -mkdir RELEASE\SRC + +copy_src: + cp -dpR downgrade_ctrl\.. RELEASE\SRC + rmdir /S /Q RELEASE\SRC\RELEASE + +mk_downgrade_ctrl: + make -C downgrade_ctrl -f Makefile + make -C downgrade660_ctrl -f Makefile + +signed_release: clean clean_prx remove_dir create_dir copy_src signed + cp EBOOT.PBP RELEASE\PSP\GAME\Downgrader\EBOOT.PBP + +hbl_release: clean clean_prx remove_dir create_dir copy_src hbl cp EBOOT.PBP RELEASE\PSP\GAME\Downgrader\EBOOT.PBP \ No newline at end of file diff --git a/src/Makefile.hbl b/src/Makefile.hbl index e4684dc..d6519df 100644 --- a/src/Makefile.hbl +++ b/src/Makefile.hbl @@ -1,21 +1,21 @@ -TARGET = downgrader -OBJS = main.o kernel_exploit.o kernel_land.o rebootex.o utils.o extras.o extra_stubs.o - -INCDIR = ../include -CFLAGS = -Os -G0 -Wall -DHBL_SUKKIRI -CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -ASFLAGS = $(CFLAGS) -c - -LIBDIR = ../lib -LIBS = -lpsppower - -PSP_FW_VERSION = 271 - -EXTRA_TARGETS = EBOOT.PBP -PSP_EBOOT_TITLE = 6.35 Downgrader - -BUILD_PRX = 1 - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - +TARGET = downgrader +OBJS = main.o kernel_exploit.o kernel_land.o rebootex.o utils.o extras.o extra_stubs.o + +INCDIR = ../include +CFLAGS = -Os -G0 -Wall -DHBL_SUKKIRI +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) -c + +LIBDIR = ../lib +LIBS = -lpsppower + +PSP_FW_VERSION = 271 + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = 6.35 Downgrader + +BUILD_PRX = 1 + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/Makefile.signed b/src/Makefile.signed index ddefdf2..97469f0 100644 --- a/src/Makefile.signed +++ b/src/Makefile.signed @@ -1,28 +1,28 @@ -release: all - bin/prxEncrypter $(TARGET).prx - pack-pbp $(EXTRA_TARGETS) PARAM.SFO icon0.png NULL NULL NULL NULL data.psp NULL - rm -f data.psp - rm -f downgrade_ctrl.h - rm -f downgrade660_ctrl.h - -TARGET = downgrader -OBJS = main.o kernel_exploit.o kernel_land.o rebootex.o utils.o extras.o extra_stubs.o - -INCDIR = ../include -CFLAGS = -Os -G0 -Wall -CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti -ASFLAGS = $(CFLAGS) -c - -LIBDIR = ../lib -LIBS = -lpsppower - -PSP_FW_VERSION = 271 - -EXTRA_TARGETS = EBOOT.PBP -PSP_EBOOT_TITLE = Chronoswitch Downgrader - -BUILD_PRX = 1 - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - +release: all + bin/prxEncrypter $(TARGET).prx + pack-pbp $(EXTRA_TARGETS) PARAM.SFO icon0.png NULL NULL NULL NULL data.psp NULL + rm -f data.psp + rm -f downgrade_ctrl.h + rm -f downgrade660_ctrl.h + +TARGET = downgrader +OBJS = main.o kernel_exploit.o kernel_land.o rebootex.o utils.o extras.o extra_stubs.o libasm/libinfinityUser.o + +INCDIR = ../include +CFLAGS = -Os -G0 -Wall +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) -c + +LIBDIR = ../lib +LIBS = -lpsppower + +PSP_FW_VERSION = 271 + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Chronoswitch Downgrader + +BUILD_PRX = 1 + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/downgrade660_ctrl/660mapfile.txt b/src/downgrade660_ctrl/660mapfile.txt index 2eddbe0..528c1ab 100644 --- a/src/downgrade660_ctrl/660mapfile.txt +++ b/src/downgrade660_ctrl/660mapfile.txt @@ -1,14 +1,14 @@ -@SysMemForKernel -0x55A40B2C:0xC4EEAF20 //NID RESOLVED -0x9697CD32:0x13F4A0DE //NID RESOLVED -0xB2C7AA36:0x83B5226D //NID RESOLVED -0x3FC9AE6A:0xC886B169 //NID RESOLVED -0x6373995D:0x07C586A1 //NID RESOLVED -@memlmd -0x7CF1CD3E:0xEF73E85B //NID RESOLVED -@LoadCoreForKernel -0xCF8A41B1:0xF6B1BF0F //NID RESOLVED -0xCCE4A157:0x40972E6E //NID RESOLVED -0xD8779AC6:0x8D46E9DF //NOT exported -@ModuleMgrForKernel -0x644395E2:0x303FAB7F //NID RESOLVED +@SysMemForKernel +0x55A40B2C:0xC4EEAF20 //NID RESOLVED +0x9697CD32:0x13F4A0DE //NID RESOLVED +0xB2C7AA36:0x83B5226D //NID RESOLVED +0x3FC9AE6A:0xC886B169 //NID RESOLVED +0x6373995D:0x07C586A1 //NID RESOLVED +@memlmd +0x7CF1CD3E:0xEF73E85B //NID RESOLVED +@LoadCoreForKernel +0xCF8A41B1:0xF6B1BF0F //NID RESOLVED +0xCCE4A157:0x40972E6E //NID RESOLVED +0xD8779AC6:0x8D46E9DF //NOT exported +@ModuleMgrForKernel +0x644395E2:0x303FAB7F //NID RESOLVED diff --git a/src/downgrade660_ctrl/Makefile b/src/downgrade660_ctrl/Makefile index c02b695..8811aaa 100644 --- a/src/downgrade660_ctrl/Makefile +++ b/src/downgrade660_ctrl/Makefile @@ -1,27 +1,27 @@ -release: all - psp-fixup-imports -m $(PSP_FW_VERSION)mapfile.txt $(TARGET).prx - psp-packer $(TARGET).prx - bin2c $(TARGET).prx ../$(TARGET).h $(TARGET) - -TARGET = downgrade660_ctrl -OBJS = main.o utils.o patch_table.o decrypt.o pspdecrypt.o extra_stubs.o - -INCDIR = ../include -CFLAGS = -Os -G0 -Wall -fno-pic -fshort-wchar -ASFLAGS = $(CFLAGS) - -BUILD_PRX = 1 -PRX_EXPORTS = exports.exp - -PSP_FW_VERSION = 660 - -USE_KERNEL_LIBS=1 -USE_KERNEL_LIBC=1 - -LIBDIR = ../lib -LDFLAGS = -nostartfiles -LIBS = -lpspsystemctrl_kernel - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - +release: all + psp-fixup-imports -m $(PSP_FW_VERSION)mapfile.txt $(TARGET).prx + psp-packer $(TARGET).prx + bin2c $(TARGET).prx ../$(TARGET).h $(TARGET) + +TARGET = downgrade660_ctrl +OBJS = main.o utils.o patch_table.o decrypt.o pspdecrypt.o extra_stubs.o ../libasm/libinfinityKernel.o + +INCDIR = ../include +CFLAGS = -Os -G0 -Wall -fno-pic -fshort-wchar +ASFLAGS = $(CFLAGS) + +BUILD_PRX = 1 +PRX_EXPORTS = exports.exp + +PSP_FW_VERSION = 660 + +USE_KERNEL_LIBS=1 +USE_KERNEL_LIBC=1 + +LIBDIR = ../lib +LDFLAGS = -nostartfiles +LIBS = -lpspsystemctrl_kernel + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/downgrade660_ctrl/decrypt.c b/src/downgrade660_ctrl/decrypt.c index 8d4ca1e..2774f0b 100644 --- a/src/downgrade660_ctrl/decrypt.c +++ b/src/downgrade660_ctrl/decrypt.c @@ -1,93 +1,93 @@ -/* - Downgrade Control -> decrypt.c -> Responsible for decryption patches and hooks - by Davee - - 31/12/2010 -*/ - -#include -#include - -#include -#include -#include - -#include "decrypt.h" -#include "patch_table.h" - -int pspDecryptPRX(void *exec, u32 exec_size, u32 *out_size); - -int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize) = NULL; -extern u32 g_spoof_ver; - -int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize) -{ - /* call the original function to decrypt the index.dat */ - int res = sceResmgr_driver_9DC14891(data, datasize, outsize); - - /* if there is a firmware version, we will generate a version.txt to downgrade */ - if (g_spoof_ver) - { - sprintf( data, - "release:%01X.%01X%01X:\n" - "build:0000,0,3,1,0:builder@vsh-build6\n" - "system:56422@release_%03X,0x%08X:\n" - "vsh:p6576@release_%03X,v57929@release_%03X,20100625:\n" - "target:1:WorldWide\n", - /* first line, version (X.YZ) */ (g_spoof_ver >> 8) & 0xF, (g_spoof_ver >> 4) & 0xF, g_spoof_ver & 0xF, - /* third line, release_XYZ + devkit */ g_spoof_ver, (((g_spoof_ver >> 8) & 0xF) << 24) | (((g_spoof_ver >> 4) & 0xF) << 16) | ((g_spoof_ver & 0xF) << 8) | 0x10, - /* forth line, release_XYZ + release_XYZ */ g_spoof_ver, g_spoof_ver - ); - } - - /* return the decryption result */ - return res; -} - -void PatchMesgled(u32 text_addr) -{ - /* if firmware is >= 6.30 */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - int model = sceKernelGetModel(); - if(model == 6 || model == 8) - { - model = 3; - } - - /* Patch mesgled to allow older updaters to boot */ - _sw(0, text_addr + g_patch_table.new_updater_check[model]); - } -} - -int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 exec_size, u32 *out_size) -{ - /* do sony decryption */ - int res = sceMesgLed_driver_81F72B1F(exec, exec_size, out_size); - - /* check for error */ - if (res != 0) - { - /* lets decrypt */ - res = pspDecryptPRX(exec, exec_size, out_size); - } - - /* return result */ - return res; -} - -int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size) -{ - /* do sony decryption */ - int res = memlmd_7CF1CD3E(exec, exec_size, out_size); - - /* check for error */ - if (res != 0) - { - /* lets decrypt */ - res = pspDecryptPRX(exec, exec_size, out_size); - } - - /* return result */ - return res; -} +/* + Downgrade Control -> decrypt.c -> Responsible for decryption patches and hooks + by Davee + + 31/12/2010 +*/ + +#include +#include + +#include +#include +#include + +#include "decrypt.h" +#include "patch_table.h" + +int pspDecryptPRX(void *exec, u32 exec_size, u32 *out_size); + +int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize) = NULL; +extern u32 g_spoof_ver; + +int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize) +{ + /* call the original function to decrypt the index.dat */ + int res = sceResmgr_driver_9DC14891(data, datasize, outsize); + + /* if there is a firmware version, we will generate a version.txt to downgrade */ + if (g_spoof_ver) + { + sprintf( data, + "release:%01X.%01X%01X:\n" + "build:0000,0,3,1,0:builder@vsh-build6\n" + "system:56422@release_%03X,0x%08X:\n" + "vsh:p6576@release_%03X,v57929@release_%03X,20100625:\n" + "target:1:WorldWide\n", + /* first line, version (X.YZ) */ (g_spoof_ver >> 8) & 0xF, (g_spoof_ver >> 4) & 0xF, g_spoof_ver & 0xF, + /* third line, release_XYZ + devkit */ g_spoof_ver, (((g_spoof_ver >> 8) & 0xF) << 24) | (((g_spoof_ver >> 4) & 0xF) << 16) | ((g_spoof_ver & 0xF) << 8) | 0x10, + /* forth line, release_XYZ + release_XYZ */ g_spoof_ver, g_spoof_ver + ); + } + + /* return the decryption result */ + return res; +} + +void PatchMesgled(u32 text_addr) +{ + /* if firmware is >= 6.30 */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + int model = sceKernelGetModel(); + if(model == 6 || model == 8) + { + model = 3; + } + + /* Patch mesgled to allow older updaters to boot */ + _sw(0, text_addr + g_patch_table.new_updater_check[model]); + } +} + +int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 exec_size, u32 *out_size) +{ + /* do sony decryption */ + int res = sceMesgLed_driver_81F72B1F(exec, exec_size, out_size); + + /* check for error */ + if (res != 0) + { + /* lets decrypt */ + res = pspDecryptPRX(exec, exec_size, out_size); + } + + /* return result */ + return res; +} + +int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size) +{ + /* do sony decryption */ + int res = memlmd_7CF1CD3E(exec, exec_size, out_size); + + /* check for error */ + if (res != 0) + { + /* lets decrypt */ + res = pspDecryptPRX(exec, exec_size, out_size); + } + + /* return result */ + return res; +} diff --git a/src/downgrade660_ctrl/decrypt.h b/src/downgrade660_ctrl/decrypt.h index 81add0c..a39d38e 100644 --- a/src/downgrade660_ctrl/decrypt.h +++ b/src/downgrade660_ctrl/decrypt.h @@ -1,80 +1,80 @@ -/* - Downgrade Control -> decrypt.h -> Provide API documentation and definitions - by Davee - - 31/12/2010 -*/ -#ifndef __DECRYPT_H__ -#define __DECRYPT_H__ - -/* our functions */ -void PatchMesgled(u32 text_addr); -int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size); -int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize); -int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 size, u32 *outsize); - -extern int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize); - -/* prototypes */ -int memlmd_7CF1CD3E(void *exec, u32 exec_size, u32 *out_size); -int sceResmgr_driver_9DC14891(void *data, u32 datasize, u32 *outsize); -int sceUtilsBufferCopyWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); -int sceUtilsBufferCopyByPollingWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); -int sceKernelPowerLock(void); -int sceKernelPowerUnlock(void); - -/* data structures */ -typedef struct -{ - u32 tag; - u8 key[16]; -} mesgled_keys_struct; - -typedef struct -{ - u32 signature; //0 - u16 mod_attribute; //4 - u16 comp_attribute; //6 - u8 module_ver_lo; //8 - u8 module_ver_hi; //9 - char modname[28]; //0xA - u8 mod_version; //0x26 - u8 nsegments; //0x27 - u32 elf_size; //0x28 - u32 psp_size; //0x2C - u32 boot_entry; //0x30 - u32 modinfo_offset; //0x34 - int bss_size; //0x38 - u16 seg_align[4]; //0x3C - u32 seg_address[4]; //0x44 - int seg_size[4]; //0x54 - u32 reserved[5]; //0x64 - u32 devkit_version; //0x78 - u8 decrypt_mode; //0x7C - u8 padding; //0x7D - u16 overlap_size; //0x7E - u8 key_data[0x30]; //0x80 - u32 comp_size; //0xB0 - int _80; //0xB4 - u32 unk_B8; //0xB8 - u32 unk_BC; //0xBC - u8 key_data2[0x10]; //0xC0 - u32 tag; //0xD0 - u8 scheck[0x58]; //0xD4 - u8 sha1_hash[0x14]; //0x12C - u8 key_data4[0x10]; //0x140 -} PSP_Header2; //0x150 - -typedef struct -{ - u32 mode; //0 - u32 unk_4; - u32 unk_8; - u32 keyseed; //12 - u32 size; //16 -} KIRK_CMD_HEADER; //20 - -#define KIRK_CMD_7 (7) -#define KIRK_CMD_SHA1 (0xB) - -#endif /* __DECRYPT_H__ */ +/* + Downgrade Control -> decrypt.h -> Provide API documentation and definitions + by Davee + + 31/12/2010 +*/ +#ifndef __DECRYPT_H__ +#define __DECRYPT_H__ + +/* our functions */ +void PatchMesgled(u32 text_addr); +int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size); +int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize); +int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 size, u32 *outsize); + +extern int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize); + +/* prototypes */ +int memlmd_7CF1CD3E(void *exec, u32 exec_size, u32 *out_size); +int sceResmgr_driver_9DC14891(void *data, u32 datasize, u32 *outsize); +int sceUtilsBufferCopyWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); +int sceUtilsBufferCopyByPollingWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); +int sceKernelPowerLock(void); +int sceKernelPowerUnlock(void); + +/* data structures */ +typedef struct +{ + u32 tag; + u8 key[16]; +} mesgled_keys_struct; + +typedef struct +{ + u32 signature; //0 + u16 mod_attribute; //4 + u16 comp_attribute; //6 + u8 module_ver_lo; //8 + u8 module_ver_hi; //9 + char modname[28]; //0xA + u8 mod_version; //0x26 + u8 nsegments; //0x27 + u32 elf_size; //0x28 + u32 psp_size; //0x2C + u32 boot_entry; //0x30 + u32 modinfo_offset; //0x34 + int bss_size; //0x38 + u16 seg_align[4]; //0x3C + u32 seg_address[4]; //0x44 + int seg_size[4]; //0x54 + u32 reserved[5]; //0x64 + u32 devkit_version; //0x78 + u8 decrypt_mode; //0x7C + u8 padding; //0x7D + u16 overlap_size; //0x7E + u8 key_data[0x30]; //0x80 + u32 comp_size; //0xB0 + int _80; //0xB4 + u32 unk_B8; //0xB8 + u32 unk_BC; //0xBC + u8 key_data2[0x10]; //0xC0 + u32 tag; //0xD0 + u8 scheck[0x58]; //0xD4 + u8 sha1_hash[0x14]; //0x12C + u8 key_data4[0x10]; //0x140 +} PSP_Header2; //0x150 + +typedef struct +{ + u32 mode; //0 + u32 unk_4; + u32 unk_8; + u32 keyseed; //12 + u32 size; //16 +} KIRK_CMD_HEADER; //20 + +#define KIRK_CMD_7 (7) +#define KIRK_CMD_SHA1 (0xB) + +#endif /* __DECRYPT_H__ */ diff --git a/src/downgrade660_ctrl/exports.exp b/src/downgrade660_ctrl/exports.exp index 6a4c945..a20b057 100644 --- a/src/downgrade660_ctrl/exports.exp +++ b/src/downgrade660_ctrl/exports.exp @@ -1,11 +1,11 @@ -# Define the exports for the prx -PSP_BEGIN_EXPORTS - -# These four lines are mandatory (although you can add other functions like module_stop) -# syslib is a psynonym for the single mandatory export. -PSP_EXPORT_START(syslib, 0, 0x8000) -PSP_EXPORT_FUNC_NID(module_start,0xD3744BE0) -PSP_EXPORT_VAR_HASH(module_info) -PSP_EXPORT_END - -PSP_END_EXPORTS +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC_NID(module_start,0xD3744BE0) +PSP_EXPORT_VAR_HASH(module_info) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/src/downgrade660_ctrl/extra_stubs.S b/src/downgrade660_ctrl/extra_stubs.S index 82cd9e7..5fb22e4 100644 --- a/src/downgrade660_ctrl/extra_stubs.S +++ b/src/downgrade660_ctrl/extra_stubs.S @@ -17,4 +17,8 @@ STUB_START "sceIdStorage_driver",0x00090011,0x00010005 STUB_FUNC 0x6FE062D1,sceIdStorageLookup - STUB_END \ No newline at end of file + STUB_END + + STUB_START "LoadCoreForKernel",0x00090011,0x00010005 + STUB_FUNC 0xBC99C625,_sceKernelFindModuleByAddress + STUB_END diff --git a/src/downgrade660_ctrl/main.c b/src/downgrade660_ctrl/main.c index 7486418..354bb00 100644 --- a/src/downgrade660_ctrl/main.c +++ b/src/downgrade660_ctrl/main.c @@ -1,373 +1,404 @@ -/* - Downgrade Control -> Restore kernel patches and enforce updater launch - by Davee - - 31/12/2010 -*/ - -#include -#include -#include - -#include -#include -#include - -#include "utils.h" -#include "patch_table.h" -#include "decrypt.h" - -PSP_MODULE_INFO("DowngraderCTRL", 0x3007, 1, 0); - -/* function pointers */ -int (* PrologueModule)(void *modmgr_param, SceModule *mod) = NULL; -STMOD_HANDLER previous = NULL; - -typedef struct __attribute__((packed)) -{ - int magic; // 0 - int version; // 4 - unsigned int keyofs; // 8 - unsigned int valofs; // 12 - int count; // 16 -} SfoHeader; - -typedef struct __attribute__((packed)) -{ - unsigned short nameofs; // 0 - char alignment; // 2 - char type; // 3 - int valsize; // 4 - int totalsize; // 8 - unsigned short valofs; // 12 - short unknown; // 16 -} SfoEntry; - -u32 g_spoof_ver = 0; -u8 g_sfo_buffer[4 << 10]; - -int ApplyFirmware(void) -{ - int i; - char *fw_data = NULL; - u8 device_fw_ver[4]; - u32 pbp_header[0x28/4]; - SfoHeader *header = (SfoHeader *)g_sfo_buffer; - SfoEntry *entries = (SfoEntry *)((char *)g_sfo_buffer + sizeof(SfoHeader)); - - /* Lets open the updater */ - char *file = (sceKernelGetModel() == 4) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.pbp") : ("ms0:/PSP/GAME/UPDATE/EBOOT.pbp"); - - /* set k1 */ - u32 k1 = pspSdkSetK1(0); - - /* lets open the file */ - SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); - - /* check for failure */ - if (fd < 0) - { - /* rage */ - pspSdkSetK1(k1); - return fd; - } - - /* read the PBP header */ - sceIoRead(fd, pbp_header, sizeof(pbp_header)); - - /* seek to the SFO */ - sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); - - /* calculate the size of the SFO */ - u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; - - /* check if greater than buffer size */ - if (sfo_size > sizeof(g_sfo_buffer)) - { - /* too much */ - pspSdkSetK1(k1); - return -2; - } - - /* read the sfo */ - sceIoRead(fd, g_sfo_buffer, sizeof(g_sfo_buffer)); - - /* close the file */ - sceIoClose(fd); - - /* now parse the SFO */ - for (i = 0; i < header->count; i++) - { - /* check this name */ - if (strcmp((char *)((char *)g_sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) - { - /* get the string */ - fw_data = (char *)((char *)g_sfo_buffer + header->valofs + entries[i].valofs); - break; - } - } - - /* see if we went through all the data */ - if (i == header->count) - { - /* error */ - pspSdkSetK1(k1); - return -3; - } - - /* ok, we have the firmware version in the eboot. */ - u32 min_ver = 0; - u32 updater_ver = (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); - - /* ok, now get the idstorage value */ - int res = sceIdStorageLookup(0x51, 0, device_fw_ver, 4); - - /* check for error */ - if (res < 0) - { - /* check model */ - if (sceKernelGetModel() != 0) - { - /* invalid error */ - return -4; - } - - /* firmware 1.00 */ - min_ver = 0x100; - } - else - { - /* convert to hex */ - min_ver = (((device_fw_ver[0] - '0') & 0xF) << 8) | (((device_fw_ver[2] - '0') & 0xF) << 4) | (((device_fw_ver[3] - '0') & 0xF) << 0); - } - - /* set the result to 0 */ - res = 0; - - /* check if the updater is less than the minimum version */ - if (updater_ver < min_ver) - { - /* ok, check for 6.35 and 09g */ - if ((min_ver != 0x630 && min_ver != 0x635) || sceKernelGetModel() != 8) - { - /* error */ - pspSdkSetK1(k1); - return -5; - } - - /* set result to 1 D: */ - res = 1; - } - - /* do spoof! */ - g_spoof_ver = updater_ver; - pspSdkSetK1(k1); - return res; -} - -#define INDEXFILE "flash0:/vsh/etc/index_04g.dat" -#define NEW_INDEXFILE "flash0:/vsh/etc/index_09g.dat" - -SceUID sceIoOpenPatched(char *file, u32 mode, u32 mode2) -{ - /* check indexfile */ - if (strcmp(file, INDEXFILE) == 0) - { - /* if read mode, copy */ - if (mode == PSP_O_RDONLY) - { - strcpy(file, NEW_INDEXFILE); - } - } - - /* call original function */ - return sceIoOpen(file, mode, mode2); -} - -int sceIoGetstatPatched(char *file, SceIoStat *stat) -{ - /* check indexfile */ - if (strcmp(file, INDEXFILE) == 0) - { - strcpy(file, NEW_INDEXFILE); - } - - /* call original function */ - return sceIoGetstat(file, stat); -} - -/* idstorage patching func */ -int (* pspUtilsBufferCopyWithRange)(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) = NULL; -int sceUtilsBufferCopyWithRangePatched(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) -{ - u8 ids_cert[0xB8]; - - /* if idstorage check */ - if (cmd == 0x12) - { - /* ok lets get the idstorage 0x100 key */ - int res = sceIdStorageLookup(0x100, 0x38, ids_cert, 0xB8); - - /* check for error */ - if (res < 0) - { - /* attempt with backup key */ - res = sceIdStorageLookup(0x120, 0x38, ids_cert, 0xB8); - - /* if error, exit */ - if (res < 0) - { - return res; - } - } - - /* yay its 0x100 key */ - /* change the model to 04g */ - ids_cert[7] = 6; - - /* copy the new certificate back */ - memcpy(src, ids_cert, sizeof(ids_cert)); - return 0; - } - - /* return function */ - return pspUtilsBufferCopyWithRange(dst, dst_size, src, src_size, cmd); -} - -int OnModuleStart(SceModule *mod) -{ - if (strcmp(mod->modname, "sceMesgLed") == 0) - { - PatchMesgled(mod->text_addr); - ClearCaches(); - } - - else if (strcmp(mod->modname, "updater") == 0) - { - /* ok, lets see what we're doing here! */ - int res = ApplyFirmware(); - - /* check for success */ - if (res >= 0) - { - /* do these patches if we have 09g going to 6.XX */ - if (res == 1) - { - /* patch the IO */ - PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0x109F50BC), sceIoOpenPatched); - PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0xACE946E8), sceIoGetstatPatched); - - /* find the function for idstorage verify */ - u32 func_address = FindFunc("sceMemlmd", "semaphore", 0x4C537C72); - - /* check if we have it... */ - if (func_address == 0) - { - /* ERROR */ - asm("break\n"); - } - - /* ok, lets patch it */ - KERNEL_HIJACK_FUNCTION(func_address, sceUtilsBufferCopyWithRangePatched, pspUtilsBufferCopyWithRange); - } - - /* patch the version check on index.dat */ - PatchSyscall(FindFunc("sceMesgLed", "sceResmgr", 0x9DC14891), sceResmgr_9DC14891_patched); - ClearCaches(); - } - } - - - /* if there is a previous handler, call it */ - if (previous) - return previous(mod); - - /* else just return 0 */ - return 0; -} - -int PrologueModulePatched(void *modmgr_param, SceModule *mod) -{ - /* modmgr_param has changed from 1.50 so I have no included the structure defintion, for an updated version a re-reverse of 6.30 modulemgr is required */ - int res = PrologueModule(modmgr_param, mod); - - /* If this function errors, the module is shutdown so we better check for it */ - if (res >= 0) - { - /* Pass the module through the OnModuleStart chain */ - OnModuleStart(mod); - } - - /* return success */ - return res; -} - -static void PatchModuleManager(void) -{ - /* find the modulemgr module */ - SceModule *mod = sceKernelFindModuleByName("sceModuleManager"); - u32 text_addr = mod->text_addr; - - /* link the original calls before hook */ - PrologueModule = (void *)(text_addr + g_patch_table.prologue_module_func); - - /* Patch call to PrologueModule from the StartModule function to allow a full coverage of loaded modules (even those without an entry point) */ - MAKE_CALL(text_addr + g_patch_table.prologue_module_call, PrologueModulePatched); -} - -static void PatchLoadCore(void) -{ - /* Find the loadcore module */ - SceModule *mod = sceKernelFindModuleByName("sceLoaderCore"); - u32 text_addr = mod->text_addr; - - /* Relink the memlmd calls (that reboot destroyed) */ - MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], text_addr + g_patch_table.memlmd_stub[0]); - MAKE_CALL(text_addr + g_patch_table.memlmd_call[1], text_addr + g_patch_table.memlmd_stub[1]); - - /* if >= 6.30 we need patches for the decryption */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - /* we need to hook updater decryption */ - MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], memlmd_7CF1CD3E_patched); - MAKE_CALL(text_addr + g_patch_table.updater_decrypt_call, sceMesgLed_driver_81F72B1F_patched); - - sceMesgLed_driver_81F72B1F = (void *)(text_addr + g_patch_table.updater_decrypt_func); - } -} - -int module_start(SceSize argsize, void *argp) -{ - /* check if we're running as a plugin or in boot */ - if (sceKernelFindModuleByName("sceInit")) - { - /* plugin, assume we've got HEN (and an M33 nid resolver) */ - /* check for >= 6.30 */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - /* this is firmware dependant :/ so not supported */ - return 0; - } - - /* register with sctrl */ - previous = sctrlHENSetStartModuleHandler(OnModuleStart); - } - else - { - /* boot */ - /* get patches and nids from loader */ - if (CopyPatchTable(&g_patch_table, (void *)PATCH_TABLE_ADDR_START, sceKernelDevkitVersion()) == 0) - { - /* no patches, no go */ - return 0; - } - - /* perform main system patches */ - PatchLoadCore(); - PatchModuleManager(); - } - - /* Clear the caches and return success */ - ClearCaches(); - return 0; -} +/* + Downgrade Control -> Restore kernel patches and enforce updater launch + by Davee + + 31/12/2010 +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "utils.h" +#include "patch_table.h" +#include "decrypt.h" + +PSP_MODULE_INFO("DowngraderCTRL", 0x3007, 1, 0); + +/* function pointers */ +int (* PrologueModule)(void *modmgr_param, SceModule2 *mod) = NULL; +STMOD_HANDLER previous = NULL; + +typedef struct __attribute__((packed)) +{ + int magic; // 0 + int version; // 4 + unsigned int keyofs; // 8 + unsigned int valofs; // 12 + int count; // 16 +} SfoHeader; + +typedef struct __attribute__((packed)) +{ + unsigned short nameofs; // 0 + char alignment; // 2 + char type; // 3 + int valsize; // 4 + int totalsize; // 8 + unsigned short valofs; // 12 + short unknown; // 16 +} SfoEntry; + +u32 g_spoof_ver = 0; +u8 g_sfo_buffer[4 << 10]; + +int ApplyFirmware(SceModule2 *mod) +{ + int i; + char *fw_data = NULL; + u8 device_fw_ver[4]; + u32 pbp_header[0x28/4]; + SfoHeader *header = (SfoHeader *)g_sfo_buffer; + SfoEntry *entries = (SfoEntry *)((char *)g_sfo_buffer + sizeof(SfoHeader)); + + /* Lets open the updater */ + char *file = (sceKernelGetModel() == 4) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.pbp") : ("ms0:/PSP/GAME/UPDATE/EBOOT.pbp"); + + /* set k1 */ + u32 k1 = pspSdkSetK1(0); + + /* lets open the file */ + SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); + + /* check for failure */ + if (fd < 0) + { + /* rage */ + pspSdkSetK1(k1); + return fd; + } + + /* read the PBP header */ + sceIoRead(fd, pbp_header, sizeof(pbp_header)); + + /* seek to the SFO */ + sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); + + /* calculate the size of the SFO */ + u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; + + /* check if greater than buffer size */ + if (sfo_size > sizeof(g_sfo_buffer)) + { + /* too much */ + pspSdkSetK1(k1); + return -2; + } + + /* read the sfo */ + sceIoRead(fd, g_sfo_buffer, sizeof(g_sfo_buffer)); + + /* close the file */ + sceIoClose(fd); + + /* now parse the SFO */ + for (i = 0; i < header->count; i++) + { + /* check this name */ + if (strcmp((char *)((char *)g_sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) + { + /* get the string */ + fw_data = (char *)((char *)g_sfo_buffer + header->valofs + entries[i].valofs); + break; + } + } + + /* see if we went through all the data */ + if (i == header->count) + { + /* error */ + pspSdkSetK1(k1); + return -3; + } + + /* ok, we have the firmware version in the eboot. */ + u32 min_ver = 0; + u32 updater_ver = (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); + + /* ok, now get the idstorage value */ + int res = sceIdStorageLookup(0x51, 0, device_fw_ver, 4); + + /* check for error */ + if (res < 0) + { + /* check model */ + if (sceKernelGetModel() != 0) + { + /* invalid error */ + return -4; + } + + /* firmware 1.00 */ + min_ver = 0x100; + } + else + { + /* convert to hex */ + min_ver = (((device_fw_ver[0] - '0') & 0xF) << 8) | (((device_fw_ver[2] - '0') & 0xF) << 4) | (((device_fw_ver[3] - '0') & 0xF) << 0); + } + + /* set the result to 0 */ + res = 0; + + /* check if the updater is less than the minimum version */ + if (updater_ver < min_ver) + { + /* ok, check for 6.35 and 09g */ + if ((min_ver != 0x630 && min_ver != 0x635) || sceKernelGetModel() != 8) + { + /* error */ + pspSdkSetK1(k1); + return -5; + } + + /* set result to 1 D: */ + res = 1; + } + + //fix the issue with 6.61 -> 6.60 + if ((sceKernelDevkitVersion() == 0x06060110) && (updater_ver == 0x660)) { + _sw(0x3C020606, 0x08801000); //lui $v0, 0x606 + _sw(0x03E00008, 0x08801004); //jr $ra + _sw(0x34420010, 0x08801008); //ori $v0, $v0, 0x10 + + //redirect sceKernelDevkitVersion in updater module + MAKE_JUMP(mod->text_addr + 0x123CD0, 0x08801000); + _sw(0, mod->text_addr + 0x123CD4); + + ClearCaches(); + } + + /* do spoof! */ + g_spoof_ver = updater_ver; + pspSdkSetK1(k1); + return res; +} + +#define INDEXFILE "flash0:/vsh/etc/index_04g.dat" +#define NEW_INDEXFILE "flash0:/vsh/etc/index_09g.dat" + +SceUID sceIoOpenPatched(char *file, u32 mode, u32 mode2) +{ + /* check indexfile */ + if (strcmp(file, INDEXFILE) == 0) + { + /* if read mode, copy */ + if (mode == PSP_O_RDONLY) + { + strcpy(file, NEW_INDEXFILE); + } + } + + /* call original function */ + return sceIoOpen(file, mode, mode2); +} + +int sceIoGetstatPatched(char *file, SceIoStat *stat) +{ + /* check indexfile */ + if (strcmp(file, INDEXFILE) == 0) + { + strcpy(file, NEW_INDEXFILE); + } + + /* call original function */ + return sceIoGetstat(file, stat); +} + +/* idstorage patching func */ +int (* pspUtilsBufferCopyWithRange)(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) = NULL; +int sceUtilsBufferCopyWithRangePatched(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) +{ + u8 ids_cert[0xB8]; + + /* if idstorage check */ + if (cmd == 0x12) + { + /* ok lets get the idstorage 0x100 key */ + int res = sceIdStorageLookup(0x100, 0x38, ids_cert, 0xB8); + + /* check for error */ + if (res < 0) + { + /* attempt with backup key */ + res = sceIdStorageLookup(0x120, 0x38, ids_cert, 0xB8); + + /* if error, exit */ + if (res < 0) + { + return res; + } + } + + /* yay its 0x100 key */ + /* change the model to 04g */ + ids_cert[7] = 6; + + /* copy the new certificate back */ + memcpy(src, ids_cert, sizeof(ids_cert)); + return 0; + } + + /* return function */ + return pspUtilsBufferCopyWithRange(dst, dst_size, src, src_size, cmd); +} + +int (* sceLflashFatfmtStartFatfmtOriginal)(int argc, char *argv[]) = NULL; + +int sceLflashFatfmtStartFatfmtPatched(int argc, char *argv[]) +{ + infSetRedirectionStatus(0); + ClearCaches(); + + return sceLflashFatfmtStartFatfmtOriginal(argc, argv); +} + +int OnModuleStart(SceModule2 *mod) +{ + if (strcmp(mod->modname, "sceMesgLed") == 0) + { + PatchMesgled(mod->text_addr); + ClearCaches(); + } + + else if (strcmp(mod->modname, "sceLflashFatfmtUpdater") == 0) + { + PatchSyscall(FindFunc("sceLflashFatfmtUpdater", "LflashFatfmt", 0xB7A424A4), sceLflashFatfmtStartFatfmtPatched); + sceLflashFatfmtStartFatfmtOriginal = FindFunc("sceLflashFatfmtUpdater", "LflashFatfmt", 0xB7A424A4); + ClearCaches(); + } + + else if (strcmp(mod->modname, "updater") == 0) + { + /* ok, lets see what we're doing here! */ + int res = ApplyFirmware(mod); + + /* check for success */ + if (res >= 0) + { + /* do these patches if we have 09g going to 6.XX */ + if (res == 1) + { + /* patch the IO */ + PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0x109F50BC), sceIoOpenPatched); + PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0xACE946E8), sceIoGetstatPatched); + + /* find the function for idstorage verify */ + u32 func_address = FindFunc("sceMemlmd", "semaphore", 0x4C537C72); + + /* check if we have it... */ + if (func_address == 0) + { + /* ERROR */ + asm("break\n"); + } + + /* ok, lets patch it */ + KERNEL_HIJACK_FUNCTION(func_address, sceUtilsBufferCopyWithRangePatched, pspUtilsBufferCopyWithRange); + } + + /* patch the version check on index.dat */ + PatchSyscall(FindFunc("sceMesgLed", "sceResmgr", 0x9DC14891), sceResmgr_9DC14891_patched); + ClearCaches(); + } + } + + + /* if there is a previous handler, call it */ + if (previous) + return previous((SceModule2 *)mod); + + /* else just return 0 */ + return 0; +} + +int PrologueModulePatched(void *modmgr_param, SceModule2 *mod) +{ + /* modmgr_param has changed from 1.50 so I have no included the structure defintion, for an updated version a re-reverse of 6.30 modulemgr is required */ + int res = PrologueModule(modmgr_param, mod); + + /* If this function errors, the module is shutdown so we better check for it */ + if (res >= 0) + { + /* Pass the module through the OnModuleStart chain */ + OnModuleStart(mod); + } + + /* return success */ + return res; +} + +static void PatchModuleManager(void) +{ + /* find the modulemgr module */ + SceModule2 *mod = (SceModule2 *)sceKernelFindModuleByName("sceModuleManager"); + u32 text_addr = mod->text_addr; + + /* link the original calls before hook */ + PrologueModule = (void *)(text_addr + g_patch_table.prologue_module_func); + + /* Patch call to PrologueModule from the StartModule function to allow a full coverage of loaded modules (even those without an entry point) */ + MAKE_CALL(text_addr + g_patch_table.prologue_module_call, PrologueModulePatched); +} + +static void PatchLoadCore(void) +{ + /* Find the loadcore module */ + SceModule2 *mod = (SceModule2 *)sceKernelFindModuleByName("sceLoaderCore"); + u32 text_addr = mod->text_addr; + + /* Relink the memlmd calls (that reboot destroyed) */ + MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], text_addr + g_patch_table.memlmd_stub[0]); + MAKE_CALL(text_addr + g_patch_table.memlmd_call[1], text_addr + g_patch_table.memlmd_stub[1]); + + /* if >= 6.30 we need patches for the decryption */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + /* we need to hook updater decryption */ + MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], memlmd_7CF1CD3E_patched); + MAKE_CALL(text_addr + g_patch_table.updater_decrypt_call, sceMesgLed_driver_81F72B1F_patched); + + sceMesgLed_driver_81F72B1F = (void *)(text_addr + g_patch_table.updater_decrypt_func); + } +} + +int module_start(SceSize argsize, void *argp) +{ + /* check if we're running as a plugin or in boot */ + if (sceKernelFindModuleByName("sceInit")) + { + /* plugin, assume we've got HEN (and an M33 nid resolver) */ + /* check for >= 6.30 */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + /* this is firmware dependant :/ so not supported */ + return 0; + } + + /* register with sctrl */ + previous = sctrlHENSetStartModuleHandler((STMOD_HANDLER)OnModuleStart); + } + else + { + /* boot */ + /* get patches and nids from loader */ + if (CopyPatchTable(&g_patch_table, (void *)PATCH_TABLE_ADDR_START, sceKernelDevkitVersion()) == 0) + { + /* no patches, no go */ + return 0; + } + + /* perform main system patches */ + PatchLoadCore(); + PatchModuleManager(); + } + + /* Clear the caches and return success */ + ClearCaches(); + return 0; +} diff --git a/src/downgrade660_ctrl/patch_table.c b/src/downgrade660_ctrl/patch_table.c index 2c3a312..5a9485c 100644 --- a/src/downgrade660_ctrl/patch_table.c +++ b/src/downgrade660_ctrl/patch_table.c @@ -1,46 +1,46 @@ -/* - Downgrade Control -> patch_table.c -> Responsible for searching and handling patch tables - by Davee - - 01/01/2011 -*/ - -#include -#include - -#include -#include -#include - -#include "patch_table.h" - -PatchTable g_patch_table; - -int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit) -{ - int i; - - /* get the number of entries in the table */ - u32 nentries = _lw((u32)_src_table); - - /* cast our pointer */ - PatchTable *src_table = (PatchTable *)(_src_table + 4); - - /* loop through the entries */ - for (i = 0; i < nentries; i++) - { - /* if same devkit */ - if (src_table->devkit == devkit) - { - /* copy over and return 1 for a complete transfer */ - memcpy(dst_table, src_table, sizeof(PatchTable)); - return 1; - } - - /* increment */ - src_table++; - } - - /* no transfer */ - return 0; -} +/* + Downgrade Control -> patch_table.c -> Responsible for searching and handling patch tables + by Davee + + 01/01/2011 +*/ + +#include +#include + +#include +#include +#include + +#include "patch_table.h" + +PatchTable g_patch_table; + +int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit) +{ + int i; + + /* get the number of entries in the table */ + u32 nentries = _lw((u32)_src_table); + + /* cast our pointer */ + PatchTable *src_table = (PatchTable *)(_src_table + 4); + + /* loop through the entries */ + for (i = 0; i < nentries; i++) + { + /* if same devkit */ + if (src_table->devkit == devkit) + { + /* copy over and return 1 for a complete transfer */ + memcpy(dst_table, src_table, sizeof(PatchTable)); + return 1; + } + + /* increment */ + src_table++; + } + + /* no transfer */ + return 0; +} diff --git a/src/downgrade660_ctrl/patch_table.h b/src/downgrade660_ctrl/patch_table.h index 35974b9..857e93e 100644 --- a/src/downgrade660_ctrl/patch_table.h +++ b/src/downgrade660_ctrl/patch_table.h @@ -1,32 +1,32 @@ -/* - Downgrade Control -> patch_table.h -> Provide API documentation and definitions for the table patching - by Davee - - 01/01/2011 -*/ -#ifndef __PATCH_TABLE_H__ -#define __PATCH_TABLE_H__ - -typedef struct -{ - u32 devkit; - u32 new_updater_check[5]; - u32 updater_decrypt_call; - u32 updater_decrypt_func; -/* u32 new_updater_keys; - u32 new_updater_t3_arg; - u32 new_updater_seed; - u32 new_updater_mode; - u32 new_updater_stack_arg;*/ - u32 prologue_module_func; - u32 prologue_module_call; - u32 memlmd_call[2]; - u32 memlmd_stub[2]; -} PatchTable; - -#define PATCH_TABLE_ADDR_START (0x88FC0000) - -extern PatchTable g_patch_table; -int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit); - -#endif /* __PATCH_TABLE_H__ */ +/* + Downgrade Control -> patch_table.h -> Provide API documentation and definitions for the table patching + by Davee + + 01/01/2011 +*/ +#ifndef __PATCH_TABLE_H__ +#define __PATCH_TABLE_H__ + +typedef struct +{ + u32 devkit; + u32 new_updater_check[5]; + u32 updater_decrypt_call; + u32 updater_decrypt_func; +/* u32 new_updater_keys; + u32 new_updater_t3_arg; + u32 new_updater_seed; + u32 new_updater_mode; + u32 new_updater_stack_arg;*/ + u32 prologue_module_func; + u32 prologue_module_call; + u32 memlmd_call[2]; + u32 memlmd_stub[2]; +} PatchTable; + +#define PATCH_TABLE_ADDR_START (0x88FC0000) + +extern PatchTable g_patch_table; +int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit); + +#endif /* __PATCH_TABLE_H__ */ diff --git a/src/downgrade660_ctrl/pspdecrypt.c b/src/downgrade660_ctrl/pspdecrypt.c index fba9df6..7e48511 100644 --- a/src/downgrade660_ctrl/pspdecrypt.c +++ b/src/downgrade660_ctrl/pspdecrypt.c @@ -1,923 +1,923 @@ -#include -#include -#include -//#include -#include -#include -#include -#include -#include - -#include "decrypt.h" -//#include -//#include - - -extern int UtilsForKernel_6C6887EE(void *, u32, void *, void *); - -////////// Decryption 1 ////////// - -// use pre-calculated keys (step1 results) - -u32 g_key0[] = -{ - 0x7b21f3be, 0x299c5e1d, 0x1c9c5e71, 0x96cb4645, 0x3c9b1be0, 0xeb85de3d, - 0x4a7f2022, 0xc2206eaa, 0xd50b3265, 0x55770567, 0x3c080840, 0x981d55f2, - 0x5fd8f6f3, 0xee8eb0c5, 0x944d8152, 0xf8278651, 0x2705bafa, 0x8420e533, - 0x27154ae9, 0x4819aa32, 0x59a3aa40, 0x2cb3cf65, 0xf274466d, 0x3a655605, - 0x21b0f88f, 0xc5b18d26, 0x64c19051, 0xd669c94e, 0xe87035f2, 0x9d3a5909, - 0x6f4e7102, 0xdca946ce, 0x8416881b, 0xbab097a5, 0x249125c6, 0xb34c0872, -}; - -u32 g_key2[] = -{ - 0xccfda932, 0x51c06f76, 0x046dcccf, 0x49e1821e, 0x7d3b024c, 0x9dda5865, - 0xcc8c9825, 0xd1e97db5, 0x6874d8cb, 0x3471c987, 0x72edb3fc, 0x81c8365d, - 0xe161e33a, 0xfc92db59, 0x2009b1ec, 0xb1a94ce4, 0x2f03696b, 0x87e236d8, - 0x3b2b8ce9, 0x0305e784, 0xf9710883, 0xb039db39, 0x893bea37, 0xe74d6805, - 0x2a5c38bd, 0xb08dc813, 0x15b32375, 0x46be4525, 0x0103fd90, 0xa90e87a2, - 0x52aba66a, 0x85bf7b80, 0x45e8ce63, 0x4dd716d3, 0xf5e30d2d, 0xaf3ae456, -}; - -u32 g_key3[] = -{ - 0xa6c8f5ca, 0x6d67c080, 0x924f4d3a, 0x047ca06a, 0x08640297, 0x4fd4a758, - 0xbd685a87, 0x9b2701c2, 0x83b62a35, 0x726b533c, 0xe522fa0c, 0xc24b06b4, - 0x459d1cac, 0xa8c5417b, 0x4fea62a2, 0x0615d742, 0x30628d09, 0xc44fab14, - 0x69ff715e, 0xd2d8837d, 0xbeed0b8b, 0x1e6e57ae, 0x61e8c402, 0xbe367a06, - 0x543f2b5e, 0xdb3ec058, 0xbe852075, 0x1e7e4dcc, 0x1564ea55, 0xec7825b4, - 0xc0538cad, 0x70f72c7f, 0x49e8c3d0, 0xeda97ec5, 0xf492b0a4, 0xe05eb02a, -}; - -u32 g_key44[] = -{ - 0xef80e005, 0x3a54689f, 0x43c99ccd, 0x1b7727be, 0x5cb80038, 0xdd2efe62, - 0xf369f92c, 0x160f94c5, 0x29560019, 0xbf3c10c5, 0xf2ce5566, 0xcea2c626, - 0xb601816f, 0x64e7481e, 0x0c34debd, 0x98f29cb0, 0x3fc504d7, 0xc8fb39f0, - 0x0221b3d8, 0x63f936a2, 0x9a3a4800, 0x6ecc32e3, 0x8e120cfd, 0xb0361623, - 0xaee1e689, 0x745502eb, 0xe4a6c61c, 0x74f23eb4, 0xd7fa5813, 0xb01916eb, - 0x12328457, 0xd2bc97d2, 0x646425d8, 0x328380a5, 0x43da8ab1, 0x4b122ac9, -}; - -u32 g_key20[] = -{ - 0x33b50800, 0xf32f5fcd, 0x3c14881f, 0x6e8a2a95, 0x29feefd5, 0x1394eae3, - 0xbd6bd443, 0x0821c083, 0xfab379d3, 0xe613e165, 0xf5a754d3, 0x108b2952, - 0x0a4b1e15, 0x61eadeba, 0x557565df, 0x3b465301, 0xae54ecc3, 0x61423309, - 0x70c9ff19, 0x5b0ae5ec, 0x989df126, 0x9d987a5f, 0x55bc750e, 0xc66eba27, - 0x2de988e8, 0xf76600da, 0x0382dccb, 0x5569f5f2, 0x8e431262, 0x288fe3d3, - 0x656f2187, 0x37d12e9c, 0x2f539eb4, 0xa492998e, 0xed3958f7, 0x39e96523, -}; - -u32 g_key3A[] = -{ - 0x67877069, 0x3abd5617, 0xc23ab1dc, 0xab57507d, 0x066a7f40, 0x24def9b9, - 0x06f759e4, 0xdcf524b1, 0x13793e5e, 0x0359022d, 0xaae7e1a2, 0x76b9b2fa, - 0x9a160340, 0x87822fba, 0x19e28fbb, 0x9e338a02, 0xd8007e9a, 0xea317af1, - 0x630671de, 0x0b67ca7c, 0x865192af, 0xea3c3526, 0x2b448c8e, 0x8b599254, - 0x4602e9cb, 0x4de16cda, 0xe164d5bb, 0x07ecd88e, 0x99ffe5f8, 0x768800c1, - 0x53b091ed, 0x84047434, 0xb426dbbc, 0x36f948bb, 0x46142158, 0x749bb492, -}; - -/* updaters keys */ -u8 updaters_keys[0x90+0x14] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x01, 0x1C, 0xE7, 0x31, 0x15, 0x6B, 0x83, - 0x3E, 0x26, 0x0D, 0xCC, 0x69, 0x36, 0x12, 0xCB, - 0xA7, 0xFD, 0x26, 0x66, 0x93, 0x2A, 0x6E, 0x1A, - 0x91, 0x2E, 0xC6, 0xFC, 0xD8, 0x2F, 0x00, 0x13, - 0x5A, 0xE2, 0xDF, 0xB6, 0xA2, 0xE4, 0x27, 0xC8, - 0x18, 0xC3, 0x50, 0x50, 0xB7, 0xE9, 0x4A, 0xED, - 0xCC, 0x3C, 0x30, 0xFD, 0x10, 0x6A, 0x2B, 0x0A, - 0x22, 0xCB, 0xC6, 0xE0, 0x20, 0x65, 0x12, 0xEB, - 0x7D, 0x4E, 0x2A, 0x37, 0x0B, 0x0A, 0xEF, 0x88, - 0xDA, 0x06, 0x54, 0xD4, 0x30, 0xAF, 0xCD, 0xCA, - 0x9A, 0xF9, 0xDA, 0x1A, 0xB0, 0x1B, 0xBB, 0x62, - 0x0C, 0xDB, 0xF8, 0x44, 0x73, 0x56, 0x14, 0x8E, - 0x93, 0xB1, 0x2C, 0xFD, 0x67, 0xE2, 0x5D, 0xCB, - 0x48, 0x5B, 0xD9, 0xB3, 0x54, 0x14, 0xD7, 0x9F, - 0x79, 0x9C, 0x24, 0xE9, 0xC2, 0x7A, 0x4E, 0x8C, - 0x4D, 0x24, 0x19, 0x94, 0xFF, 0xC9, 0xC2, 0x2D, - 0x23, 0x63, 0x51, 0xB8, 0xFA, 0xD6, 0x7F, 0xE6, - 0x5E, 0xBC, 0x32, 0xB2, 0x02, 0x13, 0xC4, 0x76 -}; - -/* locoroco, kazue, and maybe others demos keys */ -u8 demo_keys0[0x90+0x14] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x82, 0x4C, 0xA5, 0x18, 0xD3, 0xC8, 0x6E, 0xEA, - 0x17, 0x41, 0x04, 0xDC, 0xEA, 0xC5, 0x01, 0xFC, - 0x97, 0xB1, 0x94, 0x54, 0x71, 0x19, 0x22, 0xEE, - 0xE0, 0x2D, 0xE9, 0x83, 0x3D, 0x64, 0x30, 0xE6, - 0x42, 0x5C, 0x30, 0x5F, 0xEB, 0x41, 0xA0, 0xE0, - 0x62, 0xC6, 0x63, 0xEE, 0x5D, 0xA5, 0x0D, 0x1E, - 0xC2, 0x10, 0x14, 0x49, 0x06, 0xC6, 0x93, 0x84, - 0x71, 0xA5, 0x42, 0x63, 0x13, 0xF0, 0xB6, 0xD5, - 0x43, 0x51, 0x9E, 0xFA, 0x91, 0x0A, 0x7C, 0xE1, - 0x58, 0x1B, 0x95, 0x25, 0x40, 0x11, 0xF1, 0x8D, - 0xB1, 0x01, 0x8D, 0x04, 0x09, 0x54, 0x5C, 0x54, - 0xF5, 0x53, 0x08, 0xB0, 0x53, 0x85, 0xB4, 0xCE, - 0x0B, 0xF5, 0xC3, 0xFB, 0xC6, 0x55, 0x24, 0x0B, - 0xF2, 0xC6, 0x2C, 0xE4, 0x0C, 0xF0, 0x05, 0x3C, - 0xD7, 0x6C, 0x39, 0xD5, 0x87, 0x22, 0x09, 0xF7, - 0x3D, 0xC5, 0xA2, 0xFD, 0x55, 0x92, 0x3F, 0xB1, - 0xF6, 0xFE, 0xC8, 0x18, 0x1D, 0x6B, 0x04, 0x52, - 0x5F, 0x8C, 0xE8, 0xE7, 0x26, 0x5A, 0x6E, 0x5A -}; - -typedef struct -{ - u32 tag; // 4 byte value at offset 0xD0 in the PRX file - u8* key; // "step1_result" use for XOR step - u8 code; - u8 codeExtra; -} TAG_INFO; - -static const TAG_INFO g_tagInfo[] = -{ - // 1.x PRXs - { 0x00000000, (u8*)g_key0, 0x42 }, - { 0x02000000, (u8*)g_key2, 0x45 }, - { 0x03000000, (u8*)g_key3, 0x46 }, - - // 2.0 PRXs - { 0x4467415d, (u8*)g_key44, 0x59, 0x59 }, - { 0x207bbf2f, (u8*)g_key20, 0x5A, 0x5A }, - { 0x3ace4dce, (u8*)g_key3A, 0x5B, 0x5B }, - - // updaters - { 0x0b000000, updaters_keys, 0x4E }, - - // locoroco, kazue, demos - { 0x0c000000, demo_keys0, 0x4F }, -}; - -static TAG_INFO const* GetTagInfo(u32 tagFind) -{ - int iTag; - for (iTag = 0; iTag < sizeof(g_tagInfo)/sizeof(TAG_INFO); iTag++) - if (g_tagInfo[iTag].tag == tagFind) - return &g_tagInfo[iTag]; - return NULL; // not found -} - -static void ExtraV2Mangle(u8* buffer1, u8 codeExtra) -{ - static u8 g_dataTmp[20+0xA0] __attribute__((aligned(0x40))); - u8* buffer2 = g_dataTmp; // aligned - - memcpy(buffer2+20, buffer1, 0xA0); - u32* pl2 = (u32*)buffer2; - pl2[0] = 5; - pl2[1] = pl2[2] = 0; - pl2[3] = codeExtra; - pl2[4] = 0xA0; - - int ret = sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, 7); - if (ret != 0) - Kprintf("extra de-mangle returns %d\n", ret); - // copy result back - memcpy(buffer1, buffer2, 0xA0); -} - -static int Scramble(u32 *buf, u32 size, u32 code) -{ - buf[0] = 5; - buf[1] = buf[2] = 0; - buf[3] = code; - buf[4] = size; - - if (sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, 7) < 0) - { - return -1; - } - - return 0; -} - -static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag) -{ - int i, retsize; - u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20]; - - TAG_INFO const* pti = GetTagInfo(tag); - if (pti == NULL) - return -1; - - retsize = *(u32*)&pbIn[0xB0]; - - for (i = 0; i < 0x14; i++) - { - if (pti->key[i] != 0) - break; - } - - if (i == 0x14) - { - Scramble((u32 *)pti->key, 0x90, pti->code); - } - - // build conversion into pbOut - - if (pbIn != pbOut) - memcpy(pbOut, pbIn, cbTotal); - - memcpy(bD0, pbIn+0xD0, 0x80); - memcpy(b80, pbIn+0x80, 0x50); - memcpy(b00, pbIn+0x00, 0x80); - memcpy(bB0, pbIn+0xB0, 0x20); - - memset(pbOut, 0, 0x150); - memset(pbOut, 0x55, 0x40); // first $40 bytes ignored - - // step3 demangle in place - u32* pl = (u32*)(pbOut+0x2C); - pl[0] = 5; // number of ulongs in the header - pl[1] = pl[2] = 0; - pl[3] = pti->code; // initial seed for PRX - pl[4] = 0x70; // size - - // redo part of the SIG check (step2) - u8 buffer1[0x150]; - memcpy(buffer1+0x00, bD0, 0x80); - memcpy(buffer1+0x80, b80, 0x50); - memcpy(buffer1+0xD0, b00, 0x80); - if (pti->codeExtra != 0) - ExtraV2Mangle(buffer1+0x10, pti->codeExtra); - memcpy(pbOut+0x40 /* 0x2C+20 */, buffer1+0x40, 0x70); - - int ret; - int iXOR; - for (iXOR = 0; iXOR < 0x70; iXOR++) - pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ pti->key[0x14+iXOR]; - - ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7); - if (ret != 0) - { - Kprintf("mangle#7 returned $%x\n", ret); - return -1; - } - - for (iXOR = 0x6F; iXOR >= 0; iXOR--) - pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ pti->key[0x20+iXOR]; - - memset(pbOut+0xA0, 0, 0x10); // $40 bytes kept, clean up - pbOut[0xA0] = 1; - // copy unscrambled parts from header - memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros - memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header - - // step4: do the actual decryption of code block - // point 0x40 bytes into the buffer to key info - ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); - if (ret != 0) - { - /* set ECDSA flag */ - pbOut[0xA4] = 1; - - /* attempt decrypt */ - ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); - - /* check for error */ - if (ret != 0) - { - Kprintf("mangle#1 returned $%x\n", ret); - return -1; - } - } - - // return cbTotal - 0x150; // rounded up size - return retsize; -} - -////////// Decryption 2 ////////// - -/* kernel modules 2.60-2.71 */ -u8 keys260_0[0x10] = -{ - 0xC3, 0x24, 0x89, 0xD3, 0x80, 0x87, 0xB2, 0x4E, - 0x4C, 0xD7, 0x49, 0xE4, 0x9D, 0x1D, 0x34, 0xD1 - -}; - -/* user modules 2.60-2.71 */ -u8 keys260_1[0x10] = -{ - 0xF3, 0xAC, 0x6E, 0x7C, 0x04, 0x0A, 0x23, 0xE7, - 0x0D, 0x33, 0xD8, 0x24, 0x73, 0x39, 0x2B, 0x4A -}; - -/* vshmain 2.60-2.71 */ -u8 keys260_2[0x10] = -{ - 0x72, 0xB4, 0x39, 0xFF, 0x34, 0x9B, 0xAE, 0x82, - 0x30, 0x34, 0x4A, 0x1D, 0xA2, 0xD8, 0xB4, 0x3C -}; - -/* kernel modules 2.80 */ -u8 keys280_0[0x10] = -{ - 0xCA, 0xFB, 0xBF, 0xC7, 0x50, 0xEA, 0xB4, 0x40, - 0x8E, 0x44, 0x5C, 0x63, 0x53, 0xCE, 0x80, 0xB1 -}; - -/* user modules 2.80 */ -u8 keys280_1[0x10] = -{ - 0x40, 0x9B, 0xC6, 0x9B, 0xA9, 0xFB, 0x84, 0x7F, - 0x72, 0x21, 0xD2, 0x36, 0x96, 0x55, 0x09, 0x74 -}; - -/* vshmain executable 2.80 */ -u8 keys280_2[0x10] = -{ - 0x03, 0xA7, 0xCC, 0x4A, 0x5B, 0x91, 0xC2, 0x07, - 0xFF, 0xFC, 0x26, 0x25, 0x1E, 0x42, 0x4B, 0xB5 -}; - -/* kernel modules 3.00 */ -u8 keys300_0[0x10] = -{ - 0x9F, 0x67, 0x1A, 0x7A, 0x22, 0xF3, 0x59, 0x0B, - 0xAA, 0x6D, 0xA4, 0xC6, 0x8B, 0xD0, 0x03, 0x77 - -}; - -/* user modules 3.00 */ -u8 keys300_1[0x10] = -{ - 0x15, 0x07, 0x63, 0x26, 0xDB, 0xE2, 0x69, 0x34, - 0x56, 0x08, 0x2A, 0x93, 0x4E, 0x4B, 0x8A, 0xB2 - -}; - -/* vshmain 3.00 */ -u8 keys300_2[0x10] = -{ - 0x56, 0x3B, 0x69, 0xF7, 0x29, 0x88, 0x2F, 0x4C, - 0xDB, 0xD5, 0xDE, 0x80, 0xC6, 0x5C, 0xC8, 0x73 - -}; - -/* kernel modules 3.00 */ -u8 keys303_0[0x10] = -{ - 0x7b, 0xa1, 0xe2, 0x5a, 0x91, 0xb9, 0xd3, 0x13, - 0x77, 0x65, 0x4a, 0xb7, 0xc2, 0x8a, 0x10, 0xaf -}; - -/* kernel modules 3.10 */ -u8 keys310_0[0x10] = -{ - 0xa2, 0x41, 0xe8, 0x39, 0x66, 0x5b, 0xfa, 0xbb, - 0x1b, 0x2d, 0x6e, 0x0e, 0x33, 0xe5, 0xd7, 0x3f -}; - -/* user modules 3.10 */ -u8 keys310_1[0x10] = -{ - 0xA4, 0x60, 0x8F, 0xAB, 0xAB, 0xDE, 0xA5, 0x65, - 0x5D, 0x43, 0x3A, 0xD1, 0x5E, 0xC3, 0xFF, 0xEA -}; - -/* vshmain 3.10 */ -u8 keys310_2[0x10] = -{ - 0xE7, 0x5C, 0x85, 0x7A, 0x59, 0xB4, 0xE3, 0x1D, - 0xD0, 0x9E, 0xCE, 0xC2, 0xD6, 0xD4, 0xBD, 0x2B -}; - -/* reboot.bin 3.10 */ -u8 keys310_3[0x10] = -{ - 0x2E, 0x00, 0xF6, 0xF7, 0x52, 0xCF, 0x95, 0x5A, - 0xA1, 0x26, 0xB4, 0x84, 0x9B, 0x58, 0x76, 0x2F -}; - -/* kernel modules 3.30 */ -u8 keys330_0[0x10] = -{ - 0x3B, 0x9B, 0x1A, 0x56, 0x21, 0x80, 0x14, 0xED, - 0x8E, 0x8B, 0x08, 0x42, 0xFA, 0x2C, 0xDC, 0x3A -}; - -/* user modules 3.30 */ -u8 keys330_1[0x10] = -{ - 0xE8, 0xBE, 0x2F, 0x06, 0xB1, 0x05, 0x2A, 0xB9, - 0x18, 0x18, 0x03, 0xE3, 0xEB, 0x64, 0x7D, 0x26 -}; - -/* vshmain 3.30 */ -u8 keys330_2[0x10] = -{ - 0xAB, 0x82, 0x25, 0xD7, 0x43, 0x6F, 0x6C, 0xC1, - 0x95, 0xC5, 0xF7, 0xF0, 0x63, 0x73, 0x3F, 0xE7 -}; - -/* reboot.bin 3.30 */ -u8 keys330_3[0x10] = -{ - 0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F, - 0x38, 0x4C, 0x4D, 0x96, 0xBD, 0x49, 0xEC, 0x9B -}; - -/* stdio.prx 3.30 */ -u8 keys330_4[0x10] = -{ - 0xEC, 0x3B, 0xD2, 0xC0, 0xFA, 0xC1, 0xEE, 0xB9, - 0x9A, 0xBC, 0xFF, 0xA3, 0x89, 0xF2, 0x60, 0x1F -}; - -/* 3.60 common kernel modules */ -u8 keys360_0[16] = -{ - 0x3C, 0x2B, 0x51, 0xD4, 0x2D, 0x85, 0x47, 0xDA, - 0x2D, 0xCA, 0x18, 0xDF, 0xFE, 0x54, 0x09, 0xED -}; - -/* 3.60 specific slim kernel modules */ -u8 keys360_1[16] = -{ - 0x31, 0x1F, 0x98, 0xD5, 0x7B, 0x58, 0x95, 0x45, - 0x32, 0xAB, 0x3A, 0xE3, 0x89, 0x32, 0x4B, 0x34 -}; - -/* 3.70 common and fat kernel modules */ -u8 keys370_0[0x10] = -{ - 0x26, 0x38, 0x0A, 0xAC, 0xA5, 0xD8, 0x74, 0xD1, - 0x32, 0xB7, 0x2A, 0xBF, 0x79, 0x9E, 0x6D, 0xDB -}; - -/* 3.70 slim specific kernel modules */ -u8 keys370_1[0x10] = -{ - 0x53, 0xE7, 0xAB, 0xB9, 0xC6, 0x4A, 0x4B, 0x77, - 0x92, 0x17, 0xB5, 0x74, 0x0A, 0xDA, 0xA9, 0xEA -}; - -/* some 3.70 slim user modules */ -u8 keys370_2[16] = -{ - 0x71, 0x10, 0xF0, 0xA4, 0x16, 0x14, 0xD5, 0x93, - 0x12, 0xFF, 0x74, 0x96, 0xDF, 0x1F, 0xDA, 0x89 -}; - -/* 3.90 kernel */ -u8 keys390_0[16] = -{ - 0x45, 0xEF, 0x5C, 0x5D, 0xED, 0x81, 0x99, 0x84, - 0x12, 0x94, 0x8F, 0xAB, 0xE8, 0x05, 0x6D, 0x7D -}; - -/* 3.90 slim */ -u8 keys390_1[16] = -{ - 0x70, 0x1B, 0x08, 0x25, 0x22, 0xA1, 0x4D, 0x3B, - 0x69, 0x21, 0xF9, 0x71, 0x0A, 0xA8, 0x41, 0xA9 -}; - -/* 5.00 kernel */ -u8 keys500_0[16] = -{ - 0xEB, 0x1B, 0x53, 0x0B, 0x62, 0x49, 0x32, 0x58, - 0x1F, 0x83, 0x0A, 0xF4, 0x99, 0x3D, 0x75, 0xD0 -}; - -/* 5.00 kernel 2000 specific */ -u8 keys500_1[16] = -{ - 0xBA, 0xE2, 0xA3, 0x12, 0x07, 0xFF, 0x04, 0x1B, - 0x64, 0xA5, 0x11, 0x85, 0xF7, 0x2F, 0x99, 0x5B -}; - -/* 5.00 kernel 3000 specific */ -u8 keys500_2[16] = -{ - 0x2C, 0x8E, 0xAF, 0x1D, 0xFF, 0x79, 0x73, 0x1A, - 0xAD, 0x96, 0xAB, 0x09, 0xEA, 0x35, 0x59, 0x8B -}; - -u8 keys500_c[16] = -{ - 0xA3, 0x5D, 0x51, 0xE6, 0x56, 0xC8, 0x01, 0xCA, - 0xE3, 0x77, 0xBF, 0xCD, 0xFF, 0x24, 0xDA, 0x4D -}; - -u8 keys505_a[16] = -{ - 0x7B, 0x94, 0x72, 0x27, 0x4C, 0xCC, 0x54, 0x3B, - 0xAE, 0xDF, 0x46, 0x37, 0xAC, 0x01, 0x4D, 0x87 -}; - -u8 keys505_0[16] = -{ - 0x2E, 0x8E, 0x97, 0xA2, 0x85, 0x42, 0x70, 0x73, - 0x18, 0xDA, 0xA0, 0x8A, 0xF8, 0x62, 0xA2, 0xB0 -}; - -u8 keys505_1[16] = -{ - 0x58, 0x2A, 0x4C, 0x69, 0x19, 0x7B, 0x83, 0x3D, - 0xD2, 0x61, 0x61, 0xFE, 0x14, 0xEE, 0xAA, 0x11 -}; - -/* for psp 2000 file table and ipl pre-decryption */ -u8 keys02G_E[0x10] = -{ - 0x9D, 0x09, 0xFD, 0x20, 0xF3, 0x8F, 0x10, 0x69, - 0x0D, 0xB2, 0x6F, 0x00, 0xCC, 0xC5, 0x51, 0x2E -}; - -/* for psp 3000 file table and ipl pre-decryption */ -u8 keys03G_E[0x10] = -{ - 0x4F, 0x44, 0x5C, 0x62, 0xB3, 0x53, 0xC4, 0x30, - 0xFC, 0x3A, 0xA4, 0x5B, 0xEC, 0xFE, 0x51, 0xEA -}; - -/* for psp go file table and ipl pre-decryption */ -u8 keys05G_E[0x10] = -{ - 0x5D, 0xAA, 0x72, 0xF2, 0x26, 0x60, 0x4D, 0x1C, - 0xE7, 0x2D, 0xC8, 0xA3, 0x2F, 0x79, 0xC5, 0x54 -}; - -/* 5.70 PSPgo kernel*/ -u8 keys570_5k[0x10] = -{ - 0x6D, 0x72, 0xA4, 0xBA, 0x7F, 0xBF, 0xD1, 0xF1, - 0xA9, 0xF3, 0xBB, 0x07, 0x1B, 0xC0, 0xB3, 0x66 -}; - -/* 6.00-6.20 kernel and phat */ -u8 keys620_0[0x10] = -{ - 0xD6, 0xBD, 0xCE, 0x1E, 0x12, 0xAF, 0x9A, 0xE6, - 0x69, 0x30, 0xDE, 0xDA, 0x88, 0xB8, 0xFF, 0xFB -}; - -/* 6.00-6.20 slim kernel */ -u8 keys620_1[0x10] = -{ - 0x1D, 0x13, 0xE9, 0x50, 0x04, 0x73, 0x3D, 0xD2, - 0xE1, 0xDA, 0xB9, 0xC1, 0xE6, 0x7B, 0x25, 0xA7 -}; - -u8 keys620_a[0x10] = -{ - 0xAC, 0x34, 0xBA, 0xB1, 0x97, 0x8D, 0xAE, 0x6F, - 0xBA, 0xE8, 0xB1, 0xD6, 0xDF, 0xDF, 0xF1, 0xA2 -}; - -u8 keys620_e[0x10] = -{ - 0xB1, 0xB3, 0x7F, 0x76, 0xC3, 0xFB, 0x88, 0xE6, - 0xF8, 0x60, 0xD3, 0x35, 0x3C, 0xA3, 0x4E, 0xF3 -}; - -/* PSPgo internal */ -u8 keys620_5[0x10] = -{ - 0xF1, 0xBC, 0x17, 0x07, 0xAE, 0xB7, 0xC8, 0x30, - 0xD8, 0x34, 0x9D, 0x40, 0x6A, 0x8E, 0xDF, 0x4E -}; - -/* 6.XX PSPgo kernel */ -u8 keys620_5k[0x10] = -{ - 0x41, 0x8A, 0x35, 0x4F, 0x69, 0x3A, 0xDF, 0x04, - 0xFD, 0x39, 0x46, 0xA2, 0x5C, 0x2D, 0xF2, 0x21 -}; - -u8 keys620_5v[0x10] = -{ - 0xF2, 0x8F, 0x75, 0xA7, 0x31, 0x91, 0xCE, 0x9E, - 0x75, 0xBD, 0x27, 0x26, 0xB4, 0xB4, 0x0C, 0x32 -}; - -/* 6.30 phat kernel */ -u8 keys630_k1[0x10] = { - 0x36, 0xB0, 0xDC, 0xFC, 0x59, 0x2A, 0x95, 0x1D, - 0x80, 0x2D, 0x80, 0x3F, 0xCD, 0x30, 0xA0, 0x1B, -}; - -/* 6.30 phat kernel-2 */ -u8 keys630_k2[0x10] = { - 0xd4, 0x35, 0x18, 0x02, 0x29, 0x68, 0xfb, 0xa0, - 0x6a, 0xa9, 0xa5, 0xed, 0x78, 0xfd, 0x2e, 0x9d -}; - -u8 key_380280f0[0x10] = -{ - 0x97, 0x09, 0x12, 0xD3, 0xDB, 0x02, 0xBD, 0xD8, - 0xE7, 0x74, 0x51, 0xFE, 0xF0, 0xEA, 0x6C, 0x5C, -}; - -/* 6.30 slim kernel */ -u8 keys630_k3[0x10] = -{ - 0x23, 0x8D, 0x3D, 0xAE, 0x41, 0x50, 0xA0, 0xFA, - 0xF3, 0x2F, 0x32, 0xCE, 0xC7, 0x27, 0xCD, 0x50, -}; - -/* 6.30 slim pops */ -u8 keys630_k4[0x10] = -{ - 0xAA, 0xA1, 0xB5, 0x7C, 0x93, 0x5A, 0x95, 0xBD, - 0xEF, 0x69, 0x16, 0xFC, 0x2B, 0x92, 0x31, 0xDD -}; - -u8 keys630_k5[0x10] = { 0x87,0x37,0x21,0xCC,0x65,0xAE,0xAA,0x5F,0x40,0xF6,0x6F,0x2A,0x86,0xC7,0xA1,0xC8 }; -u8 keys630_k6[0x10] = { 0x8D,0xDB,0xDC,0x5C,0xF2,0x70,0x2B,0x40,0xB2,0x3D,0x00,0x09,0x61,0x7C,0x10,0x60 }; -u8 keys630_k7[0x10] = { 0x77,0x1C,0x06,0x5F,0x53,0xEC,0x3F,0xFC,0x22,0xCE,0x5A,0x27,0xFF,0x78,0xA8,0x48 }; -u8 keys630_k8[0x10] = { 0x81,0xD1,0x12,0x89,0x35,0xC8,0xEA,0x8B,0xE0,0x02,0x2D,0x2D,0x6A,0x18,0x67,0xB8 }; - -u8 keys636_k1[0x10] = { 0x07,0xE3,0x08,0x64,0x7F,0x60,0xA3,0x36,0x6A,0x76,0x21,0x44,0xC9,0xD7,0x06,0x83 }; -u8 keys636_k2[0x10] = { 0x91,0xF2,0x02,0x9E,0x63,0x32,0x30,0xA9,0x1D,0xDA,0x0B,0xA8,0xB7,0x41,0xA3,0xCC }; - -u8 keys600_1[0x10] = { 0xE3,0x52,0x39,0x97,0x3B,0x84,0x41,0x1C,0xC3,0x23,0xF1,0xB8,0xA9,0x09,0x4B,0xF0 }; -u8 keys600_2[0x10] = { 0xE1,0x45,0x93,0x2C,0x53,0xE2,0xAB,0x06,0x6F,0xB6,0x8F,0x0B,0x66,0x91,0xE7,0x1E }; - -u8 key_380283F0[0x10] = { 0x34,0x20,0x0C,0x8E,0xA1,0x86,0x79,0x84,0xAF,0x13,0xAE,0x34,0x77,0x6F,0xEA,0x89 }; - -u8 keys620_upd[0x10] = { 0xE2,0x03,0x8A,0x8C,0x33,0x81,0x4B,0x56,0x52,0x4E,0x1D,0xE5,0xA4,0x24,0x04,0xFF }; - -typedef struct -{ - u32 tag; // 4 byte value at offset 0xD0 in the PRX file - u8 *key; // 16 bytes keys - u8 code; // code for scramble - u8 type; -} TAG_INFO2; - -static TAG_INFO2 g_tagInfo2[] = -{ - { 0xA6E328F0, keys620_upd, 0x5F }, // 5.70, 6.10, 6.20 PSPgo Updater - - { 0x4C948AF0, keys636_k1, 0x43, 3}, // 6.36 - { 0x4C948BF0, keys636_k2, 0x43, 3}, // 6.36 02g - - { 0x457b80f0, keys630_k2, 0x5B, 3}, // 6.30 - { 0x457B81F0, keys630_k4, 0x5B, 3}, // 6.30 02g - { 0x457B82F0, keys630_k5, 0x5B, 3}, // 6.30 03g 04g 07g 09g - { 0x457B83F0, keys630_k7, 0x5B, 3}, // 6.30 05g - { 0x4C9484F0, keys630_k1, 0x43, 3}, // 6.30 - { 0x4C9485F0, keys630_k3, 0x43, 3}, // 6.30 02g - { 0x4C9486F0, keys630_k6, 0x43, 3}, // 6.30 03g 04g 07g 09g - { 0x4C9487F0, keys630_k8, 0x43, 3}, // 6.30 05g - - { 0x380283F0, key_380283F0, 0x5A, 3}, // 6.30 vshmain 05g - { 0x380280f0, key_380280f0, 0x5A, 3}, // 6.30 vshmain - - { 0x457B28F0, keys620_e, 0x5B }, - { 0x457B0CF0, keys620_a, 0x5B }, - { 0x380228F0, keys620_5v, 0x5A }, // PSPgo 6.XX vshmain - { 0x4C942AF0, keys620_5k, 0x43 }, // PSPgo 6.XX - { 0x4C9428F0, keys620_5 , 0x43 }, // PSPgo - { 0x4C9422F0, keys600_2, 0x43 }, // 6.00 03g 04g - { 0x4C941EF0, keys600_1, 0x43 }, - { 0x4C941DF0, keys620_1, 0x43 }, - { 0x4C941CF0, keys620_0, 0x43 }, - { 0x4C9429F0, keys570_5k, 0x43 }, // PSPgo 5.70 - { 0x4C9419F0, keys505_1, 0x43 }, - { 0x4C9418F0, keys505_0, 0x43 }, - { 0x457B0BF0, keys505_a, 0x5B }, - { 0x457B1EF0, keys500_c, 0x5B }, - { 0x4C941FF0, keys500_2, 0x43 }, - { 0x4C9417F0, keys500_1, 0x43 }, - { 0x4C9416F0, keys500_0, 0x43 }, - { 0x4C9415F0, keys390_1, 0x43 }, - { 0x4C9414F0, keys390_0, 0x43 }, - { 0x4C9412F0, keys370_0, 0x43 }, - { 0x4C9413F0, keys370_1, 0x43 }, - { 0x457B10F0, keys370_2, 0x5B }, - - { 0xD82310F0, keys02G_E, 0x51 }, - { 0xD8231EF0, keys03G_E, 0x51 }, - { 0xD82328F0, keys05G_E, 0x51 }, - - { 0x4C940DF0, keys360_0, 0x43 }, - { 0x4C9410F0, keys360_1, 0x43 }, - - { 0x4C940BF0, keys330_0, 0x43 }, - { 0x457B0AF0, keys330_1, 0x5B }, - { 0x38020AF0, keys330_2, 0x5A }, - { 0x4C940AF0, keys330_3, 0x43 }, - { 0x4C940CF0, keys330_4, 0x43 }, - - { 0xcfef09f0, keys310_0, 0x62 }, - { 0x457b08f0, keys310_1, 0x5B }, - { 0x380208F0, keys310_2, 0x5A }, - { 0xcfef08f0, keys310_3, 0x62 }, - - { 0xCFEF07F0, keys303_0, 0x62 }, - { 0xCFEF06F0, keys300_0, 0x62 }, - { 0x457B06F0, keys300_1, 0x5B }, - { 0x380206F0, keys300_2, 0x5A }, - - { 0xCFEF05F0, keys280_0, 0x62 }, - { 0x457B05F0, keys280_1, 0x5B }, - { 0x380205F0, keys280_2, 0x5A }, - { 0x16D59E03, keys260_0, 0x62 }, - { 0x76202403, keys260_1, 0x5B }, - { 0x0F037303, keys260_2, 0x5A } -}; - - -static TAG_INFO2 *GetTagInfo2(u32 tagFind) -{ - int iTag; - - for (iTag = 0; iTag < sizeof(g_tagInfo2) / sizeof(TAG_INFO2); iTag++) - { - if (g_tagInfo2[iTag].tag == tagFind) - { - return &g_tagInfo2[iTag]; - } - } - - return NULL; // not found -} - -static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag) -{ - TAG_INFO2 * pti = GetTagInfo2(tag); - - if (!pti) - { - //Kprintf("Unknown tag 0x%08X.\n", tag); - return -1; - } - - int retsize = *(int *)&inbuf[0xB0]; - u8 tmp1[0x150], tmp2[0x90+0x14], tmp3[0x60+0x14], tmp4[0x20]; - - memset(tmp1, 0, 0x150); - memset(tmp2, 0, 0x90+0x14); - memset(tmp3, 0, 0x60+0x14); - memset(tmp4, 0, 0x20); - - if (inbuf != outbuf) - memcpy(outbuf, inbuf, size); - - if (size < 0x160) - { - Kprintf("Buffer not big enough.\n"); - return -2; - } - - if (((u32)outbuf & 0x3F)) - { - Kprintf("Buffer not aligned to 64 bytes.\n"); - return -3; - } - - if ((size - 0x150) < retsize) - { - Kprintf("No enough data.\n"); - return -4; - } - - memcpy(tmp1, outbuf, 0x150); - - int i, j; - u8 *p = tmp2+0x14; - - for (i = 0; i < 9; i++) - { - for (j = 0; j < 0x10; j++) - { - p[(i << 4) + j] = pti->key[j]; - - } - - p[(i << 4)] = i; - } - - if (Scramble((u32 *)tmp2, 0x90, pti->code) < 0) - { - Kprintf("Error in Scramble #1.\n"); - return -5; - } - - memcpy(outbuf, tmp1+0xD0, 0x5C); - memcpy(outbuf+0x5C, tmp1+0x140, 0x10); - memcpy(outbuf+0x6C, tmp1+0x12C, 0x14); - memcpy(outbuf+0x80, tmp1+0x080, 0x30); - memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10); - memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10); - memcpy(outbuf+0xD0, tmp1+0x000, 0x80); - - memcpy(tmp3+0x14, outbuf+0x5C, 0x60); - - if (Scramble((u32 *)tmp3, 0x60, pti->code) < 0) - { - Kprintf("Error in Scramble #2.\n"); - return -6; - } - - memcpy(outbuf+0x5C, tmp3, 0x60); - memcpy(tmp3, outbuf+0x6C, 0x14); - memcpy(outbuf+0x70, outbuf+0x5C, 0x10); - - if(pti->type == 3) - { - memcpy(tmp4, outbuf+0x3C, 0x20); - memcpy(outbuf+0x50, tmp4, 0x20); - memset(outbuf+0x18, 0, 0x38); - }else - memset(outbuf+0x18, 0, 0x58); - - memcpy(outbuf+0x04, outbuf, 0x04); - *((u32 *)outbuf) = 0x014C; - memcpy(outbuf+0x08, tmp2, 0x10); - - /* sha-1 */ - - if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0) - { - Kprintf("Error in sceUtilsBufferCopyWithRange 0xB.\n"); - return -7; - } - - if (memcmp(outbuf, tmp3, 0x14) != 0) - { - Kprintf("SHA-1 is incorrect.\n"); - return -8; - } - - int iXOR; - - for (iXOR = 0; iXOR < 0x40; iXOR++) - { - tmp3[iXOR+0x14] = outbuf[iXOR+0x80] ^ tmp2[iXOR+0x10]; - } - - if (Scramble((u32 *)tmp3, 0x40, pti->code) != 0) - { - Kprintf("Error in Scramble #2.\n"); - return -9; - } - - for (iXOR = 0x3F; iXOR >= 0; iXOR--) - { - outbuf[iXOR+0x40] = tmp3[iXOR] ^ tmp2[iXOR+0x50]; // uns 8 - } - - if (pti->type == 3) - { - memcpy(outbuf+0x80, tmp4, 0x20); - memset(outbuf+0xA0, 0, 0x10); - *(u32*)&outbuf[0xA4] = 1; - *(u32*)&outbuf[0xA0] = 1; - } else - { - memset(outbuf+0x80, 0, 0x30); - *(u32*)&outbuf[0xA0] = 1; - } - - memcpy(outbuf+0xB0, outbuf+0xC0, 0x10); - memset(outbuf+0xC0, 0, 0x10); - memcpy(outbuf+0xD0, outbuf+0xD0, 0x80); - - // The real decryption - if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf+0x40, size-0x40, 0x1) != 0) - { - Kprintf("Error in sceUtilsBufferCopyWithRange 0x1.\n"); - return -1; - } - - if (retsize < 0x150) - { - // Fill with 0 - memset(outbuf+retsize, 0, 0x150-retsize); - } - - return retsize; -} - -int pspDecryptPRX(u8 *data, u32 size, u32 *out_size) -{ - int retsize = DecryptPRX1(data, data, size, *(u32 *)&data[0xD0]); - - if (retsize <= 0) - { - retsize = DecryptPRX2(data, data, size, *(u32 *)&data[0xD0]); - } - - if (retsize <= 0) - { - return -1; - } - - out_size[0] = retsize; - return 0; -} +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#include "decrypt.h" +//#include +//#include + + +extern int UtilsForKernel_6C6887EE(void *, u32, void *, void *); + +////////// Decryption 1 ////////// + +// use pre-calculated keys (step1 results) + +u32 g_key0[] = +{ + 0x7b21f3be, 0x299c5e1d, 0x1c9c5e71, 0x96cb4645, 0x3c9b1be0, 0xeb85de3d, + 0x4a7f2022, 0xc2206eaa, 0xd50b3265, 0x55770567, 0x3c080840, 0x981d55f2, + 0x5fd8f6f3, 0xee8eb0c5, 0x944d8152, 0xf8278651, 0x2705bafa, 0x8420e533, + 0x27154ae9, 0x4819aa32, 0x59a3aa40, 0x2cb3cf65, 0xf274466d, 0x3a655605, + 0x21b0f88f, 0xc5b18d26, 0x64c19051, 0xd669c94e, 0xe87035f2, 0x9d3a5909, + 0x6f4e7102, 0xdca946ce, 0x8416881b, 0xbab097a5, 0x249125c6, 0xb34c0872, +}; + +u32 g_key2[] = +{ + 0xccfda932, 0x51c06f76, 0x046dcccf, 0x49e1821e, 0x7d3b024c, 0x9dda5865, + 0xcc8c9825, 0xd1e97db5, 0x6874d8cb, 0x3471c987, 0x72edb3fc, 0x81c8365d, + 0xe161e33a, 0xfc92db59, 0x2009b1ec, 0xb1a94ce4, 0x2f03696b, 0x87e236d8, + 0x3b2b8ce9, 0x0305e784, 0xf9710883, 0xb039db39, 0x893bea37, 0xe74d6805, + 0x2a5c38bd, 0xb08dc813, 0x15b32375, 0x46be4525, 0x0103fd90, 0xa90e87a2, + 0x52aba66a, 0x85bf7b80, 0x45e8ce63, 0x4dd716d3, 0xf5e30d2d, 0xaf3ae456, +}; + +u32 g_key3[] = +{ + 0xa6c8f5ca, 0x6d67c080, 0x924f4d3a, 0x047ca06a, 0x08640297, 0x4fd4a758, + 0xbd685a87, 0x9b2701c2, 0x83b62a35, 0x726b533c, 0xe522fa0c, 0xc24b06b4, + 0x459d1cac, 0xa8c5417b, 0x4fea62a2, 0x0615d742, 0x30628d09, 0xc44fab14, + 0x69ff715e, 0xd2d8837d, 0xbeed0b8b, 0x1e6e57ae, 0x61e8c402, 0xbe367a06, + 0x543f2b5e, 0xdb3ec058, 0xbe852075, 0x1e7e4dcc, 0x1564ea55, 0xec7825b4, + 0xc0538cad, 0x70f72c7f, 0x49e8c3d0, 0xeda97ec5, 0xf492b0a4, 0xe05eb02a, +}; + +u32 g_key44[] = +{ + 0xef80e005, 0x3a54689f, 0x43c99ccd, 0x1b7727be, 0x5cb80038, 0xdd2efe62, + 0xf369f92c, 0x160f94c5, 0x29560019, 0xbf3c10c5, 0xf2ce5566, 0xcea2c626, + 0xb601816f, 0x64e7481e, 0x0c34debd, 0x98f29cb0, 0x3fc504d7, 0xc8fb39f0, + 0x0221b3d8, 0x63f936a2, 0x9a3a4800, 0x6ecc32e3, 0x8e120cfd, 0xb0361623, + 0xaee1e689, 0x745502eb, 0xe4a6c61c, 0x74f23eb4, 0xd7fa5813, 0xb01916eb, + 0x12328457, 0xd2bc97d2, 0x646425d8, 0x328380a5, 0x43da8ab1, 0x4b122ac9, +}; + +u32 g_key20[] = +{ + 0x33b50800, 0xf32f5fcd, 0x3c14881f, 0x6e8a2a95, 0x29feefd5, 0x1394eae3, + 0xbd6bd443, 0x0821c083, 0xfab379d3, 0xe613e165, 0xf5a754d3, 0x108b2952, + 0x0a4b1e15, 0x61eadeba, 0x557565df, 0x3b465301, 0xae54ecc3, 0x61423309, + 0x70c9ff19, 0x5b0ae5ec, 0x989df126, 0x9d987a5f, 0x55bc750e, 0xc66eba27, + 0x2de988e8, 0xf76600da, 0x0382dccb, 0x5569f5f2, 0x8e431262, 0x288fe3d3, + 0x656f2187, 0x37d12e9c, 0x2f539eb4, 0xa492998e, 0xed3958f7, 0x39e96523, +}; + +u32 g_key3A[] = +{ + 0x67877069, 0x3abd5617, 0xc23ab1dc, 0xab57507d, 0x066a7f40, 0x24def9b9, + 0x06f759e4, 0xdcf524b1, 0x13793e5e, 0x0359022d, 0xaae7e1a2, 0x76b9b2fa, + 0x9a160340, 0x87822fba, 0x19e28fbb, 0x9e338a02, 0xd8007e9a, 0xea317af1, + 0x630671de, 0x0b67ca7c, 0x865192af, 0xea3c3526, 0x2b448c8e, 0x8b599254, + 0x4602e9cb, 0x4de16cda, 0xe164d5bb, 0x07ecd88e, 0x99ffe5f8, 0x768800c1, + 0x53b091ed, 0x84047434, 0xb426dbbc, 0x36f948bb, 0x46142158, 0x749bb492, +}; + +/* updaters keys */ +u8 updaters_keys[0x90+0x14] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x01, 0x1C, 0xE7, 0x31, 0x15, 0x6B, 0x83, + 0x3E, 0x26, 0x0D, 0xCC, 0x69, 0x36, 0x12, 0xCB, + 0xA7, 0xFD, 0x26, 0x66, 0x93, 0x2A, 0x6E, 0x1A, + 0x91, 0x2E, 0xC6, 0xFC, 0xD8, 0x2F, 0x00, 0x13, + 0x5A, 0xE2, 0xDF, 0xB6, 0xA2, 0xE4, 0x27, 0xC8, + 0x18, 0xC3, 0x50, 0x50, 0xB7, 0xE9, 0x4A, 0xED, + 0xCC, 0x3C, 0x30, 0xFD, 0x10, 0x6A, 0x2B, 0x0A, + 0x22, 0xCB, 0xC6, 0xE0, 0x20, 0x65, 0x12, 0xEB, + 0x7D, 0x4E, 0x2A, 0x37, 0x0B, 0x0A, 0xEF, 0x88, + 0xDA, 0x06, 0x54, 0xD4, 0x30, 0xAF, 0xCD, 0xCA, + 0x9A, 0xF9, 0xDA, 0x1A, 0xB0, 0x1B, 0xBB, 0x62, + 0x0C, 0xDB, 0xF8, 0x44, 0x73, 0x56, 0x14, 0x8E, + 0x93, 0xB1, 0x2C, 0xFD, 0x67, 0xE2, 0x5D, 0xCB, + 0x48, 0x5B, 0xD9, 0xB3, 0x54, 0x14, 0xD7, 0x9F, + 0x79, 0x9C, 0x24, 0xE9, 0xC2, 0x7A, 0x4E, 0x8C, + 0x4D, 0x24, 0x19, 0x94, 0xFF, 0xC9, 0xC2, 0x2D, + 0x23, 0x63, 0x51, 0xB8, 0xFA, 0xD6, 0x7F, 0xE6, + 0x5E, 0xBC, 0x32, 0xB2, 0x02, 0x13, 0xC4, 0x76 +}; + +/* locoroco, kazue, and maybe others demos keys */ +u8 demo_keys0[0x90+0x14] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x82, 0x4C, 0xA5, 0x18, 0xD3, 0xC8, 0x6E, 0xEA, + 0x17, 0x41, 0x04, 0xDC, 0xEA, 0xC5, 0x01, 0xFC, + 0x97, 0xB1, 0x94, 0x54, 0x71, 0x19, 0x22, 0xEE, + 0xE0, 0x2D, 0xE9, 0x83, 0x3D, 0x64, 0x30, 0xE6, + 0x42, 0x5C, 0x30, 0x5F, 0xEB, 0x41, 0xA0, 0xE0, + 0x62, 0xC6, 0x63, 0xEE, 0x5D, 0xA5, 0x0D, 0x1E, + 0xC2, 0x10, 0x14, 0x49, 0x06, 0xC6, 0x93, 0x84, + 0x71, 0xA5, 0x42, 0x63, 0x13, 0xF0, 0xB6, 0xD5, + 0x43, 0x51, 0x9E, 0xFA, 0x91, 0x0A, 0x7C, 0xE1, + 0x58, 0x1B, 0x95, 0x25, 0x40, 0x11, 0xF1, 0x8D, + 0xB1, 0x01, 0x8D, 0x04, 0x09, 0x54, 0x5C, 0x54, + 0xF5, 0x53, 0x08, 0xB0, 0x53, 0x85, 0xB4, 0xCE, + 0x0B, 0xF5, 0xC3, 0xFB, 0xC6, 0x55, 0x24, 0x0B, + 0xF2, 0xC6, 0x2C, 0xE4, 0x0C, 0xF0, 0x05, 0x3C, + 0xD7, 0x6C, 0x39, 0xD5, 0x87, 0x22, 0x09, 0xF7, + 0x3D, 0xC5, 0xA2, 0xFD, 0x55, 0x92, 0x3F, 0xB1, + 0xF6, 0xFE, 0xC8, 0x18, 0x1D, 0x6B, 0x04, 0x52, + 0x5F, 0x8C, 0xE8, 0xE7, 0x26, 0x5A, 0x6E, 0x5A +}; + +typedef struct +{ + u32 tag; // 4 byte value at offset 0xD0 in the PRX file + u8* key; // "step1_result" use for XOR step + u8 code; + u8 codeExtra; +} TAG_INFO; + +static const TAG_INFO g_tagInfo[] = +{ + // 1.x PRXs + { 0x00000000, (u8*)g_key0, 0x42 }, + { 0x02000000, (u8*)g_key2, 0x45 }, + { 0x03000000, (u8*)g_key3, 0x46 }, + + // 2.0 PRXs + { 0x4467415d, (u8*)g_key44, 0x59, 0x59 }, + { 0x207bbf2f, (u8*)g_key20, 0x5A, 0x5A }, + { 0x3ace4dce, (u8*)g_key3A, 0x5B, 0x5B }, + + // updaters + { 0x0b000000, updaters_keys, 0x4E }, + + // locoroco, kazue, demos + { 0x0c000000, demo_keys0, 0x4F }, +}; + +static TAG_INFO const* GetTagInfo(u32 tagFind) +{ + int iTag; + for (iTag = 0; iTag < sizeof(g_tagInfo)/sizeof(TAG_INFO); iTag++) + if (g_tagInfo[iTag].tag == tagFind) + return &g_tagInfo[iTag]; + return NULL; // not found +} + +static void ExtraV2Mangle(u8* buffer1, u8 codeExtra) +{ + static u8 g_dataTmp[20+0xA0] __attribute__((aligned(0x40))); + u8* buffer2 = g_dataTmp; // aligned + + memcpy(buffer2+20, buffer1, 0xA0); + u32* pl2 = (u32*)buffer2; + pl2[0] = 5; + pl2[1] = pl2[2] = 0; + pl2[3] = codeExtra; + pl2[4] = 0xA0; + + int ret = sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, 7); + if (ret != 0) + Kprintf("extra de-mangle returns %d\n", ret); + // copy result back + memcpy(buffer1, buffer2, 0xA0); +} + +static int Scramble(u32 *buf, u32 size, u32 code) +{ + buf[0] = 5; + buf[1] = buf[2] = 0; + buf[3] = code; + buf[4] = size; + + if (sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, 7) < 0) + { + return -1; + } + + return 0; +} + +static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag) +{ + int i, retsize; + u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20]; + + TAG_INFO const* pti = GetTagInfo(tag); + if (pti == NULL) + return -1; + + retsize = *(u32*)&pbIn[0xB0]; + + for (i = 0; i < 0x14; i++) + { + if (pti->key[i] != 0) + break; + } + + if (i == 0x14) + { + Scramble((u32 *)pti->key, 0x90, pti->code); + } + + // build conversion into pbOut + + if (pbIn != pbOut) + memcpy(pbOut, pbIn, cbTotal); + + memcpy(bD0, pbIn+0xD0, 0x80); + memcpy(b80, pbIn+0x80, 0x50); + memcpy(b00, pbIn+0x00, 0x80); + memcpy(bB0, pbIn+0xB0, 0x20); + + memset(pbOut, 0, 0x150); + memset(pbOut, 0x55, 0x40); // first $40 bytes ignored + + // step3 demangle in place + u32* pl = (u32*)(pbOut+0x2C); + pl[0] = 5; // number of ulongs in the header + pl[1] = pl[2] = 0; + pl[3] = pti->code; // initial seed for PRX + pl[4] = 0x70; // size + + // redo part of the SIG check (step2) + u8 buffer1[0x150]; + memcpy(buffer1+0x00, bD0, 0x80); + memcpy(buffer1+0x80, b80, 0x50); + memcpy(buffer1+0xD0, b00, 0x80); + if (pti->codeExtra != 0) + ExtraV2Mangle(buffer1+0x10, pti->codeExtra); + memcpy(pbOut+0x40 /* 0x2C+20 */, buffer1+0x40, 0x70); + + int ret; + int iXOR; + for (iXOR = 0; iXOR < 0x70; iXOR++) + pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ pti->key[0x14+iXOR]; + + ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7); + if (ret != 0) + { + Kprintf("mangle#7 returned $%x\n", ret); + return -1; + } + + for (iXOR = 0x6F; iXOR >= 0; iXOR--) + pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ pti->key[0x20+iXOR]; + + memset(pbOut+0xA0, 0, 0x10); // $40 bytes kept, clean up + pbOut[0xA0] = 1; + // copy unscrambled parts from header + memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros + memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header + + // step4: do the actual decryption of code block + // point 0x40 bytes into the buffer to key info + ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); + if (ret != 0) + { + /* set ECDSA flag */ + pbOut[0xA4] = 1; + + /* attempt decrypt */ + ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); + + /* check for error */ + if (ret != 0) + { + Kprintf("mangle#1 returned $%x\n", ret); + return -1; + } + } + + // return cbTotal - 0x150; // rounded up size + return retsize; +} + +////////// Decryption 2 ////////// + +/* kernel modules 2.60-2.71 */ +u8 keys260_0[0x10] = +{ + 0xC3, 0x24, 0x89, 0xD3, 0x80, 0x87, 0xB2, 0x4E, + 0x4C, 0xD7, 0x49, 0xE4, 0x9D, 0x1D, 0x34, 0xD1 + +}; + +/* user modules 2.60-2.71 */ +u8 keys260_1[0x10] = +{ + 0xF3, 0xAC, 0x6E, 0x7C, 0x04, 0x0A, 0x23, 0xE7, + 0x0D, 0x33, 0xD8, 0x24, 0x73, 0x39, 0x2B, 0x4A +}; + +/* vshmain 2.60-2.71 */ +u8 keys260_2[0x10] = +{ + 0x72, 0xB4, 0x39, 0xFF, 0x34, 0x9B, 0xAE, 0x82, + 0x30, 0x34, 0x4A, 0x1D, 0xA2, 0xD8, 0xB4, 0x3C +}; + +/* kernel modules 2.80 */ +u8 keys280_0[0x10] = +{ + 0xCA, 0xFB, 0xBF, 0xC7, 0x50, 0xEA, 0xB4, 0x40, + 0x8E, 0x44, 0x5C, 0x63, 0x53, 0xCE, 0x80, 0xB1 +}; + +/* user modules 2.80 */ +u8 keys280_1[0x10] = +{ + 0x40, 0x9B, 0xC6, 0x9B, 0xA9, 0xFB, 0x84, 0x7F, + 0x72, 0x21, 0xD2, 0x36, 0x96, 0x55, 0x09, 0x74 +}; + +/* vshmain executable 2.80 */ +u8 keys280_2[0x10] = +{ + 0x03, 0xA7, 0xCC, 0x4A, 0x5B, 0x91, 0xC2, 0x07, + 0xFF, 0xFC, 0x26, 0x25, 0x1E, 0x42, 0x4B, 0xB5 +}; + +/* kernel modules 3.00 */ +u8 keys300_0[0x10] = +{ + 0x9F, 0x67, 0x1A, 0x7A, 0x22, 0xF3, 0x59, 0x0B, + 0xAA, 0x6D, 0xA4, 0xC6, 0x8B, 0xD0, 0x03, 0x77 + +}; + +/* user modules 3.00 */ +u8 keys300_1[0x10] = +{ + 0x15, 0x07, 0x63, 0x26, 0xDB, 0xE2, 0x69, 0x34, + 0x56, 0x08, 0x2A, 0x93, 0x4E, 0x4B, 0x8A, 0xB2 + +}; + +/* vshmain 3.00 */ +u8 keys300_2[0x10] = +{ + 0x56, 0x3B, 0x69, 0xF7, 0x29, 0x88, 0x2F, 0x4C, + 0xDB, 0xD5, 0xDE, 0x80, 0xC6, 0x5C, 0xC8, 0x73 + +}; + +/* kernel modules 3.00 */ +u8 keys303_0[0x10] = +{ + 0x7b, 0xa1, 0xe2, 0x5a, 0x91, 0xb9, 0xd3, 0x13, + 0x77, 0x65, 0x4a, 0xb7, 0xc2, 0x8a, 0x10, 0xaf +}; + +/* kernel modules 3.10 */ +u8 keys310_0[0x10] = +{ + 0xa2, 0x41, 0xe8, 0x39, 0x66, 0x5b, 0xfa, 0xbb, + 0x1b, 0x2d, 0x6e, 0x0e, 0x33, 0xe5, 0xd7, 0x3f +}; + +/* user modules 3.10 */ +u8 keys310_1[0x10] = +{ + 0xA4, 0x60, 0x8F, 0xAB, 0xAB, 0xDE, 0xA5, 0x65, + 0x5D, 0x43, 0x3A, 0xD1, 0x5E, 0xC3, 0xFF, 0xEA +}; + +/* vshmain 3.10 */ +u8 keys310_2[0x10] = +{ + 0xE7, 0x5C, 0x85, 0x7A, 0x59, 0xB4, 0xE3, 0x1D, + 0xD0, 0x9E, 0xCE, 0xC2, 0xD6, 0xD4, 0xBD, 0x2B +}; + +/* reboot.bin 3.10 */ +u8 keys310_3[0x10] = +{ + 0x2E, 0x00, 0xF6, 0xF7, 0x52, 0xCF, 0x95, 0x5A, + 0xA1, 0x26, 0xB4, 0x84, 0x9B, 0x58, 0x76, 0x2F +}; + +/* kernel modules 3.30 */ +u8 keys330_0[0x10] = +{ + 0x3B, 0x9B, 0x1A, 0x56, 0x21, 0x80, 0x14, 0xED, + 0x8E, 0x8B, 0x08, 0x42, 0xFA, 0x2C, 0xDC, 0x3A +}; + +/* user modules 3.30 */ +u8 keys330_1[0x10] = +{ + 0xE8, 0xBE, 0x2F, 0x06, 0xB1, 0x05, 0x2A, 0xB9, + 0x18, 0x18, 0x03, 0xE3, 0xEB, 0x64, 0x7D, 0x26 +}; + +/* vshmain 3.30 */ +u8 keys330_2[0x10] = +{ + 0xAB, 0x82, 0x25, 0xD7, 0x43, 0x6F, 0x6C, 0xC1, + 0x95, 0xC5, 0xF7, 0xF0, 0x63, 0x73, 0x3F, 0xE7 +}; + +/* reboot.bin 3.30 */ +u8 keys330_3[0x10] = +{ + 0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F, + 0x38, 0x4C, 0x4D, 0x96, 0xBD, 0x49, 0xEC, 0x9B +}; + +/* stdio.prx 3.30 */ +u8 keys330_4[0x10] = +{ + 0xEC, 0x3B, 0xD2, 0xC0, 0xFA, 0xC1, 0xEE, 0xB9, + 0x9A, 0xBC, 0xFF, 0xA3, 0x89, 0xF2, 0x60, 0x1F +}; + +/* 3.60 common kernel modules */ +u8 keys360_0[16] = +{ + 0x3C, 0x2B, 0x51, 0xD4, 0x2D, 0x85, 0x47, 0xDA, + 0x2D, 0xCA, 0x18, 0xDF, 0xFE, 0x54, 0x09, 0xED +}; + +/* 3.60 specific slim kernel modules */ +u8 keys360_1[16] = +{ + 0x31, 0x1F, 0x98, 0xD5, 0x7B, 0x58, 0x95, 0x45, + 0x32, 0xAB, 0x3A, 0xE3, 0x89, 0x32, 0x4B, 0x34 +}; + +/* 3.70 common and fat kernel modules */ +u8 keys370_0[0x10] = +{ + 0x26, 0x38, 0x0A, 0xAC, 0xA5, 0xD8, 0x74, 0xD1, + 0x32, 0xB7, 0x2A, 0xBF, 0x79, 0x9E, 0x6D, 0xDB +}; + +/* 3.70 slim specific kernel modules */ +u8 keys370_1[0x10] = +{ + 0x53, 0xE7, 0xAB, 0xB9, 0xC6, 0x4A, 0x4B, 0x77, + 0x92, 0x17, 0xB5, 0x74, 0x0A, 0xDA, 0xA9, 0xEA +}; + +/* some 3.70 slim user modules */ +u8 keys370_2[16] = +{ + 0x71, 0x10, 0xF0, 0xA4, 0x16, 0x14, 0xD5, 0x93, + 0x12, 0xFF, 0x74, 0x96, 0xDF, 0x1F, 0xDA, 0x89 +}; + +/* 3.90 kernel */ +u8 keys390_0[16] = +{ + 0x45, 0xEF, 0x5C, 0x5D, 0xED, 0x81, 0x99, 0x84, + 0x12, 0x94, 0x8F, 0xAB, 0xE8, 0x05, 0x6D, 0x7D +}; + +/* 3.90 slim */ +u8 keys390_1[16] = +{ + 0x70, 0x1B, 0x08, 0x25, 0x22, 0xA1, 0x4D, 0x3B, + 0x69, 0x21, 0xF9, 0x71, 0x0A, 0xA8, 0x41, 0xA9 +}; + +/* 5.00 kernel */ +u8 keys500_0[16] = +{ + 0xEB, 0x1B, 0x53, 0x0B, 0x62, 0x49, 0x32, 0x58, + 0x1F, 0x83, 0x0A, 0xF4, 0x99, 0x3D, 0x75, 0xD0 +}; + +/* 5.00 kernel 2000 specific */ +u8 keys500_1[16] = +{ + 0xBA, 0xE2, 0xA3, 0x12, 0x07, 0xFF, 0x04, 0x1B, + 0x64, 0xA5, 0x11, 0x85, 0xF7, 0x2F, 0x99, 0x5B +}; + +/* 5.00 kernel 3000 specific */ +u8 keys500_2[16] = +{ + 0x2C, 0x8E, 0xAF, 0x1D, 0xFF, 0x79, 0x73, 0x1A, + 0xAD, 0x96, 0xAB, 0x09, 0xEA, 0x35, 0x59, 0x8B +}; + +u8 keys500_c[16] = +{ + 0xA3, 0x5D, 0x51, 0xE6, 0x56, 0xC8, 0x01, 0xCA, + 0xE3, 0x77, 0xBF, 0xCD, 0xFF, 0x24, 0xDA, 0x4D +}; + +u8 keys505_a[16] = +{ + 0x7B, 0x94, 0x72, 0x27, 0x4C, 0xCC, 0x54, 0x3B, + 0xAE, 0xDF, 0x46, 0x37, 0xAC, 0x01, 0x4D, 0x87 +}; + +u8 keys505_0[16] = +{ + 0x2E, 0x8E, 0x97, 0xA2, 0x85, 0x42, 0x70, 0x73, + 0x18, 0xDA, 0xA0, 0x8A, 0xF8, 0x62, 0xA2, 0xB0 +}; + +u8 keys505_1[16] = +{ + 0x58, 0x2A, 0x4C, 0x69, 0x19, 0x7B, 0x83, 0x3D, + 0xD2, 0x61, 0x61, 0xFE, 0x14, 0xEE, 0xAA, 0x11 +}; + +/* for psp 2000 file table and ipl pre-decryption */ +u8 keys02G_E[0x10] = +{ + 0x9D, 0x09, 0xFD, 0x20, 0xF3, 0x8F, 0x10, 0x69, + 0x0D, 0xB2, 0x6F, 0x00, 0xCC, 0xC5, 0x51, 0x2E +}; + +/* for psp 3000 file table and ipl pre-decryption */ +u8 keys03G_E[0x10] = +{ + 0x4F, 0x44, 0x5C, 0x62, 0xB3, 0x53, 0xC4, 0x30, + 0xFC, 0x3A, 0xA4, 0x5B, 0xEC, 0xFE, 0x51, 0xEA +}; + +/* for psp go file table and ipl pre-decryption */ +u8 keys05G_E[0x10] = +{ + 0x5D, 0xAA, 0x72, 0xF2, 0x26, 0x60, 0x4D, 0x1C, + 0xE7, 0x2D, 0xC8, 0xA3, 0x2F, 0x79, 0xC5, 0x54 +}; + +/* 5.70 PSPgo kernel*/ +u8 keys570_5k[0x10] = +{ + 0x6D, 0x72, 0xA4, 0xBA, 0x7F, 0xBF, 0xD1, 0xF1, + 0xA9, 0xF3, 0xBB, 0x07, 0x1B, 0xC0, 0xB3, 0x66 +}; + +/* 6.00-6.20 kernel and phat */ +u8 keys620_0[0x10] = +{ + 0xD6, 0xBD, 0xCE, 0x1E, 0x12, 0xAF, 0x9A, 0xE6, + 0x69, 0x30, 0xDE, 0xDA, 0x88, 0xB8, 0xFF, 0xFB +}; + +/* 6.00-6.20 slim kernel */ +u8 keys620_1[0x10] = +{ + 0x1D, 0x13, 0xE9, 0x50, 0x04, 0x73, 0x3D, 0xD2, + 0xE1, 0xDA, 0xB9, 0xC1, 0xE6, 0x7B, 0x25, 0xA7 +}; + +u8 keys620_a[0x10] = +{ + 0xAC, 0x34, 0xBA, 0xB1, 0x97, 0x8D, 0xAE, 0x6F, + 0xBA, 0xE8, 0xB1, 0xD6, 0xDF, 0xDF, 0xF1, 0xA2 +}; + +u8 keys620_e[0x10] = +{ + 0xB1, 0xB3, 0x7F, 0x76, 0xC3, 0xFB, 0x88, 0xE6, + 0xF8, 0x60, 0xD3, 0x35, 0x3C, 0xA3, 0x4E, 0xF3 +}; + +/* PSPgo internal */ +u8 keys620_5[0x10] = +{ + 0xF1, 0xBC, 0x17, 0x07, 0xAE, 0xB7, 0xC8, 0x30, + 0xD8, 0x34, 0x9D, 0x40, 0x6A, 0x8E, 0xDF, 0x4E +}; + +/* 6.XX PSPgo kernel */ +u8 keys620_5k[0x10] = +{ + 0x41, 0x8A, 0x35, 0x4F, 0x69, 0x3A, 0xDF, 0x04, + 0xFD, 0x39, 0x46, 0xA2, 0x5C, 0x2D, 0xF2, 0x21 +}; + +u8 keys620_5v[0x10] = +{ + 0xF2, 0x8F, 0x75, 0xA7, 0x31, 0x91, 0xCE, 0x9E, + 0x75, 0xBD, 0x27, 0x26, 0xB4, 0xB4, 0x0C, 0x32 +}; + +/* 6.30 phat kernel */ +u8 keys630_k1[0x10] = { + 0x36, 0xB0, 0xDC, 0xFC, 0x59, 0x2A, 0x95, 0x1D, + 0x80, 0x2D, 0x80, 0x3F, 0xCD, 0x30, 0xA0, 0x1B, +}; + +/* 6.30 phat kernel-2 */ +u8 keys630_k2[0x10] = { + 0xd4, 0x35, 0x18, 0x02, 0x29, 0x68, 0xfb, 0xa0, + 0x6a, 0xa9, 0xa5, 0xed, 0x78, 0xfd, 0x2e, 0x9d +}; + +u8 key_380280f0[0x10] = +{ + 0x97, 0x09, 0x12, 0xD3, 0xDB, 0x02, 0xBD, 0xD8, + 0xE7, 0x74, 0x51, 0xFE, 0xF0, 0xEA, 0x6C, 0x5C, +}; + +/* 6.30 slim kernel */ +u8 keys630_k3[0x10] = +{ + 0x23, 0x8D, 0x3D, 0xAE, 0x41, 0x50, 0xA0, 0xFA, + 0xF3, 0x2F, 0x32, 0xCE, 0xC7, 0x27, 0xCD, 0x50, +}; + +/* 6.30 slim pops */ +u8 keys630_k4[0x10] = +{ + 0xAA, 0xA1, 0xB5, 0x7C, 0x93, 0x5A, 0x95, 0xBD, + 0xEF, 0x69, 0x16, 0xFC, 0x2B, 0x92, 0x31, 0xDD +}; + +u8 keys630_k5[0x10] = { 0x87,0x37,0x21,0xCC,0x65,0xAE,0xAA,0x5F,0x40,0xF6,0x6F,0x2A,0x86,0xC7,0xA1,0xC8 }; +u8 keys630_k6[0x10] = { 0x8D,0xDB,0xDC,0x5C,0xF2,0x70,0x2B,0x40,0xB2,0x3D,0x00,0x09,0x61,0x7C,0x10,0x60 }; +u8 keys630_k7[0x10] = { 0x77,0x1C,0x06,0x5F,0x53,0xEC,0x3F,0xFC,0x22,0xCE,0x5A,0x27,0xFF,0x78,0xA8,0x48 }; +u8 keys630_k8[0x10] = { 0x81,0xD1,0x12,0x89,0x35,0xC8,0xEA,0x8B,0xE0,0x02,0x2D,0x2D,0x6A,0x18,0x67,0xB8 }; + +u8 keys636_k1[0x10] = { 0x07,0xE3,0x08,0x64,0x7F,0x60,0xA3,0x36,0x6A,0x76,0x21,0x44,0xC9,0xD7,0x06,0x83 }; +u8 keys636_k2[0x10] = { 0x91,0xF2,0x02,0x9E,0x63,0x32,0x30,0xA9,0x1D,0xDA,0x0B,0xA8,0xB7,0x41,0xA3,0xCC }; + +u8 keys600_1[0x10] = { 0xE3,0x52,0x39,0x97,0x3B,0x84,0x41,0x1C,0xC3,0x23,0xF1,0xB8,0xA9,0x09,0x4B,0xF0 }; +u8 keys600_2[0x10] = { 0xE1,0x45,0x93,0x2C,0x53,0xE2,0xAB,0x06,0x6F,0xB6,0x8F,0x0B,0x66,0x91,0xE7,0x1E }; + +u8 key_380283F0[0x10] = { 0x34,0x20,0x0C,0x8E,0xA1,0x86,0x79,0x84,0xAF,0x13,0xAE,0x34,0x77,0x6F,0xEA,0x89 }; + +u8 keys620_upd[0x10] = { 0xE2,0x03,0x8A,0x8C,0x33,0x81,0x4B,0x56,0x52,0x4E,0x1D,0xE5,0xA4,0x24,0x04,0xFF }; + +typedef struct +{ + u32 tag; // 4 byte value at offset 0xD0 in the PRX file + u8 *key; // 16 bytes keys + u8 code; // code for scramble + u8 type; +} TAG_INFO2; + +static TAG_INFO2 g_tagInfo2[] = +{ + { 0xA6E328F0, keys620_upd, 0x5F }, // 5.70, 6.10, 6.20 PSPgo Updater + + { 0x4C948AF0, keys636_k1, 0x43, 3}, // 6.36 + { 0x4C948BF0, keys636_k2, 0x43, 3}, // 6.36 02g + + { 0x457b80f0, keys630_k2, 0x5B, 3}, // 6.30 + { 0x457B81F0, keys630_k4, 0x5B, 3}, // 6.30 02g + { 0x457B82F0, keys630_k5, 0x5B, 3}, // 6.30 03g 04g 07g 09g + { 0x457B83F0, keys630_k7, 0x5B, 3}, // 6.30 05g + { 0x4C9484F0, keys630_k1, 0x43, 3}, // 6.30 + { 0x4C9485F0, keys630_k3, 0x43, 3}, // 6.30 02g + { 0x4C9486F0, keys630_k6, 0x43, 3}, // 6.30 03g 04g 07g 09g + { 0x4C9487F0, keys630_k8, 0x43, 3}, // 6.30 05g + + { 0x380283F0, key_380283F0, 0x5A, 3}, // 6.30 vshmain 05g + { 0x380280f0, key_380280f0, 0x5A, 3}, // 6.30 vshmain + + { 0x457B28F0, keys620_e, 0x5B }, + { 0x457B0CF0, keys620_a, 0x5B }, + { 0x380228F0, keys620_5v, 0x5A }, // PSPgo 6.XX vshmain + { 0x4C942AF0, keys620_5k, 0x43 }, // PSPgo 6.XX + { 0x4C9428F0, keys620_5 , 0x43 }, // PSPgo + { 0x4C9422F0, keys600_2, 0x43 }, // 6.00 03g 04g + { 0x4C941EF0, keys600_1, 0x43 }, + { 0x4C941DF0, keys620_1, 0x43 }, + { 0x4C941CF0, keys620_0, 0x43 }, + { 0x4C9429F0, keys570_5k, 0x43 }, // PSPgo 5.70 + { 0x4C9419F0, keys505_1, 0x43 }, + { 0x4C9418F0, keys505_0, 0x43 }, + { 0x457B0BF0, keys505_a, 0x5B }, + { 0x457B1EF0, keys500_c, 0x5B }, + { 0x4C941FF0, keys500_2, 0x43 }, + { 0x4C9417F0, keys500_1, 0x43 }, + { 0x4C9416F0, keys500_0, 0x43 }, + { 0x4C9415F0, keys390_1, 0x43 }, + { 0x4C9414F0, keys390_0, 0x43 }, + { 0x4C9412F0, keys370_0, 0x43 }, + { 0x4C9413F0, keys370_1, 0x43 }, + { 0x457B10F0, keys370_2, 0x5B }, + + { 0xD82310F0, keys02G_E, 0x51 }, + { 0xD8231EF0, keys03G_E, 0x51 }, + { 0xD82328F0, keys05G_E, 0x51 }, + + { 0x4C940DF0, keys360_0, 0x43 }, + { 0x4C9410F0, keys360_1, 0x43 }, + + { 0x4C940BF0, keys330_0, 0x43 }, + { 0x457B0AF0, keys330_1, 0x5B }, + { 0x38020AF0, keys330_2, 0x5A }, + { 0x4C940AF0, keys330_3, 0x43 }, + { 0x4C940CF0, keys330_4, 0x43 }, + + { 0xcfef09f0, keys310_0, 0x62 }, + { 0x457b08f0, keys310_1, 0x5B }, + { 0x380208F0, keys310_2, 0x5A }, + { 0xcfef08f0, keys310_3, 0x62 }, + + { 0xCFEF07F0, keys303_0, 0x62 }, + { 0xCFEF06F0, keys300_0, 0x62 }, + { 0x457B06F0, keys300_1, 0x5B }, + { 0x380206F0, keys300_2, 0x5A }, + + { 0xCFEF05F0, keys280_0, 0x62 }, + { 0x457B05F0, keys280_1, 0x5B }, + { 0x380205F0, keys280_2, 0x5A }, + { 0x16D59E03, keys260_0, 0x62 }, + { 0x76202403, keys260_1, 0x5B }, + { 0x0F037303, keys260_2, 0x5A } +}; + + +static TAG_INFO2 *GetTagInfo2(u32 tagFind) +{ + int iTag; + + for (iTag = 0; iTag < sizeof(g_tagInfo2) / sizeof(TAG_INFO2); iTag++) + { + if (g_tagInfo2[iTag].tag == tagFind) + { + return &g_tagInfo2[iTag]; + } + } + + return NULL; // not found +} + +static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag) +{ + TAG_INFO2 * pti = GetTagInfo2(tag); + + if (!pti) + { + //Kprintf("Unknown tag 0x%08X.\n", tag); + return -1; + } + + int retsize = *(int *)&inbuf[0xB0]; + u8 tmp1[0x150], tmp2[0x90+0x14], tmp3[0x60+0x14], tmp4[0x20]; + + memset(tmp1, 0, 0x150); + memset(tmp2, 0, 0x90+0x14); + memset(tmp3, 0, 0x60+0x14); + memset(tmp4, 0, 0x20); + + if (inbuf != outbuf) + memcpy(outbuf, inbuf, size); + + if (size < 0x160) + { + Kprintf("Buffer not big enough.\n"); + return -2; + } + + if (((u32)outbuf & 0x3F)) + { + Kprintf("Buffer not aligned to 64 bytes.\n"); + return -3; + } + + if ((size - 0x150) < retsize) + { + Kprintf("No enough data.\n"); + return -4; + } + + memcpy(tmp1, outbuf, 0x150); + + int i, j; + u8 *p = tmp2+0x14; + + for (i = 0; i < 9; i++) + { + for (j = 0; j < 0x10; j++) + { + p[(i << 4) + j] = pti->key[j]; + + } + + p[(i << 4)] = i; + } + + if (Scramble((u32 *)tmp2, 0x90, pti->code) < 0) + { + Kprintf("Error in Scramble #1.\n"); + return -5; + } + + memcpy(outbuf, tmp1+0xD0, 0x5C); + memcpy(outbuf+0x5C, tmp1+0x140, 0x10); + memcpy(outbuf+0x6C, tmp1+0x12C, 0x14); + memcpy(outbuf+0x80, tmp1+0x080, 0x30); + memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10); + memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10); + memcpy(outbuf+0xD0, tmp1+0x000, 0x80); + + memcpy(tmp3+0x14, outbuf+0x5C, 0x60); + + if (Scramble((u32 *)tmp3, 0x60, pti->code) < 0) + { + Kprintf("Error in Scramble #2.\n"); + return -6; + } + + memcpy(outbuf+0x5C, tmp3, 0x60); + memcpy(tmp3, outbuf+0x6C, 0x14); + memcpy(outbuf+0x70, outbuf+0x5C, 0x10); + + if(pti->type == 3) + { + memcpy(tmp4, outbuf+0x3C, 0x20); + memcpy(outbuf+0x50, tmp4, 0x20); + memset(outbuf+0x18, 0, 0x38); + }else + memset(outbuf+0x18, 0, 0x58); + + memcpy(outbuf+0x04, outbuf, 0x04); + *((u32 *)outbuf) = 0x014C; + memcpy(outbuf+0x08, tmp2, 0x10); + + /* sha-1 */ + + if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0) + { + Kprintf("Error in sceUtilsBufferCopyWithRange 0xB.\n"); + return -7; + } + + if (memcmp(outbuf, tmp3, 0x14) != 0) + { + Kprintf("SHA-1 is incorrect.\n"); + return -8; + } + + int iXOR; + + for (iXOR = 0; iXOR < 0x40; iXOR++) + { + tmp3[iXOR+0x14] = outbuf[iXOR+0x80] ^ tmp2[iXOR+0x10]; + } + + if (Scramble((u32 *)tmp3, 0x40, pti->code) != 0) + { + Kprintf("Error in Scramble #2.\n"); + return -9; + } + + for (iXOR = 0x3F; iXOR >= 0; iXOR--) + { + outbuf[iXOR+0x40] = tmp3[iXOR] ^ tmp2[iXOR+0x50]; // uns 8 + } + + if (pti->type == 3) + { + memcpy(outbuf+0x80, tmp4, 0x20); + memset(outbuf+0xA0, 0, 0x10); + *(u32*)&outbuf[0xA4] = 1; + *(u32*)&outbuf[0xA0] = 1; + } else + { + memset(outbuf+0x80, 0, 0x30); + *(u32*)&outbuf[0xA0] = 1; + } + + memcpy(outbuf+0xB0, outbuf+0xC0, 0x10); + memset(outbuf+0xC0, 0, 0x10); + memcpy(outbuf+0xD0, outbuf+0xD0, 0x80); + + // The real decryption + if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf+0x40, size-0x40, 0x1) != 0) + { + Kprintf("Error in sceUtilsBufferCopyWithRange 0x1.\n"); + return -1; + } + + if (retsize < 0x150) + { + // Fill with 0 + memset(outbuf+retsize, 0, 0x150-retsize); + } + + return retsize; +} + +int pspDecryptPRX(u8 *data, u32 size, u32 *out_size) +{ + int retsize = DecryptPRX1(data, data, size, *(u32 *)&data[0xD0]); + + if (retsize <= 0) + { + retsize = DecryptPRX2(data, data, size, *(u32 *)&data[0xD0]); + } + + if (retsize <= 0) + { + return -1; + } + + out_size[0] = retsize; + return 0; +} diff --git a/src/downgrade660_ctrl/utils.c b/src/downgrade660_ctrl/utils.c index ad13890..290121d 100644 --- a/src/downgrade660_ctrl/utils.c +++ b/src/downgrade660_ctrl/utils.c @@ -1,95 +1,95 @@ -/* - Downgrade Control -> utils.c -> Responsible for providing common utilities interfacing the kernel - by Davee - - 30/12/2010 -*/ - -#include -#include - -#include -#include -#include - -#include "utils.h" - -void ClearCaches(void) -{ - sceKernelIcacheClearAll(); - sceKernelDcacheWritebackAll(); -} - -u32 FindFunc(const char *modname, const char *lib, u32 nid) -{ - int i = 0, u; - - /* try and find the module by name */ - SceModule *mod = sceKernelFindModuleByName(modname); - - /* if fail */ - if (!mod) - { - /* fail */ - return 0; - } - - /* copy over the structure data */ - u32 entry_size = mod->ent_size; - u32 entry_start = (u32)mod->ent_top; - - /* loop until end of entry table */ - while (i < entry_size) - { - /* cast structure to memory */ - SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); - - /* if there is a libname, compare it to the lib else if there is no lib and there is no libname */ - if ((entry->libname && (strcmp(entry->libname, lib) == 0)) || (lib == NULL && entry->libname == NULL)) - { - /* copy the table pointer and get the total number of entries */ - u32 *table = entry->entrytable; - int total = entry->stubcount + entry->vstubcount; - - /* if there is some entries continue */ - if (total > 0) - { - /* loop through the entries */ - for (u = 0; u < total; u++) - { - /* if the nid matches */ - if (table[u] == nid) - { - /* return the pointer */ - return table[u + total]; - } - } - } - } - - /* increment the counter */ - i += (entry->len << 2); - } - - /* could not find function */ - return 0; -} - -void PatchSyscall(u32 addr, void *newaddr) -{ - u32 *vectors, i; - - /* get the vectors address from the co-processor */ - __asm__ volatile ("cfc0 %0, $12\n" "nop\n" : "=r" (vectors)); - - /* loop through them */ - for (i = 0; i < 0x1000; i++) - { - /* if this is the address */ - if (vectors[i + 4] == addr) - { - /* then replace it :D */ - vectors[i + 4] = (u32)newaddr; - } - } -} +/* + Downgrade Control -> utils.c -> Responsible for providing common utilities interfacing the kernel + by Davee + + 30/12/2010 +*/ + +#include +#include + +#include +#include +#include + +#include "utils.h" + +void ClearCaches(void) +{ + sceKernelIcacheClearAll(); + sceKernelDcacheWritebackAll(); +} + +u32 FindFunc(const char *modname, const char *lib, u32 nid) +{ + int i = 0, u; + + /* try and find the module by name */ + SceModule2 *mod = (SceModule2 *)sceKernelFindModuleByName(modname); + + /* if fail */ + if (!mod) + { + /* fail */ + return 0; + } + + /* copy over the structure data */ + u32 entry_size = mod->ent_size; + u32 entry_start = (u32)mod->ent_top; + + /* loop until end of entry table */ + while (i < entry_size) + { + /* cast structure to memory */ + SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); + + /* if there is a libname, compare it to the lib else if there is no lib and there is no libname */ + if ((entry->libname && (strcmp(entry->libname, lib) == 0)) || (lib == NULL && entry->libname == NULL)) + { + /* copy the table pointer and get the total number of entries */ + u32 *table = entry->entrytable; + int total = entry->stubcount + entry->vstubcount; + + /* if there is some entries continue */ + if (total > 0) + { + /* loop through the entries */ + for (u = 0; u < total; u++) + { + /* if the nid matches */ + if (table[u] == nid) + { + /* return the pointer */ + return table[u + total]; + } + } + } + } + + /* increment the counter */ + i += (entry->len << 2); + } + + /* could not find function */ + return 0; +} + +void PatchSyscall(u32 addr, void *newaddr) +{ + u32 *vectors, i; + + /* get the vectors address from the co-processor */ + __asm__ volatile ("cfc0 %0, $12\n" "nop\n" : "=r" (vectors)); + + /* loop through them */ + for (i = 0; i < 0x1000; i++) + { + /* if this is the address */ + if (vectors[i + 4] == addr) + { + /* then replace it :D */ + vectors[i + 4] = (u32)newaddr; + } + } +} diff --git a/src/downgrade660_ctrl/utils.h b/src/downgrade660_ctrl/utils.h index 502b667..a14cb90 100644 --- a/src/downgrade660_ctrl/utils.h +++ b/src/downgrade660_ctrl/utils.h @@ -1,46 +1,51 @@ -/* - Downgrade Control -> utils.h -> Provide API documentation and definitions for utilities - by Davee - - 30/12/2010 -*/ -#ifndef __UTILS__H__ -#define __UTILS__H__ - -#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } - -#define KERNEL_HIJACK_FUNCTION(a, f, ptr) { \ - static u32 patch_buffer[3]; \ - _sw(_lw(a + 0x00), (u32)patch_buffer + 0x00); \ - _sw(_lw(a + 0x04), (u32)patch_buffer + 0x08);\ - MAKE_JUMP((u32)patch_buffer + 0x04, a + 0x08); \ - REDIRECT_FUNCTION(a, f); \ - ptr = (void *)patch_buffer; \ - } -/** - Clears both the instruction and data caches -*/ -void ClearCaches(void); - -/** - Allows to modify the kernel address called when a specific syscall is initiated - - @param addr: the address of the kernel function syscall you want to control - @param newaddr: the new address the syscall will call -*/ -void PatchSyscall(u32 addr, void *newaddr); - -/** - Find an export within the system - - @param modname: the name of the module containing the export - @param libname: the library the export belongs to - @param nid: the nid of the export - - @return the address of export else 0 on error -*/ -u32 FindFunc(const char *modname, const char *lib, u32 nid); - -#endif /* __UTILS__H__ */ +/* + Downgrade Control -> utils.h -> Provide API documentation and definitions for utilities + by Davee + + 30/12/2010 +*/ +#ifndef __UTILS__H__ +#define __UTILS__H__ + +#define U_EXTRACT_IMPORT(x) ((((u32)_lw((u32)x)) & ~0x08000000) << 2) +#define K_EXTRACT_IMPORT(x) (((((u32)_lw((u32)x)) & ~0x08000000) << 2) | 0x80000000) +#define U_EXTRACT_CALL(x) ((((u32)_lw((u32)x)) & ~0x0C000000) << 2) +#define K_EXTRACT_CALL(x) (((((u32)_lw((u32)x)) & ~0x0C000000) << 2) | 0x80000000) + +#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } + +#define KERNEL_HIJACK_FUNCTION(a, f, ptr) { \ + static u32 patch_buffer[3]; \ + _sw(_lw(a + 0x00), (u32)patch_buffer + 0x00); \ + _sw(_lw(a + 0x04), (u32)patch_buffer + 0x08);\ + MAKE_JUMP((u32)patch_buffer + 0x04, a + 0x08); \ + REDIRECT_FUNCTION(a, f); \ + ptr = (void *)patch_buffer; \ + } +/** + Clears both the instruction and data caches +*/ +void ClearCaches(void); + +/** + Allows to modify the kernel address called when a specific syscall is initiated + + @param addr: the address of the kernel function syscall you want to control + @param newaddr: the new address the syscall will call +*/ +void PatchSyscall(u32 addr, void *newaddr); + +/** + Find an export within the system + + @param modname: the name of the module containing the export + @param libname: the library the export belongs to + @param nid: the nid of the export + + @return the address of export else 0 on error +*/ +u32 FindFunc(const char *modname, const char *lib, u32 nid); + +#endif /* __UTILS__H__ */ diff --git a/src/downgrade_ctrl/631mapfile.txt b/src/downgrade_ctrl/631mapfile.txt index 38a0c65..7b3d700 100644 --- a/src/downgrade_ctrl/631mapfile.txt +++ b/src/downgrade_ctrl/631mapfile.txt @@ -1,14 +1,14 @@ -@SysMemForKernel -0x55A40B2C:0xF5E82409 //NID RESOLVED -0x9697CD32:0xE10F21CF //NID RESOLVED -0xB2C7AA36:0x00E9A04A //NID RESOLVED -0x3FC9AE6A:0x5E8DCA05 //NID RESOLVED -0x6373995D:0x458A70B5 //NID RESOLVED -@memlmd -0x7CF1CD3E:0xE42AFE2E //NID RESOLVED -@LoadCoreForKernel -0xCF8A41B1:0xEF8A0BEA //NID RESOLVED -0xCCE4A157:0xED53894F //NID RESOLVED -0xD8779AC6:0x8D46E9DF //NID RESOLVED -@ModuleMgrForKernel -0x644395E2:0xA95C26C8 //NID RESOLVED +@SysMemForKernel +0x55A40B2C:0xF5E82409 //NID RESOLVED +0x9697CD32:0xE10F21CF //NID RESOLVED +0xB2C7AA36:0x00E9A04A //NID RESOLVED +0x3FC9AE6A:0x5E8DCA05 //NID RESOLVED +0x6373995D:0x458A70B5 //NID RESOLVED +@memlmd +0x7CF1CD3E:0xE42AFE2E //NID RESOLVED +@LoadCoreForKernel +0xCF8A41B1:0xEF8A0BEA //NID RESOLVED +0xCCE4A157:0xED53894F //NID RESOLVED +0xD8779AC6:0x8D46E9DF //NID RESOLVED +@ModuleMgrForKernel +0x644395E2:0xA95C26C8 //NID RESOLVED diff --git a/src/downgrade_ctrl/Makefile b/src/downgrade_ctrl/Makefile index e3e3e9d..1166e1f 100644 --- a/src/downgrade_ctrl/Makefile +++ b/src/downgrade_ctrl/Makefile @@ -1,27 +1,27 @@ -release: all - psp-fixup-imports -m $(PSP_FW_VERSION)mapfile.txt $(TARGET).prx - psp-packer $(TARGET).prx - bin2c $(TARGET).prx ../$(TARGET).h $(TARGET) - -TARGET = downgrade_ctrl -OBJS = main.o utils.o patch_table.o decrypt.o pspdecrypt.o extra_stubs.o - -INCDIR = ../include -CFLAGS = -Os -G0 -Wall -fno-pic -fshort-wchar -ASFLAGS = $(CFLAGS) - -BUILD_PRX = 1 -PRX_EXPORTS = exports.exp - -PSP_FW_VERSION = 631 - -USE_KERNEL_LIBS=1 -USE_KERNEL_LIBC=1 - -LIBDIR = ../lib -LDFLAGS = -nostartfiles -LIBS = -lpspsystemctrl_kernel - -PSPSDK=$(shell psp-config --pspsdk-path) -include $(PSPSDK)/lib/build.mak - +release: all + psp-fixup-imports -m $(PSP_FW_VERSION)mapfile.txt $(TARGET).prx + psp-packer $(TARGET).prx + bin2c $(TARGET).prx ../$(TARGET).h $(TARGET) + +TARGET = downgrade_ctrl +OBJS = main.o utils.o patch_table.o decrypt.o pspdecrypt.o extra_stubs.o ../libasm/libinfinityKernel.o + +INCDIR = ../include +CFLAGS = -Os -G0 -Wall -fno-pic -fshort-wchar +ASFLAGS = $(CFLAGS) + +BUILD_PRX = 1 +PRX_EXPORTS = exports.exp + +PSP_FW_VERSION = 631 + +USE_KERNEL_LIBS=1 +USE_KERNEL_LIBC=1 + +LIBDIR = ../lib +LDFLAGS = -nostartfiles +LIBS = -lpspsystemctrl_kernel + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak + diff --git a/src/downgrade_ctrl/decrypt.c b/src/downgrade_ctrl/decrypt.c index 8d4ca1e..2774f0b 100644 --- a/src/downgrade_ctrl/decrypt.c +++ b/src/downgrade_ctrl/decrypt.c @@ -1,93 +1,93 @@ -/* - Downgrade Control -> decrypt.c -> Responsible for decryption patches and hooks - by Davee - - 31/12/2010 -*/ - -#include -#include - -#include -#include -#include - -#include "decrypt.h" -#include "patch_table.h" - -int pspDecryptPRX(void *exec, u32 exec_size, u32 *out_size); - -int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize) = NULL; -extern u32 g_spoof_ver; - -int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize) -{ - /* call the original function to decrypt the index.dat */ - int res = sceResmgr_driver_9DC14891(data, datasize, outsize); - - /* if there is a firmware version, we will generate a version.txt to downgrade */ - if (g_spoof_ver) - { - sprintf( data, - "release:%01X.%01X%01X:\n" - "build:0000,0,3,1,0:builder@vsh-build6\n" - "system:56422@release_%03X,0x%08X:\n" - "vsh:p6576@release_%03X,v57929@release_%03X,20100625:\n" - "target:1:WorldWide\n", - /* first line, version (X.YZ) */ (g_spoof_ver >> 8) & 0xF, (g_spoof_ver >> 4) & 0xF, g_spoof_ver & 0xF, - /* third line, release_XYZ + devkit */ g_spoof_ver, (((g_spoof_ver >> 8) & 0xF) << 24) | (((g_spoof_ver >> 4) & 0xF) << 16) | ((g_spoof_ver & 0xF) << 8) | 0x10, - /* forth line, release_XYZ + release_XYZ */ g_spoof_ver, g_spoof_ver - ); - } - - /* return the decryption result */ - return res; -} - -void PatchMesgled(u32 text_addr) -{ - /* if firmware is >= 6.30 */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - int model = sceKernelGetModel(); - if(model == 6 || model == 8) - { - model = 3; - } - - /* Patch mesgled to allow older updaters to boot */ - _sw(0, text_addr + g_patch_table.new_updater_check[model]); - } -} - -int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 exec_size, u32 *out_size) -{ - /* do sony decryption */ - int res = sceMesgLed_driver_81F72B1F(exec, exec_size, out_size); - - /* check for error */ - if (res != 0) - { - /* lets decrypt */ - res = pspDecryptPRX(exec, exec_size, out_size); - } - - /* return result */ - return res; -} - -int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size) -{ - /* do sony decryption */ - int res = memlmd_7CF1CD3E(exec, exec_size, out_size); - - /* check for error */ - if (res != 0) - { - /* lets decrypt */ - res = pspDecryptPRX(exec, exec_size, out_size); - } - - /* return result */ - return res; -} +/* + Downgrade Control -> decrypt.c -> Responsible for decryption patches and hooks + by Davee + + 31/12/2010 +*/ + +#include +#include + +#include +#include +#include + +#include "decrypt.h" +#include "patch_table.h" + +int pspDecryptPRX(void *exec, u32 exec_size, u32 *out_size); + +int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize) = NULL; +extern u32 g_spoof_ver; + +int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize) +{ + /* call the original function to decrypt the index.dat */ + int res = sceResmgr_driver_9DC14891(data, datasize, outsize); + + /* if there is a firmware version, we will generate a version.txt to downgrade */ + if (g_spoof_ver) + { + sprintf( data, + "release:%01X.%01X%01X:\n" + "build:0000,0,3,1,0:builder@vsh-build6\n" + "system:56422@release_%03X,0x%08X:\n" + "vsh:p6576@release_%03X,v57929@release_%03X,20100625:\n" + "target:1:WorldWide\n", + /* first line, version (X.YZ) */ (g_spoof_ver >> 8) & 0xF, (g_spoof_ver >> 4) & 0xF, g_spoof_ver & 0xF, + /* third line, release_XYZ + devkit */ g_spoof_ver, (((g_spoof_ver >> 8) & 0xF) << 24) | (((g_spoof_ver >> 4) & 0xF) << 16) | ((g_spoof_ver & 0xF) << 8) | 0x10, + /* forth line, release_XYZ + release_XYZ */ g_spoof_ver, g_spoof_ver + ); + } + + /* return the decryption result */ + return res; +} + +void PatchMesgled(u32 text_addr) +{ + /* if firmware is >= 6.30 */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + int model = sceKernelGetModel(); + if(model == 6 || model == 8) + { + model = 3; + } + + /* Patch mesgled to allow older updaters to boot */ + _sw(0, text_addr + g_patch_table.new_updater_check[model]); + } +} + +int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 exec_size, u32 *out_size) +{ + /* do sony decryption */ + int res = sceMesgLed_driver_81F72B1F(exec, exec_size, out_size); + + /* check for error */ + if (res != 0) + { + /* lets decrypt */ + res = pspDecryptPRX(exec, exec_size, out_size); + } + + /* return result */ + return res; +} + +int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size) +{ + /* do sony decryption */ + int res = memlmd_7CF1CD3E(exec, exec_size, out_size); + + /* check for error */ + if (res != 0) + { + /* lets decrypt */ + res = pspDecryptPRX(exec, exec_size, out_size); + } + + /* return result */ + return res; +} diff --git a/src/downgrade_ctrl/decrypt.h b/src/downgrade_ctrl/decrypt.h index 81add0c..a39d38e 100644 --- a/src/downgrade_ctrl/decrypt.h +++ b/src/downgrade_ctrl/decrypt.h @@ -1,80 +1,80 @@ -/* - Downgrade Control -> decrypt.h -> Provide API documentation and definitions - by Davee - - 31/12/2010 -*/ -#ifndef __DECRYPT_H__ -#define __DECRYPT_H__ - -/* our functions */ -void PatchMesgled(u32 text_addr); -int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size); -int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize); -int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 size, u32 *outsize); - -extern int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize); - -/* prototypes */ -int memlmd_7CF1CD3E(void *exec, u32 exec_size, u32 *out_size); -int sceResmgr_driver_9DC14891(void *data, u32 datasize, u32 *outsize); -int sceUtilsBufferCopyWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); -int sceUtilsBufferCopyByPollingWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); -int sceKernelPowerLock(void); -int sceKernelPowerUnlock(void); - -/* data structures */ -typedef struct -{ - u32 tag; - u8 key[16]; -} mesgled_keys_struct; - -typedef struct -{ - u32 signature; //0 - u16 mod_attribute; //4 - u16 comp_attribute; //6 - u8 module_ver_lo; //8 - u8 module_ver_hi; //9 - char modname[28]; //0xA - u8 mod_version; //0x26 - u8 nsegments; //0x27 - u32 elf_size; //0x28 - u32 psp_size; //0x2C - u32 boot_entry; //0x30 - u32 modinfo_offset; //0x34 - int bss_size; //0x38 - u16 seg_align[4]; //0x3C - u32 seg_address[4]; //0x44 - int seg_size[4]; //0x54 - u32 reserved[5]; //0x64 - u32 devkit_version; //0x78 - u8 decrypt_mode; //0x7C - u8 padding; //0x7D - u16 overlap_size; //0x7E - u8 key_data[0x30]; //0x80 - u32 comp_size; //0xB0 - int _80; //0xB4 - u32 unk_B8; //0xB8 - u32 unk_BC; //0xBC - u8 key_data2[0x10]; //0xC0 - u32 tag; //0xD0 - u8 scheck[0x58]; //0xD4 - u8 sha1_hash[0x14]; //0x12C - u8 key_data4[0x10]; //0x140 -} PSP_Header2; //0x150 - -typedef struct -{ - u32 mode; //0 - u32 unk_4; - u32 unk_8; - u32 keyseed; //12 - u32 size; //16 -} KIRK_CMD_HEADER; //20 - -#define KIRK_CMD_7 (7) -#define KIRK_CMD_SHA1 (0xB) - -#endif /* __DECRYPT_H__ */ +/* + Downgrade Control -> decrypt.h -> Provide API documentation and definitions + by Davee + + 31/12/2010 +*/ +#ifndef __DECRYPT_H__ +#define __DECRYPT_H__ + +/* our functions */ +void PatchMesgled(u32 text_addr); +int memlmd_7CF1CD3E_patched(void *exec, u32 exec_size, u32 *out_size); +int sceResmgr_9DC14891_patched(void *data, u32 datasize, u32 *outsize); +int sceMesgLed_driver_81F72B1F_patched(void *exec, u32 size, u32 *outsize); + +extern int (* sceMesgLed_driver_81F72B1F)(void *exec, u32 size, u32 *outsize); + +/* prototypes */ +int memlmd_7CF1CD3E(void *exec, u32 exec_size, u32 *out_size); +int sceResmgr_driver_9DC14891(void *data, u32 datasize, u32 *outsize); +int sceUtilsBufferCopyWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); +int sceUtilsBufferCopyByPollingWithRange(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd); +int sceKernelPowerLock(void); +int sceKernelPowerUnlock(void); + +/* data structures */ +typedef struct +{ + u32 tag; + u8 key[16]; +} mesgled_keys_struct; + +typedef struct +{ + u32 signature; //0 + u16 mod_attribute; //4 + u16 comp_attribute; //6 + u8 module_ver_lo; //8 + u8 module_ver_hi; //9 + char modname[28]; //0xA + u8 mod_version; //0x26 + u8 nsegments; //0x27 + u32 elf_size; //0x28 + u32 psp_size; //0x2C + u32 boot_entry; //0x30 + u32 modinfo_offset; //0x34 + int bss_size; //0x38 + u16 seg_align[4]; //0x3C + u32 seg_address[4]; //0x44 + int seg_size[4]; //0x54 + u32 reserved[5]; //0x64 + u32 devkit_version; //0x78 + u8 decrypt_mode; //0x7C + u8 padding; //0x7D + u16 overlap_size; //0x7E + u8 key_data[0x30]; //0x80 + u32 comp_size; //0xB0 + int _80; //0xB4 + u32 unk_B8; //0xB8 + u32 unk_BC; //0xBC + u8 key_data2[0x10]; //0xC0 + u32 tag; //0xD0 + u8 scheck[0x58]; //0xD4 + u8 sha1_hash[0x14]; //0x12C + u8 key_data4[0x10]; //0x140 +} PSP_Header2; //0x150 + +typedef struct +{ + u32 mode; //0 + u32 unk_4; + u32 unk_8; + u32 keyseed; //12 + u32 size; //16 +} KIRK_CMD_HEADER; //20 + +#define KIRK_CMD_7 (7) +#define KIRK_CMD_SHA1 (0xB) + +#endif /* __DECRYPT_H__ */ diff --git a/src/downgrade_ctrl/exports.exp b/src/downgrade_ctrl/exports.exp index 6a4c945..a20b057 100644 --- a/src/downgrade_ctrl/exports.exp +++ b/src/downgrade_ctrl/exports.exp @@ -1,11 +1,11 @@ -# Define the exports for the prx -PSP_BEGIN_EXPORTS - -# These four lines are mandatory (although you can add other functions like module_stop) -# syslib is a psynonym for the single mandatory export. -PSP_EXPORT_START(syslib, 0, 0x8000) -PSP_EXPORT_FUNC_NID(module_start,0xD3744BE0) -PSP_EXPORT_VAR_HASH(module_info) -PSP_EXPORT_END - -PSP_END_EXPORTS +# Define the exports for the prx +PSP_BEGIN_EXPORTS + +# These four lines are mandatory (although you can add other functions like module_stop) +# syslib is a psynonym for the single mandatory export. +PSP_EXPORT_START(syslib, 0, 0x8000) +PSP_EXPORT_FUNC_NID(module_start,0xD3744BE0) +PSP_EXPORT_VAR_HASH(module_info) +PSP_EXPORT_END + +PSP_END_EXPORTS diff --git a/src/downgrade_ctrl/main.c b/src/downgrade_ctrl/main.c index 7486418..b3636c9 100644 --- a/src/downgrade_ctrl/main.c +++ b/src/downgrade_ctrl/main.c @@ -1,373 +1,391 @@ -/* - Downgrade Control -> Restore kernel patches and enforce updater launch - by Davee - - 31/12/2010 -*/ - -#include -#include -#include - -#include -#include -#include - -#include "utils.h" -#include "patch_table.h" -#include "decrypt.h" - -PSP_MODULE_INFO("DowngraderCTRL", 0x3007, 1, 0); - -/* function pointers */ -int (* PrologueModule)(void *modmgr_param, SceModule *mod) = NULL; -STMOD_HANDLER previous = NULL; - -typedef struct __attribute__((packed)) -{ - int magic; // 0 - int version; // 4 - unsigned int keyofs; // 8 - unsigned int valofs; // 12 - int count; // 16 -} SfoHeader; - -typedef struct __attribute__((packed)) -{ - unsigned short nameofs; // 0 - char alignment; // 2 - char type; // 3 - int valsize; // 4 - int totalsize; // 8 - unsigned short valofs; // 12 - short unknown; // 16 -} SfoEntry; - -u32 g_spoof_ver = 0; -u8 g_sfo_buffer[4 << 10]; - -int ApplyFirmware(void) -{ - int i; - char *fw_data = NULL; - u8 device_fw_ver[4]; - u32 pbp_header[0x28/4]; - SfoHeader *header = (SfoHeader *)g_sfo_buffer; - SfoEntry *entries = (SfoEntry *)((char *)g_sfo_buffer + sizeof(SfoHeader)); - - /* Lets open the updater */ - char *file = (sceKernelGetModel() == 4) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.pbp") : ("ms0:/PSP/GAME/UPDATE/EBOOT.pbp"); - - /* set k1 */ - u32 k1 = pspSdkSetK1(0); - - /* lets open the file */ - SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); - - /* check for failure */ - if (fd < 0) - { - /* rage */ - pspSdkSetK1(k1); - return fd; - } - - /* read the PBP header */ - sceIoRead(fd, pbp_header, sizeof(pbp_header)); - - /* seek to the SFO */ - sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); - - /* calculate the size of the SFO */ - u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; - - /* check if greater than buffer size */ - if (sfo_size > sizeof(g_sfo_buffer)) - { - /* too much */ - pspSdkSetK1(k1); - return -2; - } - - /* read the sfo */ - sceIoRead(fd, g_sfo_buffer, sizeof(g_sfo_buffer)); - - /* close the file */ - sceIoClose(fd); - - /* now parse the SFO */ - for (i = 0; i < header->count; i++) - { - /* check this name */ - if (strcmp((char *)((char *)g_sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) - { - /* get the string */ - fw_data = (char *)((char *)g_sfo_buffer + header->valofs + entries[i].valofs); - break; - } - } - - /* see if we went through all the data */ - if (i == header->count) - { - /* error */ - pspSdkSetK1(k1); - return -3; - } - - /* ok, we have the firmware version in the eboot. */ - u32 min_ver = 0; - u32 updater_ver = (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); - - /* ok, now get the idstorage value */ - int res = sceIdStorageLookup(0x51, 0, device_fw_ver, 4); - - /* check for error */ - if (res < 0) - { - /* check model */ - if (sceKernelGetModel() != 0) - { - /* invalid error */ - return -4; - } - - /* firmware 1.00 */ - min_ver = 0x100; - } - else - { - /* convert to hex */ - min_ver = (((device_fw_ver[0] - '0') & 0xF) << 8) | (((device_fw_ver[2] - '0') & 0xF) << 4) | (((device_fw_ver[3] - '0') & 0xF) << 0); - } - - /* set the result to 0 */ - res = 0; - - /* check if the updater is less than the minimum version */ - if (updater_ver < min_ver) - { - /* ok, check for 6.35 and 09g */ - if ((min_ver != 0x630 && min_ver != 0x635) || sceKernelGetModel() != 8) - { - /* error */ - pspSdkSetK1(k1); - return -5; - } - - /* set result to 1 D: */ - res = 1; - } - - /* do spoof! */ - g_spoof_ver = updater_ver; - pspSdkSetK1(k1); - return res; -} - -#define INDEXFILE "flash0:/vsh/etc/index_04g.dat" -#define NEW_INDEXFILE "flash0:/vsh/etc/index_09g.dat" - -SceUID sceIoOpenPatched(char *file, u32 mode, u32 mode2) -{ - /* check indexfile */ - if (strcmp(file, INDEXFILE) == 0) - { - /* if read mode, copy */ - if (mode == PSP_O_RDONLY) - { - strcpy(file, NEW_INDEXFILE); - } - } - - /* call original function */ - return sceIoOpen(file, mode, mode2); -} - -int sceIoGetstatPatched(char *file, SceIoStat *stat) -{ - /* check indexfile */ - if (strcmp(file, INDEXFILE) == 0) - { - strcpy(file, NEW_INDEXFILE); - } - - /* call original function */ - return sceIoGetstat(file, stat); -} - -/* idstorage patching func */ -int (* pspUtilsBufferCopyWithRange)(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) = NULL; -int sceUtilsBufferCopyWithRangePatched(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) -{ - u8 ids_cert[0xB8]; - - /* if idstorage check */ - if (cmd == 0x12) - { - /* ok lets get the idstorage 0x100 key */ - int res = sceIdStorageLookup(0x100, 0x38, ids_cert, 0xB8); - - /* check for error */ - if (res < 0) - { - /* attempt with backup key */ - res = sceIdStorageLookup(0x120, 0x38, ids_cert, 0xB8); - - /* if error, exit */ - if (res < 0) - { - return res; - } - } - - /* yay its 0x100 key */ - /* change the model to 04g */ - ids_cert[7] = 6; - - /* copy the new certificate back */ - memcpy(src, ids_cert, sizeof(ids_cert)); - return 0; - } - - /* return function */ - return pspUtilsBufferCopyWithRange(dst, dst_size, src, src_size, cmd); -} - -int OnModuleStart(SceModule *mod) -{ - if (strcmp(mod->modname, "sceMesgLed") == 0) - { - PatchMesgled(mod->text_addr); - ClearCaches(); - } - - else if (strcmp(mod->modname, "updater") == 0) - { - /* ok, lets see what we're doing here! */ - int res = ApplyFirmware(); - - /* check for success */ - if (res >= 0) - { - /* do these patches if we have 09g going to 6.XX */ - if (res == 1) - { - /* patch the IO */ - PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0x109F50BC), sceIoOpenPatched); - PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0xACE946E8), sceIoGetstatPatched); - - /* find the function for idstorage verify */ - u32 func_address = FindFunc("sceMemlmd", "semaphore", 0x4C537C72); - - /* check if we have it... */ - if (func_address == 0) - { - /* ERROR */ - asm("break\n"); - } - - /* ok, lets patch it */ - KERNEL_HIJACK_FUNCTION(func_address, sceUtilsBufferCopyWithRangePatched, pspUtilsBufferCopyWithRange); - } - - /* patch the version check on index.dat */ - PatchSyscall(FindFunc("sceMesgLed", "sceResmgr", 0x9DC14891), sceResmgr_9DC14891_patched); - ClearCaches(); - } - } - - - /* if there is a previous handler, call it */ - if (previous) - return previous(mod); - - /* else just return 0 */ - return 0; -} - -int PrologueModulePatched(void *modmgr_param, SceModule *mod) -{ - /* modmgr_param has changed from 1.50 so I have no included the structure defintion, for an updated version a re-reverse of 6.30 modulemgr is required */ - int res = PrologueModule(modmgr_param, mod); - - /* If this function errors, the module is shutdown so we better check for it */ - if (res >= 0) - { - /* Pass the module through the OnModuleStart chain */ - OnModuleStart(mod); - } - - /* return success */ - return res; -} - -static void PatchModuleManager(void) -{ - /* find the modulemgr module */ - SceModule *mod = sceKernelFindModuleByName("sceModuleManager"); - u32 text_addr = mod->text_addr; - - /* link the original calls before hook */ - PrologueModule = (void *)(text_addr + g_patch_table.prologue_module_func); - - /* Patch call to PrologueModule from the StartModule function to allow a full coverage of loaded modules (even those without an entry point) */ - MAKE_CALL(text_addr + g_patch_table.prologue_module_call, PrologueModulePatched); -} - -static void PatchLoadCore(void) -{ - /* Find the loadcore module */ - SceModule *mod = sceKernelFindModuleByName("sceLoaderCore"); - u32 text_addr = mod->text_addr; - - /* Relink the memlmd calls (that reboot destroyed) */ - MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], text_addr + g_patch_table.memlmd_stub[0]); - MAKE_CALL(text_addr + g_patch_table.memlmd_call[1], text_addr + g_patch_table.memlmd_stub[1]); - - /* if >= 6.30 we need patches for the decryption */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - /* we need to hook updater decryption */ - MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], memlmd_7CF1CD3E_patched); - MAKE_CALL(text_addr + g_patch_table.updater_decrypt_call, sceMesgLed_driver_81F72B1F_patched); - - sceMesgLed_driver_81F72B1F = (void *)(text_addr + g_patch_table.updater_decrypt_func); - } -} - -int module_start(SceSize argsize, void *argp) -{ - /* check if we're running as a plugin or in boot */ - if (sceKernelFindModuleByName("sceInit")) - { - /* plugin, assume we've got HEN (and an M33 nid resolver) */ - /* check for >= 6.30 */ - if (sceKernelDevkitVersion() >= 0x06030010) - { - /* this is firmware dependant :/ so not supported */ - return 0; - } - - /* register with sctrl */ - previous = sctrlHENSetStartModuleHandler(OnModuleStart); - } - else - { - /* boot */ - /* get patches and nids from loader */ - if (CopyPatchTable(&g_patch_table, (void *)PATCH_TABLE_ADDR_START, sceKernelDevkitVersion()) == 0) - { - /* no patches, no go */ - return 0; - } - - /* perform main system patches */ - PatchLoadCore(); - PatchModuleManager(); - } - - /* Clear the caches and return success */ - ClearCaches(); - return 0; -} +/* + Downgrade Control -> Restore kernel patches and enforce updater launch + by Davee + + 31/12/2010 +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "utils.h" +#include "patch_table.h" +#include "decrypt.h" + +PSP_MODULE_INFO("DowngraderCTRL", 0x3007, 1, 0); + +/* function pointers */ +int (* PrologueModule)(void *modmgr_param, SceModule *mod) = NULL; +STMOD_HANDLER previous = NULL; + +typedef struct __attribute__((packed)) +{ + int magic; // 0 + int version; // 4 + unsigned int keyofs; // 8 + unsigned int valofs; // 12 + int count; // 16 +} SfoHeader; + +typedef struct __attribute__((packed)) +{ + unsigned short nameofs; // 0 + char alignment; // 2 + char type; // 3 + int valsize; // 4 + int totalsize; // 8 + unsigned short valofs; // 12 + short unknown; // 16 +} SfoEntry; + +u32 g_spoof_ver = 0; +u8 g_sfo_buffer[4 << 10]; + +int ApplyFirmware(void) +{ + int i; + char *fw_data = NULL; + u8 device_fw_ver[4]; + u32 pbp_header[0x28/4]; + SfoHeader *header = (SfoHeader *)g_sfo_buffer; + SfoEntry *entries = (SfoEntry *)((char *)g_sfo_buffer + sizeof(SfoHeader)); + + /* Lets open the updater */ + char *file = (sceKernelGetModel() == 4) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.pbp") : ("ms0:/PSP/GAME/UPDATE/EBOOT.pbp"); + + /* set k1 */ + u32 k1 = pspSdkSetK1(0); + + /* lets open the file */ + SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); + + /* check for failure */ + if (fd < 0) + { + /* rage */ + pspSdkSetK1(k1); + return fd; + } + + /* read the PBP header */ + sceIoRead(fd, pbp_header, sizeof(pbp_header)); + + /* seek to the SFO */ + sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); + + /* calculate the size of the SFO */ + u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; + + /* check if greater than buffer size */ + if (sfo_size > sizeof(g_sfo_buffer)) + { + /* too much */ + pspSdkSetK1(k1); + return -2; + } + + /* read the sfo */ + sceIoRead(fd, g_sfo_buffer, sizeof(g_sfo_buffer)); + + /* close the file */ + sceIoClose(fd); + + /* now parse the SFO */ + for (i = 0; i < header->count; i++) + { + /* check this name */ + if (strcmp((char *)((char *)g_sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) + { + /* get the string */ + fw_data = (char *)((char *)g_sfo_buffer + header->valofs + entries[i].valofs); + break; + } + } + + /* see if we went through all the data */ + if (i == header->count) + { + /* error */ + pspSdkSetK1(k1); + return -3; + } + + /* ok, we have the firmware version in the eboot. */ + u32 min_ver = 0; + u32 updater_ver = (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); + + /* ok, now get the idstorage value */ + int res = sceIdStorageLookup(0x51, 0, device_fw_ver, 4); + + /* check for error */ + if (res < 0) + { + /* check model */ + if (sceKernelGetModel() != 0) + { + /* invalid error */ + return -4; + } + + /* firmware 1.00 */ + min_ver = 0x100; + } + else + { + /* convert to hex */ + min_ver = (((device_fw_ver[0] - '0') & 0xF) << 8) | (((device_fw_ver[2] - '0') & 0xF) << 4) | (((device_fw_ver[3] - '0') & 0xF) << 0); + } + + /* set the result to 0 */ + res = 0; + + /* check if the updater is less than the minimum version */ + if (updater_ver < min_ver) + { + /* ok, check for 6.35 and 09g */ + if ((min_ver != 0x630 && min_ver != 0x635) || sceKernelGetModel() != 8) + { + /* error */ + pspSdkSetK1(k1); + return -5; + } + + /* set result to 1 D: */ + res = 1; + } + + /* do spoof! */ + g_spoof_ver = updater_ver; + pspSdkSetK1(k1); + return res; +} + +#define INDEXFILE "flash0:/vsh/etc/index_04g.dat" +#define NEW_INDEXFILE "flash0:/vsh/etc/index_09g.dat" + +SceUID sceIoOpenPatched(char *file, u32 mode, u32 mode2) +{ + /* check indexfile */ + if (strcmp(file, INDEXFILE) == 0) + { + /* if read mode, copy */ + if (mode == PSP_O_RDONLY) + { + strcpy(file, NEW_INDEXFILE); + } + } + + /* call original function */ + return sceIoOpen(file, mode, mode2); +} + +int sceIoGetstatPatched(char *file, SceIoStat *stat) +{ + /* check indexfile */ + if (strcmp(file, INDEXFILE) == 0) + { + strcpy(file, NEW_INDEXFILE); + } + + /* call original function */ + return sceIoGetstat(file, stat); +} + +/* idstorage patching func */ +int (* pspUtilsBufferCopyWithRange)(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) = NULL; +int sceUtilsBufferCopyWithRangePatched(void *dst, u32 dst_size, void *src, u32 src_size, u32 cmd) +{ + u8 ids_cert[0xB8]; + + /* if idstorage check */ + if (cmd == 0x12) + { + /* ok lets get the idstorage 0x100 key */ + int res = sceIdStorageLookup(0x100, 0x38, ids_cert, 0xB8); + + /* check for error */ + if (res < 0) + { + /* attempt with backup key */ + res = sceIdStorageLookup(0x120, 0x38, ids_cert, 0xB8); + + /* if error, exit */ + if (res < 0) + { + return res; + } + } + + /* yay its 0x100 key */ + /* change the model to 04g */ + ids_cert[7] = 6; + + /* copy the new certificate back */ + memcpy(src, ids_cert, sizeof(ids_cert)); + return 0; + } + + /* return function */ + return pspUtilsBufferCopyWithRange(dst, dst_size, src, src_size, cmd); +} + +int (* sceLflashFatfmtStartFatfmtOriginal)(int argc, char *argv[]) = NULL; + +int sceLflashFatfmtStartFatfmtPatched(int argc, char *argv[]) +{ + infSetRedirectionStatus(0); + ClearCaches(); + + return sceLflashFatfmtStartFatfmtOriginal(argc, argv); +} + +int OnModuleStart(SceModule *mod) +{ + if (strcmp(mod->modname, "sceMesgLed") == 0) + { + PatchMesgled(mod->text_addr); + ClearCaches(); + } + + else if (strcmp(mod->modname, "sceLflashFatfmtUpdater") == 0) + { + PatchSyscall(FindFunc("sceLflashFatfmtUpdater", "LflashFatfmt", 0xB7A424A4), sceLflashFatfmtStartFatfmtPatched); + sceLflashFatfmtStartFatfmtOriginal = FindFunc("sceLflashFatfmtUpdater", "LflashFatfmt", 0xB7A424A4); + ClearCaches(); + } + + else if (strcmp(mod->modname, "updater") == 0) + { + /* ok, lets see what we're doing here! */ + int res = ApplyFirmware(); + + /* check for success */ + if (res >= 0) + { + /* do these patches if we have 09g going to 6.XX */ + if (res == 1) + { + /* patch the IO */ + PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0x109F50BC), sceIoOpenPatched); + PatchSyscall(FindFunc("sceIOFileManager", "IoFileMgrForUser", 0xACE946E8), sceIoGetstatPatched); + + /* find the function for idstorage verify */ + u32 func_address = FindFunc("sceMemlmd", "semaphore", 0x4C537C72); + + /* check if we have it... */ + if (func_address == 0) + { + /* ERROR */ + asm("break\n"); + } + + /* ok, lets patch it */ + KERNEL_HIJACK_FUNCTION(func_address, sceUtilsBufferCopyWithRangePatched, pspUtilsBufferCopyWithRange); + } + + /* patch the version check on index.dat */ + PatchSyscall(FindFunc("sceMesgLed", "sceResmgr", 0x9DC14891), sceResmgr_9DC14891_patched); + ClearCaches(); + } + } + + + /* if there is a previous handler, call it */ + if (previous) + return previous((SceModule2 *)mod); + + /* else just return 0 */ + return 0; +} + +int PrologueModulePatched(void *modmgr_param, SceModule *mod) +{ + /* modmgr_param has changed from 1.50 so I have no included the structure defintion, for an updated version a re-reverse of 6.30 modulemgr is required */ + int res = PrologueModule(modmgr_param, mod); + + /* If this function errors, the module is shutdown so we better check for it */ + if (res >= 0) + { + /* Pass the module through the OnModuleStart chain */ + OnModuleStart(mod); + } + + /* return success */ + return res; +} + +static void PatchModuleManager(void) +{ + /* find the modulemgr module */ + SceModule *mod = sceKernelFindModuleByName("sceModuleManager"); + u32 text_addr = mod->text_addr; + + /* link the original calls before hook */ + PrologueModule = (void *)(text_addr + g_patch_table.prologue_module_func); + + /* Patch call to PrologueModule from the StartModule function to allow a full coverage of loaded modules (even those without an entry point) */ + MAKE_CALL(text_addr + g_patch_table.prologue_module_call, PrologueModulePatched); +} + +static void PatchLoadCore(void) +{ + /* Find the loadcore module */ + SceModule *mod = sceKernelFindModuleByName("sceLoaderCore"); + u32 text_addr = mod->text_addr; + + /* Relink the memlmd calls (that reboot destroyed) */ + MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], text_addr + g_patch_table.memlmd_stub[0]); + MAKE_CALL(text_addr + g_patch_table.memlmd_call[1], text_addr + g_patch_table.memlmd_stub[1]); + + /* if >= 6.30 we need patches for the decryption */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + /* we need to hook updater decryption */ + MAKE_CALL(text_addr + g_patch_table.memlmd_call[0], memlmd_7CF1CD3E_patched); + MAKE_CALL(text_addr + g_patch_table.updater_decrypt_call, sceMesgLed_driver_81F72B1F_patched); + + sceMesgLed_driver_81F72B1F = (void *)(text_addr + g_patch_table.updater_decrypt_func); + } +} + +int module_start(SceSize argsize, void *argp) +{ + /* check if we're running as a plugin or in boot */ + if (sceKernelFindModuleByName("sceInit")) + { + /* plugin, assume we've got HEN (and an M33 nid resolver) */ + /* check for >= 6.30 */ + if (sceKernelDevkitVersion() >= 0x06030010) + { + /* this is firmware dependant :/ so not supported */ + return 0; + } + + /* register with sctrl */ + previous = sctrlHENSetStartModuleHandler((STMOD_HANDLER)OnModuleStart); + } + else + { + /* boot */ + /* get patches and nids from loader */ + if (CopyPatchTable(&g_patch_table, (void *)PATCH_TABLE_ADDR_START, sceKernelDevkitVersion()) == 0) + { + /* no patches, no go */ + return 0; + } + + /* perform main system patches */ + PatchLoadCore(); + PatchModuleManager(); + } + + /* Clear the caches and return success */ + ClearCaches(); + return 0; +} diff --git a/src/downgrade_ctrl/patch_table.c b/src/downgrade_ctrl/patch_table.c index 2c3a312..5a9485c 100644 --- a/src/downgrade_ctrl/patch_table.c +++ b/src/downgrade_ctrl/patch_table.c @@ -1,46 +1,46 @@ -/* - Downgrade Control -> patch_table.c -> Responsible for searching and handling patch tables - by Davee - - 01/01/2011 -*/ - -#include -#include - -#include -#include -#include - -#include "patch_table.h" - -PatchTable g_patch_table; - -int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit) -{ - int i; - - /* get the number of entries in the table */ - u32 nentries = _lw((u32)_src_table); - - /* cast our pointer */ - PatchTable *src_table = (PatchTable *)(_src_table + 4); - - /* loop through the entries */ - for (i = 0; i < nentries; i++) - { - /* if same devkit */ - if (src_table->devkit == devkit) - { - /* copy over and return 1 for a complete transfer */ - memcpy(dst_table, src_table, sizeof(PatchTable)); - return 1; - } - - /* increment */ - src_table++; - } - - /* no transfer */ - return 0; -} +/* + Downgrade Control -> patch_table.c -> Responsible for searching and handling patch tables + by Davee + + 01/01/2011 +*/ + +#include +#include + +#include +#include +#include + +#include "patch_table.h" + +PatchTable g_patch_table; + +int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit) +{ + int i; + + /* get the number of entries in the table */ + u32 nentries = _lw((u32)_src_table); + + /* cast our pointer */ + PatchTable *src_table = (PatchTable *)(_src_table + 4); + + /* loop through the entries */ + for (i = 0; i < nentries; i++) + { + /* if same devkit */ + if (src_table->devkit == devkit) + { + /* copy over and return 1 for a complete transfer */ + memcpy(dst_table, src_table, sizeof(PatchTable)); + return 1; + } + + /* increment */ + src_table++; + } + + /* no transfer */ + return 0; +} diff --git a/src/downgrade_ctrl/patch_table.h b/src/downgrade_ctrl/patch_table.h index 35974b9..857e93e 100644 --- a/src/downgrade_ctrl/patch_table.h +++ b/src/downgrade_ctrl/patch_table.h @@ -1,32 +1,32 @@ -/* - Downgrade Control -> patch_table.h -> Provide API documentation and definitions for the table patching - by Davee - - 01/01/2011 -*/ -#ifndef __PATCH_TABLE_H__ -#define __PATCH_TABLE_H__ - -typedef struct -{ - u32 devkit; - u32 new_updater_check[5]; - u32 updater_decrypt_call; - u32 updater_decrypt_func; -/* u32 new_updater_keys; - u32 new_updater_t3_arg; - u32 new_updater_seed; - u32 new_updater_mode; - u32 new_updater_stack_arg;*/ - u32 prologue_module_func; - u32 prologue_module_call; - u32 memlmd_call[2]; - u32 memlmd_stub[2]; -} PatchTable; - -#define PATCH_TABLE_ADDR_START (0x88FC0000) - -extern PatchTable g_patch_table; -int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit); - -#endif /* __PATCH_TABLE_H__ */ +/* + Downgrade Control -> patch_table.h -> Provide API documentation and definitions for the table patching + by Davee + + 01/01/2011 +*/ +#ifndef __PATCH_TABLE_H__ +#define __PATCH_TABLE_H__ + +typedef struct +{ + u32 devkit; + u32 new_updater_check[5]; + u32 updater_decrypt_call; + u32 updater_decrypt_func; +/* u32 new_updater_keys; + u32 new_updater_t3_arg; + u32 new_updater_seed; + u32 new_updater_mode; + u32 new_updater_stack_arg;*/ + u32 prologue_module_func; + u32 prologue_module_call; + u32 memlmd_call[2]; + u32 memlmd_stub[2]; +} PatchTable; + +#define PATCH_TABLE_ADDR_START (0x88FC0000) + +extern PatchTable g_patch_table; +int CopyPatchTable(PatchTable *dst_table, void *_src_table, u32 devkit); + +#endif /* __PATCH_TABLE_H__ */ diff --git a/src/downgrade_ctrl/pspdecrypt.c b/src/downgrade_ctrl/pspdecrypt.c index ee4942e..b4a8cf0 100644 --- a/src/downgrade_ctrl/pspdecrypt.c +++ b/src/downgrade_ctrl/pspdecrypt.c @@ -1,913 +1,913 @@ -#include -#include -#include -//#include -#include -#include -#include -#include -#include - -#include "decrypt.h" -//#include -//#include - - -extern int UtilsForKernel_6C6887EE(void *, u32, void *, void *); - -////////// Decryption 1 ////////// - -// use pre-calculated keys (step1 results) - -u32 g_key0[] = -{ - 0x7b21f3be, 0x299c5e1d, 0x1c9c5e71, 0x96cb4645, 0x3c9b1be0, 0xeb85de3d, - 0x4a7f2022, 0xc2206eaa, 0xd50b3265, 0x55770567, 0x3c080840, 0x981d55f2, - 0x5fd8f6f3, 0xee8eb0c5, 0x944d8152, 0xf8278651, 0x2705bafa, 0x8420e533, - 0x27154ae9, 0x4819aa32, 0x59a3aa40, 0x2cb3cf65, 0xf274466d, 0x3a655605, - 0x21b0f88f, 0xc5b18d26, 0x64c19051, 0xd669c94e, 0xe87035f2, 0x9d3a5909, - 0x6f4e7102, 0xdca946ce, 0x8416881b, 0xbab097a5, 0x249125c6, 0xb34c0872, -}; - -u32 g_key2[] = -{ - 0xccfda932, 0x51c06f76, 0x046dcccf, 0x49e1821e, 0x7d3b024c, 0x9dda5865, - 0xcc8c9825, 0xd1e97db5, 0x6874d8cb, 0x3471c987, 0x72edb3fc, 0x81c8365d, - 0xe161e33a, 0xfc92db59, 0x2009b1ec, 0xb1a94ce4, 0x2f03696b, 0x87e236d8, - 0x3b2b8ce9, 0x0305e784, 0xf9710883, 0xb039db39, 0x893bea37, 0xe74d6805, - 0x2a5c38bd, 0xb08dc813, 0x15b32375, 0x46be4525, 0x0103fd90, 0xa90e87a2, - 0x52aba66a, 0x85bf7b80, 0x45e8ce63, 0x4dd716d3, 0xf5e30d2d, 0xaf3ae456, -}; - -u32 g_key3[] = -{ - 0xa6c8f5ca, 0x6d67c080, 0x924f4d3a, 0x047ca06a, 0x08640297, 0x4fd4a758, - 0xbd685a87, 0x9b2701c2, 0x83b62a35, 0x726b533c, 0xe522fa0c, 0xc24b06b4, - 0x459d1cac, 0xa8c5417b, 0x4fea62a2, 0x0615d742, 0x30628d09, 0xc44fab14, - 0x69ff715e, 0xd2d8837d, 0xbeed0b8b, 0x1e6e57ae, 0x61e8c402, 0xbe367a06, - 0x543f2b5e, 0xdb3ec058, 0xbe852075, 0x1e7e4dcc, 0x1564ea55, 0xec7825b4, - 0xc0538cad, 0x70f72c7f, 0x49e8c3d0, 0xeda97ec5, 0xf492b0a4, 0xe05eb02a, -}; - -u32 g_key44[] = -{ - 0xef80e005, 0x3a54689f, 0x43c99ccd, 0x1b7727be, 0x5cb80038, 0xdd2efe62, - 0xf369f92c, 0x160f94c5, 0x29560019, 0xbf3c10c5, 0xf2ce5566, 0xcea2c626, - 0xb601816f, 0x64e7481e, 0x0c34debd, 0x98f29cb0, 0x3fc504d7, 0xc8fb39f0, - 0x0221b3d8, 0x63f936a2, 0x9a3a4800, 0x6ecc32e3, 0x8e120cfd, 0xb0361623, - 0xaee1e689, 0x745502eb, 0xe4a6c61c, 0x74f23eb4, 0xd7fa5813, 0xb01916eb, - 0x12328457, 0xd2bc97d2, 0x646425d8, 0x328380a5, 0x43da8ab1, 0x4b122ac9, -}; - -u32 g_key20[] = -{ - 0x33b50800, 0xf32f5fcd, 0x3c14881f, 0x6e8a2a95, 0x29feefd5, 0x1394eae3, - 0xbd6bd443, 0x0821c083, 0xfab379d3, 0xe613e165, 0xf5a754d3, 0x108b2952, - 0x0a4b1e15, 0x61eadeba, 0x557565df, 0x3b465301, 0xae54ecc3, 0x61423309, - 0x70c9ff19, 0x5b0ae5ec, 0x989df126, 0x9d987a5f, 0x55bc750e, 0xc66eba27, - 0x2de988e8, 0xf76600da, 0x0382dccb, 0x5569f5f2, 0x8e431262, 0x288fe3d3, - 0x656f2187, 0x37d12e9c, 0x2f539eb4, 0xa492998e, 0xed3958f7, 0x39e96523, -}; - -u32 g_key3A[] = -{ - 0x67877069, 0x3abd5617, 0xc23ab1dc, 0xab57507d, 0x066a7f40, 0x24def9b9, - 0x06f759e4, 0xdcf524b1, 0x13793e5e, 0x0359022d, 0xaae7e1a2, 0x76b9b2fa, - 0x9a160340, 0x87822fba, 0x19e28fbb, 0x9e338a02, 0xd8007e9a, 0xea317af1, - 0x630671de, 0x0b67ca7c, 0x865192af, 0xea3c3526, 0x2b448c8e, 0x8b599254, - 0x4602e9cb, 0x4de16cda, 0xe164d5bb, 0x07ecd88e, 0x99ffe5f8, 0x768800c1, - 0x53b091ed, 0x84047434, 0xb426dbbc, 0x36f948bb, 0x46142158, 0x749bb492, -}; - -/* updaters keys */ -u8 updaters_keys[0x90+0x14] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x01, 0x1C, 0xE7, 0x31, 0x15, 0x6B, 0x83, - 0x3E, 0x26, 0x0D, 0xCC, 0x69, 0x36, 0x12, 0xCB, - 0xA7, 0xFD, 0x26, 0x66, 0x93, 0x2A, 0x6E, 0x1A, - 0x91, 0x2E, 0xC6, 0xFC, 0xD8, 0x2F, 0x00, 0x13, - 0x5A, 0xE2, 0xDF, 0xB6, 0xA2, 0xE4, 0x27, 0xC8, - 0x18, 0xC3, 0x50, 0x50, 0xB7, 0xE9, 0x4A, 0xED, - 0xCC, 0x3C, 0x30, 0xFD, 0x10, 0x6A, 0x2B, 0x0A, - 0x22, 0xCB, 0xC6, 0xE0, 0x20, 0x65, 0x12, 0xEB, - 0x7D, 0x4E, 0x2A, 0x37, 0x0B, 0x0A, 0xEF, 0x88, - 0xDA, 0x06, 0x54, 0xD4, 0x30, 0xAF, 0xCD, 0xCA, - 0x9A, 0xF9, 0xDA, 0x1A, 0xB0, 0x1B, 0xBB, 0x62, - 0x0C, 0xDB, 0xF8, 0x44, 0x73, 0x56, 0x14, 0x8E, - 0x93, 0xB1, 0x2C, 0xFD, 0x67, 0xE2, 0x5D, 0xCB, - 0x48, 0x5B, 0xD9, 0xB3, 0x54, 0x14, 0xD7, 0x9F, - 0x79, 0x9C, 0x24, 0xE9, 0xC2, 0x7A, 0x4E, 0x8C, - 0x4D, 0x24, 0x19, 0x94, 0xFF, 0xC9, 0xC2, 0x2D, - 0x23, 0x63, 0x51, 0xB8, 0xFA, 0xD6, 0x7F, 0xE6, - 0x5E, 0xBC, 0x32, 0xB2, 0x02, 0x13, 0xC4, 0x76 -}; - -/* locoroco, kazue, and maybe others demos keys */ -u8 demo_keys0[0x90+0x14] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x82, 0x4C, 0xA5, 0x18, 0xD3, 0xC8, 0x6E, 0xEA, - 0x17, 0x41, 0x04, 0xDC, 0xEA, 0xC5, 0x01, 0xFC, - 0x97, 0xB1, 0x94, 0x54, 0x71, 0x19, 0x22, 0xEE, - 0xE0, 0x2D, 0xE9, 0x83, 0x3D, 0x64, 0x30, 0xE6, - 0x42, 0x5C, 0x30, 0x5F, 0xEB, 0x41, 0xA0, 0xE0, - 0x62, 0xC6, 0x63, 0xEE, 0x5D, 0xA5, 0x0D, 0x1E, - 0xC2, 0x10, 0x14, 0x49, 0x06, 0xC6, 0x93, 0x84, - 0x71, 0xA5, 0x42, 0x63, 0x13, 0xF0, 0xB6, 0xD5, - 0x43, 0x51, 0x9E, 0xFA, 0x91, 0x0A, 0x7C, 0xE1, - 0x58, 0x1B, 0x95, 0x25, 0x40, 0x11, 0xF1, 0x8D, - 0xB1, 0x01, 0x8D, 0x04, 0x09, 0x54, 0x5C, 0x54, - 0xF5, 0x53, 0x08, 0xB0, 0x53, 0x85, 0xB4, 0xCE, - 0x0B, 0xF5, 0xC3, 0xFB, 0xC6, 0x55, 0x24, 0x0B, - 0xF2, 0xC6, 0x2C, 0xE4, 0x0C, 0xF0, 0x05, 0x3C, - 0xD7, 0x6C, 0x39, 0xD5, 0x87, 0x22, 0x09, 0xF7, - 0x3D, 0xC5, 0xA2, 0xFD, 0x55, 0x92, 0x3F, 0xB1, - 0xF6, 0xFE, 0xC8, 0x18, 0x1D, 0x6B, 0x04, 0x52, - 0x5F, 0x8C, 0xE8, 0xE7, 0x26, 0x5A, 0x6E, 0x5A -}; - -typedef struct -{ - u32 tag; // 4 byte value at offset 0xD0 in the PRX file - u8* key; // "step1_result" use for XOR step - u8 code; - u8 codeExtra; -} TAG_INFO; - -static const TAG_INFO g_tagInfo[] = -{ - // 1.x PRXs - { 0x00000000, (u8*)g_key0, 0x42 }, - { 0x02000000, (u8*)g_key2, 0x45 }, - { 0x03000000, (u8*)g_key3, 0x46 }, - - // 2.0 PRXs - { 0x4467415d, (u8*)g_key44, 0x59, 0x59 }, - { 0x207bbf2f, (u8*)g_key20, 0x5A, 0x5A }, - { 0x3ace4dce, (u8*)g_key3A, 0x5B, 0x5B }, - - // updaters - { 0x0b000000, updaters_keys, 0x4E }, - - // locoroco, kazue, demos - { 0x0c000000, demo_keys0, 0x4F }, -}; - -static TAG_INFO const* GetTagInfo(u32 tagFind) -{ - int iTag; - for (iTag = 0; iTag < sizeof(g_tagInfo)/sizeof(TAG_INFO); iTag++) - if (g_tagInfo[iTag].tag == tagFind) - return &g_tagInfo[iTag]; - return NULL; // not found -} - -static void ExtraV2Mangle(u8* buffer1, u8 codeExtra) -{ - static u8 g_dataTmp[20+0xA0] __attribute__((aligned(0x40))); - u8* buffer2 = g_dataTmp; // aligned - - memcpy(buffer2+20, buffer1, 0xA0); - u32* pl2 = (u32*)buffer2; - pl2[0] = 5; - pl2[1] = pl2[2] = 0; - pl2[3] = codeExtra; - pl2[4] = 0xA0; - - int ret = sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, 7); - if (ret != 0) - Kprintf("extra de-mangle returns %d\n", ret); - // copy result back - memcpy(buffer1, buffer2, 0xA0); -} - -static int Scramble(u32 *buf, u32 size, u32 code) -{ - buf[0] = 5; - buf[1] = buf[2] = 0; - buf[3] = code; - buf[4] = size; - - if (sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, 7) < 0) - { - return -1; - } - - return 0; -} - -static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag) -{ - int i, retsize; - u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20]; - - TAG_INFO const* pti = GetTagInfo(tag); - if (pti == NULL) - return -1; - - retsize = *(u32*)&pbIn[0xB0]; - - for (i = 0; i < 0x14; i++) - { - if (pti->key[i] != 0) - break; - } - - if (i == 0x14) - { - Scramble((u32 *)pti->key, 0x90, pti->code); - } - - // build conversion into pbOut - - if (pbIn != pbOut) - memcpy(pbOut, pbIn, cbTotal); - - memcpy(bD0, pbIn+0xD0, 0x80); - memcpy(b80, pbIn+0x80, 0x50); - memcpy(b00, pbIn+0x00, 0x80); - memcpy(bB0, pbIn+0xB0, 0x20); - - memset(pbOut, 0, 0x150); - memset(pbOut, 0x55, 0x40); // first $40 bytes ignored - - // step3 demangle in place - u32* pl = (u32*)(pbOut+0x2C); - pl[0] = 5; // number of ulongs in the header - pl[1] = pl[2] = 0; - pl[3] = pti->code; // initial seed for PRX - pl[4] = 0x70; // size - - // redo part of the SIG check (step2) - u8 buffer1[0x150]; - memcpy(buffer1+0x00, bD0, 0x80); - memcpy(buffer1+0x80, b80, 0x50); - memcpy(buffer1+0xD0, b00, 0x80); - if (pti->codeExtra != 0) - ExtraV2Mangle(buffer1+0x10, pti->codeExtra); - memcpy(pbOut+0x40 /* 0x2C+20 */, buffer1+0x40, 0x40); - - int ret; - int iXOR; - for (iXOR = 0; iXOR < 0x70; iXOR++) - pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ pti->key[0x14+iXOR]; - - ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7); - if (ret != 0) - { - Kprintf("mangle#7 returned $%x\n", ret); - return -1; - } - - for (iXOR = 0x6F; iXOR >= 0; iXOR--) - pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ pti->key[0x20+iXOR]; - - memset(pbOut+0x80, 0, 0x30); // $40 bytes kept, clean up - pbOut[0xA0] = 1; - // copy unscrambled parts from header - memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros - memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header - - // step4: do the actual decryption of code block - // point 0x40 bytes into the buffer to key info - ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); - if (ret != 0) - { - Kprintf("mangle#1 returned $%x\n", ret); - return -1; - } - - // return cbTotal - 0x150; // rounded up size - return retsize; -} - -////////// Decryption 2 ////////// - -/* kernel modules 2.60-2.71 */ -u8 keys260_0[0x10] = -{ - 0xC3, 0x24, 0x89, 0xD3, 0x80, 0x87, 0xB2, 0x4E, - 0x4C, 0xD7, 0x49, 0xE4, 0x9D, 0x1D, 0x34, 0xD1 - -}; - -/* user modules 2.60-2.71 */ -u8 keys260_1[0x10] = -{ - 0xF3, 0xAC, 0x6E, 0x7C, 0x04, 0x0A, 0x23, 0xE7, - 0x0D, 0x33, 0xD8, 0x24, 0x73, 0x39, 0x2B, 0x4A -}; - -/* vshmain 2.60-2.71 */ -u8 keys260_2[0x10] = -{ - 0x72, 0xB4, 0x39, 0xFF, 0x34, 0x9B, 0xAE, 0x82, - 0x30, 0x34, 0x4A, 0x1D, 0xA2, 0xD8, 0xB4, 0x3C -}; - -/* kernel modules 2.80 */ -u8 keys280_0[0x10] = -{ - 0xCA, 0xFB, 0xBF, 0xC7, 0x50, 0xEA, 0xB4, 0x40, - 0x8E, 0x44, 0x5C, 0x63, 0x53, 0xCE, 0x80, 0xB1 -}; - -/* user modules 2.80 */ -u8 keys280_1[0x10] = -{ - 0x40, 0x9B, 0xC6, 0x9B, 0xA9, 0xFB, 0x84, 0x7F, - 0x72, 0x21, 0xD2, 0x36, 0x96, 0x55, 0x09, 0x74 -}; - -/* vshmain executable 2.80 */ -u8 keys280_2[0x10] = -{ - 0x03, 0xA7, 0xCC, 0x4A, 0x5B, 0x91, 0xC2, 0x07, - 0xFF, 0xFC, 0x26, 0x25, 0x1E, 0x42, 0x4B, 0xB5 -}; - -/* kernel modules 3.00 */ -u8 keys300_0[0x10] = -{ - 0x9F, 0x67, 0x1A, 0x7A, 0x22, 0xF3, 0x59, 0x0B, - 0xAA, 0x6D, 0xA4, 0xC6, 0x8B, 0xD0, 0x03, 0x77 - -}; - -/* user modules 3.00 */ -u8 keys300_1[0x10] = -{ - 0x15, 0x07, 0x63, 0x26, 0xDB, 0xE2, 0x69, 0x34, - 0x56, 0x08, 0x2A, 0x93, 0x4E, 0x4B, 0x8A, 0xB2 - -}; - -/* vshmain 3.00 */ -u8 keys300_2[0x10] = -{ - 0x56, 0x3B, 0x69, 0xF7, 0x29, 0x88, 0x2F, 0x4C, - 0xDB, 0xD5, 0xDE, 0x80, 0xC6, 0x5C, 0xC8, 0x73 - -}; - -/* kernel modules 3.00 */ -u8 keys303_0[0x10] = -{ - 0x7b, 0xa1, 0xe2, 0x5a, 0x91, 0xb9, 0xd3, 0x13, - 0x77, 0x65, 0x4a, 0xb7, 0xc2, 0x8a, 0x10, 0xaf -}; - -/* kernel modules 3.10 */ -u8 keys310_0[0x10] = -{ - 0xa2, 0x41, 0xe8, 0x39, 0x66, 0x5b, 0xfa, 0xbb, - 0x1b, 0x2d, 0x6e, 0x0e, 0x33, 0xe5, 0xd7, 0x3f -}; - -/* user modules 3.10 */ -u8 keys310_1[0x10] = -{ - 0xA4, 0x60, 0x8F, 0xAB, 0xAB, 0xDE, 0xA5, 0x65, - 0x5D, 0x43, 0x3A, 0xD1, 0x5E, 0xC3, 0xFF, 0xEA -}; - -/* vshmain 3.10 */ -u8 keys310_2[0x10] = -{ - 0xE7, 0x5C, 0x85, 0x7A, 0x59, 0xB4, 0xE3, 0x1D, - 0xD0, 0x9E, 0xCE, 0xC2, 0xD6, 0xD4, 0xBD, 0x2B -}; - -/* reboot.bin 3.10 */ -u8 keys310_3[0x10] = -{ - 0x2E, 0x00, 0xF6, 0xF7, 0x52, 0xCF, 0x95, 0x5A, - 0xA1, 0x26, 0xB4, 0x84, 0x9B, 0x58, 0x76, 0x2F -}; - -/* kernel modules 3.30 */ -u8 keys330_0[0x10] = -{ - 0x3B, 0x9B, 0x1A, 0x56, 0x21, 0x80, 0x14, 0xED, - 0x8E, 0x8B, 0x08, 0x42, 0xFA, 0x2C, 0xDC, 0x3A -}; - -/* user modules 3.30 */ -u8 keys330_1[0x10] = -{ - 0xE8, 0xBE, 0x2F, 0x06, 0xB1, 0x05, 0x2A, 0xB9, - 0x18, 0x18, 0x03, 0xE3, 0xEB, 0x64, 0x7D, 0x26 -}; - -/* vshmain 3.30 */ -u8 keys330_2[0x10] = -{ - 0xAB, 0x82, 0x25, 0xD7, 0x43, 0x6F, 0x6C, 0xC1, - 0x95, 0xC5, 0xF7, 0xF0, 0x63, 0x73, 0x3F, 0xE7 -}; - -/* reboot.bin 3.30 */ -u8 keys330_3[0x10] = -{ - 0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F, - 0x38, 0x4C, 0x4D, 0x96, 0xBD, 0x49, 0xEC, 0x9B -}; - -/* stdio.prx 3.30 */ -u8 keys330_4[0x10] = -{ - 0xEC, 0x3B, 0xD2, 0xC0, 0xFA, 0xC1, 0xEE, 0xB9, - 0x9A, 0xBC, 0xFF, 0xA3, 0x89, 0xF2, 0x60, 0x1F -}; - -/* 3.60 common kernel modules */ -u8 keys360_0[16] = -{ - 0x3C, 0x2B, 0x51, 0xD4, 0x2D, 0x85, 0x47, 0xDA, - 0x2D, 0xCA, 0x18, 0xDF, 0xFE, 0x54, 0x09, 0xED -}; - -/* 3.60 specific slim kernel modules */ -u8 keys360_1[16] = -{ - 0x31, 0x1F, 0x98, 0xD5, 0x7B, 0x58, 0x95, 0x45, - 0x32, 0xAB, 0x3A, 0xE3, 0x89, 0x32, 0x4B, 0x34 -}; - -/* 3.70 common and fat kernel modules */ -u8 keys370_0[0x10] = -{ - 0x26, 0x38, 0x0A, 0xAC, 0xA5, 0xD8, 0x74, 0xD1, - 0x32, 0xB7, 0x2A, 0xBF, 0x79, 0x9E, 0x6D, 0xDB -}; - -/* 3.70 slim specific kernel modules */ -u8 keys370_1[0x10] = -{ - 0x53, 0xE7, 0xAB, 0xB9, 0xC6, 0x4A, 0x4B, 0x77, - 0x92, 0x17, 0xB5, 0x74, 0x0A, 0xDA, 0xA9, 0xEA -}; - -/* some 3.70 slim user modules */ -u8 keys370_2[16] = -{ - 0x71, 0x10, 0xF0, 0xA4, 0x16, 0x14, 0xD5, 0x93, - 0x12, 0xFF, 0x74, 0x96, 0xDF, 0x1F, 0xDA, 0x89 -}; - -/* 3.90 kernel */ -u8 keys390_0[16] = -{ - 0x45, 0xEF, 0x5C, 0x5D, 0xED, 0x81, 0x99, 0x84, - 0x12, 0x94, 0x8F, 0xAB, 0xE8, 0x05, 0x6D, 0x7D -}; - -/* 3.90 slim */ -u8 keys390_1[16] = -{ - 0x70, 0x1B, 0x08, 0x25, 0x22, 0xA1, 0x4D, 0x3B, - 0x69, 0x21, 0xF9, 0x71, 0x0A, 0xA8, 0x41, 0xA9 -}; - -/* 5.00 kernel */ -u8 keys500_0[16] = -{ - 0xEB, 0x1B, 0x53, 0x0B, 0x62, 0x49, 0x32, 0x58, - 0x1F, 0x83, 0x0A, 0xF4, 0x99, 0x3D, 0x75, 0xD0 -}; - -/* 5.00 kernel 2000 specific */ -u8 keys500_1[16] = -{ - 0xBA, 0xE2, 0xA3, 0x12, 0x07, 0xFF, 0x04, 0x1B, - 0x64, 0xA5, 0x11, 0x85, 0xF7, 0x2F, 0x99, 0x5B -}; - -/* 5.00 kernel 3000 specific */ -u8 keys500_2[16] = -{ - 0x2C, 0x8E, 0xAF, 0x1D, 0xFF, 0x79, 0x73, 0x1A, - 0xAD, 0x96, 0xAB, 0x09, 0xEA, 0x35, 0x59, 0x8B -}; - -u8 keys500_c[16] = -{ - 0xA3, 0x5D, 0x51, 0xE6, 0x56, 0xC8, 0x01, 0xCA, - 0xE3, 0x77, 0xBF, 0xCD, 0xFF, 0x24, 0xDA, 0x4D -}; - -u8 keys505_a[16] = -{ - 0x7B, 0x94, 0x72, 0x27, 0x4C, 0xCC, 0x54, 0x3B, - 0xAE, 0xDF, 0x46, 0x37, 0xAC, 0x01, 0x4D, 0x87 -}; - -u8 keys505_0[16] = -{ - 0x2E, 0x8E, 0x97, 0xA2, 0x85, 0x42, 0x70, 0x73, - 0x18, 0xDA, 0xA0, 0x8A, 0xF8, 0x62, 0xA2, 0xB0 -}; - -u8 keys505_1[16] = -{ - 0x58, 0x2A, 0x4C, 0x69, 0x19, 0x7B, 0x83, 0x3D, - 0xD2, 0x61, 0x61, 0xFE, 0x14, 0xEE, 0xAA, 0x11 -}; - -/* for psp 2000 file table and ipl pre-decryption */ -u8 keys02G_E[0x10] = -{ - 0x9D, 0x09, 0xFD, 0x20, 0xF3, 0x8F, 0x10, 0x69, - 0x0D, 0xB2, 0x6F, 0x00, 0xCC, 0xC5, 0x51, 0x2E -}; - -/* for psp 3000 file table and ipl pre-decryption */ -u8 keys03G_E[0x10] = -{ - 0x4F, 0x44, 0x5C, 0x62, 0xB3, 0x53, 0xC4, 0x30, - 0xFC, 0x3A, 0xA4, 0x5B, 0xEC, 0xFE, 0x51, 0xEA -}; - -/* for psp go file table and ipl pre-decryption */ -u8 keys05G_E[0x10] = -{ - 0x5D, 0xAA, 0x72, 0xF2, 0x26, 0x60, 0x4D, 0x1C, - 0xE7, 0x2D, 0xC8, 0xA3, 0x2F, 0x79, 0xC5, 0x54 -}; - -/* 5.70 PSPgo kernel*/ -u8 keys570_5k[0x10] = -{ - 0x6D, 0x72, 0xA4, 0xBA, 0x7F, 0xBF, 0xD1, 0xF1, - 0xA9, 0xF3, 0xBB, 0x07, 0x1B, 0xC0, 0xB3, 0x66 -}; - -/* 6.00-6.20 kernel and phat */ -u8 keys620_0[0x10] = -{ - 0xD6, 0xBD, 0xCE, 0x1E, 0x12, 0xAF, 0x9A, 0xE6, - 0x69, 0x30, 0xDE, 0xDA, 0x88, 0xB8, 0xFF, 0xFB -}; - -/* 6.00-6.20 slim kernel */ -u8 keys620_1[0x10] = -{ - 0x1D, 0x13, 0xE9, 0x50, 0x04, 0x73, 0x3D, 0xD2, - 0xE1, 0xDA, 0xB9, 0xC1, 0xE6, 0x7B, 0x25, 0xA7 -}; - -u8 keys620_a[0x10] = -{ - 0xAC, 0x34, 0xBA, 0xB1, 0x97, 0x8D, 0xAE, 0x6F, - 0xBA, 0xE8, 0xB1, 0xD6, 0xDF, 0xDF, 0xF1, 0xA2 -}; - -u8 keys620_e[0x10] = -{ - 0xB1, 0xB3, 0x7F, 0x76, 0xC3, 0xFB, 0x88, 0xE6, - 0xF8, 0x60, 0xD3, 0x35, 0x3C, 0xA3, 0x4E, 0xF3 -}; - -/* PSPgo internal */ -u8 keys620_5[0x10] = -{ - 0xF1, 0xBC, 0x17, 0x07, 0xAE, 0xB7, 0xC8, 0x30, - 0xD8, 0x34, 0x9D, 0x40, 0x6A, 0x8E, 0xDF, 0x4E -}; - -/* 6.XX PSPgo kernel */ -u8 keys620_5k[0x10] = -{ - 0x41, 0x8A, 0x35, 0x4F, 0x69, 0x3A, 0xDF, 0x04, - 0xFD, 0x39, 0x46, 0xA2, 0x5C, 0x2D, 0xF2, 0x21 -}; - -u8 keys620_5v[0x10] = -{ - 0xF2, 0x8F, 0x75, 0xA7, 0x31, 0x91, 0xCE, 0x9E, - 0x75, 0xBD, 0x27, 0x26, 0xB4, 0xB4, 0x0C, 0x32 -}; - -/* 6.30 phat kernel */ -u8 keys630_k1[0x10] = { - 0x36, 0xB0, 0xDC, 0xFC, 0x59, 0x2A, 0x95, 0x1D, - 0x80, 0x2D, 0x80, 0x3F, 0xCD, 0x30, 0xA0, 0x1B, -}; - -/* 6.30 phat kernel-2 */ -u8 keys630_k2[0x10] = { - 0xd4, 0x35, 0x18, 0x02, 0x29, 0x68, 0xfb, 0xa0, - 0x6a, 0xa9, 0xa5, 0xed, 0x78, 0xfd, 0x2e, 0x9d -}; - -u8 key_380280f0[0x10] = -{ - 0x97, 0x09, 0x12, 0xD3, 0xDB, 0x02, 0xBD, 0xD8, - 0xE7, 0x74, 0x51, 0xFE, 0xF0, 0xEA, 0x6C, 0x5C, -}; - -/* 6.30 slim kernel */ -u8 keys630_k3[0x10] = -{ - 0x23, 0x8D, 0x3D, 0xAE, 0x41, 0x50, 0xA0, 0xFA, - 0xF3, 0x2F, 0x32, 0xCE, 0xC7, 0x27, 0xCD, 0x50, -}; - -/* 6.30 slim pops */ -u8 keys630_k4[0x10] = -{ - 0xAA, 0xA1, 0xB5, 0x7C, 0x93, 0x5A, 0x95, 0xBD, - 0xEF, 0x69, 0x16, 0xFC, 0x2B, 0x92, 0x31, 0xDD -}; - -u8 keys630_k5[0x10] = { 0x87,0x37,0x21,0xCC,0x65,0xAE,0xAA,0x5F,0x40,0xF6,0x6F,0x2A,0x86,0xC7,0xA1,0xC8 }; -u8 keys630_k6[0x10] = { 0x8D,0xDB,0xDC,0x5C,0xF2,0x70,0x2B,0x40,0xB2,0x3D,0x00,0x09,0x61,0x7C,0x10,0x60 }; -u8 keys630_k7[0x10] = { 0x77,0x1C,0x06,0x5F,0x53,0xEC,0x3F,0xFC,0x22,0xCE,0x5A,0x27,0xFF,0x78,0xA8,0x48 }; -u8 keys630_k8[0x10] = { 0x81,0xD1,0x12,0x89,0x35,0xC8,0xEA,0x8B,0xE0,0x02,0x2D,0x2D,0x6A,0x18,0x67,0xB8 }; - -u8 keys636_k1[0x10] = { 0x07,0xE3,0x08,0x64,0x7F,0x60,0xA3,0x36,0x6A,0x76,0x21,0x44,0xC9,0xD7,0x06,0x83 }; -u8 keys636_k2[0x10] = { 0x91,0xF2,0x02,0x9E,0x63,0x32,0x30,0xA9,0x1D,0xDA,0x0B,0xA8,0xB7,0x41,0xA3,0xCC }; - -u8 keys600_1[0x10] = { 0xE3,0x52,0x39,0x97,0x3B,0x84,0x41,0x1C,0xC3,0x23,0xF1,0xB8,0xA9,0x09,0x4B,0xF0 }; -u8 keys600_2[0x10] = { 0xE1,0x45,0x93,0x2C,0x53,0xE2,0xAB,0x06,0x6F,0xB6,0x8F,0x0B,0x66,0x91,0xE7,0x1E }; - -u8 key_380283F0[0x10] = { 0x34,0x20,0x0C,0x8E,0xA1,0x86,0x79,0x84,0xAF,0x13,0xAE,0x34,0x77,0x6F,0xEA,0x89 }; - -u8 keys620_upd[0x10] = { 0xE2,0x03,0x8A,0x8C,0x33,0x81,0x4B,0x56,0x52,0x4E,0x1D,0xE5,0xA4,0x24,0x04,0xFF }; - -typedef struct -{ - u32 tag; // 4 byte value at offset 0xD0 in the PRX file - u8 *key; // 16 bytes keys - u8 code; // code for scramble - u8 type; -} TAG_INFO2; - -static TAG_INFO2 g_tagInfo2[] = -{ - { 0xA6E328F0, keys620_upd, 0x5F }, // 5.70, 6.10, 6.20 PSPgo Updater - - { 0x4C948AF0, keys636_k1, 0x43, 3}, // 6.36 - { 0x4C948BF0, keys636_k2, 0x43, 3}, // 6.36 02g - - { 0x457b80f0, keys630_k2, 0x5B, 3}, // 6.30 - { 0x457B81F0, keys630_k4, 0x5B, 3}, // 6.30 02g - { 0x457B82F0, keys630_k5, 0x5B, 3}, // 6.30 03g 04g 07g 09g - { 0x457B83F0, keys630_k7, 0x5B, 3}, // 6.30 05g - { 0x4C9484F0, keys630_k1, 0x43, 3}, // 6.30 - { 0x4C9485F0, keys630_k3, 0x43, 3}, // 6.30 02g - { 0x4C9486F0, keys630_k6, 0x43, 3}, // 6.30 03g 04g 07g 09g - { 0x4C9487F0, keys630_k8, 0x43, 3}, // 6.30 05g - - { 0x380283F0, key_380283F0, 0x5A, 3}, // 6.30 vshmain 05g - { 0x380280f0, key_380280f0, 0x5A, 3}, // 6.30 vshmain - - { 0x457B28F0, keys620_e, 0x5B }, - { 0x457B0CF0, keys620_a, 0x5B }, - { 0x380228F0, keys620_5v, 0x5A }, // PSPgo 6.XX vshmain - { 0x4C942AF0, keys620_5k, 0x43 }, // PSPgo 6.XX - { 0x4C9428F0, keys620_5 , 0x43 }, // PSPgo - { 0x4C9422F0, keys600_2, 0x43 }, // 6.00 03g 04g - { 0x4C941EF0, keys600_1, 0x43 }, - { 0x4C941DF0, keys620_1, 0x43 }, - { 0x4C941CF0, keys620_0, 0x43 }, - { 0x4C9429F0, keys570_5k, 0x43 }, // PSPgo 5.70 - { 0x4C9419F0, keys505_1, 0x43 }, - { 0x4C9418F0, keys505_0, 0x43 }, - { 0x457B0BF0, keys505_a, 0x5B }, - { 0x457B1EF0, keys500_c, 0x5B }, - { 0x4C941FF0, keys500_2, 0x43 }, - { 0x4C9417F0, keys500_1, 0x43 }, - { 0x4C9416F0, keys500_0, 0x43 }, - { 0x4C9415F0, keys390_1, 0x43 }, - { 0x4C9414F0, keys390_0, 0x43 }, - { 0x4C9412F0, keys370_0, 0x43 }, - { 0x4C9413F0, keys370_1, 0x43 }, - { 0x457B10F0, keys370_2, 0x5B }, - - { 0xD82310F0, keys02G_E, 0x51 }, - { 0xD8231EF0, keys03G_E, 0x51 }, - { 0xD82328F0, keys05G_E, 0x51 }, - - { 0x4C940DF0, keys360_0, 0x43 }, - { 0x4C9410F0, keys360_1, 0x43 }, - - { 0x4C940BF0, keys330_0, 0x43 }, - { 0x457B0AF0, keys330_1, 0x5B }, - { 0x38020AF0, keys330_2, 0x5A }, - { 0x4C940AF0, keys330_3, 0x43 }, - { 0x4C940CF0, keys330_4, 0x43 }, - - { 0xcfef09f0, keys310_0, 0x62 }, - { 0x457b08f0, keys310_1, 0x5B }, - { 0x380208F0, keys310_2, 0x5A }, - { 0xcfef08f0, keys310_3, 0x62 }, - - { 0xCFEF07F0, keys303_0, 0x62 }, - { 0xCFEF06F0, keys300_0, 0x62 }, - { 0x457B06F0, keys300_1, 0x5B }, - { 0x380206F0, keys300_2, 0x5A }, - - { 0xCFEF05F0, keys280_0, 0x62 }, - { 0x457B05F0, keys280_1, 0x5B }, - { 0x380205F0, keys280_2, 0x5A }, - { 0x16D59E03, keys260_0, 0x62 }, - { 0x76202403, keys260_1, 0x5B }, - { 0x0F037303, keys260_2, 0x5A } -}; - - -static TAG_INFO2 *GetTagInfo2(u32 tagFind) -{ - int iTag; - - for (iTag = 0; iTag < sizeof(g_tagInfo2) / sizeof(TAG_INFO2); iTag++) - { - if (g_tagInfo2[iTag].tag == tagFind) - { - return &g_tagInfo2[iTag]; - } - } - - return NULL; // not found -} - -static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag) -{ - TAG_INFO2 * pti = GetTagInfo2(tag); - - if (!pti) - { - //Kprintf("Unknown tag 0x%08X.\n", tag); - return -1; - } - - int retsize = *(int *)&inbuf[0xB0]; - u8 tmp1[0x150], tmp2[0x90+0x14], tmp3[0x60+0x14], tmp4[0x20]; - - memset(tmp1, 0, 0x150); - memset(tmp2, 0, 0x90+0x14); - memset(tmp3, 0, 0x60+0x14); - memset(tmp4, 0, 0x20); - - if (inbuf != outbuf) - memcpy(outbuf, inbuf, size); - - if (size < 0x160) - { - Kprintf("Buffer not big enough.\n"); - return -2; - } - - if (((u32)outbuf & 0x3F)) - { - Kprintf("Buffer not aligned to 64 bytes.\n"); - return -3; - } - - if ((size - 0x150) < retsize) - { - Kprintf("No enough data.\n"); - return -4; - } - - memcpy(tmp1, outbuf, 0x150); - - int i, j; - u8 *p = tmp2+0x14; - - for (i = 0; i < 9; i++) - { - for (j = 0; j < 0x10; j++) - { - p[(i << 4) + j] = pti->key[j]; - - } - - p[(i << 4)] = i; - } - - if (Scramble((u32 *)tmp2, 0x90, pti->code) < 0) - { - Kprintf("Error in Scramble #1.\n"); - return -5; - } - - memcpy(outbuf, tmp1+0xD0, 0x5C); - memcpy(outbuf+0x5C, tmp1+0x140, 0x10); - memcpy(outbuf+0x6C, tmp1+0x12C, 0x14); - memcpy(outbuf+0x80, tmp1+0x080, 0x30); - memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10); - memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10); - memcpy(outbuf+0xD0, tmp1+0x000, 0x80); - - memcpy(tmp3+0x14, outbuf+0x5C, 0x60); - - if (Scramble((u32 *)tmp3, 0x60, pti->code) < 0) - { - Kprintf("Error in Scramble #2.\n"); - return -6; - } - - memcpy(outbuf+0x5C, tmp3, 0x60); - memcpy(tmp3, outbuf+0x6C, 0x14); - memcpy(outbuf+0x70, outbuf+0x5C, 0x10); - - if(pti->type == 3) - { - memcpy(tmp4, outbuf+0x3C, 0x20); - memcpy(outbuf+0x50, tmp4, 0x20); - memset(outbuf+0x18, 0, 0x38); - }else - memset(outbuf+0x18, 0, 0x58); - - memcpy(outbuf+0x04, outbuf, 0x04); - *((u32 *)outbuf) = 0x014C; - memcpy(outbuf+0x08, tmp2, 0x10); - - /* sha-1 */ - - if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0) - { - Kprintf("Error in sceUtilsBufferCopyWithRange 0xB.\n"); - return -7; - } - - if (memcmp(outbuf, tmp3, 0x14) != 0) - { - Kprintf("SHA-1 is incorrect.\n"); - return -8; - } - - int iXOR; - - for (iXOR = 0; iXOR < 0x40; iXOR++) - { - tmp3[iXOR+0x14] = outbuf[iXOR+0x80] ^ tmp2[iXOR+0x10]; - } - - if (Scramble((u32 *)tmp3, 0x40, pti->code) != 0) - { - Kprintf("Error in Scramble #2.\n"); - return -9; - } - - for (iXOR = 0x3F; iXOR >= 0; iXOR--) - { - outbuf[iXOR+0x40] = tmp3[iXOR] ^ tmp2[iXOR+0x50]; // uns 8 - } - - if (pti->type == 3) - { - memcpy(outbuf+0x80, tmp4, 0x20); - memset(outbuf+0xA0, 0, 0x10); - *(u32*)&outbuf[0xA4] = 1; - *(u32*)&outbuf[0xA0] = 1; - } else - { - memset(outbuf+0x80, 0, 0x30); - *(u32*)&outbuf[0xA0] = 1; - } - - memcpy(outbuf+0xB0, outbuf+0xC0, 0x10); - memset(outbuf+0xC0, 0, 0x10); - memcpy(outbuf+0xD0, outbuf+0xD0, 0x80); - - // The real decryption - if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf+0x40, size-0x40, 0x1) != 0) - { - Kprintf("Error in sceUtilsBufferCopyWithRange 0x1.\n"); - return -1; - } - - if (retsize < 0x150) - { - // Fill with 0 - memset(outbuf+retsize, 0, 0x150-retsize); - } - - return retsize; -} - -int pspDecryptPRX(u8 *data, u32 size, u32 *out_size) -{ - int retsize = DecryptPRX1(data, data, size, *(u32 *)&data[0xD0]); - - if (retsize <= 0) - { - retsize = DecryptPRX2(data, data, size, *(u32 *)&data[0xD0]); - } - - if (retsize <= 0) - { - return -1; - } - - out_size[0] = retsize; - return 0; -} +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#include "decrypt.h" +//#include +//#include + + +extern int UtilsForKernel_6C6887EE(void *, u32, void *, void *); + +////////// Decryption 1 ////////// + +// use pre-calculated keys (step1 results) + +u32 g_key0[] = +{ + 0x7b21f3be, 0x299c5e1d, 0x1c9c5e71, 0x96cb4645, 0x3c9b1be0, 0xeb85de3d, + 0x4a7f2022, 0xc2206eaa, 0xd50b3265, 0x55770567, 0x3c080840, 0x981d55f2, + 0x5fd8f6f3, 0xee8eb0c5, 0x944d8152, 0xf8278651, 0x2705bafa, 0x8420e533, + 0x27154ae9, 0x4819aa32, 0x59a3aa40, 0x2cb3cf65, 0xf274466d, 0x3a655605, + 0x21b0f88f, 0xc5b18d26, 0x64c19051, 0xd669c94e, 0xe87035f2, 0x9d3a5909, + 0x6f4e7102, 0xdca946ce, 0x8416881b, 0xbab097a5, 0x249125c6, 0xb34c0872, +}; + +u32 g_key2[] = +{ + 0xccfda932, 0x51c06f76, 0x046dcccf, 0x49e1821e, 0x7d3b024c, 0x9dda5865, + 0xcc8c9825, 0xd1e97db5, 0x6874d8cb, 0x3471c987, 0x72edb3fc, 0x81c8365d, + 0xe161e33a, 0xfc92db59, 0x2009b1ec, 0xb1a94ce4, 0x2f03696b, 0x87e236d8, + 0x3b2b8ce9, 0x0305e784, 0xf9710883, 0xb039db39, 0x893bea37, 0xe74d6805, + 0x2a5c38bd, 0xb08dc813, 0x15b32375, 0x46be4525, 0x0103fd90, 0xa90e87a2, + 0x52aba66a, 0x85bf7b80, 0x45e8ce63, 0x4dd716d3, 0xf5e30d2d, 0xaf3ae456, +}; + +u32 g_key3[] = +{ + 0xa6c8f5ca, 0x6d67c080, 0x924f4d3a, 0x047ca06a, 0x08640297, 0x4fd4a758, + 0xbd685a87, 0x9b2701c2, 0x83b62a35, 0x726b533c, 0xe522fa0c, 0xc24b06b4, + 0x459d1cac, 0xa8c5417b, 0x4fea62a2, 0x0615d742, 0x30628d09, 0xc44fab14, + 0x69ff715e, 0xd2d8837d, 0xbeed0b8b, 0x1e6e57ae, 0x61e8c402, 0xbe367a06, + 0x543f2b5e, 0xdb3ec058, 0xbe852075, 0x1e7e4dcc, 0x1564ea55, 0xec7825b4, + 0xc0538cad, 0x70f72c7f, 0x49e8c3d0, 0xeda97ec5, 0xf492b0a4, 0xe05eb02a, +}; + +u32 g_key44[] = +{ + 0xef80e005, 0x3a54689f, 0x43c99ccd, 0x1b7727be, 0x5cb80038, 0xdd2efe62, + 0xf369f92c, 0x160f94c5, 0x29560019, 0xbf3c10c5, 0xf2ce5566, 0xcea2c626, + 0xb601816f, 0x64e7481e, 0x0c34debd, 0x98f29cb0, 0x3fc504d7, 0xc8fb39f0, + 0x0221b3d8, 0x63f936a2, 0x9a3a4800, 0x6ecc32e3, 0x8e120cfd, 0xb0361623, + 0xaee1e689, 0x745502eb, 0xe4a6c61c, 0x74f23eb4, 0xd7fa5813, 0xb01916eb, + 0x12328457, 0xd2bc97d2, 0x646425d8, 0x328380a5, 0x43da8ab1, 0x4b122ac9, +}; + +u32 g_key20[] = +{ + 0x33b50800, 0xf32f5fcd, 0x3c14881f, 0x6e8a2a95, 0x29feefd5, 0x1394eae3, + 0xbd6bd443, 0x0821c083, 0xfab379d3, 0xe613e165, 0xf5a754d3, 0x108b2952, + 0x0a4b1e15, 0x61eadeba, 0x557565df, 0x3b465301, 0xae54ecc3, 0x61423309, + 0x70c9ff19, 0x5b0ae5ec, 0x989df126, 0x9d987a5f, 0x55bc750e, 0xc66eba27, + 0x2de988e8, 0xf76600da, 0x0382dccb, 0x5569f5f2, 0x8e431262, 0x288fe3d3, + 0x656f2187, 0x37d12e9c, 0x2f539eb4, 0xa492998e, 0xed3958f7, 0x39e96523, +}; + +u32 g_key3A[] = +{ + 0x67877069, 0x3abd5617, 0xc23ab1dc, 0xab57507d, 0x066a7f40, 0x24def9b9, + 0x06f759e4, 0xdcf524b1, 0x13793e5e, 0x0359022d, 0xaae7e1a2, 0x76b9b2fa, + 0x9a160340, 0x87822fba, 0x19e28fbb, 0x9e338a02, 0xd8007e9a, 0xea317af1, + 0x630671de, 0x0b67ca7c, 0x865192af, 0xea3c3526, 0x2b448c8e, 0x8b599254, + 0x4602e9cb, 0x4de16cda, 0xe164d5bb, 0x07ecd88e, 0x99ffe5f8, 0x768800c1, + 0x53b091ed, 0x84047434, 0xb426dbbc, 0x36f948bb, 0x46142158, 0x749bb492, +}; + +/* updaters keys */ +u8 updaters_keys[0x90+0x14] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0B, 0x01, 0x1C, 0xE7, 0x31, 0x15, 0x6B, 0x83, + 0x3E, 0x26, 0x0D, 0xCC, 0x69, 0x36, 0x12, 0xCB, + 0xA7, 0xFD, 0x26, 0x66, 0x93, 0x2A, 0x6E, 0x1A, + 0x91, 0x2E, 0xC6, 0xFC, 0xD8, 0x2F, 0x00, 0x13, + 0x5A, 0xE2, 0xDF, 0xB6, 0xA2, 0xE4, 0x27, 0xC8, + 0x18, 0xC3, 0x50, 0x50, 0xB7, 0xE9, 0x4A, 0xED, + 0xCC, 0x3C, 0x30, 0xFD, 0x10, 0x6A, 0x2B, 0x0A, + 0x22, 0xCB, 0xC6, 0xE0, 0x20, 0x65, 0x12, 0xEB, + 0x7D, 0x4E, 0x2A, 0x37, 0x0B, 0x0A, 0xEF, 0x88, + 0xDA, 0x06, 0x54, 0xD4, 0x30, 0xAF, 0xCD, 0xCA, + 0x9A, 0xF9, 0xDA, 0x1A, 0xB0, 0x1B, 0xBB, 0x62, + 0x0C, 0xDB, 0xF8, 0x44, 0x73, 0x56, 0x14, 0x8E, + 0x93, 0xB1, 0x2C, 0xFD, 0x67, 0xE2, 0x5D, 0xCB, + 0x48, 0x5B, 0xD9, 0xB3, 0x54, 0x14, 0xD7, 0x9F, + 0x79, 0x9C, 0x24, 0xE9, 0xC2, 0x7A, 0x4E, 0x8C, + 0x4D, 0x24, 0x19, 0x94, 0xFF, 0xC9, 0xC2, 0x2D, + 0x23, 0x63, 0x51, 0xB8, 0xFA, 0xD6, 0x7F, 0xE6, + 0x5E, 0xBC, 0x32, 0xB2, 0x02, 0x13, 0xC4, 0x76 +}; + +/* locoroco, kazue, and maybe others demos keys */ +u8 demo_keys0[0x90+0x14] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x82, 0x4C, 0xA5, 0x18, 0xD3, 0xC8, 0x6E, 0xEA, + 0x17, 0x41, 0x04, 0xDC, 0xEA, 0xC5, 0x01, 0xFC, + 0x97, 0xB1, 0x94, 0x54, 0x71, 0x19, 0x22, 0xEE, + 0xE0, 0x2D, 0xE9, 0x83, 0x3D, 0x64, 0x30, 0xE6, + 0x42, 0x5C, 0x30, 0x5F, 0xEB, 0x41, 0xA0, 0xE0, + 0x62, 0xC6, 0x63, 0xEE, 0x5D, 0xA5, 0x0D, 0x1E, + 0xC2, 0x10, 0x14, 0x49, 0x06, 0xC6, 0x93, 0x84, + 0x71, 0xA5, 0x42, 0x63, 0x13, 0xF0, 0xB6, 0xD5, + 0x43, 0x51, 0x9E, 0xFA, 0x91, 0x0A, 0x7C, 0xE1, + 0x58, 0x1B, 0x95, 0x25, 0x40, 0x11, 0xF1, 0x8D, + 0xB1, 0x01, 0x8D, 0x04, 0x09, 0x54, 0x5C, 0x54, + 0xF5, 0x53, 0x08, 0xB0, 0x53, 0x85, 0xB4, 0xCE, + 0x0B, 0xF5, 0xC3, 0xFB, 0xC6, 0x55, 0x24, 0x0B, + 0xF2, 0xC6, 0x2C, 0xE4, 0x0C, 0xF0, 0x05, 0x3C, + 0xD7, 0x6C, 0x39, 0xD5, 0x87, 0x22, 0x09, 0xF7, + 0x3D, 0xC5, 0xA2, 0xFD, 0x55, 0x92, 0x3F, 0xB1, + 0xF6, 0xFE, 0xC8, 0x18, 0x1D, 0x6B, 0x04, 0x52, + 0x5F, 0x8C, 0xE8, 0xE7, 0x26, 0x5A, 0x6E, 0x5A +}; + +typedef struct +{ + u32 tag; // 4 byte value at offset 0xD0 in the PRX file + u8* key; // "step1_result" use for XOR step + u8 code; + u8 codeExtra; +} TAG_INFO; + +static const TAG_INFO g_tagInfo[] = +{ + // 1.x PRXs + { 0x00000000, (u8*)g_key0, 0x42 }, + { 0x02000000, (u8*)g_key2, 0x45 }, + { 0x03000000, (u8*)g_key3, 0x46 }, + + // 2.0 PRXs + { 0x4467415d, (u8*)g_key44, 0x59, 0x59 }, + { 0x207bbf2f, (u8*)g_key20, 0x5A, 0x5A }, + { 0x3ace4dce, (u8*)g_key3A, 0x5B, 0x5B }, + + // updaters + { 0x0b000000, updaters_keys, 0x4E }, + + // locoroco, kazue, demos + { 0x0c000000, demo_keys0, 0x4F }, +}; + +static TAG_INFO const* GetTagInfo(u32 tagFind) +{ + int iTag; + for (iTag = 0; iTag < sizeof(g_tagInfo)/sizeof(TAG_INFO); iTag++) + if (g_tagInfo[iTag].tag == tagFind) + return &g_tagInfo[iTag]; + return NULL; // not found +} + +static void ExtraV2Mangle(u8* buffer1, u8 codeExtra) +{ + static u8 g_dataTmp[20+0xA0] __attribute__((aligned(0x40))); + u8* buffer2 = g_dataTmp; // aligned + + memcpy(buffer2+20, buffer1, 0xA0); + u32* pl2 = (u32*)buffer2; + pl2[0] = 5; + pl2[1] = pl2[2] = 0; + pl2[3] = codeExtra; + pl2[4] = 0xA0; + + int ret = sceUtilsBufferCopyWithRange(buffer2, 20+0xA0, buffer2, 20+0xA0, 7); + if (ret != 0) + Kprintf("extra de-mangle returns %d\n", ret); + // copy result back + memcpy(buffer1, buffer2, 0xA0); +} + +static int Scramble(u32 *buf, u32 size, u32 code) +{ + buf[0] = 5; + buf[1] = buf[2] = 0; + buf[3] = code; + buf[4] = size; + + if (sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size+0x14, 7) < 0) + { + return -1; + } + + return 0; +} + +static int DecryptPRX1(const u8* pbIn, u8* pbOut, int cbTotal, u32 tag) +{ + int i, retsize; + u8 bD0[0x80], b80[0x50], b00[0x80], bB0[0x20]; + + TAG_INFO const* pti = GetTagInfo(tag); + if (pti == NULL) + return -1; + + retsize = *(u32*)&pbIn[0xB0]; + + for (i = 0; i < 0x14; i++) + { + if (pti->key[i] != 0) + break; + } + + if (i == 0x14) + { + Scramble((u32 *)pti->key, 0x90, pti->code); + } + + // build conversion into pbOut + + if (pbIn != pbOut) + memcpy(pbOut, pbIn, cbTotal); + + memcpy(bD0, pbIn+0xD0, 0x80); + memcpy(b80, pbIn+0x80, 0x50); + memcpy(b00, pbIn+0x00, 0x80); + memcpy(bB0, pbIn+0xB0, 0x20); + + memset(pbOut, 0, 0x150); + memset(pbOut, 0x55, 0x40); // first $40 bytes ignored + + // step3 demangle in place + u32* pl = (u32*)(pbOut+0x2C); + pl[0] = 5; // number of ulongs in the header + pl[1] = pl[2] = 0; + pl[3] = pti->code; // initial seed for PRX + pl[4] = 0x70; // size + + // redo part of the SIG check (step2) + u8 buffer1[0x150]; + memcpy(buffer1+0x00, bD0, 0x80); + memcpy(buffer1+0x80, b80, 0x50); + memcpy(buffer1+0xD0, b00, 0x80); + if (pti->codeExtra != 0) + ExtraV2Mangle(buffer1+0x10, pti->codeExtra); + memcpy(pbOut+0x40 /* 0x2C+20 */, buffer1+0x40, 0x40); + + int ret; + int iXOR; + for (iXOR = 0; iXOR < 0x70; iXOR++) + pbOut[0x40+iXOR] = pbOut[0x40+iXOR] ^ pti->key[0x14+iXOR]; + + ret = sceUtilsBufferCopyWithRange(pbOut+0x2C, 20+0x70, pbOut+0x2C, 20+0x70, 7); + if (ret != 0) + { + Kprintf("mangle#7 returned $%x\n", ret); + return -1; + } + + for (iXOR = 0x6F; iXOR >= 0; iXOR--) + pbOut[0x40+iXOR] = pbOut[0x2C+iXOR] ^ pti->key[0x20+iXOR]; + + memset(pbOut+0x80, 0, 0x30); // $40 bytes kept, clean up + pbOut[0xA0] = 1; + // copy unscrambled parts from header + memcpy(pbOut+0xB0, bB0, 0x20); // file size + lots of zeros + memcpy(pbOut+0xD0, b00, 0x80); // ~PSP header + + // step4: do the actual decryption of code block + // point 0x40 bytes into the buffer to key info + ret = sceUtilsBufferCopyWithRange(pbOut, cbTotal, pbOut+0x40, cbTotal-0x40, 0x1); + if (ret != 0) + { + Kprintf("mangle#1 returned $%x\n", ret); + return -1; + } + + // return cbTotal - 0x150; // rounded up size + return retsize; +} + +////////// Decryption 2 ////////// + +/* kernel modules 2.60-2.71 */ +u8 keys260_0[0x10] = +{ + 0xC3, 0x24, 0x89, 0xD3, 0x80, 0x87, 0xB2, 0x4E, + 0x4C, 0xD7, 0x49, 0xE4, 0x9D, 0x1D, 0x34, 0xD1 + +}; + +/* user modules 2.60-2.71 */ +u8 keys260_1[0x10] = +{ + 0xF3, 0xAC, 0x6E, 0x7C, 0x04, 0x0A, 0x23, 0xE7, + 0x0D, 0x33, 0xD8, 0x24, 0x73, 0x39, 0x2B, 0x4A +}; + +/* vshmain 2.60-2.71 */ +u8 keys260_2[0x10] = +{ + 0x72, 0xB4, 0x39, 0xFF, 0x34, 0x9B, 0xAE, 0x82, + 0x30, 0x34, 0x4A, 0x1D, 0xA2, 0xD8, 0xB4, 0x3C +}; + +/* kernel modules 2.80 */ +u8 keys280_0[0x10] = +{ + 0xCA, 0xFB, 0xBF, 0xC7, 0x50, 0xEA, 0xB4, 0x40, + 0x8E, 0x44, 0x5C, 0x63, 0x53, 0xCE, 0x80, 0xB1 +}; + +/* user modules 2.80 */ +u8 keys280_1[0x10] = +{ + 0x40, 0x9B, 0xC6, 0x9B, 0xA9, 0xFB, 0x84, 0x7F, + 0x72, 0x21, 0xD2, 0x36, 0x96, 0x55, 0x09, 0x74 +}; + +/* vshmain executable 2.80 */ +u8 keys280_2[0x10] = +{ + 0x03, 0xA7, 0xCC, 0x4A, 0x5B, 0x91, 0xC2, 0x07, + 0xFF, 0xFC, 0x26, 0x25, 0x1E, 0x42, 0x4B, 0xB5 +}; + +/* kernel modules 3.00 */ +u8 keys300_0[0x10] = +{ + 0x9F, 0x67, 0x1A, 0x7A, 0x22, 0xF3, 0x59, 0x0B, + 0xAA, 0x6D, 0xA4, 0xC6, 0x8B, 0xD0, 0x03, 0x77 + +}; + +/* user modules 3.00 */ +u8 keys300_1[0x10] = +{ + 0x15, 0x07, 0x63, 0x26, 0xDB, 0xE2, 0x69, 0x34, + 0x56, 0x08, 0x2A, 0x93, 0x4E, 0x4B, 0x8A, 0xB2 + +}; + +/* vshmain 3.00 */ +u8 keys300_2[0x10] = +{ + 0x56, 0x3B, 0x69, 0xF7, 0x29, 0x88, 0x2F, 0x4C, + 0xDB, 0xD5, 0xDE, 0x80, 0xC6, 0x5C, 0xC8, 0x73 + +}; + +/* kernel modules 3.00 */ +u8 keys303_0[0x10] = +{ + 0x7b, 0xa1, 0xe2, 0x5a, 0x91, 0xb9, 0xd3, 0x13, + 0x77, 0x65, 0x4a, 0xb7, 0xc2, 0x8a, 0x10, 0xaf +}; + +/* kernel modules 3.10 */ +u8 keys310_0[0x10] = +{ + 0xa2, 0x41, 0xe8, 0x39, 0x66, 0x5b, 0xfa, 0xbb, + 0x1b, 0x2d, 0x6e, 0x0e, 0x33, 0xe5, 0xd7, 0x3f +}; + +/* user modules 3.10 */ +u8 keys310_1[0x10] = +{ + 0xA4, 0x60, 0x8F, 0xAB, 0xAB, 0xDE, 0xA5, 0x65, + 0x5D, 0x43, 0x3A, 0xD1, 0x5E, 0xC3, 0xFF, 0xEA +}; + +/* vshmain 3.10 */ +u8 keys310_2[0x10] = +{ + 0xE7, 0x5C, 0x85, 0x7A, 0x59, 0xB4, 0xE3, 0x1D, + 0xD0, 0x9E, 0xCE, 0xC2, 0xD6, 0xD4, 0xBD, 0x2B +}; + +/* reboot.bin 3.10 */ +u8 keys310_3[0x10] = +{ + 0x2E, 0x00, 0xF6, 0xF7, 0x52, 0xCF, 0x95, 0x5A, + 0xA1, 0x26, 0xB4, 0x84, 0x9B, 0x58, 0x76, 0x2F +}; + +/* kernel modules 3.30 */ +u8 keys330_0[0x10] = +{ + 0x3B, 0x9B, 0x1A, 0x56, 0x21, 0x80, 0x14, 0xED, + 0x8E, 0x8B, 0x08, 0x42, 0xFA, 0x2C, 0xDC, 0x3A +}; + +/* user modules 3.30 */ +u8 keys330_1[0x10] = +{ + 0xE8, 0xBE, 0x2F, 0x06, 0xB1, 0x05, 0x2A, 0xB9, + 0x18, 0x18, 0x03, 0xE3, 0xEB, 0x64, 0x7D, 0x26 +}; + +/* vshmain 3.30 */ +u8 keys330_2[0x10] = +{ + 0xAB, 0x82, 0x25, 0xD7, 0x43, 0x6F, 0x6C, 0xC1, + 0x95, 0xC5, 0xF7, 0xF0, 0x63, 0x73, 0x3F, 0xE7 +}; + +/* reboot.bin 3.30 */ +u8 keys330_3[0x10] = +{ + 0xA8, 0xB1, 0x47, 0x77, 0xDC, 0x49, 0x6A, 0x6F, + 0x38, 0x4C, 0x4D, 0x96, 0xBD, 0x49, 0xEC, 0x9B +}; + +/* stdio.prx 3.30 */ +u8 keys330_4[0x10] = +{ + 0xEC, 0x3B, 0xD2, 0xC0, 0xFA, 0xC1, 0xEE, 0xB9, + 0x9A, 0xBC, 0xFF, 0xA3, 0x89, 0xF2, 0x60, 0x1F +}; + +/* 3.60 common kernel modules */ +u8 keys360_0[16] = +{ + 0x3C, 0x2B, 0x51, 0xD4, 0x2D, 0x85, 0x47, 0xDA, + 0x2D, 0xCA, 0x18, 0xDF, 0xFE, 0x54, 0x09, 0xED +}; + +/* 3.60 specific slim kernel modules */ +u8 keys360_1[16] = +{ + 0x31, 0x1F, 0x98, 0xD5, 0x7B, 0x58, 0x95, 0x45, + 0x32, 0xAB, 0x3A, 0xE3, 0x89, 0x32, 0x4B, 0x34 +}; + +/* 3.70 common and fat kernel modules */ +u8 keys370_0[0x10] = +{ + 0x26, 0x38, 0x0A, 0xAC, 0xA5, 0xD8, 0x74, 0xD1, + 0x32, 0xB7, 0x2A, 0xBF, 0x79, 0x9E, 0x6D, 0xDB +}; + +/* 3.70 slim specific kernel modules */ +u8 keys370_1[0x10] = +{ + 0x53, 0xE7, 0xAB, 0xB9, 0xC6, 0x4A, 0x4B, 0x77, + 0x92, 0x17, 0xB5, 0x74, 0x0A, 0xDA, 0xA9, 0xEA +}; + +/* some 3.70 slim user modules */ +u8 keys370_2[16] = +{ + 0x71, 0x10, 0xF0, 0xA4, 0x16, 0x14, 0xD5, 0x93, + 0x12, 0xFF, 0x74, 0x96, 0xDF, 0x1F, 0xDA, 0x89 +}; + +/* 3.90 kernel */ +u8 keys390_0[16] = +{ + 0x45, 0xEF, 0x5C, 0x5D, 0xED, 0x81, 0x99, 0x84, + 0x12, 0x94, 0x8F, 0xAB, 0xE8, 0x05, 0x6D, 0x7D +}; + +/* 3.90 slim */ +u8 keys390_1[16] = +{ + 0x70, 0x1B, 0x08, 0x25, 0x22, 0xA1, 0x4D, 0x3B, + 0x69, 0x21, 0xF9, 0x71, 0x0A, 0xA8, 0x41, 0xA9 +}; + +/* 5.00 kernel */ +u8 keys500_0[16] = +{ + 0xEB, 0x1B, 0x53, 0x0B, 0x62, 0x49, 0x32, 0x58, + 0x1F, 0x83, 0x0A, 0xF4, 0x99, 0x3D, 0x75, 0xD0 +}; + +/* 5.00 kernel 2000 specific */ +u8 keys500_1[16] = +{ + 0xBA, 0xE2, 0xA3, 0x12, 0x07, 0xFF, 0x04, 0x1B, + 0x64, 0xA5, 0x11, 0x85, 0xF7, 0x2F, 0x99, 0x5B +}; + +/* 5.00 kernel 3000 specific */ +u8 keys500_2[16] = +{ + 0x2C, 0x8E, 0xAF, 0x1D, 0xFF, 0x79, 0x73, 0x1A, + 0xAD, 0x96, 0xAB, 0x09, 0xEA, 0x35, 0x59, 0x8B +}; + +u8 keys500_c[16] = +{ + 0xA3, 0x5D, 0x51, 0xE6, 0x56, 0xC8, 0x01, 0xCA, + 0xE3, 0x77, 0xBF, 0xCD, 0xFF, 0x24, 0xDA, 0x4D +}; + +u8 keys505_a[16] = +{ + 0x7B, 0x94, 0x72, 0x27, 0x4C, 0xCC, 0x54, 0x3B, + 0xAE, 0xDF, 0x46, 0x37, 0xAC, 0x01, 0x4D, 0x87 +}; + +u8 keys505_0[16] = +{ + 0x2E, 0x8E, 0x97, 0xA2, 0x85, 0x42, 0x70, 0x73, + 0x18, 0xDA, 0xA0, 0x8A, 0xF8, 0x62, 0xA2, 0xB0 +}; + +u8 keys505_1[16] = +{ + 0x58, 0x2A, 0x4C, 0x69, 0x19, 0x7B, 0x83, 0x3D, + 0xD2, 0x61, 0x61, 0xFE, 0x14, 0xEE, 0xAA, 0x11 +}; + +/* for psp 2000 file table and ipl pre-decryption */ +u8 keys02G_E[0x10] = +{ + 0x9D, 0x09, 0xFD, 0x20, 0xF3, 0x8F, 0x10, 0x69, + 0x0D, 0xB2, 0x6F, 0x00, 0xCC, 0xC5, 0x51, 0x2E +}; + +/* for psp 3000 file table and ipl pre-decryption */ +u8 keys03G_E[0x10] = +{ + 0x4F, 0x44, 0x5C, 0x62, 0xB3, 0x53, 0xC4, 0x30, + 0xFC, 0x3A, 0xA4, 0x5B, 0xEC, 0xFE, 0x51, 0xEA +}; + +/* for psp go file table and ipl pre-decryption */ +u8 keys05G_E[0x10] = +{ + 0x5D, 0xAA, 0x72, 0xF2, 0x26, 0x60, 0x4D, 0x1C, + 0xE7, 0x2D, 0xC8, 0xA3, 0x2F, 0x79, 0xC5, 0x54 +}; + +/* 5.70 PSPgo kernel*/ +u8 keys570_5k[0x10] = +{ + 0x6D, 0x72, 0xA4, 0xBA, 0x7F, 0xBF, 0xD1, 0xF1, + 0xA9, 0xF3, 0xBB, 0x07, 0x1B, 0xC0, 0xB3, 0x66 +}; + +/* 6.00-6.20 kernel and phat */ +u8 keys620_0[0x10] = +{ + 0xD6, 0xBD, 0xCE, 0x1E, 0x12, 0xAF, 0x9A, 0xE6, + 0x69, 0x30, 0xDE, 0xDA, 0x88, 0xB8, 0xFF, 0xFB +}; + +/* 6.00-6.20 slim kernel */ +u8 keys620_1[0x10] = +{ + 0x1D, 0x13, 0xE9, 0x50, 0x04, 0x73, 0x3D, 0xD2, + 0xE1, 0xDA, 0xB9, 0xC1, 0xE6, 0x7B, 0x25, 0xA7 +}; + +u8 keys620_a[0x10] = +{ + 0xAC, 0x34, 0xBA, 0xB1, 0x97, 0x8D, 0xAE, 0x6F, + 0xBA, 0xE8, 0xB1, 0xD6, 0xDF, 0xDF, 0xF1, 0xA2 +}; + +u8 keys620_e[0x10] = +{ + 0xB1, 0xB3, 0x7F, 0x76, 0xC3, 0xFB, 0x88, 0xE6, + 0xF8, 0x60, 0xD3, 0x35, 0x3C, 0xA3, 0x4E, 0xF3 +}; + +/* PSPgo internal */ +u8 keys620_5[0x10] = +{ + 0xF1, 0xBC, 0x17, 0x07, 0xAE, 0xB7, 0xC8, 0x30, + 0xD8, 0x34, 0x9D, 0x40, 0x6A, 0x8E, 0xDF, 0x4E +}; + +/* 6.XX PSPgo kernel */ +u8 keys620_5k[0x10] = +{ + 0x41, 0x8A, 0x35, 0x4F, 0x69, 0x3A, 0xDF, 0x04, + 0xFD, 0x39, 0x46, 0xA2, 0x5C, 0x2D, 0xF2, 0x21 +}; + +u8 keys620_5v[0x10] = +{ + 0xF2, 0x8F, 0x75, 0xA7, 0x31, 0x91, 0xCE, 0x9E, + 0x75, 0xBD, 0x27, 0x26, 0xB4, 0xB4, 0x0C, 0x32 +}; + +/* 6.30 phat kernel */ +u8 keys630_k1[0x10] = { + 0x36, 0xB0, 0xDC, 0xFC, 0x59, 0x2A, 0x95, 0x1D, + 0x80, 0x2D, 0x80, 0x3F, 0xCD, 0x30, 0xA0, 0x1B, +}; + +/* 6.30 phat kernel-2 */ +u8 keys630_k2[0x10] = { + 0xd4, 0x35, 0x18, 0x02, 0x29, 0x68, 0xfb, 0xa0, + 0x6a, 0xa9, 0xa5, 0xed, 0x78, 0xfd, 0x2e, 0x9d +}; + +u8 key_380280f0[0x10] = +{ + 0x97, 0x09, 0x12, 0xD3, 0xDB, 0x02, 0xBD, 0xD8, + 0xE7, 0x74, 0x51, 0xFE, 0xF0, 0xEA, 0x6C, 0x5C, +}; + +/* 6.30 slim kernel */ +u8 keys630_k3[0x10] = +{ + 0x23, 0x8D, 0x3D, 0xAE, 0x41, 0x50, 0xA0, 0xFA, + 0xF3, 0x2F, 0x32, 0xCE, 0xC7, 0x27, 0xCD, 0x50, +}; + +/* 6.30 slim pops */ +u8 keys630_k4[0x10] = +{ + 0xAA, 0xA1, 0xB5, 0x7C, 0x93, 0x5A, 0x95, 0xBD, + 0xEF, 0x69, 0x16, 0xFC, 0x2B, 0x92, 0x31, 0xDD +}; + +u8 keys630_k5[0x10] = { 0x87,0x37,0x21,0xCC,0x65,0xAE,0xAA,0x5F,0x40,0xF6,0x6F,0x2A,0x86,0xC7,0xA1,0xC8 }; +u8 keys630_k6[0x10] = { 0x8D,0xDB,0xDC,0x5C,0xF2,0x70,0x2B,0x40,0xB2,0x3D,0x00,0x09,0x61,0x7C,0x10,0x60 }; +u8 keys630_k7[0x10] = { 0x77,0x1C,0x06,0x5F,0x53,0xEC,0x3F,0xFC,0x22,0xCE,0x5A,0x27,0xFF,0x78,0xA8,0x48 }; +u8 keys630_k8[0x10] = { 0x81,0xD1,0x12,0x89,0x35,0xC8,0xEA,0x8B,0xE0,0x02,0x2D,0x2D,0x6A,0x18,0x67,0xB8 }; + +u8 keys636_k1[0x10] = { 0x07,0xE3,0x08,0x64,0x7F,0x60,0xA3,0x36,0x6A,0x76,0x21,0x44,0xC9,0xD7,0x06,0x83 }; +u8 keys636_k2[0x10] = { 0x91,0xF2,0x02,0x9E,0x63,0x32,0x30,0xA9,0x1D,0xDA,0x0B,0xA8,0xB7,0x41,0xA3,0xCC }; + +u8 keys600_1[0x10] = { 0xE3,0x52,0x39,0x97,0x3B,0x84,0x41,0x1C,0xC3,0x23,0xF1,0xB8,0xA9,0x09,0x4B,0xF0 }; +u8 keys600_2[0x10] = { 0xE1,0x45,0x93,0x2C,0x53,0xE2,0xAB,0x06,0x6F,0xB6,0x8F,0x0B,0x66,0x91,0xE7,0x1E }; + +u8 key_380283F0[0x10] = { 0x34,0x20,0x0C,0x8E,0xA1,0x86,0x79,0x84,0xAF,0x13,0xAE,0x34,0x77,0x6F,0xEA,0x89 }; + +u8 keys620_upd[0x10] = { 0xE2,0x03,0x8A,0x8C,0x33,0x81,0x4B,0x56,0x52,0x4E,0x1D,0xE5,0xA4,0x24,0x04,0xFF }; + +typedef struct +{ + u32 tag; // 4 byte value at offset 0xD0 in the PRX file + u8 *key; // 16 bytes keys + u8 code; // code for scramble + u8 type; +} TAG_INFO2; + +static TAG_INFO2 g_tagInfo2[] = +{ + { 0xA6E328F0, keys620_upd, 0x5F }, // 5.70, 6.10, 6.20 PSPgo Updater + + { 0x4C948AF0, keys636_k1, 0x43, 3}, // 6.36 + { 0x4C948BF0, keys636_k2, 0x43, 3}, // 6.36 02g + + { 0x457b80f0, keys630_k2, 0x5B, 3}, // 6.30 + { 0x457B81F0, keys630_k4, 0x5B, 3}, // 6.30 02g + { 0x457B82F0, keys630_k5, 0x5B, 3}, // 6.30 03g 04g 07g 09g + { 0x457B83F0, keys630_k7, 0x5B, 3}, // 6.30 05g + { 0x4C9484F0, keys630_k1, 0x43, 3}, // 6.30 + { 0x4C9485F0, keys630_k3, 0x43, 3}, // 6.30 02g + { 0x4C9486F0, keys630_k6, 0x43, 3}, // 6.30 03g 04g 07g 09g + { 0x4C9487F0, keys630_k8, 0x43, 3}, // 6.30 05g + + { 0x380283F0, key_380283F0, 0x5A, 3}, // 6.30 vshmain 05g + { 0x380280f0, key_380280f0, 0x5A, 3}, // 6.30 vshmain + + { 0x457B28F0, keys620_e, 0x5B }, + { 0x457B0CF0, keys620_a, 0x5B }, + { 0x380228F0, keys620_5v, 0x5A }, // PSPgo 6.XX vshmain + { 0x4C942AF0, keys620_5k, 0x43 }, // PSPgo 6.XX + { 0x4C9428F0, keys620_5 , 0x43 }, // PSPgo + { 0x4C9422F0, keys600_2, 0x43 }, // 6.00 03g 04g + { 0x4C941EF0, keys600_1, 0x43 }, + { 0x4C941DF0, keys620_1, 0x43 }, + { 0x4C941CF0, keys620_0, 0x43 }, + { 0x4C9429F0, keys570_5k, 0x43 }, // PSPgo 5.70 + { 0x4C9419F0, keys505_1, 0x43 }, + { 0x4C9418F0, keys505_0, 0x43 }, + { 0x457B0BF0, keys505_a, 0x5B }, + { 0x457B1EF0, keys500_c, 0x5B }, + { 0x4C941FF0, keys500_2, 0x43 }, + { 0x4C9417F0, keys500_1, 0x43 }, + { 0x4C9416F0, keys500_0, 0x43 }, + { 0x4C9415F0, keys390_1, 0x43 }, + { 0x4C9414F0, keys390_0, 0x43 }, + { 0x4C9412F0, keys370_0, 0x43 }, + { 0x4C9413F0, keys370_1, 0x43 }, + { 0x457B10F0, keys370_2, 0x5B }, + + { 0xD82310F0, keys02G_E, 0x51 }, + { 0xD8231EF0, keys03G_E, 0x51 }, + { 0xD82328F0, keys05G_E, 0x51 }, + + { 0x4C940DF0, keys360_0, 0x43 }, + { 0x4C9410F0, keys360_1, 0x43 }, + + { 0x4C940BF0, keys330_0, 0x43 }, + { 0x457B0AF0, keys330_1, 0x5B }, + { 0x38020AF0, keys330_2, 0x5A }, + { 0x4C940AF0, keys330_3, 0x43 }, + { 0x4C940CF0, keys330_4, 0x43 }, + + { 0xcfef09f0, keys310_0, 0x62 }, + { 0x457b08f0, keys310_1, 0x5B }, + { 0x380208F0, keys310_2, 0x5A }, + { 0xcfef08f0, keys310_3, 0x62 }, + + { 0xCFEF07F0, keys303_0, 0x62 }, + { 0xCFEF06F0, keys300_0, 0x62 }, + { 0x457B06F0, keys300_1, 0x5B }, + { 0x380206F0, keys300_2, 0x5A }, + + { 0xCFEF05F0, keys280_0, 0x62 }, + { 0x457B05F0, keys280_1, 0x5B }, + { 0x380205F0, keys280_2, 0x5A }, + { 0x16D59E03, keys260_0, 0x62 }, + { 0x76202403, keys260_1, 0x5B }, + { 0x0F037303, keys260_2, 0x5A } +}; + + +static TAG_INFO2 *GetTagInfo2(u32 tagFind) +{ + int iTag; + + for (iTag = 0; iTag < sizeof(g_tagInfo2) / sizeof(TAG_INFO2); iTag++) + { + if (g_tagInfo2[iTag].tag == tagFind) + { + return &g_tagInfo2[iTag]; + } + } + + return NULL; // not found +} + +static int DecryptPRX2(const u8 *inbuf, u8 *outbuf, u32 size, u32 tag) +{ + TAG_INFO2 * pti = GetTagInfo2(tag); + + if (!pti) + { + //Kprintf("Unknown tag 0x%08X.\n", tag); + return -1; + } + + int retsize = *(int *)&inbuf[0xB0]; + u8 tmp1[0x150], tmp2[0x90+0x14], tmp3[0x60+0x14], tmp4[0x20]; + + memset(tmp1, 0, 0x150); + memset(tmp2, 0, 0x90+0x14); + memset(tmp3, 0, 0x60+0x14); + memset(tmp4, 0, 0x20); + + if (inbuf != outbuf) + memcpy(outbuf, inbuf, size); + + if (size < 0x160) + { + Kprintf("Buffer not big enough.\n"); + return -2; + } + + if (((u32)outbuf & 0x3F)) + { + Kprintf("Buffer not aligned to 64 bytes.\n"); + return -3; + } + + if ((size - 0x150) < retsize) + { + Kprintf("No enough data.\n"); + return -4; + } + + memcpy(tmp1, outbuf, 0x150); + + int i, j; + u8 *p = tmp2+0x14; + + for (i = 0; i < 9; i++) + { + for (j = 0; j < 0x10; j++) + { + p[(i << 4) + j] = pti->key[j]; + + } + + p[(i << 4)] = i; + } + + if (Scramble((u32 *)tmp2, 0x90, pti->code) < 0) + { + Kprintf("Error in Scramble #1.\n"); + return -5; + } + + memcpy(outbuf, tmp1+0xD0, 0x5C); + memcpy(outbuf+0x5C, tmp1+0x140, 0x10); + memcpy(outbuf+0x6C, tmp1+0x12C, 0x14); + memcpy(outbuf+0x80, tmp1+0x080, 0x30); + memcpy(outbuf+0xB0, tmp1+0x0C0, 0x10); + memcpy(outbuf+0xC0, tmp1+0x0B0, 0x10); + memcpy(outbuf+0xD0, tmp1+0x000, 0x80); + + memcpy(tmp3+0x14, outbuf+0x5C, 0x60); + + if (Scramble((u32 *)tmp3, 0x60, pti->code) < 0) + { + Kprintf("Error in Scramble #2.\n"); + return -6; + } + + memcpy(outbuf+0x5C, tmp3, 0x60); + memcpy(tmp3, outbuf+0x6C, 0x14); + memcpy(outbuf+0x70, outbuf+0x5C, 0x10); + + if(pti->type == 3) + { + memcpy(tmp4, outbuf+0x3C, 0x20); + memcpy(outbuf+0x50, tmp4, 0x20); + memset(outbuf+0x18, 0, 0x38); + }else + memset(outbuf+0x18, 0, 0x58); + + memcpy(outbuf+0x04, outbuf, 0x04); + *((u32 *)outbuf) = 0x014C; + memcpy(outbuf+0x08, tmp2, 0x10); + + /* sha-1 */ + + if (sceUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, 0x0B) != 0) + { + Kprintf("Error in sceUtilsBufferCopyWithRange 0xB.\n"); + return -7; + } + + if (memcmp(outbuf, tmp3, 0x14) != 0) + { + Kprintf("SHA-1 is incorrect.\n"); + return -8; + } + + int iXOR; + + for (iXOR = 0; iXOR < 0x40; iXOR++) + { + tmp3[iXOR+0x14] = outbuf[iXOR+0x80] ^ tmp2[iXOR+0x10]; + } + + if (Scramble((u32 *)tmp3, 0x40, pti->code) != 0) + { + Kprintf("Error in Scramble #2.\n"); + return -9; + } + + for (iXOR = 0x3F; iXOR >= 0; iXOR--) + { + outbuf[iXOR+0x40] = tmp3[iXOR] ^ tmp2[iXOR+0x50]; // uns 8 + } + + if (pti->type == 3) + { + memcpy(outbuf+0x80, tmp4, 0x20); + memset(outbuf+0xA0, 0, 0x10); + *(u32*)&outbuf[0xA4] = 1; + *(u32*)&outbuf[0xA0] = 1; + } else + { + memset(outbuf+0x80, 0, 0x30); + *(u32*)&outbuf[0xA0] = 1; + } + + memcpy(outbuf+0xB0, outbuf+0xC0, 0x10); + memset(outbuf+0xC0, 0, 0x10); + memcpy(outbuf+0xD0, outbuf+0xD0, 0x80); + + // The real decryption + if (sceUtilsBufferCopyWithRange(outbuf, size, outbuf+0x40, size-0x40, 0x1) != 0) + { + Kprintf("Error in sceUtilsBufferCopyWithRange 0x1.\n"); + return -1; + } + + if (retsize < 0x150) + { + // Fill with 0 + memset(outbuf+retsize, 0, 0x150-retsize); + } + + return retsize; +} + +int pspDecryptPRX(u8 *data, u32 size, u32 *out_size) +{ + int retsize = DecryptPRX1(data, data, size, *(u32 *)&data[0xD0]); + + if (retsize <= 0) + { + retsize = DecryptPRX2(data, data, size, *(u32 *)&data[0xD0]); + } + + if (retsize <= 0) + { + return -1; + } + + out_size[0] = retsize; + return 0; +} diff --git a/src/downgrade_ctrl/utils.c b/src/downgrade_ctrl/utils.c index ad13890..f3e6fe0 100644 --- a/src/downgrade_ctrl/utils.c +++ b/src/downgrade_ctrl/utils.c @@ -1,95 +1,95 @@ -/* - Downgrade Control -> utils.c -> Responsible for providing common utilities interfacing the kernel - by Davee - - 30/12/2010 -*/ - -#include -#include - -#include -#include -#include - -#include "utils.h" - -void ClearCaches(void) -{ - sceKernelIcacheClearAll(); - sceKernelDcacheWritebackAll(); -} - -u32 FindFunc(const char *modname, const char *lib, u32 nid) -{ - int i = 0, u; - - /* try and find the module by name */ - SceModule *mod = sceKernelFindModuleByName(modname); - - /* if fail */ - if (!mod) - { - /* fail */ - return 0; - } - - /* copy over the structure data */ - u32 entry_size = mod->ent_size; - u32 entry_start = (u32)mod->ent_top; - - /* loop until end of entry table */ - while (i < entry_size) - { - /* cast structure to memory */ - SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); - - /* if there is a libname, compare it to the lib else if there is no lib and there is no libname */ - if ((entry->libname && (strcmp(entry->libname, lib) == 0)) || (lib == NULL && entry->libname == NULL)) - { - /* copy the table pointer and get the total number of entries */ - u32 *table = entry->entrytable; - int total = entry->stubcount + entry->vstubcount; - - /* if there is some entries continue */ - if (total > 0) - { - /* loop through the entries */ - for (u = 0; u < total; u++) - { - /* if the nid matches */ - if (table[u] == nid) - { - /* return the pointer */ - return table[u + total]; - } - } - } - } - - /* increment the counter */ - i += (entry->len << 2); - } - - /* could not find function */ - return 0; -} - -void PatchSyscall(u32 addr, void *newaddr) -{ - u32 *vectors, i; - - /* get the vectors address from the co-processor */ - __asm__ volatile ("cfc0 %0, $12\n" "nop\n" : "=r" (vectors)); - - /* loop through them */ - for (i = 0; i < 0x1000; i++) - { - /* if this is the address */ - if (vectors[i + 4] == addr) - { - /* then replace it :D */ - vectors[i + 4] = (u32)newaddr; - } - } -} +/* + Downgrade Control -> utils.c -> Responsible for providing common utilities interfacing the kernel + by Davee + + 30/12/2010 +*/ + +#include +#include + +#include +#include +#include + +#include "utils.h" + +void ClearCaches(void) +{ + sceKernelIcacheClearAll(); + sceKernelDcacheWritebackAll(); +} + +u32 FindFunc(const char *modname, const char *lib, u32 nid) +{ + int i = 0, u; + + /* try and find the module by name */ + SceModule *mod = sceKernelFindModuleByName(modname); + + /* if fail */ + if (!mod) + { + /* fail */ + return 0; + } + + /* copy over the structure data */ + u32 entry_size = mod->ent_size; + u32 entry_start = (u32)mod->ent_top; + + /* loop until end of entry table */ + while (i < entry_size) + { + /* cast structure to memory */ + SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); + + /* if there is a libname, compare it to the lib else if there is no lib and there is no libname */ + if ((entry->libname && (strcmp(entry->libname, lib) == 0)) || (lib == NULL && entry->libname == NULL)) + { + /* copy the table pointer and get the total number of entries */ + u32 *table = entry->entrytable; + int total = entry->stubcount + entry->vstubcount; + + /* if there is some entries continue */ + if (total > 0) + { + /* loop through the entries */ + for (u = 0; u < total; u++) + { + /* if the nid matches */ + if (table[u] == nid) + { + /* return the pointer */ + return table[u + total]; + } + } + } + } + + /* increment the counter */ + i += (entry->len << 2); + } + + /* could not find function */ + return 0; +} + +void PatchSyscall(u32 addr, void *newaddr) +{ + u32 *vectors, i; + + /* get the vectors address from the co-processor */ + __asm__ volatile ("cfc0 %0, $12\n" "nop\n" : "=r" (vectors)); + + /* loop through them */ + for (i = 0; i < 0x1000; i++) + { + /* if this is the address */ + if (vectors[i + 4] == addr) + { + /* then replace it :D */ + vectors[i + 4] = (u32)newaddr; + } + } +} diff --git a/src/downgrade_ctrl/utils.h b/src/downgrade_ctrl/utils.h index 502b667..02a95fc 100644 --- a/src/downgrade_ctrl/utils.h +++ b/src/downgrade_ctrl/utils.h @@ -1,46 +1,46 @@ -/* - Downgrade Control -> utils.h -> Provide API documentation and definitions for utilities - by Davee - - 30/12/2010 -*/ -#ifndef __UTILS__H__ -#define __UTILS__H__ - -#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } - -#define KERNEL_HIJACK_FUNCTION(a, f, ptr) { \ - static u32 patch_buffer[3]; \ - _sw(_lw(a + 0x00), (u32)patch_buffer + 0x00); \ - _sw(_lw(a + 0x04), (u32)patch_buffer + 0x08);\ - MAKE_JUMP((u32)patch_buffer + 0x04, a + 0x08); \ - REDIRECT_FUNCTION(a, f); \ - ptr = (void *)patch_buffer; \ - } -/** - Clears both the instruction and data caches -*/ -void ClearCaches(void); - -/** - Allows to modify the kernel address called when a specific syscall is initiated - - @param addr: the address of the kernel function syscall you want to control - @param newaddr: the new address the syscall will call -*/ -void PatchSyscall(u32 addr, void *newaddr); - -/** - Find an export within the system - - @param modname: the name of the module containing the export - @param libname: the library the export belongs to - @param nid: the nid of the export - - @return the address of export else 0 on error -*/ -u32 FindFunc(const char *modname, const char *lib, u32 nid); - -#endif /* __UTILS__H__ */ +/* + Downgrade Control -> utils.h -> Provide API documentation and definitions for utilities + by Davee + + 30/12/2010 +*/ +#ifndef __UTILS__H__ +#define __UTILS__H__ + +#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } + +#define KERNEL_HIJACK_FUNCTION(a, f, ptr) { \ + static u32 patch_buffer[3]; \ + _sw(_lw(a + 0x00), (u32)patch_buffer + 0x00); \ + _sw(_lw(a + 0x04), (u32)patch_buffer + 0x08);\ + MAKE_JUMP((u32)patch_buffer + 0x04, a + 0x08); \ + REDIRECT_FUNCTION(a, f); \ + ptr = (void *)patch_buffer; \ + } +/** + Clears both the instruction and data caches +*/ +void ClearCaches(void); + +/** + Allows to modify the kernel address called when a specific syscall is initiated + + @param addr: the address of the kernel function syscall you want to control + @param newaddr: the new address the syscall will call +*/ +void PatchSyscall(u32 addr, void *newaddr); + +/** + Find an export within the system + + @param modname: the name of the module containing the export + @param libname: the library the export belongs to + @param nid: the nid of the export + + @return the address of export else 0 on error +*/ +u32 FindFunc(const char *modname, const char *lib, u32 nid); + +#endif /* __UTILS__H__ */ diff --git a/src/extra_stubs.S b/src/extra_stubs.S index 6314337..ca4fd54 100644 --- a/src/extra_stubs.S +++ b/src/extra_stubs.S @@ -1,21 +1,21 @@ - .set noreorder - -#include "pspstub.s" - - STUB_START "sceNetInet",0x00090000,0x00010005 - STUB_FUNC 0x1BDF5D13,sceNetInetInetAton - STUB_END - - STUB_START "sceUtility_private",0x40090000,0x00020005 - STUB_FUNC 0xE65F37C8,sceUtilityPowerRegisterCallback - STUB_FUNC 0x9ABAFCC5,sceUtilityPowerunRegisterCallback - STUB_END - - STUB_START "sceNetIfhandle_lib",0x40090000,0x00010005 - STUB_FUNC 0xE80F00A4, sceNetMPulldown - STUB_END - - STUB_START "UtilsForUser",0x40000011,0x00020005 - STUB_FUNC 0x920F104A,sceKernelIcacheInvalidateAll - STUB_FUNC 0xB435DEC5,sceKernelDcacheWritebackInvalidateAll + .set noreorder + +#include "pspstub.s" + + STUB_START "sceNetInet",0x00090000,0x00010005 + STUB_FUNC 0x1BDF5D13,sceNetInetInetAton + STUB_END + + STUB_START "sceUtility_private",0x40090000,0x00020005 + STUB_FUNC 0xE65F37C8,sceUtilityPowerRegisterCallback + STUB_FUNC 0x9ABAFCC5,sceUtilityPowerunRegisterCallback + STUB_END + + STUB_START "sceNetIfhandle_lib",0x40090000,0x00010005 + STUB_FUNC 0xE80F00A4, sceNetMPulldown + STUB_END + + STUB_START "UtilsForUser",0x40000011,0x00020005 + STUB_FUNC 0x920F104A,sceKernelIcacheInvalidateAll + STUB_FUNC 0xB435DEC5,sceKernelDcacheWritebackInvalidateAll STUB_END \ No newline at end of file diff --git a/src/extras.S b/src/extras.S index 79574bf..188263d 100644 --- a/src/extras.S +++ b/src/extras.S @@ -1,15 +1,15 @@ - .set noreorder - -.global getPowerAddress -.ent getPowerAddress -getPowerAddress: - addiu $sp, $sp, -8 - sw $ra, 0($sp) - move $a1, $a0 - jal sceUtilityPowerRegisterCallback - move $a0, $0 - move $v0, $v1 - lw $ra, 0($sp) - jr $ra - addiu $sp, $sp, 8 + .set noreorder + +.global getPowerAddress +.ent getPowerAddress +getPowerAddress: + addiu $sp, $sp, -8 + sw $ra, 0($sp) + move $a1, $a0 + jal sceUtilityPowerRegisterCallback + move $a0, $0 + move $v0, $v1 + lw $ra, 0($sp) + jr $ra + addiu $sp, $sp, 8 .end getPowerAddress \ No newline at end of file diff --git a/src/include/libinfinity.h b/src/include/libinfinity.h new file mode 100644 index 0000000..5184866 --- /dev/null +++ b/src/include/libinfinity.h @@ -0,0 +1,57 @@ +/* + +Copyright (C) 2015, David "Davee" Morgan + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef LIBINFINITY_H +#define LIBINFINITY_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + @return The version of the persistent aspect of Infinity. +*/ +unsigned int infGetVersion(void); + +/** + @return The version of the bootloader. +*/ +unsigned int infGetCoreVersion(void); + +/** + @return non-zero if redirection is enabled else redirection is disabled and the logical IO operations can be performed. +*/ +int infGetRedirectionStatus(void); + +/** + Set whether to enable or disable redirection. + By default redirection is enabled and is required for infinity to operate. By disabling you enable the ability to format flash0 and write to the bootloader of infinity. Ensure to re-enable redirection if you intend to warm-reboot. +*/ +void infSetRedirectionStatus(int enabled); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // LIBINFINITY_H diff --git a/src/include/systemctrl.h b/src/include/systemctrl.h new file mode 100644 index 0000000..3c8381b --- /dev/null +++ b/src/include/systemctrl.h @@ -0,0 +1,394 @@ +#ifndef __SCTRLLIBRARY_H__ +#define __SCTRLLIBRARY_H__ + +#include +#include +#include +#include + +enum BootLoadFlags +{ + BOOTLOAD_VSH = 1, + BOOTLOAD_GAME = 2, + BOOTLOAD_UPDATER = 4, + BOOTLOAD_POPS = 8, + BOOTLOAD_UMDEMU = 64, /* for original NP9660 */ + BOOTLOAD_MLNAPP = 128, +}; + +/** + * Restart the vsh. + * + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL + * + * @returns < 0 on some errors. + * +*/ +int sctrlKernelExitVSH(struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute the EBOOT.BIN from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHDisc(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a disc. + * It is the function used by the firmware to execute an updater from a disc. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHDiscUpdater(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute an updater from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs1(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute games (and homebrew :P) from a memory stick. + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs2(const char *file, struct SceKernelLoadExecVSHParam *param); +int sctrlKernelLoadExecVSHEf2(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute ... ? + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs3(const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Executes a new executable from a memory stick. + * It is the function used by the firmware to execute psx games + * + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHMs4(const char *file, struct SceKernelLoadExecVSHParam *param); + + +/** + * Executes a new executable with the specified apitype + * + * @param apitype - The apitype + * @param file - The file to execute. + * @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL. + * + * @returns < 0 on some errors. +*/ +int sctrlKernelLoadExecVSHWithApitype(int apitype, const char *file, struct SceKernelLoadExecVSHParam *param); + +/** + * Sets the api type + * + * @param apitype - The apitype to set + * @returns the previous apitype + * + * @Note - this will modify also the value of sceKernelBootFrom, since the value of + * bootfrom is calculated from the apitype +*/ +int sctrlKernelSetInitApitype(int apitype); + +/** + * Sets the filename of the launched executable. + * + * @param filename - The filename to set + * @returns 0 on success +*/ +int sctrlKernelSetInitFileName(char *filename); + +/** + * Sets the init key config + * + * @param key - The key code + * @returns the previous key config +*/ +int sctrlKernelSetInitKeyConfig(int key); + +/** + * Sets the user level of the current thread + * + * @param level - The user level + * @return the previous user level on success + */ +int sctrlKernelSetUserLevel(int level); + +/** + * Sets the devkit version + * + * @param version - The devkit version to set + * @return the previous devkit version + * +*/ +int sctrlKernelSetDevkitVersion(int version); + +/** + * Checks if we are in SE. + * + * @returns 1 if we are in SE-C or later, 0 if we are in HEN-D or later, + * and < 0 (a kernel error code) in any other case +*/ +int sctrlHENIsSE(); + +/** + * Checks if we are in Devhook. + * + * @returns 1 if we are in SE-C/HEN-D for devhook or later, 0 if we are in normal SE-C/HEN-D or later, + * and < 0 (a kernel error code) in any other case +*/ +int sctrlHENIsDevhook(); + +/** + * Gets the HEN version + * + * @returns - The HEN version + * + * HEN D / SE-C : 0x00000400 + */ +int sctrlHENGetVersion(); + +/** + * Gets the HEN minor version + * + * @returns - The HEN minor version + */ +int sctrlHENGetMinorVersion(); + +/** + * Finds a driver + * + * @param drvname - The name of the driver (without ":" or numbers) + * + * @returns the driver if found, NULL otherwise + * + */ +PspIoDrv *sctrlHENFindDriver(char *drvname); + +/** + * Finds a function. + * + * @param modname - The module where to search the function + * @param libname - The library name + * @nid - The nid of the function + * + * @returns - The function address or 0 if not found + * +*/ +u32 sctrlHENFindFunction(char *modname, char *libname, u32 nid); + +typedef struct SceModule2 { + struct SceModule2 *next; + unsigned short attribute; + unsigned char version[2]; + char modname[27]; + char terminal; + unsigned int unknown1; + unsigned int unknown2; + SceUID modid; + unsigned int unknown3[2]; + u32 mpid_text; // 0x38 + u32 mpid_data; // 0x3C + void * ent_top; + unsigned int ent_size; + void * stub_top; + unsigned int stub_size; + unsigned int unknown4[5]; + unsigned int entry_addr; + unsigned int gp_value; + unsigned int text_addr; + unsigned int text_size; + unsigned int data_size; + unsigned int bss_size; + unsigned int nsegment; + unsigned int segmentaddr[4]; + unsigned int segmentsize[4]; +} SceModule2; + +typedef int (* STMOD_HANDLER)(SceModule2 *); + +/** + * Sets a function to be called just before module_start of a module is gonna be called (useful for patching purposes) + * + * @param handler - The function, that will receive the module structure before the module is started. + * + * @returns - The previous set function (NULL if none); + * @Note: because only one handler function is handled by HEN, you should + * call the previous function in your code. + * + * @Example: + * + * STMOD_HANDLER previous = NULL; + * + * int OnModuleStart(SceModule2 *mod); + * + * void somepointofmycode() + * { + * previous = sctrlHENSetStartModuleHandler(OnModuleStart); + * } + * + * int OnModuleStart(SceModule2 *mod) + * { + * if (strcmp(mod->modname, "vsh_module") == 0) + * { + * // Do something with vsh module here + * } + * + * if (!previous) + * return 0; + * + * // Call previous handler + * + * return previous(mod); + * } + * + * @Note2: The above example should be compiled with the flag -fno-pic + * in order to avoid problems with gp register that may lead to a crash. + * +*/ +STMOD_HANDLER sctrlHENSetStartModuleHandler(STMOD_HANDLER handler); + +typedef int (* KDEC_HANDLER)(u32 *buf, int size, int *retSize, int m); +typedef int (* MDEC_HANDLER)(u32 *tag, u8 *keys, u32 code, u32 *buf, int size, int *retSize, int m, void *unk0, int unk1, int unk2, int unk3, int unk4); + +/** + * Sets the speed (only for kernel usage) + * + * @param cpu - The cpu speed + * @param bus - The bus speed +*/ +void sctrlHENSetSpeed(int cpu, int bus); + +/** + * Sets the partition 2 and 8 memory for next loadexec. + * + * @param p2 - The size in MB for the user partition. Must be > 0 + * @param p8 - The size in MB for partition 8. Can be 0. + * + * @returns 0 on success, < 0 on error. + * This function is only available in the slim. The function will fail + * if p2+p8 > 52 or p2 == 0 +*/ +int sctrlHENSetMemory(u32 p2, u32 p8); + +void sctrlHENPatchSyscall(void *addr, void *newaddr); + +int sctrlKernelQuerySystemCall(void *func_addr); + +int sctrlKernelBootFrom(void); + +/** + * Patch module by offset + * + * @param modname - module name + * @param inst - instruction + * @param offset - module patch offset + * + * @return < 0 on error + */ +int sctrlPatchModule(char *modname, u32 inst, u32 offset); + +/** + * Get module text address + * + * @param modname - module name + * + * @return text address, or 0 if not found + */ +u32 sctrlModuleTextAddr(char *modname); + +/** + * Get sceInit module text address + * + * @note Only useful before sceInit exits + * + * @return text address, or 0 if not found + */ +u32 sctrlGetInitTextAddr(void); + +/** + * Set custom start module handler + * It can be used to replace a system module + * + * @note: func returns -1 to ignore the module and load the original module. Or new modid if replace is done. + */ +void sctrlSetCustomStartModule(int (*func)(int modid, SceSize argsize, void *argp, int *modstatus, SceKernelSMOption *opt)); + +/** + * Loads a module on next reboot. Only kernel mode. + * + * @param module_after - The path of the module which is loaded after the module to be loaded. + The module passed to this function will be loaded just before that module. + * @param buf - The buffer containing the module - Don't deallocate this one. It has to reside in kernel memory. + * @param size - The size of the module + * @param flags - The modes in which the module should be loaded, one of BootLoadFlags + * + * @Example: + * sctrlHENLoadModuleOnReboot("/kd/usersystemlib.prx", module_buffer, module_size, BOOTLOAD_GAME | BOOTLOAD_POPS | BOOTLOAD_UMDEMU); + * + * This will load the module contained in module_buffer just before /kd/usersystemlib.prx in the next reboot, if the mode of next reboot is game, pops or umdemu + * + * @Remarks: Don't use too early modules in first param like "/kd/init.prx" or "/kd/systemctrl.prx", or your module may not load properly + * Only one module will be loaded on reboot with this function. + * If this function is called many times, only the last one will be considered. + * By making a module to load itself using this function, and calling + * sctrlHENLoadModuleOnReboot on module_start, a prx can cause itself to be resident in the modes choosen by flags. + * If all flags are selected, the module will stay resident until a psp shutdown, or until sctrlHENLoadModuleOnReboot is not called. +*/ + +void sctrlHENLoadModuleOnReboot(char *module_after, void *buf, int size, int flags); + +/** + * Enable/disable NID Resolver on particular library + * + * @param libname the name of the library to be enabled/disabled + * @param enabled 0 - disabled, != 0 - enabled + * + * @Example: + * sctrlKernelSetNidResolver("sceImpose_driver", 0); // disable sceImpose_driver resolving + * + * @return previous value if set, < 0 on error + */ +int sctrlKernelSetNidResolver(char *libname, u32 enabled); + +/** + * Get a random u32 key from PSP Kirk PRNG + */ +u32 sctrlKernelRand(void); + +/** + * Get the real unspoofed Ethernet (MAC) Address of the systems WLAN chip + * + * @param mac Out-Buffer (6B) for real MAC Address + * + * @return 0 on success, < 0 on error + */ +int sctrlGetRealEthernetAddress(uint8_t * mac); + +#endif diff --git a/src/kernel_exploit.c b/src/kernel_exploit.c index ccef37d..99f2e1b 100644 --- a/src/kernel_exploit.c +++ b/src/kernel_exploit.c @@ -1,500 +1,509 @@ -/* - Downgrade Launcher -> kernel_exploit.c -> Responsible for doin' sum epik lolhax on teh kurnal - by Davee - - 28/12/2010 -*/ - -#include -#include -#include - -#include -#include - -#include "kernel_exploit.h" -#include "kernel_land.h" -#include "utils.h" -#include "rebootex.h" - -int sceKernelPowerLock(void *ptr, u32 kexec_address); -u32 getPowerAddress(SceUID callback); - -/* function pointers */ -int (* sceKernelUtilsMd5BlockInitHax)(u32 addr, u32 check_result, u32 unused2, u32 k1) = (void *)sceKernelUtilsMd5BlockInit; -int (* sceHttpStorageOpen) (u32 kaddrs, u32 unk, u32 unk2); - -int sceUtilityPowerRegisterCallback(int slot, SceUID callback); - -int sceUtilityPowerunRegisterCallback(int slot); - -/* globals */ -u32 g_kfunctions_resolved = 0; - -int DummyCallback(void) -{ - return 0; -} - -int pre_kernel(int (* kfunc)(void)) -{ - int i; - - /* set $k1 */ - asm("move $k1, $0\n"); - - /* check if we've resolved the kernel function pointers */ - if (g_kfunctions_resolved == 0) - { - /* Resolve the kernel function */ - /* Search kmem for the sceKernelFindModuleByName */ - for (i = 0x88000000; i < (0x88400000 - 0x54 - 4); i += 4) - { - if (_lw(i+0x00) == 0x27BDFFE0 && _lw(i+0x04) == 0xAFB40010 && - _lw(i+0x08) == 0xAFB3000C && _lw(i+0x0C) == 0xAFB20008 && - _lw(i+0x10) == 0x00009021 && _lw(i+0x14) == 0x02409821 && - _lw(i+0x54) == 0x0263202A) - { - /* found it, i = address of function */ - pspKernelFindModuleByName = (void *)i; - break; - } - } - - /* find our functions */ - if(g_devkit_version == FIRMWARE_VERSION_660) - { - pspKernelGetModel = (void *)FindProc("sceSystemMemoryManager", "SysMemForKernel", 0x07C586A1); //6.60 - pspKernelLoadExecVSHEf1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x16A68007); //6.60 - pspKernelLoadExecVSHMs1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x4FB44D27); //6.60 - - pspSysconGetBaryonVersion = (void *)FindProc("sceSYSCON_Driver", "sceSyscon_driver", 0x7EC5A957); - pspIoOpen = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x109F50BC); - pspIoWrite = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); - pspIoClose = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); - } - else - { - pspKernelGetModel = (void *)FindProc("sceSystemMemoryManager", "SysMemForKernel", 0x458A70B5); //6.31/6.35 - pspKernelLoadExecVSHEf1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0xCEFE1100); //6.31/6.35 - pspKernelLoadExecVSHMs1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x7286CF0B); //6.31/6.35 - - pspSysconGetBaryonVersion = (void *)FindProc("sceSYSCON_Driver", "sceSyscon_driver", 0x7EC5A957); - pspIoOpen = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x109F50BC); - pspIoWrite = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); - pspIoClose = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); - } - - /* set resolved flag */ - g_kfunctions_resolved = 1; - } - - /* Clear the caches */ - KClearCaches(); - return kfunc(); -} - - -int repairKernel631(void) -{ - /* repair the MD5 functionality */ - _sw(0x00003821, 0x88000000 + 0xF270); - _sw(0x001B3AC0, 0x88000000 + 0xF274); - _sw(0x3C068002, 0x88000000 + 0xF278); - _sw(0x00E42824, 0x88000000 + 0xF27C); - - /* repair the suspend library */ - _sw(0x8CC54230, 0x88000000 + 0xCD38); - _sw(0x00402021, 0x88000000 + 0xCD3C); - _sw(0x24A20001, 0x88000000 + 0xCD40); - _sw(0x0E0047EE, 0x88000000 + 0xCD44); - _sw(0xACC24230, 0x88000000 + 0xCD48); - _sw(0x0A003348, 0x88000000 + 0xCD4C); - _sw(0x00001021, 0x88000000 + 0xCD50); - - return 0; -} - -int repairKernel635(void) -{ - /* repair the MD5 functionality */ - _sw(0x00003821, 0x88000000 + 0xF150); - _sw(0x001B3AC0, 0x88000000 + 0xF154); - _sw(0x3C068002, 0x88000000 + 0xF158); - _sw(0x00E42824, 0x88000000 + 0xF15C); - - /* repair the suspend library */ - _sw(0x8CC540F0, 0x88000000 + 0xCC18); - _sw(0x00402021, 0x88000000 + 0xCC1C); - _sw(0x24A20001, 0x88000000 + 0xCC20); - _sw(0x0E0047A6, 0x88000000 + 0xCC24); - _sw(0xACC240F0, 0x88000000 + 0xCC28); - _sw(0x0A003300, 0x88000000 + 0xCC2C); - _sw(0x00001021, 0x88000000 + 0xCC30); - - return 0; -} - -int execKernelFunction631(void *kfunc) -{ - /* set a pointer sequence in order the comply with the exploits loading sequence */ - u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; - u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; - - /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ - int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x4234); - - /* clear the caches and return the value from the kernel function */ - ClearCaches(); - return res; -} - -int execKernelFunction635(void *kfunc) -{ - /* set a pointer sequence in order the comply with the exploits loading sequence */ - u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; - u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; - - /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ - int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x40F4); - - /* clear the caches and return the value from the kernel function */ - ClearCaches(); - return res; -} - -int execKernelFunction660(void *kfunc) -{ - /* set a pointer sequence in order the comply with the exploits loading sequence */ - u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; - u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; - - /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ - int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x40F8); - - /* clear the caches and return the value from the kernel function */ - ClearCaches(); - return res; -} - -int execKernelFunction(void *kfunc) -{ - /* execute kernel mode pending on the system version */ - if (sceKernelDevkitVersion() == FIRMWARE_VERSION_631) - { - /* 6.31 exploit */ - return execKernelFunction631(kfunc); - } - else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_635 || - sceKernelDevkitVersion() == FIRMWARE_VERSION_638 || - sceKernelDevkitVersion() == FIRMWARE_VERSION_639) - { - /* 6.35 exploit */ - return execKernelFunction635(kfunc); - } - else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_660) - { - return execKernelFunction660(kfunc); - } - - return 0; -} - -SceLibraryStubTable *findLibraryByName(char *libname, u32 address) -{ - u32 i = 0; - - /* search through umem for the libname */ - for (i = address; i < (0x08800000 + (24 << 20)); i += 4) - { - /* cast a stub */ - SceLibraryStubTable *stub = (SceLibraryStubTable *)i; - - /* check for valid address */ - if ((stub->libname != libname) && isValidUserAddress((void *)stub->libname) && isValidUserAddress(stub->nidtable) && isValidUserAddress(stub->stubtable)) - { - /* check libname */ - if (strcmp(libname, stub->libname) == 0) - { - /* found it */ - return stub; - } - } - } - - /* error */ - ErrorExit(5000, "Error, could not find library %s\n", libname); - return NULL; -} - -void *getFunctionFromLibrary(SceLibraryStubTable *stub, u32 nid) -{ - int i; - - /* cast this so we're not always loading from stub struct */ - u32 *nids = stub->nidtable; - - /* loop through */ - for (i = 0; i < stub->stubcount; i++) - { - /* check for nid */ - if (nids[i] == nid) - { - /* we got it, pal */ - return (void *)((u32)stub->stubtable + (i << 3)); - } - } - - /* error, not found */ - ErrorExit(5000, "Error, could not find nid 0x%08X in library %s\n", nid, stub->libname); - return NULL; -} - -void doKernelExploit631(void) -{ - u32 power_address = 0; - -#ifdef HBL_SUKKIRI - /* get proper MD5 imports (HBL does not resolve properly) */ - u32 address = (u32)findLibraryByName("sceNetIfhandle_lib", 0x08800000); - SceLibraryStubTable *stub = findLibraryByName("UtilsForUser", address - 0x500); - - /* copy over the stubs */ - memcpy(sceKernelUtilsMd5BlockInit, getFunctionFromLibrary(stub, 0x9E5C5086), 8); - memcpy(sceKernelUtilsMd5BlockUpdate, getFunctionFromLibrary(stub, 0x61E1E525), 8); - memcpy(sceKernelUtilsMd5BlockResult, getFunctionFromLibrary(stub, 0xB8D24E78), 8); - - /* get our stub pointer */ - stub = findLibraryByName("sceUtility_private", 0x08800000); - - /* get our exploit functions */ - memcpy(sceUtilityPowerRegisterCallback, getFunctionFromLibrary(stub, 0xE65F37C8), 8); //6.31 nid - memcpy(sceUtilityPowerunRegisterCallback, getFunctionFromLibrary(stub, 0x9ABAFCC5), 8); //6.31 nid -#endif - - /* create a callback */ - SceUID callback = sceKernelCreateCallback("Callback", (void *)DummyCallback, NULL); - - /* check for error */ - if (callback < 0) - { - return ErrorExit(5000, "Error creating callback\n"); - } - - /* register slot 0 (ignore error, use to ensure slot has a registered entry) */ - sceUtilityPowerRegisterCallback(0, callback); - - /* get the power address */ - power_address = getPowerAddress(callback); - - /* unregister again */ - sceUtilityPowerunRegisterCallback(0); - - /* bingo, we've got it! set sysmem addr to seek backwards from this address so when used in the callback func, it is directly at sysmem */ - u32 sysmem_addr = (~(power_address - 0x88000000) + 1) >> 4; - - /* unregister in order to remove any positive value ignore return value */ - sceUtilityPowerunRegisterCallback(sysmem_addr + 0xF27); //6.31 - - /* commit changes */ - ClearCaches(); - - /* call register callback in order to activate the exploit */ - int res = sceUtilityPowerRegisterCallback(sysmem_addr + 0xF27, callback); //6.31 - - /* check for error */ - if (res < 0) - { - /* error activating exploit */ - return ErrorExit(5000, "Error 0x%08X activating kernel exploit\n", res); - } - - /* delete the callback */ - sceKernelDeleteCallback(callback); - - /* clear caches */ - ClearCaches(); - - /* now use the MD5 function to cause exploit */ - sceKernelUtilsMd5BlockInitHax(0x8800CD54 - 28, 0, 0, 0); //6.31 - - /* clear caches, allow changes to commit */ - ClearCaches(); - - /* now you can use the 6.31 kernel call */ - execKernelFunction631(repairKernel631); -} - -void doKernelExploit635(void) -{ - u32 power_address = 0; - -#ifdef HBL_SUKKIRI - /* get proper MD5 imports (HBL does not resolve properly) */ - u32 address = (u32)findLibraryByName("sceNetIfhandle_lib", 0x08800000); - SceLibraryStubTable *stub = findLibraryByName("UtilsForUser", address - 0x500); - - /* copy over the stubs */ - memcpy(sceKernelUtilsMd5BlockInit, getFunctionFromLibrary(stub, 0x9E5C5086), 8); - memcpy(sceKernelUtilsMd5BlockUpdate, getFunctionFromLibrary(stub, 0x61E1E525), 8); - memcpy(sceKernelUtilsMd5BlockResult, getFunctionFromLibrary(stub, 0xB8D24E78), 8); - - /* get our stub pointer */ - stub = findLibraryByName("sceUtility_private", 0x08800000); - - /* get our exploit functions */ - memcpy(sceUtilityPowerRegisterCallback, getFunctionFromLibrary(stub, 0xE65F37C8), 8); //6.31/6.35 nid - memcpy(sceUtilityPowerunRegisterCallback, getFunctionFromLibrary(stub, 0x9ABAFCC5), 8); //6.31/6.35 nid -#endif - - /* create a callback */ - SceUID callback = sceKernelCreateCallback("Callback", (void *)DummyCallback, NULL); - - /* check for error */ - if (callback < 0) - { - return ErrorExit(5000, "Error creating callback\n"); - } - - /* register slot 0 (ignore error, use to ensure slot has a registered entry) */ - sceUtilityPowerRegisterCallback(0, callback); - - /* get the power address */ - power_address = getPowerAddress(callback); - - /* unregister again */ - sceUtilityPowerunRegisterCallback(0); - - /* bingo, we've got it! set sysmem addr to seek backwards from this address so when used in the callback func, it is directly at sysmem */ - u32 sysmem_addr = (~(power_address - 0x88000000) + 1) >> 4; - - /* unregister in order to remove any positive value ignore return value */ - sceUtilityPowerunRegisterCallback(sysmem_addr + 0xF15); //6.35 - - /* commit changes */ - ClearCaches(); - - /* call register callback in order to activate the exploit */ - int res = sceUtilityPowerRegisterCallback(sysmem_addr + 0xF15, callback); //6.35 - - /* check for error */ - if (res < 0) - { - /* error activating exploit */ - return ErrorExit(5000, "Error 0x%08X activating kernel exploit\n", res); - } - - /* delete the callback */ - sceKernelDeleteCallback(callback); - - /* clear caches */ - ClearCaches(); - - /* now use the MD5 function to cause exploit */ - sceKernelUtilsMd5BlockInitHax(0x8800CC34 - 28, 0, 0, 0); //6.35 - - /* clear caches, allow changes to commit */ - ClearCaches(); - - /* now you can use the 6.35 kernel call */ - execKernelFunction635(repairKernel635); -} - -int nopOut() -{ - _sw(0x00000000, 0x8800CC34); - return 0; -} - -void doKernelExploit638(void) -{ - int modid, i; - - /* Load necessary modules */ - for(i = 1; i < 7; i++) - modid = sceUtilityLoadNetModule(i); - - SceLibraryStubTable *stub = findLibraryByName("sceHttpStorage", 0x08800000); - sceHttpStorageOpen = (void *) getFunctionFromLibrary(stub, 0x700AAD44); - - /* Overwrite the addition of a global, so I can write to a direct address */ - int ret = sceHttpStorageOpen(-0x990>>2, 0, 0); - - /* DelayThread fixes, REQUIRED */ - sceKernelDelayThread(1000000); - ClearCaches(); - - /* vsync 0xFFFF out powerLock */ - ret = sceHttpStorageOpen(0x8800CC34>>2, 0, 0); - ClearCaches(); - - /* use PowerLock to run the function nopOut in kmode, which nop's out the vsync, so now non vfpu enabled threads can use powerLock */ - execKernelFunction635(nopOut); - - /* Finally, Clear caches */ - ClearCaches(); - - /* Unload Modules */ - for(i = 6; i > 0; i--) - sceUtilityUnloadNetModule(i); -} - -void doKernelExploit660(void) -{ - u32 val; - sceKernelIfHandleParam param_top; - sceKernelIfHandleParam param_sub; - - sceUtilityLoadNetModule(1); - - memset(¶m_top, 0, sizeof(sceKernelIfHandleParam)); - memset(¶m_sub, 0, sizeof(sceKernelIfHandleParam)); - - val = 0; - - /* Fill sub structure */ - param_sub.unk_8 = (u32)&val; - param_sub.unk_12 = sizeof(u32); - - /* Fill top structure */ - param_top.unk_0 = ¶m_sub; - param_top.unk_12 = 1; - param_top.unk_18 = 1; - param_top.unk_68 = (u32)¶m_top; - param_top.unk_8 = 0x8800CBB8 - param_top.unk_12; - param_top.unk_48 = 0x8800CBB8; - param_top.unk_60 = sizeof(u32); - - sceNetMPulldown(¶m_top, 0, param_top.unk_12 + sizeof(u32), NULL); - - ClearCaches(); -} - -void doKernelExploit(void) -{ - /* ok, lets check firmware version */ - if (sceKernelDevkitVersion() == FIRMWARE_VERSION_631) - { - /* do ksploit for 6.31 */ - doKernelExploit631(); - } - else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_635) - { - /* do ksploit for 6.35 */ - doKernelExploit635(); - } - else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_638 || sceKernelDevkitVersion() == FIRMWARE_VERSION_639) - { - /* do ksploit for 6.38 */ - doKernelExploit638(); - } - else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_660) - { - doKernelExploit660(); - } - else - { - /* not supported */ - ErrorExit(5000, "Error, your firmware is not supported.\n"); - } -} +/* + Downgrade Launcher -> kernel_exploit.c -> Responsible for doin' sum epik lolhax on teh kurnal + by Davee + + 28/12/2010 +*/ + +#include +#include +#include + +#include +#include + +#include "kernel_exploit.h" +#include "kernel_land.h" +#include "utils.h" +#include "rebootex.h" + +int sceKernelPowerLock(void *ptr, u32 kexec_address); +u32 getPowerAddress(SceUID callback); +int sceNetMPulldown(sceKernelIfHandleParam *, int, int, void *); + +/* function pointers */ +int (* sceKernelUtilsMd5BlockInitHax)(u32 addr, u32 check_result, u32 unused2, u32 k1) = (void *)sceKernelUtilsMd5BlockInit; +int (* sceHttpStorageOpen) (u32 kaddrs, u32 unk, u32 unk2); + +int sceUtilityPowerRegisterCallback(int slot, SceUID callback); + +int sceUtilityPowerunRegisterCallback(int slot); + +/* globals */ +u32 g_kfunctions_resolved = 0; + +int DummyCallback(void) +{ + return 0; +} + +int pre_kernel(int (* kfunc)(void)) +{ + int i; + + /* set $k1 */ + asm("move $k1, $0\n"); + + /* check if we've resolved the kernel function pointers */ + if (g_kfunctions_resolved == 0) + { + /* Resolve the kernel function */ + /* Search kmem for the sceKernelFindModuleByName */ + for (i = 0x88000000; i < (0x88400000 - 0x54 - 4); i += 4) + { + if (_lw(i+0x00) == 0x27BDFFE0 && _lw(i+0x04) == 0xAFB40010 && + _lw(i+0x08) == 0xAFB3000C && _lw(i+0x0C) == 0xAFB20008 && + _lw(i+0x10) == 0x00009021 && _lw(i+0x14) == 0x02409821 && + _lw(i+0x54) == 0x0263202A) + { + /* found it, i = address of function */ + pspKernelFindModuleByName = (void *)i; + break; + } + } + + /* find our functions */ + if((g_devkit_version == FIRMWARE_VERSION_660) || (g_devkit_version == FIRMWARE_VERSION_661)) + { + pspKernelGetModel = (void *)FindProc("sceSystemMemoryManager", "SysMemForKernel", 0x07C586A1); //6.60 + pspKernelLoadExecVSHEf1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x16A68007); //6.60 + pspKernelLoadExecVSHMs1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x4FB44D27); //6.60 + + pspSysconGetBaryonVersion = (void *)FindProc("sceSYSCON_Driver", "sceSyscon_driver", 0x7EC5A957); + pspIoOpen = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x109F50BC); + pspIoWrite = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); + pspIoClose = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); + } + else + { + pspKernelGetModel = (void *)FindProc("sceSystemMemoryManager", "SysMemForKernel", 0x458A70B5); //6.31/6.35 + pspKernelLoadExecVSHEf1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0xCEFE1100); //6.31/6.35 + pspKernelLoadExecVSHMs1 = (void *)FindProc("sceLoadExec", "LoadExecForKernel", 0x7286CF0B); //6.31/6.35 + + pspSysconGetBaryonVersion = (void *)FindProc("sceSYSCON_Driver", "sceSyscon_driver", 0x7EC5A957); + pspIoOpen = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x109F50BC); + pspIoWrite = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); + pspIoClose = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); + } + + /* set resolved flag */ + g_kfunctions_resolved = 1; + } + + /* Clear the caches */ + KClearCaches(); + return kfunc(); +} + + +int repairKernel631(void) +{ + /* repair the MD5 functionality */ + _sw(0x00003821, 0x88000000 + 0xF270); + _sw(0x001B3AC0, 0x88000000 + 0xF274); + _sw(0x3C068002, 0x88000000 + 0xF278); + _sw(0x00E42824, 0x88000000 + 0xF27C); + + /* repair the suspend library */ + _sw(0x8CC54230, 0x88000000 + 0xCD38); + _sw(0x00402021, 0x88000000 + 0xCD3C); + _sw(0x24A20001, 0x88000000 + 0xCD40); + _sw(0x0E0047EE, 0x88000000 + 0xCD44); + _sw(0xACC24230, 0x88000000 + 0xCD48); + _sw(0x0A003348, 0x88000000 + 0xCD4C); + _sw(0x00001021, 0x88000000 + 0xCD50); + + return 0; +} + +int repairKernel635(void) +{ + /* repair the MD5 functionality */ + _sw(0x00003821, 0x88000000 + 0xF150); + _sw(0x001B3AC0, 0x88000000 + 0xF154); + _sw(0x3C068002, 0x88000000 + 0xF158); + _sw(0x00E42824, 0x88000000 + 0xF15C); + + /* repair the suspend library */ + _sw(0x8CC540F0, 0x88000000 + 0xCC18); + _sw(0x00402021, 0x88000000 + 0xCC1C); + _sw(0x24A20001, 0x88000000 + 0xCC20); + _sw(0x0E0047A6, 0x88000000 + 0xCC24); + _sw(0xACC240F0, 0x88000000 + 0xCC28); + _sw(0x0A003300, 0x88000000 + 0xCC2C); + _sw(0x00001021, 0x88000000 + 0xCC30); + + return 0; +} + +int execKernelFunction631(void *kfunc) +{ + /* set a pointer sequence in order the comply with the exploits loading sequence */ + u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; + u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; + + /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ + int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x4234); + + /* clear the caches and return the value from the kernel function */ + ClearCaches(); + return res; +} + +int execKernelFunction635(void *kfunc) +{ + /* set a pointer sequence in order the comply with the exploits loading sequence */ + u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; + u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; + + /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ + int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x40F4); + + /* clear the caches and return the value from the kernel function */ + ClearCaches(); + return res; +} + +int execKernelFunction660(void *kfunc) +{ + /* set a pointer sequence in order the comply with the exploits loading sequence */ + u32 kernel_exec_func = ((u32)pre_kernel) | 0x80000000; + u32 kernel_exec_ptr = ((u32)&kernel_exec_func) - 16; + + /* syscall jump into kmode which will end up jumping to pre_kernel_entry function */ + int res = sceKernelPowerLock((void *)((u32)kfunc | 0x80000000), ((u32)&kernel_exec_ptr) - 0x40F8); + + /* clear the caches and return the value from the kernel function */ + ClearCaches(); + return res; +} + +int execKernelFunction(void *kfunc) +{ + /* execute kernel mode pending on the system version */ + if (sceKernelDevkitVersion() == FIRMWARE_VERSION_631) + { + /* 6.31 exploit */ + return execKernelFunction631(kfunc); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_635 || + sceKernelDevkitVersion() == FIRMWARE_VERSION_638 || + sceKernelDevkitVersion() == FIRMWARE_VERSION_639) + { + /* 6.35 exploit */ + return execKernelFunction635(kfunc); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_660) + { + return execKernelFunction660(kfunc); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_661) + { + return execKernelFunction660(kfunc); + } + + return 0; +} + +SceLibraryStubTable *findLibraryByName(char *libname, u32 address) +{ + u32 i = 0; + + /* search through umem for the libname */ + for (i = address; i < (0x08800000 + (24 << 20)); i += 4) + { + /* cast a stub */ + SceLibraryStubTable *stub = (SceLibraryStubTable *)i; + + /* check for valid address */ + if ((stub->libname != libname) && isValidUserAddress((void *)stub->libname) && isValidUserAddress(stub->nidtable) && isValidUserAddress(stub->stubtable)) + { + /* check libname */ + if (strcmp(libname, stub->libname) == 0) + { + /* found it */ + return stub; + } + } + } + + /* error */ + ErrorExit(5000, "Error, could not find library %s\n", libname); + return NULL; +} + +void *getFunctionFromLibrary(SceLibraryStubTable *stub, u32 nid) +{ + int i; + + /* cast this so we're not always loading from stub struct */ + u32 *nids = stub->nidtable; + + /* loop through */ + for (i = 0; i < stub->stubcount; i++) + { + /* check for nid */ + if (nids[i] == nid) + { + /* we got it, pal */ + return (void *)((u32)stub->stubtable + (i << 3)); + } + } + + /* error, not found */ + ErrorExit(5000, "Error, could not find nid 0x%08X in library %s\n", nid, stub->libname); + return NULL; +} + +void doKernelExploit631(void) +{ + u32 power_address = 0; + +#ifdef HBL_SUKKIRI + /* get proper MD5 imports (HBL does not resolve properly) */ + u32 address = (u32)findLibraryByName("sceNetIfhandle_lib", 0x08800000); + SceLibraryStubTable *stub = findLibraryByName("UtilsForUser", address - 0x500); + + /* copy over the stubs */ + memcpy(sceKernelUtilsMd5BlockInit, getFunctionFromLibrary(stub, 0x9E5C5086), 8); + memcpy(sceKernelUtilsMd5BlockUpdate, getFunctionFromLibrary(stub, 0x61E1E525), 8); + memcpy(sceKernelUtilsMd5BlockResult, getFunctionFromLibrary(stub, 0xB8D24E78), 8); + + /* get our stub pointer */ + stub = findLibraryByName("sceUtility_private", 0x08800000); + + /* get our exploit functions */ + memcpy(sceUtilityPowerRegisterCallback, getFunctionFromLibrary(stub, 0xE65F37C8), 8); //6.31 nid + memcpy(sceUtilityPowerunRegisterCallback, getFunctionFromLibrary(stub, 0x9ABAFCC5), 8); //6.31 nid +#endif + + /* create a callback */ + SceUID callback = sceKernelCreateCallback("Callback", (void *)DummyCallback, NULL); + + /* check for error */ + if (callback < 0) + { + return ErrorExit(5000, "Error creating callback\n"); + } + + /* register slot 0 (ignore error, use to ensure slot has a registered entry) */ + sceUtilityPowerRegisterCallback(0, callback); + + /* get the power address */ + power_address = getPowerAddress(callback); + + /* unregister again */ + sceUtilityPowerunRegisterCallback(0); + + /* bingo, we've got it! set sysmem addr to seek backwards from this address so when used in the callback func, it is directly at sysmem */ + u32 sysmem_addr = (~(power_address - 0x88000000) + 1) >> 4; + + /* unregister in order to remove any positive value ignore return value */ + sceUtilityPowerunRegisterCallback(sysmem_addr + 0xF27); //6.31 + + /* commit changes */ + ClearCaches(); + + /* call register callback in order to activate the exploit */ + int res = sceUtilityPowerRegisterCallback(sysmem_addr + 0xF27, callback); //6.31 + + /* check for error */ + if (res < 0) + { + /* error activating exploit */ + return ErrorExit(5000, "Error 0x%08X activating kernel exploit\n", res); + } + + /* delete the callback */ + sceKernelDeleteCallback(callback); + + /* clear caches */ + ClearCaches(); + + /* now use the MD5 function to cause exploit */ + sceKernelUtilsMd5BlockInitHax(0x8800CD54 - 28, 0, 0, 0); //6.31 + + /* clear caches, allow changes to commit */ + ClearCaches(); + + /* now you can use the 6.31 kernel call */ + execKernelFunction631(repairKernel631); +} + +void doKernelExploit635(void) +{ + u32 power_address = 0; + +#ifdef HBL_SUKKIRI + /* get proper MD5 imports (HBL does not resolve properly) */ + u32 address = (u32)findLibraryByName("sceNetIfhandle_lib", 0x08800000); + SceLibraryStubTable *stub = findLibraryByName("UtilsForUser", address - 0x500); + + /* copy over the stubs */ + memcpy(sceKernelUtilsMd5BlockInit, getFunctionFromLibrary(stub, 0x9E5C5086), 8); + memcpy(sceKernelUtilsMd5BlockUpdate, getFunctionFromLibrary(stub, 0x61E1E525), 8); + memcpy(sceKernelUtilsMd5BlockResult, getFunctionFromLibrary(stub, 0xB8D24E78), 8); + + /* get our stub pointer */ + stub = findLibraryByName("sceUtility_private", 0x08800000); + + /* get our exploit functions */ + memcpy(sceUtilityPowerRegisterCallback, getFunctionFromLibrary(stub, 0xE65F37C8), 8); //6.31/6.35 nid + memcpy(sceUtilityPowerunRegisterCallback, getFunctionFromLibrary(stub, 0x9ABAFCC5), 8); //6.31/6.35 nid +#endif + + /* create a callback */ + SceUID callback = sceKernelCreateCallback("Callback", (void *)DummyCallback, NULL); + + /* check for error */ + if (callback < 0) + { + return ErrorExit(5000, "Error creating callback\n"); + } + + /* register slot 0 (ignore error, use to ensure slot has a registered entry) */ + sceUtilityPowerRegisterCallback(0, callback); + + /* get the power address */ + power_address = getPowerAddress(callback); + + /* unregister again */ + sceUtilityPowerunRegisterCallback(0); + + /* bingo, we've got it! set sysmem addr to seek backwards from this address so when used in the callback func, it is directly at sysmem */ + u32 sysmem_addr = (~(power_address - 0x88000000) + 1) >> 4; + + /* unregister in order to remove any positive value ignore return value */ + sceUtilityPowerunRegisterCallback(sysmem_addr + 0xF15); //6.35 + + /* commit changes */ + ClearCaches(); + + /* call register callback in order to activate the exploit */ + int res = sceUtilityPowerRegisterCallback(sysmem_addr + 0xF15, callback); //6.35 + + /* check for error */ + if (res < 0) + { + /* error activating exploit */ + return ErrorExit(5000, "Error 0x%08X activating kernel exploit\n", res); + } + + /* delete the callback */ + sceKernelDeleteCallback(callback); + + /* clear caches */ + ClearCaches(); + + /* now use the MD5 function to cause exploit */ + sceKernelUtilsMd5BlockInitHax(0x8800CC34 - 28, 0, 0, 0); //6.35 + + /* clear caches, allow changes to commit */ + ClearCaches(); + + /* now you can use the 6.35 kernel call */ + execKernelFunction635(repairKernel635); +} + +int nopOut() +{ + _sw(0x00000000, 0x8800CC34); + return 0; +} + +void doKernelExploit638(void) +{ + int modid, i; + + /* Load necessary modules */ + for(i = 1; i < 7; i++) + modid = sceUtilityLoadNetModule(i); + + SceLibraryStubTable *stub = findLibraryByName("sceHttpStorage", 0x08800000); + sceHttpStorageOpen = (void *) getFunctionFromLibrary(stub, 0x700AAD44); + + /* Overwrite the addition of a global, so I can write to a direct address */ + int ret = sceHttpStorageOpen(-0x990>>2, 0, 0); + + /* DelayThread fixes, REQUIRED */ + sceKernelDelayThread(1000000); + ClearCaches(); + + /* vsync 0xFFFF out powerLock */ + ret = sceHttpStorageOpen(0x8800CC34>>2, 0, 0); + ClearCaches(); + + /* use PowerLock to run the function nopOut in kmode, which nop's out the vsync, so now non vfpu enabled threads can use powerLock */ + execKernelFunction635(nopOut); + + /* Finally, Clear caches */ + ClearCaches(); + + /* Unload Modules */ + for(i = 6; i > 0; i--) + sceUtilityUnloadNetModule(i); +} + +void doKernelExploit660(void) +{ + u32 val; + sceKernelIfHandleParam param_top; + sceKernelIfHandleParam param_sub; + + sceUtilityLoadNetModule(1); + + memset(¶m_top, 0, sizeof(sceKernelIfHandleParam)); + memset(¶m_sub, 0, sizeof(sceKernelIfHandleParam)); + + val = 0; + + /* Fill sub structure */ + param_sub.unk_8 = (u32)&val; + param_sub.unk_12 = sizeof(u32); + + /* Fill top structure */ + param_top.unk_0 = ¶m_sub; + param_top.unk_12 = 1; + param_top.unk_18 = 1; + param_top.unk_68 = (u32)¶m_top; + param_top.unk_8 = 0x8800CBB8 - param_top.unk_12; + param_top.unk_48 = 0x8800CBB8; + param_top.unk_60 = sizeof(u32); + + sceNetMPulldown(¶m_top, 0, param_top.unk_12 + sizeof(u32), NULL); + + ClearCaches(); +} + +void doKernelExploit(void) +{ + /* ok, lets check firmware version */ + if (sceKernelDevkitVersion() == FIRMWARE_VERSION_631) + { + /* do ksploit for 6.31 */ + doKernelExploit631(); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_635) + { + /* do ksploit for 6.35 */ + doKernelExploit635(); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_638 || sceKernelDevkitVersion() == FIRMWARE_VERSION_639) + { + /* do ksploit for 6.38 */ + doKernelExploit638(); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_660) + { + doKernelExploit660(); + } + else if (sceKernelDevkitVersion() == FIRMWARE_VERSION_661) + { + doKernelExploit660(); + } + else + { + /* not supported */ + ErrorExit(5000, "Error, your firmware is not supported.\n"); + } +} diff --git a/src/kernel_exploit.h b/src/kernel_exploit.h index 5a54644..993560e 100644 --- a/src/kernel_exploit.h +++ b/src/kernel_exploit.h @@ -1,38 +1,38 @@ -/* - Downgrade Launcher -> patch_table.h -> Provide API documentation and definitions for the table patching - by Davee - - 01/01/2011 -*/ -#ifndef __KERNEL_EXPLOIT_H__ -#define __KERNEL_EXPLOIT_H__ - -/* prototypes */ -void doKernelExploit(void); -int execKernelFunction(void *kfunc); - -typedef struct sceKernelIfHandleParam -{ - struct sceKernelIfHandleParam *unk_0; - u32 unk_4; - u32 unk_8; - u32 unk_12; - u16 unk_16; - u16 unk_18; - u32 unk_20; - u32 unk_24; - u32 unk_28; - u32 unk_32; - u32 unk_36; - u32 unk_40; - u32 unk_44; - u32 unk_48; - u32 unk_52; - u32 unk_56; - u32 unk_60; - u32 unk_64; - u32 unk_68; - u32 unk_72; -} sceKernelIfHandleParam; - -#endif /* __KERNEL_EXPLOIT_H__ */ +/* + Downgrade Launcher -> patch_table.h -> Provide API documentation and definitions for the table patching + by Davee + + 01/01/2011 +*/ +#ifndef __KERNEL_EXPLOIT_H__ +#define __KERNEL_EXPLOIT_H__ + +/* prototypes */ +void doKernelExploit(void); +int execKernelFunction(void *kfunc); + +typedef struct sceKernelIfHandleParam +{ + struct sceKernelIfHandleParam *unk_0; + u32 unk_4; + u32 unk_8; + u32 unk_12; + u16 unk_16; + u16 unk_18; + u32 unk_20; + u32 unk_24; + u32 unk_28; + u32 unk_32; + u32 unk_36; + u32 unk_40; + u32 unk_44; + u32 unk_48; + u32 unk_52; + u32 unk_56; + u32 unk_60; + u32 unk_64; + u32 unk_68; + u32 unk_72; +} sceKernelIfHandleParam; + +#endif /* __KERNEL_EXPLOIT_H__ */ diff --git a/src/kernel_land.c b/src/kernel_land.c index 87e9960..9c39778 100644 --- a/src/kernel_land.c +++ b/src/kernel_land.c @@ -1,301 +1,327 @@ -/* - Downgrade Launcher -> kernel_land.c -> Responsible for containing code access in kernel mode - by Davee - - 28/12/2010 -*/ - -#include -#include -#include - -#include -#include - -#include "kernel_land.h" -#include "rebootex.h" -#include "utils.h" -#include "downgrade_ctrl/patch_table.h" - -/* function pointers */ -int (* pspKernelGetModel)(void) = NULL; -int (* pspSysconGetBaryonVersion)(u32 *baryon) = NULL; -SceModule *(* pspKernelFindModuleByName)(const char *name) = NULL; -int (* pspKernelLoadExecVSHEf1)(const char *path, struct SceKernelLoadExecVSHParam *param) = NULL; -int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExecVSHParam *param) = NULL; -SceUID (* pspIoOpen)(char *file, int flags, SceMode mode) = NULL; -int (* pspIoWrite)(SceUID fd, void *data, u32 len) = NULL; -int (* pspIoClose)(SceUID fd) = NULL; - -/* globals */ -struct SceKernelLoadExecVSHParam g_exec_param; - -u32 getBaryon(void) -{ - u32 baryon; - - /* get the baryon version */ - pspSysconGetBaryonVersion(&baryon); - - /* return it */ - return baryon; -} - -int getModel(void) -{ - /* return the PSP model */ - return pspKernelGetModel(); -} - -int delete_resume_game(void) -{ - u8 _header[512+64]; - - /* use a pointer for math ease */ - u8 *header = _header; - - /* align to 64 */ - header = (u8 *)((u32)header & ~0x3F); header = (u8 *)((u32)header + 0x40); - - /* now clear it */ - memset(header, 0, 512); - - /* open hibernation fs */ - SceUID fd = pspIoOpen("eflash0a:__hibernation", 0x04000003, 0); - - /* check for error */ - if (fd < 0) - { - /* return error */ - return fd; - } - - /* write the blank header */ - int written = pspIoWrite(fd, header, 512); - - /* check for error */ - if (written < 0) - { - /* close file */ - pspIoClose(fd); - - /* return the error code */ - return written; - } - - /* return result */ - return pspIoClose(fd); -} - -int patch_loadexec_phat(void) -{ - /* Find the LoadExec */ - SceModule *mod = pspKernelFindModuleByName("sceLoadExec"); - - if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660) - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 - } - else - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 - - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 - } - - KClearCaches(); - - /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); -} - -int patch_loadexec_slim(void) -{ - /* Find the LoadExec */ - SceModule *mod = pspKernelFindModuleByName("sceLoadExec"); - - if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660) - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 - } - else - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 - - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 - } - - KClearCaches(); - - /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); -} - -int patch_loadexec_3000(void) -{ - /* Find the LoadExec */ - SceModule *mod = pspKernelFindModuleByName("sceLoadExec"); - - if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660) - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 - } - else - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 - - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 - } - - KClearCaches(); - - /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); -} - -int patch_loadexec_4000(void) -{ - /* Find the LoadExec */ - SceModule *mod = pspKernelFindModuleByName("sceLoadExec"); - - if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660) - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 - } - else - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 - - /* get past the userlevel check */ - MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 - } - - KClearCaches(); - - /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); -} - -int patch_loadexec_pspgo(void) -{ - /* Find the LoadExec */ - SceModule *mod = pspKernelFindModuleByName("sceLoadExec"); - - if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660) - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2FF8, RebootEntryPatched); //6.38 - - /* get past the userlevel checks for VSH */ - MAKE_RELATIVE_BRANCH(0x2624, 0x266C, mod->text_addr); //6.31/6.35 - } - else - { - /* Patch the reboot process */ - MAKE_CALL(mod->text_addr + 0x2FE0, RebootEntryPatched); //6.31/6.35 - - /* get past the userlevel checks for VSH */ - MAKE_RELATIVE_BRANCH(0x260C, 0x2658, mod->text_addr); //6.31/6.35 - } - - /* clear the caches */ - KClearCaches(); - - /* reboot into the updater */ - return pspKernelLoadExecVSHEf1(PSPGO_UPDATER_PATH, &g_exec_param); -} - -int launch_updater(void) -{ - KClearCaches(); - - int res = -1; - - /* clear our param */ - memset(&g_exec_param, 0, sizeof(struct SceKernelLoadExecVSHParam)); - - /* fill the field */ - g_exec_param.size = sizeof(struct SceKernelLoadExecVSHParam); - g_exec_param.argp = (pspKernelGetModel() == 4) ? (PSPGO_UPDATER_PATH) : (OTHER_UPDATER_PATH); - g_exec_param.args = strlen(g_exec_param.argp) + 1; - g_exec_param.key = "updater"; - g_exec_param.vshmain_args_size = 0; - g_exec_param.vshmain_args = NULL; - g_exec_param.configfile = NULL; - g_exec_param.unk4 = 0; - g_exec_param.unk5 = 0x10000; - - /* get the model */ - u32 model = pspKernelGetModel(); - - if(model == 6 || model == 8) - { - model = 3; - } - - /* launch a loadexec patch depending on model */ - switch (model) - { - /* PSP PHAT */ - case 0: - { - /* launch the updater and patch reboot */ - res = patch_loadexec_phat(); - break; - } - - /* PSP SLIM */ - case 1: - { - /* launch the updater and patch reboot */ - res = patch_loadexec_slim(); - break; - } - - /* PSP 3000 */ - case 2: - { - /* launch the updater and patch reboot */ - res = patch_loadexec_3000(); - break; - } - - /* PSP 4000 */ - case 3: - { - /* launch the updater and patch reboot */ - res = patch_loadexec_4000(); - break; - } - - /* PSP Go */ - case 4: - { - /* launch the updater and patch reboot */ - res = patch_loadexec_pspgo(); - break; - } - } - - /* return result */ - return res; -} +/* + Downgrade Launcher -> kernel_land.c -> Responsible for containing code access in kernel mode + by Davee + + 28/12/2010 +*/ + +#include +#include +#include + +#include +#include + +#include "kernel_land.h" +#include "rebootex.h" +#include "utils.h" +#include "downgrade_ctrl/patch_table.h" + +/* function pointers */ +int (* pspKernelGetModel)(void) = NULL; +int (* pspSysconGetBaryonVersion)(u32 *baryon) = NULL; +SceModule2 *(* pspKernelFindModuleByName)(const char *name) = NULL; +int (* pspKernelLoadExecVSHEf1)(const char *path, struct SceKernelLoadExecVSHParam *param) = NULL; +int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExecVSHParam *param) = NULL; +SceUID (* pspIoOpen)(char *file, int flags, SceMode mode) = NULL; +int (* pspIoWrite)(SceUID fd, void *data, u32 len) = NULL; +int (* pspIoClose)(SceUID fd) = NULL; + +/* globals */ +struct SceKernelLoadExecVSHParam g_exec_param; + +u32 getBaryon(void) +{ + u32 baryon; + + /* get the baryon version */ + pspSysconGetBaryonVersion(&baryon); + + /* return it */ + return baryon; +} + +int getModel(void) +{ + /* return the PSP model */ + return pspKernelGetModel(); +} + +int delete_resume_game(void) +{ + u8 _header[512+64]; + + /* use a pointer for math ease */ + u8 *header = _header; + + /* align to 64 */ + header = (u8 *)((u32)header & ~0x3F); header = (u8 *)((u32)header + 0x40); + + /* now clear it */ + memset(header, 0, 512); + + /* open hibernation fs */ + SceUID fd = pspIoOpen("eflash0a:__hibernation", 0x04000003, 0); + + /* check for error */ + if (fd < 0) + { + /* return error */ + return fd; + } + + /* write the blank header */ + int written = pspIoWrite(fd, header, 512); + + /* check for error */ + if (written < 0) + { + /* close file */ + pspIoClose(fd); + + /* return the error code */ + return written; + } + + /* return result */ + return pspIoClose(fd); +} + +int patch_loadexec_phat(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 + } + else + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 + + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 + } + + KClearCaches(); + + /* just return 0 */ + return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); +} + +int patch_loadexec_slim(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 + } + else + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 + + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 + } + + KClearCaches(); + + /* just return 0 */ + return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); +} + +int patch_loadexec_3000(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 + } + else + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 + + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 + } + + KClearCaches(); + + /* just return 0 */ + return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); +} + +int patch_loadexec_4000(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 + } + else + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2D94, RebootEntryPatched); //6.31/6.35 + + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23B8, 0x2400, mod->text_addr); //6.31/6.35 + } + + KClearCaches(); + + /* just return 0 */ + return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); +} + +int patch_loadexec_pspgo(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_638 || g_devkit_version == FIRMWARE_VERSION_639 || g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2FF8, RebootEntryPatched); //6.38 + + /* get past the userlevel checks for VSH */ + MAKE_RELATIVE_BRANCH(0x2624, 0x266C, mod->text_addr); //6.31/6.35 + } + else + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2FE0, RebootEntryPatched); //6.31/6.35 + + /* get past the userlevel checks for VSH */ + MAKE_RELATIVE_BRANCH(0x260C, 0x2658, mod->text_addr); //6.31/6.35 + } + + /* clear the caches */ + KClearCaches(); + + /* reboot into the updater */ + return pspKernelLoadExecVSHEf1(PSPGO_UPDATER_PATH, &g_exec_param); +} + +int patch_loadexec_street(void) +{ + /* Find the LoadExec */ + SceModule2 *mod = pspKernelFindModuleByName("sceLoadExec"); + + if(g_devkit_version == FIRMWARE_VERSION_660 || g_devkit_version == FIRMWARE_VERSION_661) + { + /* Patch the reboot process */ + MAKE_CALL(mod->text_addr + 0x2DAC, RebootEntryPatched); //6.38 + /* get past the userlevel check */ + MAKE_RELATIVE_BRANCH(0x23D0, 0x2418, mod->text_addr); //6.38 + } + + KClearCaches(); + + /* just return 0 */ + return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); +} + +int launch_updater(void) +{ + KClearCaches(); + + int res = -1; + + /* clear our param */ + memset(&g_exec_param, 0, sizeof(struct SceKernelLoadExecVSHParam)); + + /* fill the field */ + g_exec_param.size = sizeof(struct SceKernelLoadExecVSHParam); + g_exec_param.argp = (pspKernelGetModel() == 4) ? (PSPGO_UPDATER_PATH) : (OTHER_UPDATER_PATH); + g_exec_param.args = strlen(g_exec_param.argp) + 1; + g_exec_param.key = "updater"; + g_exec_param.vshmain_args_size = 0; + g_exec_param.vshmain_args = NULL; + g_exec_param.configfile = NULL; + g_exec_param.unk4 = 0; + g_exec_param.unk5 = 0x10000; + + /* get the model */ + u32 model = pspKernelGetModel(); + + if(model == 6 || model == 8) + { + model = 3; + } + + /* launch a loadexec patch depending on model */ + switch (model) + { + /* PSP PHAT */ + case 0: + { + /* launch the updater and patch reboot */ + res = patch_loadexec_phat(); + break; + } + + /* PSP SLIM */ + case 1: + { + /* launch the updater and patch reboot */ + res = patch_loadexec_slim(); + break; + } + + /* PSP 3000 */ + case 2: + { + /* launch the updater and patch reboot */ + res = patch_loadexec_3000(); + break; + } + + /* PSP 4000 */ + case 3: + { + /* launch the updater and patch reboot */ + res = patch_loadexec_4000(); + break; + } + + /* PSP Go */ + case 4: + { + /* launch the updater and patch reboot */ + res = patch_loadexec_pspgo(); + break; + } + + /* PSP E-1000 (Street) */ + case 10: + { + res = patch_loadexec_street(); + break; + } + } + + /* return result */ + return res; +} diff --git a/src/kernel_land.h b/src/kernel_land.h index d23dff1..0c2b50a 100644 --- a/src/kernel_land.h +++ b/src/kernel_land.h @@ -1,26 +1,27 @@ -/* - Downgrade Launcher -> kernel_land.h -> Provide API documentation and definitions for the kernel operations - by Davee - - 28/12/2010 -*/ -#ifndef __KERNEL_LAND_H__ -#define __KERNEL_LAND_H__ - -#include - -int getModel(void); -u32 getBaryon(void); -int launch_updater(void); -int delete_resume_game(void); - -extern int (* pspKernelGetModel)(void); -extern int (* pspSysconGetBaryonVersion)(u32 *baryon); -extern SceModule *(* pspKernelFindModuleByName)(const char *name); -extern int (* pspKernelLoadExecVSHEf1)(const char *path, struct SceKernelLoadExecVSHParam *param); -extern int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExecVSHParam *param); -extern SceUID (* pspIoOpen)(char *file, int flags, SceMode mode); -extern int (* pspIoWrite)(SceUID fd, void *data, u32 len); -extern int (* pspIoClose)(SceUID fd); - -#endif /* __KERNEL_LAND_H__ */ +/* + Downgrade Launcher -> kernel_land.h -> Provide API documentation and definitions for the kernel operations + by Davee + + 28/12/2010 +*/ +#ifndef __KERNEL_LAND_H__ +#define __KERNEL_LAND_H__ + +#include +#include "include/systemctrl.h" + +int getModel(void); +u32 getBaryon(void); +int launch_updater(void); +int delete_resume_game(void); + +extern int (* pspKernelGetModel)(void); +extern int (* pspSysconGetBaryonVersion)(u32 *baryon); +extern SceModule2 *(* pspKernelFindModuleByName)(const char *name); +extern int (* pspKernelLoadExecVSHEf1)(const char *path, struct SceKernelLoadExecVSHParam *param); +extern int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExecVSHParam *param); +extern SceUID (* pspIoOpen)(char *file, int flags, SceMode mode); +extern int (* pspIoWrite)(SceUID fd, void *data, u32 len); +extern int (* pspIoClose)(SceUID fd); + +#endif /* __KERNEL_LAND_H__ */ diff --git a/src/lib/libpspsystemctrl_kernel.a b/src/lib/libpspsystemctrl_kernel.a new file mode 100644 index 0000000..d25c873 Binary files /dev/null and b/src/lib/libpspsystemctrl_kernel.a differ diff --git a/src/libasm/libinfinityKernel.S b/src/libasm/libinfinityKernel.S new file mode 100644 index 0000000..b4df9db --- /dev/null +++ b/src/libasm/libinfinityKernel.S @@ -0,0 +1,10 @@ +.set noreorder + +#include "pspstub.s" + +STUB_START "libinfinityKernel",0x00090000,0x00040005 +STUB_FUNC 0x0527FEC1,infGetVersion +STUB_FUNC 0xA69B7B7E,infGetCoreVersion +STUB_FUNC 0x3AE45BE1,infGetRedirectionStatus +STUB_FUNC 0xD81F887B,infSetRedirectionStatus +STUB_END diff --git a/src/libasm/libinfinityUser.S b/src/libasm/libinfinityUser.S new file mode 100644 index 0000000..70bdc12 --- /dev/null +++ b/src/libasm/libinfinityUser.S @@ -0,0 +1,10 @@ +.set noreorder + +#include "pspstub.s" + +STUB_START "libinfinityUser",0x40090000,0x00040005 +STUB_FUNC 0x0527FEC1,infGetVersion +STUB_FUNC 0xA69B7B7E,infGetCoreVersion +STUB_FUNC 0x3AE45BE1,infGetRedirectionStatus +STUB_FUNC 0xD81F887B,infSetRedirectionStatus +STUB_END diff --git a/src/main.c b/src/main.c index 4301b19..d23bc10 100644 --- a/src/main.c +++ b/src/main.c @@ -1,339 +1,373 @@ -/* - Downgrade Launcher R1 - by Davee - - Fin-rev 24/01/2011 -*/ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "utils.h" -#include "kernel_land.h" -#include "kernel_exploit.h" -#include "rebootex.h" - -PSP_MODULE_INFO("Chronoswitch", 0, 1, 1); -PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU); -PSP_HEAP_SIZE_KB(3 << 10); - -#define DOWNGRADER_VER ("5.0") - -typedef struct __attribute__((packed)) -{ - int magic; // 0 - int version; // 4 - unsigned int keyofs; // 8 - unsigned int valofs; // 12 - int count; // 16 -} SfoHeader; - -typedef struct __attribute__((packed)) -{ - unsigned short nameofs; // 0 - char alignment; // 2 - char type; // 3 - int valsize; // 4 - int totalsize; // 8 - unsigned short valofs; // 12 - short unknown; // 16 -} SfoEntry; - -u32 get_updater_version(u32 is_pspgo) -{ - int i; - char *fw_data; - u32 pbp_header[0x28/4]; - u8 sfo_buffer[4 << 10]; - SfoHeader *header = (SfoHeader *)sfo_buffer; - SfoEntry *entries = (SfoEntry *)((char *)sfo_buffer + sizeof(SfoHeader)); - - /* Lets open the updater */ - char *file = (is_pspgo) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.pbp") : ("ms0:/PSP/GAME/UPDATE/EBOOT.pbp"); - - /* open file */ - SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); - - /* check for failure */ - if (fd < 0) - { - /* error firmware */ - return 0xFFF; - } - - /* read the PBP header */ - sceIoRead(fd, pbp_header, sizeof(pbp_header)); - - /* seek to the SFO */ - sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); - - /* calculate the size of the SFO */ - u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; - - /* check if greater than buffer size */ - if (sfo_size > sizeof(sfo_buffer)) - { - /* too much */ - sceIoClose(fd); - return 0xFFF; - } - - /* read the sfo */ - sceIoRead(fd, sfo_buffer, sizeof(sfo_buffer)); - - /* close the file */ - sceIoClose(fd); - - /* now parse the SFO */ - for (i = 0; i < header->count; i++) - { - /* check this name */ - if (strcmp((char *)((char *)sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) - { - /* get the string */ - fw_data = (char *)((char *)sfo_buffer + header->valofs + entries[i].valofs); - break; - } - } - - /* see if we went through all the data */ - if (i == header->count) - { - return 0xFFF; - } - - /* return the firmware version */ - return (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); -} - -int main(int argc, char *argv[]) -{ - int res; - SceCtrlData pad_data; - u32 cur_buttons, prev_buttons = 0; - -#ifdef HBL_SUKKIRI - pspUtilityHtmlViewerParam html_param; -#endif - - /* initialise the PSP screen */ - pspDebugScreenInit(); - pspDebugScreenSetTextColor(0x00D05435); - - /* display welcome message */ - printf( - "Chronoswitch Downgrader" "\n" - "Version %s. Built %s %s" "\n" "\n" - - "Contributions:" "\n" - "\t" "6.31/6.35 Support added by Davee" "\n" - "\t" "6.38/6.39/6.60 Support added by some1" "\n" "\n" - - "Web:" "\n" - "\t" "http://lolhax.org" "\n" "\n" - , DOWNGRADER_VER, __DATE__, __TIME__); - -#ifdef HBL_SUKKIRI - /* Clear html param to 0 */ - memset(&html_param, 0, sizeof(pspUtilityHtmlViewerParam)); - - /* set enough params in html viewer to get through to module loading */ - html_param.base.size = sizeof(pspUtilityHtmlViewerParam); - html_param.base.accessThread = 0xF; - - /* call sceUtilityHtmlViewerInitStart to load the htmlviewer_utility.prx which imports sceutility/scepower exploit */ - res = sceUtilityHtmlViewerInitStart(&html_param); - - /* check error */ - if (res < 0) - { - /* this could be an HBL resolving issue... */ - ErrorExit(5000, "Error 0x%08X starting htmlviewer\n", res); - } - - /* wait a second for htmlviewer to get loaded */ - sceKernelDelayThread(1 * 1000 * 1000); -#endif - - /* check firmware*/ - printf("Checking firmware... "); - - /* do the kernel exploit */ - doKernelExploit(); - - /* printf ok message */ - printf("OK\n"); - - /* set the devkit */ - g_devkit_version = sceKernelDevkitVersion(); - - /* get the PSP model */ - int model = execKernelFunction(getModel); - int true_model = model; - - /* check for real model if it claims it is a 04g (can be 09g) */ - if (model == 3) - { - /* get the baryon */ - u32 baryon = execKernelFunction(getBaryon); - - /* now get the determinating model */ - u32 det_model = (baryon >> 16) & 0xFF; - - /* now check if it is within range */ - if (det_model >= 0x2E && det_model < 0x30) - { - /* it's a 09g (or a sneaky 07g...) */ - if ((baryon >> 24) == 1) - { - /* 07g!! */ - true_model = 6; - } - else - { - /* 09g */ - true_model = 8; - } - } - } - - /* display model */ - printf("Your PSP reports model %02ig.\n", model+1); - - /* check if real != true */ - if (true_model != model) - { - /* display */ - printf("Your PSP is originally a %02ig model.\n", true_model + 1); - ErrorExit(10000, "Due to the experimental nature of the whole 09g to 04g downgrade, functionality to change firmware is prohibited through this program."); - } - - /* delay the thread */ - sceKernelDelayThread(5*1000*1000); - - /* check for 09g, we treat this as a 04g */ - if(model == 8) - { - model = 3; - } - - /* check for unsupported model */ - if (model != 0 && /* PSP PHAT */ - model != 1 && /* PSP SLIM */ - model != 2 && /* PSP 3000 */ - model != 3 && /* PSP 4000 */ - model != 4 /* PSPgo */ - ) - { - /* unsupported */ - ErrorExit(5000, "PSP %02ig not supported.\n", model+1); - } - - /* check for pspgo */ - if (model == 4) - { - printf("\n" "Your PSPgo will require deletion of the [Resume Game] feature. Proceed? (X = Yes, R = No)\n"); - - while (1) - { - sceCtrlPeekBufferPositive(&pad_data, 1); - - /* filter out previous buttons */ - cur_buttons = pad_data.Buttons & ~prev_buttons; - prev_buttons = pad_data.Buttons; - - /* check for cross */ - if (cur_buttons & PSP_CTRL_CROSS) - { - break; - } - - else if (cur_buttons & PSP_CTRL_RTRIGGER) - { - ErrorExit(5000, "Exiting in 5 seconds.\n"); - } - } - - /* delete resume game */ - if (execKernelFunction(delete_resume_game) < 0) - { - /* ERROR */ - ErrorExit(5000, "Error deleting [Resume Game]. Exiting for safety reasons.\n"); - } - } - - /* get the updater version */ - u32 upd_ver = get_updater_version(model == 4); - - /* do confirmation stuff */ - printf("Will attempt to Downgrade: %X.%X -> %X.%X.\n", (g_devkit_version >> 24) & 0xF, ((g_devkit_version >> 12) & 0xF0) | ((g_devkit_version >> 8) & 0xF), (upd_ver >> 8) & 0xF, upd_ver & 0xFF); - printf("X to continue, R to exit.\n"); - - /* get button */ - while (1) - { - sceCtrlPeekBufferPositive(&pad_data, 1); - - /* filter out previous buttons */ - cur_buttons = pad_data.Buttons & ~prev_buttons; - prev_buttons = pad_data.Buttons; - - /* check for cross */ - if (cur_buttons & PSP_CTRL_CROSS) - { - break; - } - - else if (cur_buttons & PSP_CTRL_RTRIGGER) - { - ErrorExit(5000, "Exiting in 5 seconds.\n"); - } - } - - /* clear screen */ - pspDebugScreenClear(); - - /* update should be OK, go for it */ - printf("By running this application and launching the SCE updater you accept all responsibility of any damage, temporary or permament, that may occur when using this application. This application has been tested with no loss of functionality or any damage to the system, however it cannot be guaranteed to be completely safe." "\n" "BY RUNNING THIS APPLICATION YOU ACCEPT ALL THE RISK INVOLVED.\n\n" "Press X to start SCE updater. Press R to exit\n"); - - while (1) - { - sceCtrlPeekBufferPositive(&pad_data, 1); - - /* filter out previous buttons */ - cur_buttons = pad_data.Buttons & ~prev_buttons; - prev_buttons = pad_data.Buttons; - - /* check for cross */ - if (cur_buttons & PSP_CTRL_CROSS) - { - break; - } - - else if (cur_buttons & PSP_CTRL_RTRIGGER) - { - ErrorExit(5000, "Exiting in 5 seconds.\n"); - } - } - - printf("OK, good for launch\n"); - - /* go go go go go */ - res = execKernelFunction(launch_updater); - - printf("loading SCE updater failed = 0x%08X\n", res); - sceKernelDelayThread(5 *1000*1000); - sceKernelExitGame(); - return 0; -} +/* + Downgrade Launcher R1 + by Davee + + Fin-rev 24/01/2011 +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "utils.h" +#include "kernel_land.h" +#include "kernel_exploit.h" +#include "rebootex.h" + +PSP_MODULE_INFO("Chronoswitch", 0, 1, 1); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU); +PSP_HEAP_SIZE_KB(3 << 10); + +#define DOWNGRADER_VER ("7.0") + +typedef struct __attribute__((packed)) +{ + int magic; // 0 + int version; // 4 + unsigned int keyofs; // 8 + unsigned int valofs; // 12 + int count; // 16 +} SfoHeader; + +typedef struct __attribute__((packed)) +{ + unsigned short nameofs; // 0 + char alignment; // 2 + char type; // 3 + int valsize; // 4 + int totalsize; // 8 + unsigned short valofs; // 12 + short unknown; // 16 +} SfoEntry; + +u32 get_updater_version(u32 is_pspgo) +{ + int i; + char *fw_data = NULL; + u32 pbp_header[0x28/4]; + u8 sfo_buffer[4 << 10]; + SfoHeader *header = (SfoHeader *)sfo_buffer; + SfoEntry *entries = (SfoEntry *)((char *)sfo_buffer + sizeof(SfoHeader)); + + /* Lets open the updater */ + char *file = (is_pspgo) ? ("ef0:/PSP/GAME/UPDATE/EBOOT.PBP") : ("ms0:/PSP/GAME/UPDATE/EBOOT.PBP"); + + /* open file */ + SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); + + /* check for failure */ + if (fd < 0) + { + /* error firmware */ + return 0xFFF; + } + + /* read the PBP header */ + sceIoRead(fd, pbp_header, sizeof(pbp_header)); + + /* seek to the SFO */ + sceIoLseek32(fd, pbp_header[8/4], PSP_SEEK_SET); + + /* calculate the size of the SFO */ + u32 sfo_size = pbp_header[12/4] - pbp_header[8/4]; + + /* check if greater than buffer size */ + if (sfo_size > sizeof(sfo_buffer)) + { + /* too much */ + sceIoClose(fd); + return 0xFFF; + } + + /* read the sfo */ + sceIoRead(fd, sfo_buffer, sizeof(sfo_buffer)); + + /* close the file */ + sceIoClose(fd); + + /* now parse the SFO */ + for (i = 0; i < header->count; i++) + { + /* check this name */ + if (strcmp((char *)((char *)sfo_buffer + header->keyofs + entries[i].nameofs), "UPDATER_VER") == 0) + { + /* get the string */ + fw_data = (char *)((char *)sfo_buffer + header->valofs + entries[i].valofs); + break; + } + } + + /* see if we went through all the data */ + if (i == header->count) + { + return 0xFFF; + } + + /* return the firmware version */ + return (((fw_data[0] - '0') & 0xF) << 8) | (((fw_data[2] - '0') & 0xF) << 4) | (((fw_data[3] - '0') & 0xF) << 0); +} + +int main(int argc, char *argv[]) +{ + int res; + SceCtrlData pad_data; + u32 cur_buttons, prev_buttons = 0; + +#ifdef HBL_SUKKIRI + pspUtilityHtmlViewerParam html_param; +#endif + + /* initialise the PSP screen */ + pspDebugScreenInit(); + pspDebugScreenSetTextColor(0x00D05435); + + /* display welcome message */ + printf( + "Chronoswitch Downgrader" "\n" + "Version %s. Built %s %s" "\n" "\n" + + "Contributions:" "\n" + "\t" "6.31/6.35 Support added by Davee" "\n" + "\t" "6.38/6.39/6.60 Support added by some1" "\n" + "\t" "6.61 Support added by qwikrazor87" "\n" "\n" + + "Web:" "\n" + "\t" "https://lolhax.org" "\n" "\n" + , DOWNGRADER_VER, __DATE__, __TIME__); + +#ifdef HBL_SUKKIRI + /* Clear html param to 0 */ + memset(&html_param, 0, sizeof(pspUtilityHtmlViewerParam)); + + /* set enough params in html viewer to get through to module loading */ + html_param.base.size = sizeof(pspUtilityHtmlViewerParam); + html_param.base.accessThread = 0xF; + + /* call sceUtilityHtmlViewerInitStart to load the htmlviewer_utility.prx which imports sceutility/scepower exploit */ + res = sceUtilityHtmlViewerInitStart(&html_param); + + /* check error */ + if (res < 0) + { + /* this could be an HBL resolving issue... */ + ErrorExit(5000, "Error 0x%08X starting htmlviewer\n", res); + } + + /* wait a second for htmlviewer to get loaded */ + sceKernelDelayThread(1 * 1000 * 1000); +#endif + + /* check firmware*/ + printf("Checking firmware... "); + + /* do the kernel exploit */ + doKernelExploit(); + + /* printf ok message */ + printf("OK\n"); + + /* set the devkit */ + g_devkit_version = sceKernelDevkitVersion(); + + /* get the PSP model */ + int model = execKernelFunction(getModel); + int true_model = model; + + /* check for real model if it claims it is a 04g (can be 09g) */ + if (model == 3) + { + /* get the baryon */ + u32 baryon = execKernelFunction(getBaryon); + + /* now get the determinating model */ + u32 det_model = (baryon >> 16) & 0xFF; + + /* now check if it is within range */ + if (det_model >= 0x2E && det_model < 0x30) + { + /* it's a 09g (or a sneaky 07g...) */ + if ((baryon >> 24) == 1) + { + /* 07g!! */ + true_model = 6; + } + else + { + /* 09g */ + true_model = 8; + } + } + } + + /* display model */ + printf("Your PSP reports model %02ig.\n", model+1); + + /* check if real != true */ + if (true_model != model) + { + /* display */ + printf("Your PSP is originally a %02ig model.\n", true_model + 1); + ErrorExit(10000, "Due to the experimental nature of the whole 09g to 04g downgrade, functionality to change firmware is prohibited through this program."); + } + + /* delay the thread */ + sceKernelDelayThread(5*1000*1000); + + /* check for 09g, we treat this as a 04g */ + if(model == 8) + { + model = 3; + } + + /* check for unsupported model */ + if (model != 0 && /* PSP PHAT */ + model != 1 && /* PSP SLIM */ + model != 2 && /* PSP 3000 */ + model != 3 && /* PSP 4000 */ + model != 4 && /* PSPgo */ + model != 10 /* PSP E-1000 (Street) */ + ) + { + /* unsupported */ + ErrorExit(5000, "PSP %02ig not supported.\n", model+1); + } + + /* check for pspgo */ + if (model == 4) + { + printf("\n" "Your PSPgo will require deletion of the [Resume Game] feature. Proceed? (X = Yes, R = No)\n"); + + while (1) + { + sceCtrlPeekBufferPositive(&pad_data, 1); + + /* filter out previous buttons */ + cur_buttons = pad_data.Buttons & ~prev_buttons; + prev_buttons = pad_data.Buttons; + + /* check for cross */ + if (cur_buttons & PSP_CTRL_CROSS) + { + break; + } + + else if (cur_buttons & PSP_CTRL_RTRIGGER) + { + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + } + + /* delete resume game */ + if (execKernelFunction(delete_resume_game) < 0) + { + /* ERROR */ + ErrorExit(5000, "Error deleting [Resume Game]. Exiting for safety reasons.\n"); + } + } + + int isInfinity = !(infGetVersion() & 0x80000000); + + if (isInfinity) + { + printf("\n" "Your PSP is running Infinity and reflashing is slightly more risky. Proceed? (X = Yes, R = No)\n"); + + while (1) + { + sceCtrlPeekBufferPositive(&pad_data, 1); + + /* filter out previous buttons */ + cur_buttons = pad_data.Buttons & ~prev_buttons; + prev_buttons = pad_data.Buttons; + + /* check for cross */ + if (cur_buttons & PSP_CTRL_CROSS) + { + break; + } + + else if (cur_buttons & PSP_CTRL_RTRIGGER) + { + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + } + } + + /* get the updater version */ + u32 upd_ver = get_updater_version(model == 4); + + if ((model == 10) && (upd_ver < 0x660)) { + printf("This app does not support downgrading a PSP 11g below 6.60.\n"); + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + + /* do confirmation stuff */ + printf("Will attempt to Downgrade: %X.%X -> %X.%X.\n", (g_devkit_version >> 24) & 0xF, ((g_devkit_version >> 12) & 0xF0) | ((g_devkit_version >> 8) & 0xF), (upd_ver >> 8) & 0xF, upd_ver & 0xFF); + printf("X to continue, R to exit.\n"); + + /* get button */ + while (1) + { + sceCtrlPeekBufferPositive(&pad_data, 1); + + /* filter out previous buttons */ + cur_buttons = pad_data.Buttons & ~prev_buttons; + prev_buttons = pad_data.Buttons; + + /* check for cross */ + if (cur_buttons & PSP_CTRL_CROSS) + { + break; + } + + else if (cur_buttons & PSP_CTRL_RTRIGGER) + { + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + } + + /* clear screen */ + pspDebugScreenClear(); + + /* update should be OK, go for it */ + printf("By running this application and launching the SCE updater you accept all responsibility of any damage, temporary or permament, that may occur when using this application. This application has been tested with no loss of functionality or any damage to the system, however it cannot be guaranteed to be completely safe." "\n" "BY RUNNING THIS APPLICATION YOU ACCEPT ALL THE RISK INVOLVED.\n\n" "Press X to start SCE updater. Press R to exit\n"); + + while (1) + { + sceCtrlPeekBufferPositive(&pad_data, 1); + + /* filter out previous buttons */ + cur_buttons = pad_data.Buttons & ~prev_buttons; + prev_buttons = pad_data.Buttons; + + /* check for cross */ + if (cur_buttons & PSP_CTRL_CROSS) + { + break; + } + + else if (cur_buttons & PSP_CTRL_RTRIGGER) + { + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + } + + printf("OK, good for launch\n"); + + /* go go go go go */ + res = execKernelFunction(launch_updater); + + printf("loading SCE updater failed = 0x%08X\n", res); + sceKernelDelayThread(5 *1000*1000); + sceKernelExitGame(); + return 0; +} diff --git a/src/patch_table.h b/src/patch_table.h index ecba060..209930c 100644 --- a/src/patch_table.h +++ b/src/patch_table.h @@ -1,104 +1,119 @@ -/* - Downgrade Launcher -> patch_table.h -> Provide API documentation and definitions for the table patching - by Davee - - 01/01/2011 -*/ -#ifndef __PATCH_TABLE_H__ -#define __PATCH_TABLE_H__ - -#include "utils.h" - -typedef struct -{ - u32 devkit; - u32 new_updater_check[5]; - u32 updater_decrypt_call; - u32 updater_decrypt_func; - u32 prologue_module_func; - u32 prologue_module_call; - u32 memlmd_call[2]; - u32 memlmd_stub[2]; -} PatchTable; - -PatchTable g_patch_table[] = -{ - { - FIRMWARE_VERSION_631, - { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, - - /* for 05g mesgled */ - 0x6B44, //mesgled updater decrypt call - 0x83E8, //mesgled updater decrypt func - - 0x8138, //prologue func - 0x705C, //prologue call - - { 0x6930, 0x6954 }, //memlmd calls - { 0x8398, 0x8378 }, //memlmd stubs - }, - - { - FIRMWARE_VERSION_635, - { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, - - /* for 05g mesgled */ - 0x5EB8, //mesgled updater decrypt call - 0x7B58, //mesgled updater decrypt func - - 0x8134, //prologue func - 0x7058, //prologue call - - { 0x5CA4, 0x5CC8 }, //memlmd calls - { 0x7B08, 0x7AE8 }, //memlmd stubs - }, - - { - FIRMWARE_VERSION_638, - { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, - - /* for 05g mesgled */ - 0x5EB8, //mesgled updater decrypt call - 0x7B58, //mesgled updater decrypt func - - 0x8134, //prologue func - 0x7058, //prologue call - - { 0x5CA4, 0x5CC8 }, //memlmd calls - { 0x7B08, 0x7AE8 }, //memlmd stubs - }, - - { - FIRMWARE_VERSION_639, - { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, - - /* for 05g mesgled */ - 0x5EB8, //mesgled updater decrypt call - 0x7B58, //mesgled updater decrypt func - - 0x8130, //prologue func - 0x7054, //prologue call - - { 0x5CA4, 0x5CC8 }, //memlmd calls - { 0x7B08, 0x7AE8 }, //memlmd stubs - }, - - { - FIRMWARE_VERSION_660, - { 0x0B24, 0x0B24, 0x0B24, 0x0B24, 0x0B24, }, - - /* for 05g mesgled */ - 0x5B84, //mesgled updater decrypt call - 0x78AC, //mesgled updater decrypt func - - 0x8124, //prologue func - 0x7048, //prologue call - - { 0x5970, 0x5994 }, //memlmd calls - { 0x783C, 0x7824 }, //memlmd stubs - }, -}; - -#define PATCH_TABLE_ADDR_START (0x88FC0000) - -#endif /* __PATCH_TABLE_H__ */ +/* + Downgrade Launcher -> patch_table.h -> Provide API documentation and definitions for the table patching + by Davee + + 01/01/2011 +*/ +#ifndef __PATCH_TABLE_H__ +#define __PATCH_TABLE_H__ + +#include "utils.h" + +typedef struct +{ + u32 devkit; + u32 new_updater_check[5]; + u32 updater_decrypt_call; + u32 updater_decrypt_func; + u32 prologue_module_func; + u32 prologue_module_call; + u32 memlmd_call[2]; + u32 memlmd_stub[2]; +} PatchTable; + +PatchTable g_patch_table[] = +{ + { + FIRMWARE_VERSION_631, + { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, + + /* for 05g mesgled */ + 0x6B44, //mesgled updater decrypt call + 0x83E8, //mesgled updater decrypt func + + 0x8138, //prologue func + 0x705C, //prologue call + + { 0x6930, 0x6954 }, //memlmd calls + { 0x8398, 0x8378 }, //memlmd stubs + }, + + { + FIRMWARE_VERSION_635, + { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, + + /* for 05g mesgled */ + 0x5EB8, //mesgled updater decrypt call + 0x7B58, //mesgled updater decrypt func + + 0x8134, //prologue func + 0x7058, //prologue call + + { 0x5CA4, 0x5CC8 }, //memlmd calls + { 0x7B08, 0x7AE8 }, //memlmd stubs + }, + + { + FIRMWARE_VERSION_638, + { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, + + /* for 05g mesgled */ + 0x5EB8, //mesgled updater decrypt call + 0x7B58, //mesgled updater decrypt func + + 0x8134, //prologue func + 0x7058, //prologue call + + { 0x5CA4, 0x5CC8 }, //memlmd calls + { 0x7B08, 0x7AE8 }, //memlmd stubs + }, + + { + FIRMWARE_VERSION_639, + { 0x0D78, 0x0D78, 0x0D78, 0x0D78, 0x0D78, }, + + /* for 05g mesgled */ + 0x5EB8, //mesgled updater decrypt call + 0x7B58, //mesgled updater decrypt func + + 0x8130, //prologue func + 0x7054, //prologue call + + { 0x5CA4, 0x5CC8 }, //memlmd calls + { 0x7B08, 0x7AE8 }, //memlmd stubs + }, + + { + FIRMWARE_VERSION_660, + { 0x0B24, 0x0B24, 0x0B24, 0x0B24, 0x0B24, }, + + /* for 05g mesgled */ + 0x5B84, //mesgled updater decrypt call + 0x78AC, //mesgled updater decrypt func + + 0x8124, //prologue func + 0x7048, //prologue call + + { 0x5970, 0x5994 }, //memlmd calls + { 0x783C, 0x7824 }, //memlmd stubs + }, + + { + FIRMWARE_VERSION_661, + { 0x0B24, 0x0B24, 0x0B24, 0x0B24, 0x0B24, }, + + /* for 05g mesgled */ + 0x5B84, //mesgled updater decrypt call + 0x78AC, //mesgled updater decrypt func + + 0x8124, //prologue func + 0x7048, //prologue call + + { 0x5970, 0x5994 }, //memlmd calls + { 0x783C, 0x7824 }, //memlmd stubs + }, +}; + +#define PATCH_TABLE_ADDR_START (0x88FC0000) + +#endif /* __PATCH_TABLE_H__ */ diff --git a/src/rebootex.c b/src/rebootex.c index ba82da0..d700c7b 100644 --- a/src/rebootex.c +++ b/src/rebootex.c @@ -1,779 +1,799 @@ -/* - Downgrade Launcher -> rebootex.c -> Provide patches to the Sony reboot.bin to insert our downgrade controller - by Davee - - 28/12/2010 -*/ - -#include -#include - -#include -#include - -#include "utils.h" -#include "rebootex.h" -#include "patch_table.h" -#include "kernel_land.h" - -#include "downgrade_ctrl.h" -#include "downgrade660_ctrl.h" - -/* global variables */ -u32 g_module_seek = 0; -u32 g_module_opened = 0; -void *g_module = NULL; -u32 g_devkit_version = 0; - -/* function pointers */ -int (* sceBootLfatOpen)(char *path) = NULL; -int (* sceBootLfatRead)(void *data, int size) = NULL; -int (* sceBootLfatClose)(void) = NULL; - -u32 (* sceKernelCheckPspConfig)(void *btcnf_data, u32 size, int flag) = NULL; - -int (* DecryptExecutable)(void *buffer, int size, int *outsize) = NULL; -int (* VerifySigncheck)(void *buffer, int size) = NULL; - -/* The Sony Reboot */ -int (* sceReboot)(void *reboot_param, void *exec_param, int api, int initial_rnd) = (void *)0x88600000; - -int sceBootLfatOpenPatched(char *path) -{ - /* check the path for our virtual module */ - if (strcmp(path, "/kd/strange.charm") == 0) - { - /* set seek to 0 and set to opened and return success */ - g_module_seek = 0; - g_module_opened = 1; - - return 0; - } - - /* return original function */ - return sceBootLfatOpen(path); -} - -int sceBootLfatReadPatched(void *data, int size) -{ - /* check if the module is virtually opened */ - if (g_module_opened) - { - /* get the remaining size */ - u32 remain = size_downgrade_ctrl - g_module_seek; - - /* now do some math to calculate how much we will copy (as read is done in 32KiB chunks) */ - remain = (remain < (32 << 10)) ? (remain) : (32 << 10); - - /* copy over data */ - memcpy(data, downgrade_ctrl + g_module_seek, remain); - - /* increment the seek */ - g_module_seek += remain; - - /* returned copied size */ - return remain; - } - - /* return the read data */ - return sceBootLfatRead(data, size); -} - -int sceBootLfatReadPatched660(void *data, int size) -{ - /* check if the module is virtually opened */ - if (g_module_opened) - { - /* get the remaining size */ - u32 remain = size_downgrade660_ctrl - g_module_seek; - - /* now do some math to calculate how much we will copy (as read is done in 32KiB chunks) */ - remain = (remain < (32 << 10)) ? (remain) : (32 << 10); - - /* copy over data */ - memcpy(data, downgrade660_ctrl + g_module_seek, remain); - - /* increment the seek */ - g_module_seek += remain; - - /* returned copied size */ - return remain; - } - - /* return the read data */ - return sceBootLfatRead(data, size); -} - -int sceBootLfatClosePatched(void) -{ - /* check if the module is virtually opened */ - if (g_module_opened) - { - /* it is, interally close and return success */ - g_module_opened = 0; - return 0; - } - - /* return the original */ - return sceBootLfatClose(); -} - -/* BTCNF INJECION CODE BY BUBBLETUNE (bubbletune.x-fusion.co.uk) */ -int InsertModuleBtcnf(char *new_mod, char *before_mod, BtcnfHeader *header, int *size, u16 flags) -{ - /* cast and declare our local variables */ - int i, j; - ModeEntry *modes = (ModeEntry *)((u32)header + header->modestart); - ModuleEntry *modules = (ModuleEntry *)((u32)header + header->modulestart); - char *names = (char *)((u32)header + header->modnamestart); - int len = strlen(new_mod) + 1; - - /* loop through the modules */ - for (i = 0; i < header->nmodules; i++) - { - /* if we find the module we want to insert before */ - if (memcmp(names + modules[i].stroffset, before_mod, strlen(before_mod) + 1) == 0) - { - /* found it! lets move the the whole section so we can fit another entry*/ - memmove(modules + i + 1, modules + i, (*size)-header->modulestart-(i*sizeof(ModuleEntry))); - - /* update all the header variables */ - header->modnamestart += sizeof(ModuleEntry); - header->modnameend += sizeof(ModuleEntry); - *size += sizeof(ModuleEntry); - header->nmodules++; - - /* add the new information */ - modules[i].stroffset = header->modnameend-header->modnamestart; - modules[i].flags = flags; - - /* copy the string over :P */ - memcpy((char *)header + header->modnameend, new_mod, len); - - /* update the new size and the header modname end */ - *size += len; - header->modnameend += len; - - /* change the modes */ - for (j = 0; j < header->nmodes; j++) - { - modes[j].searchstart = 0; - modes[j].maxsearch++; - } - - /* return success */ - return 0; - } - } - - /* return fail */ - return -1; -} - -u32 sceKernelCheckPspConfigPatched(void *btcnf_data, u32 size, int flag) -{ - /* cast our variables and declare */ - BtcnfHeader *header = (BtcnfHeader *)btcnf_data; - - /* decrypt the btcnf so we have the decrypted version */ - int nsize = sceKernelCheckPspConfig(btcnf_data, size, flag); - - /* check the signature is valid */ - if (header->signature == 0x0F803001) - { - /* insert the module path into the config */ - InsertModuleBtcnf("/kd/strange.charm", "/kd/init.prx", btcnf_data, &nsize, (BOOTLOAD_VSH | BOOTLOAD_GAME | BOOTLOAD_POPS | BOOTLOAD_UPDATER | BOOTLOAD_UMDEMU | BOOTLOAD_MLNAPP)); - } - - /* return the new size */ - return nsize; -} - -int DecryptExecutablePatched(void *header, int size, int *outsize) -{ - /* check for decryption tag */ - if (_lw((u32)header + 0x130) == 0x626F6F42) - { - *outsize = _lw((u32)header + 0xB0); - memmove(header, header + 0x150, *outsize); - return 0; - } - - /* return the real decryption code */ - return DecryptExecutable(header, size, outsize); -} - -int VerifySigncheckPatched(void *buffer, int size) -{ - int i; - /* loop through the signcheck */ - for (i = 0; i < 0x58; i++) - { - /* if byte is 0 then call the signcheck removal */ - if (((u8 *)buffer)[0xD4 + i]) - { - /* remove signcheck */ - return VerifySigncheck(buffer, size); - } - } - - /* return success :D */ - return 0; -} - -int LoadCoreModuleStart631(int (* module_bootstart)(u32 argsize, void *argp), void *argp) -{ - /* get text_addr by substituting from module_bootstart address */ - u32 text_addr = ((u32)module_bootstart) - 0xBC4; - - /* assign our function pointers */ - DecryptExecutable = (void *)(text_addr + 0x8398); - VerifySigncheck = (void *)(text_addr + 0x8378); - - /* patch the calls to the decryption */ - MAKE_CALL(text_addr + 0x6930, DecryptExecutablePatched); - - /* patch calls to the unsigncheck routines */ - MAKE_CALL(text_addr + 0x6954, VerifySigncheckPatched); - - /* call the loadcore bootstart */ - return module_bootstart(8, argp); -} - -int LoadCoreModuleStart635(int (* module_bootstart)(u32 argsize, void *argp), void *argp) -{ - /* get text_addr by substituting from module_bootstart address */ - u32 text_addr = ((u32)module_bootstart) - 0xBBC; - - /* assign our function pointers */ - DecryptExecutable = (void *)(text_addr + 0x7B08); - VerifySigncheck = (void *)(text_addr + 0x7AE8); - - /* patch the calls to the decryption */ - MAKE_CALL(text_addr + 0x5CA4, DecryptExecutablePatched); - - /* patch calls to the unsigncheck routines */ - MAKE_CALL(text_addr + 0x5CC8, VerifySigncheckPatched); - - /* call the loadcore bootstart */ - return module_bootstart(8, argp); -} - -int LoadCoreModuleStart638(int (* module_bootstart)(u32 argsize, void *argp), void *argp) -{ - /* get text_addr by substituting from module_bootstart address */ - u32 text_addr = ((u32)module_bootstart) - 0xBBC; - - /* assign our function pointers */ - DecryptExecutable = (void *)(text_addr + 0x7B08); - VerifySigncheck = (void *)(text_addr + 0x7AE8); - - /* patch the calls to the decryption */ - MAKE_CALL(text_addr + 0x5CA4, DecryptExecutablePatched); - - /* patch calls to the unsigncheck routines */ - MAKE_CALL(text_addr + 0x5CC8, VerifySigncheckPatched); - - /* call the loadcore bootstart */ - return module_bootstart(8, argp); -} - -int LoadCoreModuleStart660(int (* module_bootstart)(u32 argsize, void *argp), void *argp) -{ - /* get text_addr by substituting from module_bootstart address */ - u32 text_addr = ((u32)module_bootstart) - 0xAF8; - - /* assign our function pointers */ - DecryptExecutable = (void *)(text_addr + 0x783C); - VerifySigncheck = (void *)(text_addr + 0x7824); - - /* patch the calls to the decryption */ - MAKE_CALL(text_addr + 0x5970, DecryptExecutablePatched); - - /* patch calls to the unsigncheck routines */ - MAKE_CALL(text_addr + 0x5994, VerifySigncheckPatched); - - /* call the loadcore bootstart */ - return module_bootstart(8, argp); -} - - -int RebootEntryPatched(void *reboot_param, void *exec_param, u32 api, u32 initial_rnd) -{ - u32 model = _lw((u32)reboot_param + 44); - - if(model == 6 || model == 8) - { - model = 3; - } - - /* Copy the patch table */ - _sw(sizeof(g_patch_table)/sizeof(PatchTable), PATCH_TABLE_ADDR_START); - memcpy((void *)(PATCH_TABLE_ADDR_START + 4), g_patch_table, sizeof(g_patch_table)); - - /* check the devkit */ - if (g_devkit_version == FIRMWARE_VERSION_631) - { - /* lets fixup our executable */ - _sw(TAG_631, (u32)downgrade_ctrl + 0xD0); - _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); - - /* model specific patches */ - switch (model) - { - case 0: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608624; - sceBootLfatRead = (void *)0x88608798; - sceBootLfatClose = (void *)0x8860873C; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602764, sceBootLfatOpenPatched); - MAKE_CALL(0x886027D4, sceBootLfatReadPatched); - MAKE_CALL(0x88602800, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860588C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x88607348, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x8860389C); - _sw(0x24020001, 0x886038A0); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x8860275C); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x886027B0); - _sw(0x00000000, 0x886027C8); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607648); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605758); - MAKE_JUMP(0x88605760, LoadCoreModuleStart631); - - break; - } - - case 1: - case 2: - case 3: - case 4: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x886086F0; - sceBootLfatRead = (void *)0x88608864; - sceBootLfatClose = (void *)0x88608808; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602834, sceBootLfatOpenPatched); - MAKE_CALL(0x886028A4, sceBootLfatReadPatched); - MAKE_CALL(0x886028D0, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860595C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x88607438, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x8860396C); - _sw(0x24020001, 0x88603970); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x8860282C); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x88602880); - _sw(0x00000000, 0x88602898); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607714); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605828); - MAKE_JUMP(0x88605830, LoadCoreModuleStart631); - - break; - } - } - } - - /* check the devkit */ - else if (g_devkit_version == FIRMWARE_VERSION_635) - { - /* lets fixup our executable */ - _sw(TAG_635, (u32)downgrade_ctrl + 0xD0); - _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); - - /* model specific patches */ - switch (model) - { - case 0: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608624; - sceBootLfatRead = (void *)0x88608798; - sceBootLfatClose = (void *)0x8860873C; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602764, sceBootLfatOpenPatched); - MAKE_CALL(0x886027D4, sceBootLfatReadPatched); - MAKE_CALL(0x88602800, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860588C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x88607348, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x8860389C); - _sw(0x24020001, 0x886038A0); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x8860275C); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x886027B0); - _sw(0x00000000, 0x886027C8); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607648); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605758); - MAKE_JUMP(0x88605760, LoadCoreModuleStart635); - - break; - } - - case 1: - case 2: - case 3: - case 4: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x886086F0; - sceBootLfatRead = (void *)0x88608864; - sceBootLfatClose = (void *)0x88608808; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602834, sceBootLfatOpenPatched); - MAKE_CALL(0x886028A4, sceBootLfatReadPatched); - MAKE_CALL(0x886028D0, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860595C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x88607438, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x8860396C); - _sw(0x24020001, 0x88603970); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x8860282C); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x88602880); - _sw(0x00000000, 0x88602898); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607714); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605828); - MAKE_JUMP(0x88605830, LoadCoreModuleStart635); - break; - } - } - } - - /* check the devkit */ - else if (g_devkit_version == FIRMWARE_VERSION_638) - { - /* lets fixup our executable */ - _sw(TAG_638, (u32)downgrade_ctrl + 0xD0); - _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); - - /* model specific patches */ - switch (model) - { - case 0: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608250; - sceBootLfatRead = (void *)0x886083C4; - sceBootLfatClose = (void *)0x88608368; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602768, sceBootLfatOpenPatched); - MAKE_CALL(0x886027D8, sceBootLfatReadPatched); - MAKE_CALL(0x88602804, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860569C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x8860711C, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603848); - _sw(0x24020001, 0x8860384C); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x88602760); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x886027B4); - _sw(0x00000000, 0x886027CC); - - /* btcnf module hash check */ - _sw(0x00000000, 0x886073B4); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605588); - MAKE_JUMP(0x88605590, LoadCoreModuleStart638); - - break; - } - - case 1: - case 2: - case 3: - case 4: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608320; - sceBootLfatRead = (void *)0x88608494; - sceBootLfatClose = (void *)0x88608438; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602838, sceBootLfatOpenPatched); - MAKE_CALL(0x886028A8, sceBootLfatReadPatched); - MAKE_CALL(0x886028D4, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860576C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x886071EC, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603918); - _sw(0x24020001, 0x8860391C); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x88602830); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x88602884); - _sw(0x00000000, 0x8860289C); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607484); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605658); - MAKE_JUMP(0x88605660, LoadCoreModuleStart638); - break; - } - } - } - - else if (g_devkit_version == FIRMWARE_VERSION_639) - { - /* lets fixup our executable */ - _sw(TAG_638, (u32)downgrade_ctrl + 0xD0); - _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); - - /* model specific patches */ - switch (model) - { - case 0: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608250; - sceBootLfatRead = (void *)0x886083C4; - sceBootLfatClose = (void *)0x88608368; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602768, sceBootLfatOpenPatched); - MAKE_CALL(0x886027D8, sceBootLfatReadPatched); - MAKE_CALL(0x88602804, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860569C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x8860711C, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603848); - _sw(0x24020001, 0x8860384C); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x88602760); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x886027B4); - _sw(0x00000000, 0x886027CC); - - /* btcnf module hash check */ - _sw(0x00000000, 0x886073B4); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605588); - MAKE_JUMP(0x88605590, LoadCoreModuleStart638); - - break; - } - - case 1: - case 2: - case 3: - case 4: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x88608320; - sceBootLfatRead = (void *)0x88608494; - sceBootLfatClose = (void *)0x88608438; - - /* lets patch the IO drivers */ - MAKE_CALL(0x88602838, sceBootLfatOpenPatched); - MAKE_CALL(0x886028A8, sceBootLfatReadPatched); - MAKE_CALL(0x886028D4, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860576C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x886071EC, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603918); - _sw(0x24020001, 0x8860391C); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x88602830); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x88602884); - _sw(0x00000000, 0x8860289C); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607484); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605658); - MAKE_JUMP(0x88605660, LoadCoreModuleStart638); - break; - } - } - } - - else if (g_devkit_version == FIRMWARE_VERSION_660) - { - /* lets fixup our executable */ - _sw(TAG_660, (u32)downgrade660_ctrl + 0xD0); - _sw(MODULE_ID_TAG, (u32)downgrade660_ctrl + 0x130); - - /* model specific patches */ - switch (model) - { - case 0: - { - - /* link our function pointers */ - sceBootLfatOpen = (void *)0x8860822C; - sceBootLfatRead = (void *)0x886083A0; - sceBootLfatClose = (void *)0x88608344; - - /* lets patch the IO drivers */ - MAKE_CALL(0x886027C4, sceBootLfatOpenPatched); - MAKE_CALL(0x88602834, sceBootLfatReadPatched660); - MAKE_CALL(0x88602860, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860574C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x886070F8, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603880); - _sw(0x24020001, 0x88603884); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x886027BC); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x88602810); - _sw(0x00000000, 0x88602828); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607390); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x88605638); - MAKE_JUMP(0x88605640, LoadCoreModuleStart660); - - break; - } - - case 1: - case 2: - case 3: - case 4: - { - /* link our function pointers */ - sceBootLfatOpen = (void *)0x886082EC; - sceBootLfatRead = (void *)0x88608460; - sceBootLfatClose = (void *)0x88608404; - - /* lets patch the IO drivers */ - MAKE_CALL(0x8860288C, sceBootLfatOpenPatched); - MAKE_CALL(0x886028FC, sceBootLfatReadPatched660); - MAKE_CALL(0x88602928, sceBootLfatClosePatched); - - /* link our function pointers */ - sceKernelCheckPspConfig = (void *)0x8860580C; - - /* patch the pspbtcnf.bin decryption */ - MAKE_CALL(0x886071B8, sceKernelCheckPspConfigPatched); - - /* force removeByDebugSection success */ - _sw(0x03E00008, 0x88603948); - _sw(0x24020001, 0x8860394C); - - /* prevent sceBootLfatfsMount failing */ - _sw(0x00000000, 0x88602884); - - /* prevent this lseek failure */ - _sw(0x00000000, 0x886028D8); - _sw(0x00000000, 0x886028F0); - - /* btcnf module hash check */ - _sw(0x00000000, 0x88607450); - - /* patch loadcore.prx module_start */ - _sw(0x02202021, 0x886056F8); - MAKE_JUMP(0x88605700, LoadCoreModuleStart660); - break; - } - } - } - - /* Clear the caches */ - KClearCaches(); - - /* lets start the reboot process */ - return sceReboot(reboot_param, exec_param, api, initial_rnd); -} +/* + Downgrade Launcher -> rebootex.c -> Provide patches to the Sony reboot.bin to insert our downgrade controller + by Davee + + 28/12/2010 +*/ + +#include +#include + +#include +#include + +#include "utils.h" +#include "rebootex.h" +#include "patch_table.h" +#include "kernel_land.h" + +#include "downgrade_ctrl.h" +#include "downgrade660_ctrl.h" + +/* global variables */ +u32 g_module_seek = 0; +u32 g_module_opened = 0; +void *g_module = NULL; +u32 g_devkit_version = 0; + +/* function pointers */ +int (* sceBootLfatOpen)(char *path) = NULL; +int (* sceBootLfatRead)(void *data, int size) = NULL; +int (* sceBootLfatClose)(void) = NULL; + +u32 (* sceKernelCheckPspConfig)(void *btcnf_data, u32 size, int flag) = NULL; + +int (* DecryptExecutable)(void *buffer, int size, int *outsize) = NULL; +int (* VerifySigncheck)(void *buffer, int size) = NULL; + +/* The Sony Reboot */ +int (* sceReboot)(void *reboot_param, void *exec_param, int api, int initial_rnd) = (void *)0x88600000; + +int sceBootLfatOpenPatched(char *path) +{ + /* check the path for our virtual module */ + if (strcmp(path, "/chrono/strange.charm") == 0) + { + /* set seek to 0 and set to opened and return success */ + g_module_seek = 0; + g_module_opened = 1; + + return 0; + } + + /* return original function */ + return sceBootLfatOpen(path); +} + +int sceBootLfatReadPatched(void *data, int size) +{ + /* check if the module is virtually opened */ + if (g_module_opened) + { + /* get the remaining size */ + u32 remain = size_downgrade_ctrl - g_module_seek; + + /* now do some math to calculate how much we will copy (as read is done in 32KiB chunks) */ + remain = (remain < (32 << 10)) ? (remain) : (32 << 10); + + /* copy over data */ + memcpy(data, downgrade_ctrl + g_module_seek, remain); + + /* increment the seek */ + g_module_seek += remain; + + /* returned copied size */ + return remain; + } + + /* return the read data */ + return sceBootLfatRead(data, size); +} + +int sceBootLfatReadPatched660(void *data, int size) +{ + /* check if the module is virtually opened */ + if (g_module_opened) + { + /* get the remaining size */ + u32 remain = size_downgrade660_ctrl - g_module_seek; + + /* now do some math to calculate how much we will copy (as read is done in 32KiB chunks) */ + remain = (remain < (32 << 10)) ? (remain) : (32 << 10); + + /* copy over data */ + memcpy(data, downgrade660_ctrl + g_module_seek, remain); + + /* increment the seek */ + g_module_seek += remain; + + /* returned copied size */ + return remain; + } + + /* return the read data */ + return sceBootLfatRead(data, size); +} + +int sceBootLfatClosePatched(void) +{ + /* check if the module is virtually opened */ + if (g_module_opened) + { + /* it is, interally close and return success */ + g_module_opened = 0; + return 0; + } + + /* return the original */ + return sceBootLfatClose(); +} + +/* BTCNF INJECION CODE BY BUBBLETUNE (bubbletune.x-fusion.co.uk) */ +int InsertModuleBtcnf(char *new_mod, char *before_mod, BtcnfHeader *header, int *size, u16 flags) +{ + /* cast and declare our local variables */ + int i, j; + ModeEntry *modes = (ModeEntry *)((u32)header + header->modestart); + ModuleEntry *modules = (ModuleEntry *)((u32)header + header->modulestart); + char *names = (char *)((u32)header + header->modnamestart); + int len = strlen(new_mod) + 1; + + /* loop through the modules */ + for (i = 0; i < header->nmodules; i++) + { + /* if we find the module we want to insert before */ + if (memcmp(names + modules[i].stroffset, before_mod, strlen(before_mod) + 1) == 0) + { + /* found it! lets move the the whole section so we can fit another entry*/ + memmove(modules + i + 1, modules + i, (*size)-header->modulestart-(i*sizeof(ModuleEntry))); + + /* update all the header variables */ + header->modnamestart += sizeof(ModuleEntry); + header->modnameend += sizeof(ModuleEntry); + *size += sizeof(ModuleEntry); + header->nmodules++; + + /* add the new information */ + modules[i].stroffset = header->modnameend-header->modnamestart; + modules[i].flags = flags; + + /* copy the string over :P */ + memcpy((char *)header + header->modnameend, new_mod, len); + + /* update the new size and the header modname end */ + *size += len; + header->modnameend += len; + + /* change the modes */ + for (j = 0; j < header->nmodes; j++) + { + modes[j].searchstart = 0; + modes[j].maxsearch++; + } + + /* return success */ + return 0; + } + } + + /* return fail */ + return -1; +} + +u32 sceKernelCheckPspConfigPatched(void *btcnf_data, u32 size, int flag) +{ + /* cast our variables and declare */ + BtcnfHeader *header = (BtcnfHeader *)btcnf_data; + + /* decrypt the btcnf so we have the decrypted version */ + int nsize = sceKernelCheckPspConfig(btcnf_data, size, flag); + + /* check the signature is valid */ + if (header->signature == 0x0F803001) + { + /* insert the module path into the config */ + InsertModuleBtcnf("/chrono/strange.charm", "/kd/init.prx", btcnf_data, &nsize, (BOOTLOAD_VSH | BOOTLOAD_GAME | BOOTLOAD_POPS | BOOTLOAD_UPDATER | BOOTLOAD_UMDEMU | BOOTLOAD_MLNAPP)); + } + + /* return the new size */ + return nsize; +} + +int DecryptExecutablePatched(void *header, int size, int *outsize) +{ + /* check for decryption tag */ + if (_lw((u32)header + 0x130) == 0x626F6F42) + { + *outsize = _lw((u32)header + 0xB0); + memmove(header, header + 0x150, *outsize); + return 0; + } + + /* return the real decryption code */ + return DecryptExecutable(header, size, outsize); +} + +int VerifySigncheckPatched(void *buffer, int size) +{ + int i; + /* loop through the signcheck */ + for (i = 0; i < 0x58; i++) + { + /* if byte is 0 then call the signcheck removal */ + if (((u8 *)buffer)[0xD4 + i]) + { + /* remove signcheck */ + return VerifySigncheck(buffer, size); + } + } + + /* return success :D */ + return 0; +} + +int LoadCoreModuleStart631(int (* module_bootstart)(u32 argsize, void *argp), void *argp) +{ + /* get text_addr by substituting from module_bootstart address */ + u32 text_addr = ((u32)module_bootstart) - 0xBC4; + + /* assign our function pointers */ + DecryptExecutable = (void *)(text_addr + 0x8398); + VerifySigncheck = (void *)(text_addr + 0x8378); + + /* patch the calls to the decryption */ + MAKE_CALL(text_addr + 0x6930, DecryptExecutablePatched); + + /* patch calls to the unsigncheck routines */ + MAKE_CALL(text_addr + 0x6954, VerifySigncheckPatched); + + KClearCaches(); + + /* call the loadcore bootstart */ + return module_bootstart(8, argp); +} + +int LoadCoreModuleStart635(int (* module_bootstart)(u32 argsize, void *argp), void *argp) +{ + /* get text_addr by substituting from module_bootstart address */ + u32 text_addr = ((u32)module_bootstart) - 0xBBC; + + /* assign our function pointers */ + DecryptExecutable = (void *)(text_addr + 0x7B08); + VerifySigncheck = (void *)(text_addr + 0x7AE8); + + /* patch the calls to the decryption */ + MAKE_CALL(text_addr + 0x5CA4, DecryptExecutablePatched); + + /* patch calls to the unsigncheck routines */ + MAKE_CALL(text_addr + 0x5CC8, VerifySigncheckPatched); + + KClearCaches(); + + /* call the loadcore bootstart */ + return module_bootstart(8, argp); +} + +int LoadCoreModuleStart638(int (* module_bootstart)(u32 argsize, void *argp), void *argp) +{ + /* get text_addr by substituting from module_bootstart address */ + u32 text_addr = ((u32)module_bootstart) - 0xBBC; + + /* assign our function pointers */ + DecryptExecutable = (void *)(text_addr + 0x7B08); + VerifySigncheck = (void *)(text_addr + 0x7AE8); + + /* patch the calls to the decryption */ + MAKE_CALL(text_addr + 0x5CA4, DecryptExecutablePatched); + + /* patch calls to the unsigncheck routines */ + MAKE_CALL(text_addr + 0x5CC8, VerifySigncheckPatched); + + KClearCaches(); + + /* call the loadcore bootstart */ + return module_bootstart(8, argp); +} + +int LoadCoreModuleStart660(int (* module_bootstart)(u32 argsize, void *argp), void *argp) +{ + /* get text_addr by substituting from module_bootstart address */ + u32 text_addr = ((u32)module_bootstart) - 0xAF8; + + /* assign our function pointers */ + DecryptExecutable = (void *)(text_addr + 0x783C); + VerifySigncheck = (void *)(text_addr + 0x7824); + + /* patch the calls to the decryption */ + MAKE_CALL(text_addr + 0x5970, DecryptExecutablePatched); + + /* patch calls to the unsigncheck routines */ + MAKE_CALL(text_addr + 0x5994, VerifySigncheckPatched); + + KClearCaches(); + /* call the loadcore bootstart */ + return module_bootstart(8, argp); +} + + +int RebootEntryPatched(void *reboot_param, void *exec_param, u32 api, u32 initial_rnd) +{ + u32 model = _lw((u32)reboot_param + 44); + + if(model == 6 || model == 8) + { + model = 3; + } + + /* Copy the patch table */ + _sw(sizeof(g_patch_table)/sizeof(PatchTable), PATCH_TABLE_ADDR_START); + memcpy((void *)(PATCH_TABLE_ADDR_START + 4), g_patch_table, sizeof(g_patch_table)); + + /* check the devkit */ + if (g_devkit_version == FIRMWARE_VERSION_631) + { + /* lets fixup our executable */ + _sw(TAG_631, (u32)downgrade_ctrl + 0xD0); + _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); + + /* model specific patches */ + switch (model) + { + case 0: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608624; + sceBootLfatRead = (void *)0x88608798; + sceBootLfatClose = (void *)0x8860873C; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602764, sceBootLfatOpenPatched); + MAKE_CALL(0x886027D4, sceBootLfatReadPatched); + MAKE_CALL(0x88602800, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860588C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x88607348, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x8860389C); + _sw(0x24020001, 0x886038A0); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x8860275C); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x886027B0); + _sw(0x00000000, 0x886027C8); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607648); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605758); + MAKE_JUMP(0x88605760, LoadCoreModuleStart631); + + break; + } + + case 1: + case 2: + case 3: + case 4: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x886086F0; + sceBootLfatRead = (void *)0x88608864; + sceBootLfatClose = (void *)0x88608808; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602834, sceBootLfatOpenPatched); + MAKE_CALL(0x886028A4, sceBootLfatReadPatched); + MAKE_CALL(0x886028D0, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860595C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x88607438, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x8860396C); + _sw(0x24020001, 0x88603970); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x8860282C); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x88602880); + _sw(0x00000000, 0x88602898); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607714); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605828); + MAKE_JUMP(0x88605830, LoadCoreModuleStart631); + + break; + } + } + } + + /* check the devkit */ + else if (g_devkit_version == FIRMWARE_VERSION_635) + { + /* lets fixup our executable */ + _sw(TAG_635, (u32)downgrade_ctrl + 0xD0); + _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); + + /* model specific patches */ + switch (model) + { + case 0: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608624; + sceBootLfatRead = (void *)0x88608798; + sceBootLfatClose = (void *)0x8860873C; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602764, sceBootLfatOpenPatched); + MAKE_CALL(0x886027D4, sceBootLfatReadPatched); + MAKE_CALL(0x88602800, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860588C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x88607348, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x8860389C); + _sw(0x24020001, 0x886038A0); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x8860275C); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x886027B0); + _sw(0x00000000, 0x886027C8); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607648); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605758); + MAKE_JUMP(0x88605760, LoadCoreModuleStart635); + + break; + } + + case 1: + case 2: + case 3: + case 4: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x886086F0; + sceBootLfatRead = (void *)0x88608864; + sceBootLfatClose = (void *)0x88608808; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602834, sceBootLfatOpenPatched); + MAKE_CALL(0x886028A4, sceBootLfatReadPatched); + MAKE_CALL(0x886028D0, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860595C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x88607438, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x8860396C); + _sw(0x24020001, 0x88603970); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x8860282C); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x88602880); + _sw(0x00000000, 0x88602898); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607714); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605828); + MAKE_JUMP(0x88605830, LoadCoreModuleStart635); + break; + } + } + } + + /* check the devkit */ + else if (g_devkit_version == FIRMWARE_VERSION_638) + { + /* lets fixup our executable */ + _sw(TAG_638, (u32)downgrade_ctrl + 0xD0); + _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); + + /* model specific patches */ + switch (model) + { + case 0: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608250; + sceBootLfatRead = (void *)0x886083C4; + sceBootLfatClose = (void *)0x88608368; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602768, sceBootLfatOpenPatched); + MAKE_CALL(0x886027D8, sceBootLfatReadPatched); + MAKE_CALL(0x88602804, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860569C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x8860711C, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603848); + _sw(0x24020001, 0x8860384C); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x88602760); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x886027B4); + _sw(0x00000000, 0x886027CC); + + /* btcnf module hash check */ + _sw(0x00000000, 0x886073B4); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605588); + MAKE_JUMP(0x88605590, LoadCoreModuleStart638); + + break; + } + + case 1: + case 2: + case 3: + case 4: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608320; + sceBootLfatRead = (void *)0x88608494; + sceBootLfatClose = (void *)0x88608438; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602838, sceBootLfatOpenPatched); + MAKE_CALL(0x886028A8, sceBootLfatReadPatched); + MAKE_CALL(0x886028D4, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860576C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x886071EC, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603918); + _sw(0x24020001, 0x8860391C); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x88602830); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x88602884); + _sw(0x00000000, 0x8860289C); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607484); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605658); + MAKE_JUMP(0x88605660, LoadCoreModuleStart638); + break; + } + } + } + + else if (g_devkit_version == FIRMWARE_VERSION_639) + { + /* lets fixup our executable */ + _sw(TAG_638, (u32)downgrade_ctrl + 0xD0); + _sw(MODULE_ID_TAG, (u32)downgrade_ctrl + 0x130); + + /* model specific patches */ + switch (model) + { + case 0: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608250; + sceBootLfatRead = (void *)0x886083C4; + sceBootLfatClose = (void *)0x88608368; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602768, sceBootLfatOpenPatched); + MAKE_CALL(0x886027D8, sceBootLfatReadPatched); + MAKE_CALL(0x88602804, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860569C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x8860711C, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603848); + _sw(0x24020001, 0x8860384C); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x88602760); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x886027B4); + _sw(0x00000000, 0x886027CC); + + /* btcnf module hash check */ + _sw(0x00000000, 0x886073B4); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605588); + MAKE_JUMP(0x88605590, LoadCoreModuleStart638); + + break; + } + + case 1: + case 2: + case 3: + case 4: + { + /* link our function pointers */ + sceBootLfatOpen = (void *)0x88608320; + sceBootLfatRead = (void *)0x88608494; + sceBootLfatClose = (void *)0x88608438; + + /* lets patch the IO drivers */ + MAKE_CALL(0x88602838, sceBootLfatOpenPatched); + MAKE_CALL(0x886028A8, sceBootLfatReadPatched); + MAKE_CALL(0x886028D4, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860576C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x886071EC, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603918); + _sw(0x24020001, 0x8860391C); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x88602830); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x88602884); + _sw(0x00000000, 0x8860289C); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607484); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605658); + MAKE_JUMP(0x88605660, LoadCoreModuleStart638); + break; + } + } + } + + else if ((g_devkit_version == FIRMWARE_VERSION_660) || (g_devkit_version == FIRMWARE_VERSION_661)) + { + /* lets fixup our executable */ + _sw(TAG_660, (u32)downgrade660_ctrl + 0xD0); + _sw(MODULE_ID_TAG, (u32)downgrade660_ctrl + 0x130); + + /* model specific patches */ + switch (model) + { + case 0: + { + + /* link our function pointers */ + if (g_devkit_version == FIRMWARE_VERSION_660) { + sceBootLfatOpen = (void *)0x8860822C; + sceBootLfatRead = (void *)0x886083A0; + sceBootLfatClose = (void *)0x88608344; + } else if (g_devkit_version == FIRMWARE_VERSION_661) { + sceBootLfatOpen = (void *)0x8860B6C0; + sceBootLfatRead = (void *)0x8860AD58; + sceBootLfatClose = (void *)0x88609C78; + } + + /* lets patch the IO drivers */ + MAKE_CALL(0x886027C4, sceBootLfatOpenPatched); + MAKE_CALL(0x88602834, sceBootLfatReadPatched660); + MAKE_CALL(0x88602860, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860574C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x886070F8, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603880); + _sw(0x24020001, 0x88603884); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x886027BC); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x88602810); + _sw(0x00000000, 0x88602828); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607390); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x88605638); + MAKE_JUMP(0x88605640, LoadCoreModuleStart660); + + break; + } + + case 1: + case 2: + case 3: + case 4: + case 10: + { + /* link our function pointers */ + if (g_devkit_version == FIRMWARE_VERSION_660) { + sceBootLfatOpen = (void *)0x886082EC; + sceBootLfatRead = (void *)0x88608460; + sceBootLfatClose = (void *)0x88608404; + } else if (g_devkit_version == FIRMWARE_VERSION_661) { + sceBootLfatOpen = (void *)0x8860B780; + sceBootLfatRead = (void *)0x8860AE18; + sceBootLfatClose = (void *)0x88609D38; + } + + /* lets patch the IO drivers */ + MAKE_CALL(0x8860288C, sceBootLfatOpenPatched); + MAKE_CALL(0x886028FC, sceBootLfatReadPatched660); + MAKE_CALL(0x88602928, sceBootLfatClosePatched); + + /* link our function pointers */ + sceKernelCheckPspConfig = (void *)0x8860580C; + + /* patch the pspbtcnf.bin decryption */ + MAKE_CALL(0x886071B8, sceKernelCheckPspConfigPatched); + + /* force removeByDebugSection success */ + _sw(0x03E00008, 0x88603948); + _sw(0x24020001, 0x8860394C); + + /* prevent sceBootLfatfsMount failing */ + _sw(0x00000000, 0x88602884); + + /* prevent this lseek failure */ + _sw(0x00000000, 0x886028D8); + _sw(0x00000000, 0x886028F0); + + /* btcnf module hash check */ + _sw(0x00000000, 0x88607450); + + /* patch loadcore.prx module_start */ + _sw(0x02202021, 0x886056F8); + MAKE_JUMP(0x88605700, LoadCoreModuleStart660); + break; + } + } + } + + /* Clear the caches */ + KClearCaches(); + + /* lets start the reboot process */ + return sceReboot(reboot_param, exec_param, api, initial_rnd); +} diff --git a/src/rebootex.h b/src/rebootex.h index 8edaf5c..6816553 100644 --- a/src/rebootex.h +++ b/src/rebootex.h @@ -1,70 +1,59 @@ -/* - Downgrade Launcher -> rebootex.h -> Provide API documentation and definitions for the reboot patching processes - by Davee - - 28/12/2010 -*/ -#ifndef __REBOOTEX_H__ -#define __REBOOTEX_H__ - -#define TAG_631 (0x4C9484F0) -#define TAG_635 (0x4C9484F0) -#define TAG_638 (0x4C948AF0) -#define TAG_639 (0x4C948AF0) -#define TAG_660 (0x4C9494F0) -#define MODULE_ID_TAG (0x626F6F42) - -/* variables */ -extern u32 g_devkit_version; - -/* Functions */ -int RebootEntryPatched(void *reboot_param, void *exec_param, u32 api, u32 initial_rnd); - -typedef struct BtcnfHeader -{ - u32 signature; // 0 - u32 devkit; // 4 - u32 unknown[2]; // 8 - u32 modestart; // 0x10 - int nmodes; // 0x14 - u32 unknown2[2]; // 0x18 - u32 modulestart; // 0x20 - int nmodules; // 0x24 - u32 unknown3[2]; // 0x28 - u32 modnamestart; // 0x30 - u32 modnameend; // 0x34 - u32 unknown4[2]; // 0x38 -} __attribute__((packed)) BtcnfHeader; - -typedef struct ModeEntry -{ - u16 maxsearch; - u16 searchstart; // - int mode1; - int mode2; - int reserved[5]; -} __attribute__((packed)) ModeEntry; - -typedef struct ModuleEntry -{ - u32 stroffset; // 0 - int reserved; // 4 - u16 flags; // 8 - u8 loadmode; // 10 - u8 signcheck; // 11 - int reserved2; // 12 - u8 hash[0x10]; // 16 -} __attribute__((packed)) ModuleEntry; // 32 - -enum BootLoadFlags -{ - BOOTLOAD_VSH = 1, - BOOTLOAD_GAME = 2, - BOOTLOAD_UPDATER = 4, - BOOTLOAD_POPS = 8, - BOOTLOAD_UNK = 32, - BOOTLOAD_UMDEMU = 64, /* for original NP9660 */ - BOOTLOAD_MLNAPP = 128, -}; - -#endif /* __REBOOTEX_H__ */ +/* + Downgrade Launcher -> rebootex.h -> Provide API documentation and definitions for the reboot patching processes + by Davee + + 28/12/2010 +*/ +#ifndef __REBOOTEX_H__ +#define __REBOOTEX_H__ + +#define TAG_631 (0x4C9484F0) +#define TAG_635 (0x4C9484F0) +#define TAG_638 (0x4C948AF0) +#define TAG_639 (0x4C948AF0) +#define TAG_660 (0x4C9494F0) +#define MODULE_ID_TAG (0x626F6F42) + +/* variables */ +extern u32 g_devkit_version; + +/* Functions */ +int RebootEntryPatched(void *reboot_param, void *exec_param, u32 api, u32 initial_rnd); + +typedef struct BtcnfHeader +{ + u32 signature; // 0 + u32 devkit; // 4 + u32 unknown[2]; // 8 + u32 modestart; // 0x10 + int nmodes; // 0x14 + u32 unknown2[2]; // 0x18 + u32 modulestart; // 0x20 + int nmodules; // 0x24 + u32 unknown3[2]; // 0x28 + u32 modnamestart; // 0x30 + u32 modnameend; // 0x34 + u32 unknown4[2]; // 0x38 +} __attribute__((packed)) BtcnfHeader; + +typedef struct ModeEntry +{ + u16 maxsearch; + u16 searchstart; // + int mode1; + int mode2; + int reserved[5]; +} __attribute__((packed)) ModeEntry; + +typedef struct ModuleEntry +{ + u32 stroffset; // 0 + int reserved; // 4 + u16 flags; // 8 + u8 loadmode; // 10 + u8 signcheck; // 11 + int reserved2; // 12 + u8 hash[0x10]; // 16 +} __attribute__((packed)) ModuleEntry; // 32 + +#endif /* __REBOOTEX_H__ */ diff --git a/src/utils.c b/src/utils.c index 753f26f..6d4e42d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,118 +1,120 @@ -/* - Downgrade Launcher -> utils.c -> Responsible for providing common utilities - by Davee - - 28/12/2010 -*/ - -#include -#include - -#include -#include -#include - -#include "utils.h" -#include "kernel_land.h" - -int isValidUserAddress(void *addr) -{ - return ((u32)((u32)addr - 0x08800000) < (24 << 20)) ? (1) : (0); -} - -void KClearCaches(void) -{ - /* Clear the Icache */ - asm("\ - .word 0x40088000; .word 0x24091000; .word 0x7D081240;\ - .word 0x01094804; .word 0x4080E000; .word 0x4080E800;\ - .word 0x00004021; .word 0xBD010000; .word 0xBD030000;\ - .word 0x25080040; .word 0x1509FFFC; .word 0x00000000;\ - "::); - - /* Clear the dcache */ - asm("\ - .word 0x40088000; .word 0x24090800; .word 0x7D081180;\ - .word 0x01094804; .word 0x00004021; .word 0xBD140000;\ - .word 0xBD140000; .word 0x25080040; .word 0x1509FFFC;\ - .word 0x00000000; .word 0x0000000F; .word 0x00000000;\ - "::); -} - -void ClearCaches(void) -{ - sceKernelDcacheWritebackInvalidateAll(); - sceKernelIcacheInvalidateAll(); -} - -u32 FindProc(char *modname, char *lib, u32 nid) -{ - /* declare our local vars */ - int i = 0, u; - - /* find the module */ - SceModule *mod = pspKernelFindModuleByName(modname); - - /* if no mod, error */ - if (mod == NULL) - { - return 0; - } - - /* get the entry info */ - u32 entry_size = mod->ent_size; - u32 entry_start = (u32)mod->ent_top; - - /* scan through the export list */ - while (i < entry_size) - { - /* point to the entry */ - SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); - - /* if there is a libname, check if it's the libname we want */ - if (entry->libname && (strcmp((char *)entry->libname, lib) == 0)) - { - /* now lets scan through the stubs for our nid */ - u32 *table = entry->entrytable; - int total = entry->stubcount + entry->vstubcount; - - /* if there is nids, lets continue */ - if (total > 0) - { - /* scan through the nidtable */ - for (u = 0; u < total; u++) - { - /* check if its the nid we're looking for */ - if (table[u] == nid) - { - /* our nid, let return the address */ - return table[u + total]; - } - } - } - } - - /* update entry counter */ - i += (entry->len << 2); - } - - /* lib not found ): */ - return 0; -} - -void ErrorExit(int millisecs, char *fmt, ...) -{ - va_list list; - char msg[256]; - - /* collate args into string */ - va_start(list, fmt); - vsprintf(msg, fmt, list); - va_end(list); - - /* print string */ - printf(msg); - - sceKernelDelayThread(millisecs*1000); - sceKernelExitGame(); -} +/* + Downgrade Launcher -> utils.c -> Responsible for providing common utilities + by Davee + + 28/12/2010 +*/ + +#include +#include + +#include +#include +#include + +#include "utils.h" +#include "kernel_land.h" + +void sceKernelIcacheInvalidateAll(void); + +int isValidUserAddress(void *addr) +{ + return ((u32)((u32)addr - 0x08800000) < (24 << 20)) ? (1) : (0); +} + +void KClearCaches(void) +{ + /* Clear the Icache */ + asm("\ + .word 0x40088000; .word 0x24091000; .word 0x7D081240;\ + .word 0x01094804; .word 0x4080E000; .word 0x4080E800;\ + .word 0x00004021; .word 0xBD010000; .word 0xBD030000;\ + .word 0x25080040; .word 0x1509FFFC; .word 0x00000000;\ + "::); + + /* Clear the dcache */ + asm("\ + .word 0x40088000; .word 0x24090800; .word 0x7D081180;\ + .word 0x01094804; .word 0x00004021; .word 0xBD140000;\ + .word 0xBD140000; .word 0x25080040; .word 0x1509FFFC;\ + .word 0x00000000; .word 0x0000000F; .word 0x00000000;\ + "::); +} + +void ClearCaches(void) +{ + sceKernelDcacheWritebackInvalidateAll(); + sceKernelIcacheInvalidateAll(); +} + +u32 FindProc(char *modname, char *lib, u32 nid) +{ + /* declare our local vars */ + int i = 0, u; + + /* find the module */ + SceModule2 *mod = pspKernelFindModuleByName(modname); + + /* if no mod, error */ + if (mod == NULL) + { + return 0; + } + + /* get the entry info */ + u32 entry_size = mod->ent_size; + u32 entry_start = (u32)mod->ent_top; + + /* scan through the export list */ + while (i < entry_size) + { + /* point to the entry */ + SceLibraryEntryTable *entry = (SceLibraryEntryTable *)(entry_start + i); + + /* if there is a libname, check if it's the libname we want */ + if (entry->libname && (strcmp((char *)entry->libname, lib) == 0)) + { + /* now lets scan through the stubs for our nid */ + u32 *table = entry->entrytable; + int total = entry->stubcount + entry->vstubcount; + + /* if there is nids, lets continue */ + if (total > 0) + { + /* scan through the nidtable */ + for (u = 0; u < total; u++) + { + /* check if its the nid we're looking for */ + if (table[u] == nid) + { + /* our nid, let return the address */ + return table[u + total]; + } + } + } + } + + /* update entry counter */ + i += (entry->len << 2); + } + + /* lib not found ): */ + return 0; +} + +void ErrorExit(int millisecs, char *fmt, ...) +{ + va_list list; + char msg[256]; + + /* collate args into string */ + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + /* print string */ + printf(msg); + + sceKernelDelayThread(millisecs*1000); + sceKernelExitGame(); +} diff --git a/src/utils.h b/src/utils.h index b5b46d7..c0d4eeb 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,66 +1,67 @@ -/* - Downgrade Launcher -> utils.h -> Provide documentation for standard proceedures - by Davee - - 28/12/2010 -*/ -#ifndef __UTILS__H__ -#define __UTILS__H__ - -#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) -#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } -#define MAKE_RELATIVE_BRANCH(a, f, t) _sw((0x10000000 | ((((f - a) >> 2) - 1) & 0xFFFF)), a + t) - -#define FIRMWARE_VERSION_631 (0x06030110) -#define FIRMWARE_VERSION_635 (0x06030510) -#define FIRMWARE_VERSION_638 (0x06030810) -#define FIRMWARE_VERSION_639 (0x06030910) -#define FIRMWARE_VERSION_660 (0x06060010) - -#define PSPGO_UPDATER_PATH "ef0:/PSP/GAME/UPDATE/EBOOT.PBP" -#define OTHER_UPDATER_PATH "ms0:/PSP/GAME/UPDATE/EBOOT.PBP" - -#define printf pspDebugScreenPrintf - -/** - Clears both the instruction and data caches USER MODE ONLY -*/ -void ClearCaches(void); - -/** - Clears both the instruction and data caches KERNEL MODE ONLY -*/ -void KClearCaches(void); - -/** - checks whether or not a pointer is a valid pointer into userspace - - @param addr: the pointer to check - @return 1 on valid else 0 on invalid -*/ -int isValidUserAddress(void *addr); - -/** - Find an export within the system - - @param modname: the name of the module containing the export - @param libname: the library the export belongs to - @param nid: the nid of the export - - @return the address of export else 0 on error -*/ -u32 FindProc(char *modname, char *lib, u32 nid); - -/** - Display an error and exit game - - @param millisecs: the amount of time to delay before exiting (in milliseconds) - @param fmt: a formattable string with args to follow -*/ -void ErrorExit(int millisecs, char *fmt, ...); - -/* internal prototypes */ -void clearIcache(void); - -#endif /* __UTILS__H__ */ +/* + Downgrade Launcher -> utils.h -> Provide documentation for standard proceedures + by Davee + + 28/12/2010 +*/ +#ifndef __UTILS__H__ +#define __UTILS__H__ + +#define MAKE_JUMP(a, f) _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define MAKE_CALL(a, f) _sw(0x0C000000 | (((u32)(f) >> 2) & 0x03ffffff), a) +#define REDIRECT_FUNCTION(a, f) { u32 address = a; _sw(0x08000000 | (((u32)(f) >> 2) & 0x03ffffff), address); _sw(0, address+4); } +#define MAKE_RELATIVE_BRANCH(a, f, t) _sw((0x10000000 | ((((f - a) >> 2) - 1) & 0xFFFF)), a + t) + +#define FIRMWARE_VERSION_631 (0x06030110) +#define FIRMWARE_VERSION_635 (0x06030510) +#define FIRMWARE_VERSION_638 (0x06030810) +#define FIRMWARE_VERSION_639 (0x06030910) +#define FIRMWARE_VERSION_660 (0x06060010) +#define FIRMWARE_VERSION_661 (0x06060110) + +#define PSPGO_UPDATER_PATH "ef0:/PSP/GAME/UPDATE/EBOOT.PBP" +#define OTHER_UPDATER_PATH "ms0:/PSP/GAME/UPDATE/EBOOT.PBP" + +#define printf pspDebugScreenPrintf + +/** + Clears both the instruction and data caches USER MODE ONLY +*/ +void ClearCaches(void); + +/** + Clears both the instruction and data caches KERNEL MODE ONLY +*/ +void KClearCaches(void); + +/** + checks whether or not a pointer is a valid pointer into userspace + + @param addr: the pointer to check + @return 1 on valid else 0 on invalid +*/ +int isValidUserAddress(void *addr); + +/** + Find an export within the system + + @param modname: the name of the module containing the export + @param libname: the library the export belongs to + @param nid: the nid of the export + + @return the address of export else 0 on error +*/ +u32 FindProc(char *modname, char *lib, u32 nid); + +/** + Display an error and exit game + + @param millisecs: the amount of time to delay before exiting (in milliseconds) + @param fmt: a formattable string with args to follow +*/ +void ErrorExit(int millisecs, char *fmt, ...); + +/* internal prototypes */ +void clearIcache(void); + +#endif /* __UTILS__H__ */