diff --git a/README.md b/README.md index a6e17a5..598aad2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,30 @@ +# Repo moved to [ChronoSwitch](https://github.com/PSP-Archive/Chronoswitch) + + # Chronoswitch Downgrader Chronoswitch is a downgrader for the Playstation Portable (PSP). ## Installation Download and extract the latest version from the releases on this github page. Copy the `PSP` folder from the extracted output to your memory stick. You will need the firmware update for version you wish to downgrade to. If you want to downgrade to 6.60, you will need the 6.60 official update. If you're downgrading a PSPgo, make sure you download the official firmware appropriate for that device. -Copy the official firmware update to `PSP/GAME/UPDATE/EBOOT.PBP` on your memory stick. If you're using a PSPgo, make sure this copied to the internal storage instead. +Copy the official firmware update to `PSP/GAME/UPDATE/EBOOT.PBP` on your memory stick. If you're using a PSPgo, you can use internal storage or the memory stick for the official firmware EBOOT The downgrader is "signed", and can be launched without having a custom firmware installed. Once you run the application, follow the on-screen instructions. ## Changelog +### Version 7.6.1 +* Added more print statements for less common issues with parsing EBOOT.PBP or the buffer +### Version 7.6 +* Changed Default color, makes it a bit easier to read. +* Detect which OFW you have to make sure your flashing the proper model OFW. ( i.e You can only flash GO OFW on GO and vice versa ) +### Version 7.5 +* Updated Tools to encrypt EBOOT to be OS agnostic ( from Yoti's psp_pspident ) +* Bugfix: GO had issue running with just Infinity/OFW running. +### Version 7.4 +* PSP GO cleanup +* Detect if EBOOT.PBP is missing from `PSP/GAME/UPDATE/` +### Version 7.3 +* PSP GO can boot from ms0/ef0 ### Version 7.2 * Replaced 'factory firmware limitation', which prevented certain PSPs from being downgradable at all or limited them from being downgraded to certain firmwares they theoretically support. * This fixes most cases where an IDXFFFFFFFF or CAAFFFFFCF7 error could appear. diff --git a/src/Makefile.signed b/src/Makefile.signed index 6cc1a89..f2e702a 100644 --- a/src/Makefile.signed +++ b/src/Makefile.signed @@ -1,25 +1,33 @@ +UNAME := $(shell uname) 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 +ifeq ($(UNAME), Linux) + bin/psptools/pack_ms_game.py --vanity "$(PSP_EBOOT_TITLE)" EBOOT.PBP EBOOT.PBP +else + bin\\psptools\\pack_ms_game.py --vanity "$(PSP_EBOOT_TITLE)" EBOOT.PBP EBOOT.PBP +endif + unpack-pbp EBOOT.PBP + 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 + @mkdir -p PSP/GAME/ChronoSwitch + @cp EBOOT.PBP PSP/GAME/ChronoSwitch/ 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 +INCDIR = include CFLAGS = -Os -G0 -Wall CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti ASFLAGS = $(CFLAGS) -c -LIBDIR = ../lib +LIBDIR = lib LIBS = -lpsppower PSP_FW_VERSION = 271 EXTRA_TARGETS = EBOOT.PBP -PSP_EBOOT_TITLE = Chronoswitch Downgrader v7.2 +PSP_EBOOT_TITLE = Chronoswitch Downgrader v7.6.1 BUILD_PRX = 1 diff --git a/src/bin/prxEncrypter.exe b/src/bin/prxEncrypter.exe deleted file mode 100644 index 3428331..0000000 Binary files a/src/bin/prxEncrypter.exe and /dev/null differ diff --git a/src/bin/psptools/pack_btcnf.py b/src/bin/psptools/pack_btcnf.py new file mode 100755 index 0000000..c696ce1 --- /dev/null +++ b/src/bin/psptools/pack_btcnf.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import argparse + +from psptool.pack import pack_btcnf +from psptool.prx import encrypt + +parser = argparse.ArgumentParser(description="Infinity Boot Config Packer") +parser.add_argument('input', type=argparse.FileType('rb'), + help='The raw text file to pack') +parser.add_argument('--vanity', type=str, + help='Some vanity text in the executable header') +parser.add_argument('output', type=str, + help='The output to write the packed text') +args = parser.parse_args() + +executable = args.input.read() +executable = encrypt(pack_btcnf(executable, + psptag=0x00000000), vanity=args.vanity) + +with open(args.output, 'wb') as f: + f.write(executable) diff --git a/src/bin/psptools/pack_kernel_module.py b/src/bin/psptools/pack_kernel_module.py new file mode 100755 index 0000000..39c1f87 --- /dev/null +++ b/src/bin/psptools/pack_kernel_module.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import argparse + +from psptool.pack import pack_prx +from psptool.prx import encrypt + +parser = argparse.ArgumentParser(description="Infinity Kernel Module Packer") +parser.add_argument('input', type=argparse.FileType('rb'), + help='The raw kernel PRX to pack') +parser.add_argument('--vanity', type=str, + help='Some vanity text in the executable header') +parser.add_argument('output', type=str, + help='The output to write the packed PRX') +args = parser.parse_args() + +executable = args.input.read() +executable = encrypt(pack_prx(executable, is_pbp=False, + psptag=lambda x: 0x00000000), vanity=args.vanity) + +with open(args.output, 'wb') as f: + f.write(executable) diff --git a/src/bin/psptools/pack_ms_game.py b/src/bin/psptools/pack_ms_game.py new file mode 100755 index 0000000..b960d7f --- /dev/null +++ b/src/bin/psptools/pack_ms_game.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import argparse + +from psptool.pbp import is_pbp, PBP +from psptool.pack import pack_prx +from psptool.prx import encrypt + +parser = argparse.ArgumentParser(description="Infinity Game Packer") +parser.add_argument('input', type=argparse.FileType('rb'), + help='The raw PBP to pack') +parser.add_argument('--vanity', type=str, + help='Some vanity text in the executable header') +parser.add_argument('output', type=str, + help='The output to write the packed PBP') +args = parser.parse_args() + +executable = args.input.read() + +if not is_pbp(executable): + raise ValueError("not a PBP") + +# Although there are several tags for MS demos, 0x0C000000 is the most +# portable as it exists in every firmware +pbp = PBP(executable) +pbp.prx = encrypt(pack_prx(pbp.prx, is_pbp=True, + psptag=lambda x: 0x0C000000), vanity=args.vanity) + +with open(args.output, 'wb') as f: + f.write(pbp.pack()) diff --git a/src/bin/psptools/pack_updater.py b/src/bin/psptools/pack_updater.py new file mode 100755 index 0000000..fed09d5 --- /dev/null +++ b/src/bin/psptools/pack_updater.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import argparse + +from psptool.pbp import is_pbp, PBP +from psptool.pack import pack_prx +from psptool.prx import encrypt + +parser = argparse.ArgumentParser(description="Infinity Updater Packer") +parser.add_argument('input', type=argparse.FileType('rb'), + help='The raw PBP to pack') +parser.add_argument('--vanity', type=str, + help='Some vanity text in the executable header') +parser.add_argument('output', type=str, + help='The output to write the packed PBP') +args = parser.parse_args() + +executable = args.input.read() + +if not is_pbp(executable): + raise ValueError("not a PBP") + +pbp = PBP(executable) +pbp.prx = encrypt(pack_prx(pbp.prx, is_pbp=True, + psptag=lambda x: 0x0B000000), vanity=args.vanity) + +with open(args.output, 'wb') as f: + f.write(pbp.pack()) diff --git a/src/bin/psptools/pack_user_fw_module.py b/src/bin/psptools/pack_user_fw_module.py new file mode 100755 index 0000000..1949ae8 --- /dev/null +++ b/src/bin/psptools/pack_user_fw_module.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import argparse + +from psptool.pack import pack_prx +from psptool.prx import encrypt + +parser = argparse.ArgumentParser( + description="Infinity User Firmware Module Packer") +parser.add_argument('input', type=argparse.FileType('rb'), + help='The raw user PRX to pack') +parser.add_argument('--id', type=str, help='The btcnf id to set') +parser.add_argument('output', type=str, + help='The output to write the packed PRX') +args = parser.parse_args() + +executable = args.input.read() +executable = encrypt(pack_prx(executable, is_pbp=False, + psptag=lambda x: 0x457B8AF0), id=bytes.fromhex(args.id)) + +with open(args.output, 'wb') as f: + f.write(executable) diff --git a/src/bin/psptools/psptool/.gitignore b/src/bin/psptools/psptool/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/src/bin/psptools/psptool/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/src/bin/psptools/psptool/__init__.py b/src/bin/psptools/psptool/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/bin/psptools/psptool/kirk.py b/src/bin/psptools/psptool/kirk.py new file mode 100644 index 0000000..8bad818 --- /dev/null +++ b/src/bin/psptools/psptool/kirk.py @@ -0,0 +1,289 @@ +import struct +import hashlib +from Crypto.Cipher import AES +from Crypto.Hash import CMAC +from Crypto import Random +from ecdsa.ellipticcurve import CurveFp, Point +from ecdsa.curves import Curve +from ecdsa import SigningKey, VerifyingKey +from ecdsa.numbertheory import inverse_mod + +_k1_key = '98C940975C1D10E87FE60EA3FD03A8BA' + +_k4_k7_keys = [ + '2C92E5902B86C106B72EEA6CD4EC7248', + '058DC80B33A5BF9D5698FAE0D3715E1F', + 'B813C35EC64441E3DC3C16F5B45E6484', + '9802C4E6EC9E9E2FFC634CE42FBB4668', + '99244CD258F51BCBB0619CA73830075F', + '0225D7BA63ECB94A9D237601B3F6AC17', + '6099F28170560E5F747CB520C0CDC23C', + '76368B438F77D87EFE5FB6115939885C', + '14A115EB434A1BA4905E03B617A15C04', + 'E65803D9A71AA87F059D229DAF5453D0', + 'BA3480B428A7CA5F216412F70FBB7323', + '72AD35AC9AC3130A778CB19D88550B0C', + '8485C848750843BC9B9AECA79C7F6018', + 'B5B16EDE23A97B0EA17CDBA2DCDEC46E', + 'C871FDB3BCC5D2F2E2D7729DDF826882', + '0ABB336C96D4CDD8CB5F4BE0BADB9E03', + '32295BD5EAF7A34216C88E48FF50D371', + '46F25E8E4D2AA540730BC46E47EE6F0A', + '5DC71139D01938BC027FDDDCB0837D9D', + '51DD65F071A4E5EA6AAF12194129B8F4', + '03763C6865C69B0FFE8FD8EEA43616A0', + '7D50B85CAF6769F0E54AA8098B0EBE1C', + '72684B32AC3B332F2A7AFC9E14D56F6B', + '201D31964AD99FBF32D5D61C491BD9FC', + 'F8D84463D610D12A448E9690A6BB0BAD', + '5CD4057FA13060440AD9B6745F244F4E', + 'F48AD678599C22C1D411933DF845B893', + 'CAE7D287A2ECC1CD94542B5E1D9488B2', + 'DE26D37A39956C2AD8C3A6AF21EBB301', + '7CB68B4DA38D1DD932679CA99FFB2852', + 'A0B556B469AB368F36DEC9092ECB41B1', + '939DE19B725FEEE2452ABC1706D14769', + 'A4A4E621382EF1AF7B177AE842AD0031', + 'C37F13E8CF84DB34747BC3A0F19D3A73', + '2BF7838AD898E95FA5F901DA61FE35BB', + 'C704621E714A66EA62E04B203DB8C2E5', + 'C933859AAB00CDCE4D8B8E9F3DE6C00F', + '1842561F2B5F34E3513EB78977431A65', + 'DCB0A0065A50A14E59AC973F1758A3A3', + 'C4DBAE83E29CF254A3DD374E807BF425', + 'BFAEEB498265C57C64B8C17E19064409', + '797CECC3B3EE0AC03BD8E6C1E0A8B1A4', + '7534FE0BD6D0C28D68D4E02AE7D5D155', + 'FAB35326974F4EDFE4C3A814C32F0F88', + 'EC97B386B433C6BF4E539D95EBB979E4', + 'B320A204CF480629B5DD8EFC98D4177B', + '5DFC0D4F2C39DA684A3374ED4958A73A', + 'D75A5422CED9A3D62B557D8DE8BEC7EC', + '6B4AEE4345AE7007CF8DCF4E4AE93CFA', + '2B522F664C2D114CFE61318C56784EA6', + '3AA34E44C66FAF7BFAE55327EFCFCC24', + '2B5C78BFC38E499D41C33C5C7B2796CE', + 'F37EEAD2C0C8231DA99BFA495DB7081B', + '708D4E6FD1F66F1D1E1FCB02F9B39926', + '0F6716E180699C51FCC7AD6E4FB846C9', + '560A494A844C8ED982EE0B6DC57D208D', + '12468D7E1C42209BBA5426835EB03303', + 'C43BB6D653EE67493EA95FBC0CED6F8A', + '2CC3CF8C2878A5A663E2AF2D715E86BA', + '833DA70CED6A2012D196E6FE5C4D37C5', + 'C743D06742EE90B8CA75503520ADBCCE', + '8AE3663F8D9E82A1EDE68C9CE8256DAA', + '7FC96F0BB1485CA55DD364B77AF5E4EA', + '91B765788BCB8BD402ED553A6662D0AD', + '2824F9101B8D0F7B6EB263B5B55B2EBB', + '30E2575DE0A249CEE8CF2B5E4D9F52C7', + '5EE50439623202FA85393F72BB77FD1A', + 'F88174B1BDE9BFDD45E2F55589CF46AB', + '7DF49265E3FAD678D6FE78ADBB3DFB63', + '747FD62DC7A1CA96E27ACEFFAA723FF7', + '1E58EBD065BBF168C5BDF746BA7BE100', + '24347DAF5E4B35727A52276BA05474DB', + '09B1C705C35F536677C0EB3677DF8307', + 'CCBE615C05A20033378E5964A7DD703D', + '0D4750BBFCB0028130E184DEA8D48413', + '0CFD679AF9B4724FD78DD6E99642288B', + '7AD31A8B4BEFC2C2B39901A9FE76B987', + 'BE787817C7F16F1AE0EF3BDE4CC2D786', + '7CD8B891910A4314D0533DD84C45BE16', + '32722C8807CF357D4A2F511944AE68DA', + '7E6BBFF6F687B898EEB51B3216E46E5D', + '08EA5A8349B59DB53E0779B19A59A354', + 'F31281BFE69F51D164082521FFBB2261', + 'AFFE8EB13DD17ED80A61241C959256B6', + '92CDB4C25BF2355A2309E819C9144235', + 'E1C65B226BE1DA02BA18FA21349EF96D', + '14EC76CE97F38A0A34506C539A5C9AB4', + '1C9BC490E3066481FA59FDB600BB2870', + '43A5CACC0D6C2D3F2BD989676B3F7F57', + '00EFFD1808A405893C38FB2572706106', + 'EEAF49E009879BEFAAD6326A3213C429', + '8D26B90F431DBB08DB1DDAC5B52C92ED', + '577C3060AE6EBEAE3AAB1819C571680B', + '115A5D20D53A8DD39CC5AF410F0F186F', + '0D4D51AB2379BF803ABFB90E75FC14BF', + '9993DA3E7D2E5B15F252A4E66BB85A98', + 'F42830A5FB0D8D760EA671C22BDE669D', + 'FB5FEB7FC7DCDD693701979B29035C47', + '02326AE7D396CE7F1C419DD65207ED09', + '9C9B1372F8C640CF1C62F5D592DDB582', + '03B302E85FF381B13B8DAA2A90FF5E61', + 'BCD7F9D32FACF847C0FB4D2F309ABDA6', + 'F55596E97FAF867FACB33AE69C8B6F93', + 'EE297093F94E445944171F8E86E170FC', + 'E434520CF088CFC8CD781B6CCF8C48C4', + 'C1BF66818EF953F2E1266B6F550CC9CD', + '560FFF8F3C9649144516F1BCBFCEA30C', + '2408DC753760A29F0554B5F243857399', + 'DDD5B56A59C55AE83B9667C75C2AE2DC', + 'AA686772E02D44D5CDBB6504BCD5BF4E', + '1F17F014E777A2FE4B136B56CD7EF7E9', + 'C93548CF558D7503896B2EEB618CA902', + 'DE34C541E7CA86E8BEA7C31CECE4360F', + 'DDE5FF551B74F6F4E016D7AB22311B6A', + 'B0E93521333FD7BAB4762CCB4D8008D8', + '381469C4C3F91B9633638E4D5F3DF029', + 'FA486AD98E6716EF6AB087F589457F2A', + '321A091250148A3E963DEA025932E18F', + '4B00BE29BCB02864CEFD43A96FD95CED', + '577DC4FF0244E28091F4CA0A7569FDA8', + '835336C61803E43E4EB30F6B6E799B7A', + '5C9265FD7B596AA37A2F509D85E927F8', + '9A39FB89DF55B2601424CEA6D9650A9D', + '8B75BE91A8C75AD2D7A594A01CBB9591', + '95C21B8D05ACF5EC5AEE77812395C4D7', + 'B9A461643633FA5D9488E2D3281E01A2', + 'B8B084FB9F4CFAF730FE7325A2AB897D', + '5F8C179FC1B21DF1F6367A9CF7D3D47C' +] + + +def _kirk1_curve(): + # ECDSA curve + p = 0xFFFFFFFFFFFFFFFF00000001FFFFFFFFFFFFFFFF + a = -3 + b = 0x65D1488C0359E234ADC95BD3908014BD91A525F9 + Gx = 0x2259ACEE15489CB096A882F0AE1CF9FD8EE5F8FA + Gy = 0x604358456D0A1CB2908DE90F27D75C82BEC108C0 + r = 0xffffffffffffffff0001b5c617f290eae1dbad8f + curve = CurveFp(p, a, b) + generator = Point(curve, Gx, Gy, r) + return Curve("kirk1", curve, generator, (1, 3, 3, 7, 4)) + + +def _kirk11_curve(): + # ECDSA curve + p = 0xFFFFFFFFFFFFFFFF00000001FFFFFFFFFFFFFFFF + a = -3 + b = 0xA68BEDC33418029C1D3CE33B9A321FCCBB9E0F0B + Gx = 0x128EC4256487FD8FDF64E2437BC0A1F6D5AFDE2C + Gy = 0x5958557EB1DB001260425524DBC379D5AC5F4ADF + r = 0xFFFFFFFFFFFFFFFEFFFFB5AE3C523E63944F2127 + curve = CurveFp(p, a, b) + generator = Point(curve, Gx, Gy, r) + return Curve("kirk11", curve, generator, (1, 3, 3, 7, 4)) + + +_k_ecdsa_sign = SigningKey.from_string(bytes.fromhex( + 'F392E26490B80FD889F2D9722C1F34D7274F983D'), curve=_kirk1_curve()) +_k_ecdsa_verify = _k_ecdsa_sign.get_verifying_key() + + +def _verify_cmac(key, block, size, offset): + cobj = CMAC.new(key, ciphermod=AES) + cobj.update(block[0x60:0x60+0x30]) + cobj.verify(block[0x20:0x30]) + cobj = CMAC.new(key, ciphermod=AES) + cobj.update(block[0x60:0x90+size+offset]) + cobj.verify(block[0x30:0x40]) + + +def _verify_ecdsa(block, size, offset): + _k_ecdsa_verify.verify(block[0x10:0x10+0x28], block[0x60:0x60+0x30]) + _k_ecdsa_verify.verify(block[0x38:0x38+0x28], + block[0x60:0x60+0x30+size+offset]) + + +def kirk1(block): + mode = struct.unpack("> 8) & 0xFF + self.modname = modinfo.modname + self.elf_size = len(executable) + + self.entry = elf.e_entry + self.nsegments = elf.e_phnum if elf.e_phnum < 2 else 2 + self.seg_align = [ + x.p_align for x in elf.phdrs[:self.nsegments]] + [0]*(4-self.nsegments) + self.seg_address = [ + x.p_vaddr for x in elf.phdrs[:self.nsegments]] + [0]*(4-self.nsegments) + self.seg_size = [ + x.p_memsz for x in elf.phdrs[:self.nsegments]] + [0]*(4-self.nsegments) + + bss = next(x for x in elf.shdrs if elf.strtab[x.sh_name:].split( + '\0')[0] == '.bss') + self.bss_size = bss.sh_size + + self.devkitversion = 0 + + if modinfo.is_kernel(): + # self.devkitversion = 0x06060110 if self.attribute & 0x2000 else 0x05070110 + self.decrypt_mode = 1 + + elif is_pbp: + # check if VSH API (updater) + if (self.attribute & 0x800) == 0x800: + self.decrypt_mode = 0xC + + # check if APP API (comics, etc) + elif (self.attribute & 0x600) == 0x600: + self.decrypt_mode = 0xE + + # check if USB WLAN API (skype, etc) + elif (self.attribute & 0x400) == 0x400: + self.decrypt_mode = 0x4 + + # set to MS API + else: + # TODO: could check the SFO for POPS... + # MS games must set attribute to 0x200 for firmware 2.00+ + # On firmware <2.00 it must be set to 0 + self.attribute |= 0x200 + self.decrypt_mode = 0xD + + else: + # standalone user prx + # check for VSH API + if (self.attribute & 0x800) == 0x800: + self.decrypt_mode = 3 + + # standard user prx + else: + self.devkitversion = 0x05070210 + self.decrypt_mode = 4 + + # to be filled in by caller + self.psptag = None + self.oetag = None + self.comp_size = None + self.psp_size = None + + self.reserved = [0]*5 + self.key_data0 = [0xDA]*0x30 + self.reserved2 = [0]*2 + self.key_data1 = [0xDA]*0x10 + self.signcheck = [0]*0x58 + self.key_data2 = 0 + self.key_data3 = [0xDA]*0x1C + + def pack(self): + return struct.pack(' 0 else None + return {"name": meta.name, "flags": meta.flags, "file": file} diff --git a/src/bin/psptools/psptools.txt b/src/bin/psptools/psptools.txt new file mode 100644 index 0000000..4fd4781 --- /dev/null +++ b/src/bin/psptools/psptools.txt @@ -0,0 +1 @@ +https://github.com/galaxyhaxz/Infinity/commit/6de980d8fbcaad8bf7a1e7d48a3b476a55752088 diff --git a/src/bin/psptools/requirements.txt b/src/bin/psptools/requirements.txt new file mode 100644 index 0000000..96fed4b --- /dev/null +++ b/src/bin/psptools/requirements.txt @@ -0,0 +1,2 @@ +ecdsa +pycryptodome \ No newline at end of file diff --git a/src/downgrade660_ctrl/main.c b/src/downgrade660_ctrl/main.c index eb6511e..3f6956a 100644 --- a/src/downgrade660_ctrl/main.c +++ b/src/downgrade660_ctrl/main.c @@ -14,12 +14,15 @@ #include #include +#include "common.h" + #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; @@ -57,16 +60,26 @@ int ApplyFirmware(SceModule2 *mod) 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"); - + SceIoStat stats; + int status; + + status = sceIoGetstat(eboot_path, &stats); + + if(status < 0) { + eboot_path[0] = 'm'; + eboot_path[1] = 's'; + status = sceIoGetstat(eboot_path, &stats); + + } + /* set k1 */ u32 k1 = pspSdkSetK1(0); /* lets open the file */ - SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); + SceUID fd; /* check for failure */ - if (fd < 0) + if ((fd = sceIoOpen(eboot_path, PSP_O_RDONLY, 0777)) < 0) { /* rage */ pspSdkSetK1(k1); diff --git a/src/downgrade_ctrl/main.c b/src/downgrade_ctrl/main.c index 5b0e85f..854ab21 100644 --- a/src/downgrade_ctrl/main.c +++ b/src/downgrade_ctrl/main.c @@ -8,12 +8,15 @@ #include #include #include +#include #include #include #include #include +#include "common.h" + #include "utils.h" #include "patch_table.h" #include "decrypt.h" @@ -57,16 +60,25 @@ int ApplyFirmware(void) 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"); + SceIoStat stats; + int status; + + status = sceIoGetstat(eboot_path, &stats); + + if(status < 0) { + eboot_path[0] = 'm'; + eboot_path[1] = 's'; + status = sceIoGetstat(eboot_path, &stats); + } /* set k1 */ u32 k1 = pspSdkSetK1(0); /* lets open the file */ - SceUID fd = sceIoOpen(file, PSP_O_RDONLY, 0777); + SceUID fd; /* check for failure */ - if (fd < 0) + if ((fd = sceIoOpen(eboot_path, PSP_O_RDONLY, 0777)) < 0) { /* rage */ pspSdkSetK1(k1); diff --git a/src/include/common.h b/src/include/common.h new file mode 100644 index 0000000..4075fb8 --- /dev/null +++ b/src/include/common.h @@ -0,0 +1,4 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ +char eboot_path[] = "ef0:/PSP/GAME/UPDATE/EBOOT.PBP"; +#endif diff --git a/src/kernel_exploit.c b/src/kernel_exploit.c index 99f2e1b..4f43aea 100644 --- a/src/kernel_exploit.c +++ b/src/kernel_exploit.c @@ -65,12 +65,15 @@ int pre_kernel(int (* kfunc)(void)) /* find our functions */ if((g_devkit_version == FIRMWARE_VERSION_660) || (g_devkit_version == FIRMWARE_VERSION_661)) { + pspKernelGetModel = (void *)FindProc("sceSystemMemoryManager", "SysMemForKernel", 0x07C586A1); //6.60 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); + pspIoAssign = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0xB2A628C1); + pspIoUnAssign = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x6D08A871); pspIoWrite = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x42EC03AC); pspIoClose = (void *)FindProc("sceIOFileManager", "IoFileMgrForKernel", 0x810C4BC3); } diff --git a/src/kernel_land.c b/src/kernel_land.c index 9c39778..9e9351c 100644 --- a/src/kernel_land.c +++ b/src/kernel_land.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,10 @@ #include "utils.h" #include "downgrade_ctrl/patch_table.h" + +extern char eboot_path[]; + + /* function pointers */ int (* pspKernelGetModel)(void) = NULL; int (* pspSysconGetBaryonVersion)(u32 *baryon) = NULL; @@ -26,6 +31,9 @@ int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExecVSHPar SceUID (* pspIoOpen)(char *file, int flags, SceMode mode) = NULL; int (* pspIoWrite)(SceUID fd, void *data, u32 len) = NULL; int (* pspIoClose)(SceUID fd) = NULL; +int (* pspIoAssign)(const char *dev1, const char *dev2, const char *dev3, int mode, void *unk1, long unk2) = NULL; +int (* pspIoUnAssign)(const char *dev) = NULL; + /* globals */ struct SceKernelLoadExecVSHParam g_exec_param; @@ -47,6 +55,15 @@ int getModel(void) return pspKernelGetModel(); } + +int reassign() { + u32 ret; + pspIoUnAssign("ms0:"); + pspIoAssign("ms0:","msstor0p1:","fatms0:",IOASSIGN_RDWR,NULL,0); + ret = pspIoOpen(eboot_path, PSP_O_RDONLY, 0777); + return ret; +} + int delete_resume_game(void) { u8 _header[512+64]; @@ -111,7 +128,7 @@ int patch_loadexec_phat(void) KClearCaches(); /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); } int patch_loadexec_slim(void) @@ -138,7 +155,7 @@ int patch_loadexec_slim(void) KClearCaches(); /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); } int patch_loadexec_3000(void) @@ -165,7 +182,7 @@ int patch_loadexec_3000(void) KClearCaches(); /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); } int patch_loadexec_4000(void) @@ -192,7 +209,7 @@ int patch_loadexec_4000(void) KClearCaches(); /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); } int patch_loadexec_pspgo(void) @@ -220,8 +237,13 @@ int patch_loadexec_pspgo(void) /* clear the caches */ KClearCaches(); - /* reboot into the updater */ - return pspKernelLoadExecVSHEf1(PSPGO_UPDATER_PATH, &g_exec_param); + if(strstr(eboot_path, "ms0")) { + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); + } + else { + /* reboot into the updater */ + return pspKernelLoadExecVSHEf1(eboot_path, &g_exec_param); + } } int patch_loadexec_street(void) @@ -240,13 +262,13 @@ int patch_loadexec_street(void) KClearCaches(); /* just return 0 */ - return pspKernelLoadExecVSHMs1(OTHER_UPDATER_PATH, &g_exec_param); + return pspKernelLoadExecVSHMs1(eboot_path, &g_exec_param); } -int launch_updater(void) +int launch_updater() { KClearCaches(); - + int res = -1; /* clear our param */ @@ -254,7 +276,7 @@ int launch_updater(void) /* 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.argp = eboot_path; g_exec_param.args = strlen(g_exec_param.argp) + 1; g_exec_param.key = "updater"; g_exec_param.vshmain_args_size = 0; diff --git a/src/kernel_land.h b/src/kernel_land.h index 0c2b50a..3ce61cd 100644 --- a/src/kernel_land.h +++ b/src/kernel_land.h @@ -13,8 +13,11 @@ int getModel(void); u32 getBaryon(void); int launch_updater(void); +int reassign(void); int delete_resume_game(void); +//extern char eboot_path[]; + extern int (* pspKernelGetModel)(void); extern int (* pspSysconGetBaryonVersion)(u32 *baryon); extern SceModule2 *(* pspKernelFindModuleByName)(const char *name); @@ -23,5 +26,9 @@ extern int (* pspKernelLoadExecVSHMs1)(const char *path, struct SceKernelLoadExe extern SceUID (* pspIoOpen)(char *file, int flags, SceMode mode); extern int (* pspIoWrite)(SceUID fd, void *data, u32 len); extern int (* pspIoClose)(SceUID fd); +extern int (* pspIoRead)(int fd, void* data, int size); +extern int (* pspIoAssign)(const char *dev1, const char *dev2, const char *dev3, int mode, void *unk1, long unk2); +extern int (* pspIoUnAssign)(const char *dev); +extern int (* pspIoLseek32)(int fd, int offset, int whence); #endif /* __KERNEL_LAND_H__ */ diff --git a/src/main.c b/src/main.c index 7826abc..d0a694f 100644 --- a/src/main.c +++ b/src/main.c @@ -13,22 +13,26 @@ #include #include #include +#include #include #include #include #include +#include "common.h" + #include "utils.h" #include "kernel_land.h" #include "kernel_exploit.h" #include "rebootex.h" -PSP_MODULE_INFO("Chronoswitch", 0, 1, 1); +PSP_MODULE_INFO("Chronoswitch", 0, 7, 61); PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU); PSP_HEAP_SIZE_KB(3 << 10); -#define DOWNGRADER_VER ("7.2") +#define DOWNGRADER_VER ("7.6.1") + typedef struct __attribute__((packed)) { @@ -50,7 +54,7 @@ typedef struct __attribute__((packed)) short unknown; // 16 } SfoEntry; -u32 get_updater_version(u32 is_pspgo) +u32 get_updater_version(char *argv) { int i; char *fw_data = NULL; @@ -60,23 +64,62 @@ u32 get_updater_version(u32 is_pspgo) 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); - + SceIoStat stats; + int status; + + status = sceIoGetstat(eboot_path, &stats); + + if(status < 0) { + eboot_path[0] = 'm'; + eboot_path[1] = 's'; + } + + status = sceIoGetstat(eboot_path, &stats); + + int go_fw = -1; + + int go_check = sceIoOpen(eboot_path, PSP_O_RDONLY, 0); + sceIoLseek32(go_check, 0x346F, PSP_SEEK_SET); + u8 go_buf[1] = { 0 }; + sceIoRead(go_check, go_buf, 1); + if(go_buf[0] == 0x63) + go_fw = 1; + sceIoLseek32(go_check, 0, PSP_SEEK_SET); + sceIoClose(go_check); + + if(status < 0 && !strstr(argv, "ef0")) { + printf("\nHmmmm? Are you sure you have EBOOT.PBP in PSP/GAME/UPDATE/ ???\n"); + return 0xFFF; + } + /* 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); + int model = execKernelFunction(getModel); + if(model == 4 && go_fw < 0) { + pspDebugScreenSetTextColor(0xCC0000FF); + printf("\nYour running OFW from a X000 Series, it should be for the GO OFW\n"); + pspDebugScreenSetTextColor(0x00BFFF); + return 0xFFF; + } + else if(model != 4 && go_fw == 1) { + pspDebugScreenSetTextColor(0xCC0000FF); + printf("\nYour running OFW from a GO, it should be for the X000 OFW Series\n"); + pspDebugScreenSetTextColor(0x00BFFF); + return 0xFFF; + } + else if(model == 4 && strstr(argv, "ef0") && go_fw >= 0) { return 0xFA4E; /* FAKE some reason CS on ef0 does not like reading from ms0 */ } + SceUID fd = sceIoOpen(eboot_path, PSP_O_RDONLY, 0777); + if (fd < 0) + { + printf("\nHmmmm? Are you sure you have EBOOT.PBP in PSP/GAME/UPDATE/ ???\n"); + /* 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]; @@ -85,15 +128,16 @@ u32 get_updater_version(u32 is_pspgo) if (sfo_size > sizeof(sfo_buffer)) { /* too much */ + printf("\nTo much deditated wammm ... Perhaps not have all your plugins running right now ...\n"); sceIoClose(fd); return 0xFFF; } - - /* read the sfo */ - sceIoRead(fd, sfo_buffer, sizeof(sfo_buffer)); - - /* close the file */ - sceIoClose(fd); + + /* 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++) @@ -110,6 +154,7 @@ u32 get_updater_version(u32 is_pspgo) /* see if we went through all the data */ if (i == header->count) { + printf("\nHmmm SFO count is too big ... Looks like the EBOOT.PBP is corrupted somehow.\n"); return 0xFFF; } @@ -129,21 +174,28 @@ int main(int argc, char *argv[]) /* initialise the PSP screen */ pspDebugScreenInit(); - pspDebugScreenSetTextColor(0x00D05435); + pspDebugScreenSetTextColor(0x00BFFF); + //pspDebugScreenSetTextColor(0x00D05435); /* display welcome message */ printf( "Chronoswitch Downgrader" "\n" - "Version %s. Built %s %s" "\n" "\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" + "\t" "6.61 Support added by qwikrazor87" "\n" + "\t" "Removed factory firmware limits (and more) by TheZett" "\n" + "\t" "GO ms0/ef0 UPDATE support added by krazynez" "\n" "\n" + "Testers:" "\n" + "\t" "Peter Lustig" "\n" + "\t" "Nall (nallwolf)" "\n" + "\t" "Total Kommando" "\n" "\n" "Web:" "\n" - "\t" "https://lolhax.org" "\n" "\n" - , DOWNGRADER_VER, __DATE__, __TIME__); + "\t" "https://lolhax.org" "\n" + , DOWNGRADER_VER, __DATE__, __TIME__ "\n"); #ifdef HBL_SUKKIRI /* Clear html param to 0 */ @@ -254,7 +306,25 @@ int main(int argc, char *argv[]) sceKernelDelayThread(4*1000*1000); /* get the updater version */ - u32 upd_ver = get_updater_version(model == 4); + u32 upd_ver = get_updater_version(argv[0]); + + if (upd_ver == 0xFFF) { + printf("\nPress 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_RTRIGGER) + { + ErrorExit(5000, "Exiting in 5 seconds.\n"); + } + } + } /* make sure that we are not attempting to downgrade a PSP below its firmware boundaries */ @@ -372,8 +442,13 @@ int main(int argc, char *argv[]) } /* do confirmation stuff */ - printf("\n" "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"); + if(model == 4 && strstr(argv[0], "ef0")) { + printf("\nX to continue, R to exit.\n"); + } + else { + printf("\n" "Currently Running: %X.%X going to Downgrade/Reinstall: %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("\nX to continue, R to exit.\n"); + } /* get button */ while (1) @@ -383,6 +458,7 @@ int main(int argc, char *argv[]) /* 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) diff --git a/src/utils.h b/src/utils.h index c0d4eeb..5704dea 100644 --- a/src/utils.h +++ b/src/utils.h @@ -19,9 +19,6 @@ #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 /**