PCSX2 compatible image for debugging

This commit is contained in:
CTurt 2020-08-11 20:22:34 +01:00
parent f5e380970b
commit 4a13fcfd3c
18 changed files with 90 additions and 71 deletions

View file

@ -0,0 +1,21 @@
STAGE1_LOAD_ADDRESS = 0xa0062C48 # hardware
STAGE1_LOAD_ADDRESS_STRING = '\x48\x2c\x06\xa0'
IOP_READ_SECTORS = 0x5DD0C # 0xb260c + 0x5c700 - 0xb1000
IOP_ORIGINAL_RETURN_ADDRESS = 0x5ED30 # 0xb3630 + 0x5c700 - 0xb1000
IOP_RETURN_ADDRESS_LOCATION = 0x1F30AC # 0x1f62ac + 0x1F3058 - 0x1f6258
#IOP_PAYLOAD_ENTRY = `$(IOP_OBJDUMP) -t ioppayload.iop.elf | grep " _start"`
IOP_PAYLOAD_ENTRY = 0xa00fd178 # Set this manually for now.
IOP_PAYLOAD_ADDRESS = 0xa00fd000
EE_PAYLOAD_ADDRESS = 0x01fff800
#isoinfo -l -i dvd.iso | grep "BOOT.ELF"
#var=`isoinfo -l -i dvd.iso | grep "BOOT.ELF" | grep -o -P "[0-9]*? -"`
# LOAD_ELF_FROM_OFFSET =
LOAD_ELF_FROM_OFFSET = 0x5BB000 # Set this manually for now
include Mainrules.mk

View file

@ -0,0 +1,21 @@
STAGE1_LOAD_ADDRESS = 0xa00b7548
STAGE1_LOAD_ADDRESS_STRING = '\x48\x75\x0b\xa0'
IOP_READ_SECTORS = 0xb260c
IOP_ORIGINAL_RETURN_ADDRESS = 0xb3630
IOP_RETURN_ADDRESS_LOCATION = 0x1f62ac
#IOP_PAYLOAD_ENTRY = `$(IOP_OBJDUMP) -t ioppayload.iop.elf | grep " _start"`
IOP_PAYLOAD_ENTRY = 0xa00fd178 # Set this manually for now.
IOP_PAYLOAD_ADDRESS = 0xa00fd000
EE_PAYLOAD_ADDRESS = 0x01fff800
#isoinfo -l -i dvd.iso | grep "BOOT.ELF"
#var=`isoinfo -l -i dvd.iso | grep "BOOT.ELF" | grep -o -P "[0-9]*? -"`
# LOAD_ELF_FROM_OFFSET =
LOAD_ELF_FROM_OFFSET = 0x5BB000 # Set this manually for now
include Mainrules.mk

View file

@ -1,10 +1,3 @@
#STAGE1_LOAD_ADDRESS = 0x1f62b0
#STAGE1_LOAD_ADDRESS = 0xa01f62b0 # repacked
#STAGE1_LOAD_ADDRESS = 0xA01F30B0 # (0xa0000000 + 0x01f62b0 + 0x1F3058 - 0x1f6258) # hardware
# (0xb7548 + 0x5c700 - 0xb1000) = 0x62C48
STAGE1_LOAD_ADDRESS = 0xa0062C48 # hardware
EE_CC = ee-gcc EE_CC = ee-gcc
EE_LD = ee-ld EE_LD = ee-ld
EE_AS = ee-as EE_AS = ee-as
@ -16,37 +9,27 @@ IOP_AS = iop-as
IOP_OBJCOPY = iop-objcopy IOP_OBJCOPY = iop-objcopy
IOP_OBJDUMP = iop-objdump IOP_OBJDUMP = iop-objdump
IOP_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -g IOP_SYMBOLS = -DREAD_SECTORS=$(IOP_READ_SECTORS) -DORIGINAL_RETURN_ADDRESS=$(IOP_ORIGINAL_RETURN_ADDRESS) -DRETURN_ADDRESS_LOCATION=$(IOP_RETURN_ADDRESS_LOCATION)
IOP_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -g $(IOP_SYMBOLS)
EE_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -Wl,-z,max-page-size=0x1 EE_CFLAGS = -O2 -G 0 -nostartfiles -nostdlib -ffreestanding -Wl,-z,max-page-size=0x1
#IOP_PAYLOAD_ENTRY = `$(IOP_OBJDUMP) -t ioppayload.iop.elf | grep " _start"`
#IOP_PAYLOAD_ENTRY = 0xa0460178 # Set this manually for now.
IOP_PAYLOAD_ENTRY = 0xa00fd178 # Set this manually for now.
IOP_STAGE1_SIZE = `stat -c '%s' stage1.iop.bin` IOP_STAGE1_SIZE = `stat -c '%s' stage1.iop.bin`
IOP_PAYLOAD_SIZE = `stat -c '%s' ioppayload.iop.bin` IOP_PAYLOAD_SIZE = `stat -c '%s' ioppayload.iop.bin`
#IOP_PAYLOAD_ADDRESS = 0x460000
#IOP_PAYLOAD_ADDRESS = 0xa0460000
IOP_PAYLOAD_ADDRESS = 0xa00fd000
EE_PAYLOAD_ADDRESS = 0x01fff800
#isoinfo -l -i dvd.iso | grep "BOOT.ELF"
#var=`isoinfo -l -i dvd.iso | grep "BOOT.ELF" | grep -o -P "[0-9]*? -"`
# LOAD_ELF_FROM_OFFSET =
LOAD_ELF_FROM_OFFSET = 0x5BB000 # Set this manually for now
all: dvd.iso
dvd.iso: dvd.base.iso stage1.iop.bin ioppayload.iop.bin dvd.iso: dvd.base.iso stage1.iop.bin ioppayload.iop.bin
cp dvd.base.iso dvd.iso
#genisoimage -udf -o dvd.iso udf/ #genisoimage -udf -o dvd.iso udf/
# @echo Insert 0x00000048 to offset 0x0818AC in dvd.iso # @echo Insert 0x00000048 to offset 0x0818AC in dvd.iso
# @echo Insert 0x00004000 to offset 0x0818B0 in dvd.iso # @echo Insert 0x00004000 to offset 0x0818B0 in dvd.iso
# @echo Insert 0x000B7548 to offset 0x0818F4 in dvd.iso # @echo Insert 0x000B7548 to offset 0x0818F4 in dvd.iso
# For now it's easier to just use a base dvd rather than attempting to generate an image and patch it
cp dvd.base.iso dvd.iso
# Return address 0x00818f4 = 530676
printf $(STAGE1_LOAD_ADDRESS_STRING) | dd of=dvd.iso bs=1 seek=530676 count=4 conv=notrunc
# Old toolchains don't support this option, so just copy byte-by-byte...
# bs=4096 iflag=skip_bytes,count_bytes # bs=4096 iflag=skip_bytes,count_bytes
# 0x820f8 = 532728 # 0x820f8 = 532728

Binary file not shown.

Binary file not shown.

View file

@ -7,10 +7,6 @@ _start:
# Point stack to end of scratchpad RAM # Point stack to end of scratchpad RAM
#la $sp, 0x70004000 #la $sp, 0x70004000
# debug
la $v0, 0x01FFF7D0
sw $v0, 0($v0)
.global main .global main
#la $v1, 0x01 #la $v1, 0x01
#la $a0, 0x7f #la $a0, 0x7f

Binary file not shown.

Binary file not shown.

View file

@ -1,38 +1,38 @@
// ElReino & CTurt 2020 // ElReino & CTurt 2020
int (*SifIopReset)(char *, int) = (void *)0x85360; //int (*SifIopReset)(char *, int) = (void *)0x85360;
void (*SifInitRpc)(int) = (void *)0x84500; //void (*SifInitRpc)(int) = (void *)0x84500;
void (*SifExitRpc)(void) = (void *)0x84690; //void (*SifExitRpc)(void) = (void *)0x84690;
extern void SifWriteBackDCache(void *ptr, int size); extern void SifWriteBackDCache(void *ptr, int size);
extern int SifSetReg(unsigned int register_num, unsigned int register_value); extern int SifSetReg(unsigned int register_num, unsigned int register_value);
extern int SifGetReg(unsigned int register_num); extern int SifGetReg(unsigned int register_num);
static int SifIopSync(void) { //static int SifIopSync(void) {
#define SIF_REG_SMFLAG 4 // #define SIF_REG_SMFLAG 4
#define SIF_STAT_BOOTEND 0x40000 // #define SIF_STAT_BOOTEND 0x40000
return((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0); // return((SifGetReg(SIF_REG_SMFLAG) & SIF_STAT_BOOTEND) != 0);
} //}
static void flush(void) { static void flush(void) {
asm volatile("la $v1, 0x64; la $a0, 0; syscall 0x64"); /* FlushCache data writeback */ 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 */ asm volatile("la $v1, 0x64; la $a0, 2; syscall 0x64"); // FlushCache instruction invalidate
} }
int main(void) { int main(void) {
volatile int *waitAddress = (void *)0x21FFF7F0; volatile int *waitAddress = (void *)0x21FFF7F0;
while(!*waitAddress); while(!*waitAddress);
volatile void **entry_point_address = (void *)0x01FFF7E0;
// cdrom0:
volatile void **argument = (void *)0x01FFF7D0;
*(volatile int *)0x01FFF7D0 = 0x01FFF7D8;
*(volatile int *)0x01FFF7D8 = 0x6F726463;
*(volatile int *)0x01FFF7DC = 0x003A306D;
flush(); flush();
// These aren't needed to launch uLE at least, and make compatibility worse, so commented out... //ExecPS2(*entry_point_address, 0, 0, 0);
//SifInitRpc(0); ExecPS2(*entry_point_address, 0, 1, argument); // kHn: arg == cdrom0:
//SifExitRpc();
//while(!SifIopReset("", 0));
//while(!SifIopSync()){};
// //SifInitRpc(0);
volatile void **entry_point_address = (void *)0x01FFF7E0;
ExecPS2(*entry_point_address, 0, 0, 0);
} }

Binary file not shown.

View file

@ -59,13 +59,12 @@ typedef struct {
* number 0x41C00000. * number 0x41C00000.
*/ */
//int (*readSectors)(int count, int sector, void *destination) = (void *)0xb260c; // repacked ELF int (*readSectors)(int count, int sector, void *destination) = (void *)READ_SECTORS;
int (*readSectors)(int count, int sector, void *destination) = (void *)(0xb260c + 0x5c700 - 0xb1000); // real hardware
int (*sceSifSetDma)(struct SifDmaTransfer *, int num) = (void *)0x16fc8; int (*sceSifSetDma)(struct SifDmaTransfer *, int num) = (void *)0x16fc8;
int (*sceSifDmaStat)(int trid) = (void *)0x17170; int (*sceSifDmaStat)(int trid) = (void *)0x17170;
void (*flushIcache)(void) = (void*)0x2f40; void (*flushIcache)(void) = (void*)0x2f40;
void (*flushDcache)(void) = (void*)0x3148; void (*flushDcache)(void) = (void*)0x3044;
void (*printf)(char *, ...) = (void *)0x1ab84; void (*printf)(char *, ...) = (void *)0x1ab84;
static void transfer_to_ee(void *dest, void *src, unsigned int size); static void transfer_to_ee(void *dest, void *src, unsigned int size);

View file

@ -1,18 +1,11 @@
# ElReino & CTurt 2020 # ElReino & CTurt 2020
# entry 0xb7548 # repacked readSectors = READ_SECTORS
# entry (0xb7548 + 0x5c700 - 0xb1000) = 0x62C48 (0xa0062C48) # hardware
#readSector = 0xb260c # repacked
readSector = (0xb260c + 0x5c700 - 0xb1000) # real hardware - through wle
#readSector = (0xb260c + - 0xb1000 - 0x400) # real hardware
flushIcache = 0x00002f40 flushIcache = 0x00002f40
flushDcache = 0x0003044 flushDcache = 0x0003044
flushDcacheWrapper = 0x0057f1c #flushDcacheWrapper = 0x0057f1c
#iop_payload_address = 0x460000 #iop_payload_address = 0x460000
#iop_payload_address = 0xa0460000 #iop_payload_address = 0xa0460000
@ -27,7 +20,7 @@ _start:
la $a0, (IOP_PAYLOAD_SIZE / 0x800) + 1 # count la $a0, (IOP_PAYLOAD_SIZE / 0x800) + 1 # count
la $a1, 0x700000 / 0x800 # sector la $a1, 0x700000 / 0x800 # sector
la $a2, iop_payload_address # destination la $a2, iop_payload_address # destination
jal readSector jal readSectors
#jal flushIcache #jal flushIcache
#jal flushDcache #jal flushDcache
@ -37,13 +30,8 @@ _start:
jalr $v0 jalr $v0
# Return gracefully back to original return address # Return gracefully back to original return address
#la $a0, 0x1f62ac # repacked la $a0, RETURN_ADDRESS_LOCATION
#la $a0, (0x1f62ac + 0x1F3058 - 0x1f6258) # hardware la $ra, ORIGINAL_RETURN_ADDRESS # hardware
la $a0, (0x1f62ac + 0x001F3058 - 0x1f6258) # hardware
#la $ra, 0xb3630 # repacked
la $ra, (0xb3630 + 0x5c700 - 0xb1000) # hardware
#la $ra, (0xb3630 + - 0xb1000 - 0x400) # hardware
sw $ra, 0($a0) sw $ra, 0($a0)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -127,7 +127,7 @@ You can run `readelf -l` to verify your executable satisfies this requirement. F
00 .text .ctors .dtors .rodata .data .jcr .sdata .sbss .bss 00 .text .ctors .dtors .rodata .data .jcr .sdata .sbss .bss
## Replacing the initial program - Phat ## Replacing the initial program - Phat
The ELF is read from `0x5bb000` in the ISO file. The ELF is read from `0x5bb000` in the ISO file, copy to that location with a hex editor to replace it.
## Loading backups ## Loading backups
It's possible to patch backup images of commercial games to make them bootable using this exploit. I didn't want to maintain this tool, so it's not included in this repository, but can be found by searching for something like FreeDVDBoot ESR auto patcher. It's possible to patch backup images of commercial games to make them bootable using this exploit. I didn't want to maintain this tool, so it's not included in this repository, but can be found by searching for something like FreeDVDBoot ESR auto patcher.
@ -137,5 +137,16 @@ The default payload will boot `VIDEO_TS/VTS_02_0.IFO` as an ELF file, but tweaks
If you wish to update the loader payload, run `build.sh` inside `PAYLOAD` directory, and copy the output `.bin` files into `VIDEO_TS/VIDEO_TS.IFO` at the offsets displayed by the output of the command. If you wish to update the loader payload, run `build.sh` inside `PAYLOAD` directory, and copy the output `.bin` files into `VIDEO_TS/VIDEO_TS.IFO` at the offsets displayed by the output of the command.
## DEVELOPMENT: Replacing the loader payload - Phat
Run the following to build a new `dvd.iso`:
`make -f 2.10.mk`
If you want to test on PCSX2 using KrHacken's repacked DVD players, it loads `udfio` at a different base address, use the repacked makefile to build an image for testing on the emulator:
`make -f 2.10_repacked.mk`
`clean` before switching between these, or use `-B` flag.
## PORTING: ## PORTING:
Please read my technical writeup, to understand how the exploit works. I've also provided some [notes about porting](https://cturt.github.io/FreeDVDBoot/portingnotes.html) in the [`gh-pages`](https://github.com/CTurt/FreeDVDBoot/tree/gh-pages) branch. Please read my technical writeup, to understand how the exploit works. I've also provided some [notes about porting](https://cturt.github.io/FreeDVDBoot/portingnotes.html) in the [`gh-pages`](https://github.com/CTurt/FreeDVDBoot/tree/gh-pages) branch.