HYBRID LET'S GOOO
This commit is contained in:
parent
7192bb2469
commit
7f8a425808
13 changed files with 241 additions and 3 deletions
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VIDEO_TS.IFO
Normal file
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VIDEO_TS.IFO
Normal file
Binary file not shown.
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VTS_01_0.IFO
Normal file
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VTS_01_0.IFO
Normal file
Binary file not shown.
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VTS_02_0.IFO
Normal file
BIN
Filesystems/3.10EU + 3.11EUMACDGJ hybrid/VIDEO_TS/VTS_02_0.IFO
Normal file
Binary file not shown.
19
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/build.sh
Normal file
19
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/build.sh
Normal file
|
|
@ -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"
|
||||
65
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/crt0.S
Normal file
65
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/crt0.S
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# OK, so in the hybrid disc, 3.10 stage 2 is at 0x3000 as normal, but 3.11 stage 2 is modified to start at 0x38000
|
||||
# that's why we need to modify this file, just the LBA load on line 31 and the padding
|
||||
|
||||
.set noreorder # If we're writing assembly, why would we want this?
|
||||
|
||||
.section .text.startup
|
||||
|
||||
.equ getBufferInternal, 0x2986a0
|
||||
.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, 0x3800 / 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"
|
||||
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/fullpayload.bin
Normal file
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/fullpayload.bin
Normal file
Binary file not shown.
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/fullpayload.elf
Normal file
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/fullpayload.elf
Normal file
Binary file not shown.
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.bin
Normal file
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.bin
Normal file
Binary file not shown.
141
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.c
Normal file
141
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <stddef.h>
|
||||
|
||||
// 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);
|
||||
}
|
||||
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.elf
Normal file
BIN
PAYLOADS/PAYLOAD 3.10 modified for the hybrid/payload.elf
Normal file
Binary file not shown.
BIN
PREBUILT ISOs/hybrid 3.10 and 3.11.iso
Normal file
BIN
PREBUILT ISOs/hybrid 3.10 and 3.11.iso
Normal file
Binary file not shown.
|
|
@ -14,6 +14,8 @@ Currently only support:
|
|||
- 3.10 (E or U - maybe other regions too, untested - with English language set in settings) - confirmed working on hardware by CTurt, and others
|
||||
- 3.11 (all regions - EUMACDGJ - with English language set in settings) - confirmed working on hardware by [MrMario2011](https://twitter.com/MrMario2011/status/1277586569738813440), and others
|
||||
|
||||
UPDATE: Experimental hybrid ISO - 3.10 and 3.11 support merged into one now available, burn `PREBUILT ISOs/hybrid 3.10 and 3.11.iso` and set language to English :)
|
||||
|
||||
Please don't bother trying on a not supported firmware/language configuration, it won't work...
|
||||
|
||||
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).
|
||||
|
|
@ -27,12 +29,12 @@ You should use DVD-R (others work but put more strain on PS2 laser), and make su
|
|||
If you intend to make your own image containing additional homebrew / modified initial loader, please read on. Step 1 is the same, first identify firmware version.
|
||||
|
||||
### Step 2: Copy your homebrew
|
||||
Once you've identified your console's DVD Player version, copy all of the homebrew you would like to include on the disc into that directory (EG: `3.10EU/`).
|
||||
Once you've identified your console's DVD Player version, copy all of the homebrew you would like to include on the disc into that directory in the `Filesystem` (EG: `Filesystem/3.10EU/`).
|
||||
|
||||
### Step 3: Make an image
|
||||
Once you've placed all the homebrew files you'd like into the directory, generate a UDF image of the directory. The easiest way is probably to install `genisoimage` (comes pre-installed on many Linux distributions like Ubuntu) / `mkisofs` and run the following (where `exploit.iso` is the output and `3.10EU` is the directory containing `VIDEO_TS` and any homebrew):
|
||||
|
||||
genisoimage -udf -o exploit.iso 3.10EU
|
||||
genisoimage -udf -o exploit.iso Filesystem/3.10EU
|
||||
|
||||
### Step 4: Test and burn
|
||||
I would recommend you test in PCSX2 first, but since [PCSX2 doesn't support loading the DVD Player](https://github.com/PCSX2/pcsx2/issues/1981), you have to decrypt and repack it yourself, which is beyond the scope of this README. With that said, if you aren't touching anything in `VIDEO_TS`, there shouldn't really be any reason for the exploit to fail.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ Insert fullpayload.bin into VIDEO_TS.IFO at offset 0x2ba4
|
|||
test, and see ule boot successfully in pcsx2!
|
||||
|
||||
|
||||
3.11E (English language)
|
||||
3.11 all (English language)
|
||||
getDiscData and getDiscByte seem the same as in 3.11J
|
||||
overflow call is also at 0x257564
|
||||
fpIndex also 0x143bc4a
|
||||
|
|
@ -68,3 +68,14 @@ 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
|
||||
|
||||
|
||||
|
||||
hybrid 3.10 + 3.11
|
||||
so starting with a 3.11 base VIDEO_TS.IFO
|
||||
currentDiscBytePointer offset for 3.10 is 00002744
|
||||
for 3.11 is 0000277c
|
||||
copy 3.10 currentDiscBytePointer and endDiscBytePointer corruption to its offset (8 bytes at 00002744)
|
||||
fpIndex for 3.10 is offset 00002faa, so copy those 2 bytes over
|
||||
payload for 3.10 is at 0x2bb4
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue