-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit aaac11a
Showing
15 changed files
with
1,094 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# payload artifacts | ||
*.bin | ||
*.elf | ||
*.o | ||
*.gci | ||
# executable artifacts | ||
*.exe | ||
gci_builder | ||
*.dSYM | ||
# other stuff | ||
*.zip |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
GCIBUILDER := gci_builder | ||
ifeq ($(OS),Windows_NT) | ||
GCIBUILDER := $(addsuffix .exe,$(GCIBUILDER)) | ||
endif | ||
|
||
PAYLOAD_DIR := gc_payload | ||
GCI_BUILDER_DIR := gci_builder_src | ||
|
||
.PHONY: $(GCIBUILDER) payload_bins eur usa clean | ||
all: eur usa | ||
|
||
$(GCIBUILDER): | ||
@$(MAKE) -C $(GCI_BUILDER_DIR) | ||
@cp $(GCI_BUILDER_DIR)/$(GCIBUILDER) $(GCIBUILDER) | ||
|
||
payload_bins: | ||
@$(MAKE) -C $(PAYLOAD_DIR) | ||
|
||
eur: payload_bins $(GCIBUILDER) | ||
@./$(GCIBUILDER) $(PAYLOAD_DIR)/robohaxx-EUR.bin E | ||
|
||
usa: payload_bins $(GCIBUILDER) | ||
@./$(GCIBUILDER) $(PAYLOAD_DIR)/robohaxx-USA.bin U | ||
|
||
clean: | ||
@$(MAKE) -C $(PAYLOAD_DIR) clean | ||
@$(MAKE) -C $(GCI_BUILDER_DIR) clean | ||
@-rm $(GCIBUILDER) | ||
@-rm *.gci |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# robohaxx: stackcry | ||
|
||
A savegame exploit / homebrew entrypoint for the game Robotech: Battlecry on the GameCube. | ||
|
||
Compatible with both USA and EUR revisions of the game. (Only USA has been tested on real GC hardware.) | ||
|
||
["it's a stack overflow in the profile name on a 6th gen console game"](https://tenor.com/view/buzz-lightyear-factory-you-will-never-find-another-store-shelf-a-bunch-of-buzz-lightyears-gif-21719996) (Tenor GIF link) | ||
|
||
## How to Use | ||
|
||
1. Copy the .gci file for your region from [the robohaxx releases page](https://github.com/InvoxiPlayGames/robohaxx/releases) | ||
to your Memory Card using [GCMM](https://github.com/suloku/gcmm/releases). | ||
* While you're here, make sure you have the latest Swiss boot GCI, too. (Or any other boot.dol.) | ||
* Ensure there are **NO** other savegames for Robotech: Battlecry on the memory card. | ||
2. Launch Robotech: Battlecry. | ||
3. At the main menu, select the "Load Game" option. | ||
4. Afetr a few seconds, Swiss (or any other homebrew) *should* load! | ||
|
||
## Credits | ||
|
||
Thank you to [FIX94](https://github.com/FIX94) for the gc-exploit-common-loader DOL loader, and for | ||
example code for memory card loaders in other GC savegame exploits. | ||
|
||
Thanks to [Essem](https://github.com/TheEssem) for testing on real hardware, and being the inspiration behind this | ||
[by just wanting a way to launch Swiss that isn't Animal Crossing.](https://wetdry.world/@esm/110792836912696997) | ||
|
||
## Building from Source | ||
|
||
The source has two components, the memory card loader and the GCI builder. The memory card loader will | ||
build if you have devkitPPC installed (although any powerpc-eabi GCC will work, change the Makefile). | ||
|
||
The GCI builder should build on any macOS/Linux system, and should be fine building under MingW64 on Windows. | ||
|
||
The Makefile in the root of the repository will compile the memcard loader for EUR and USA regions, | ||
compile the GCI builder, and then build the robohaxx GCI savefiles. Type `make` at a terminal. | ||
|
||
If you only want to build for a specific region, type `make usa` or `make eur`. | ||
|
||
## License | ||
|
||
The memory card loader and GCI builder are licensed under the GNU General Public License version 2. See attached | ||
LICENSE file for more details. | ||
|
||
This chain uses FIX94's [gc-exploit-common-loader](https://github.com/FIX94/gc-exploit-common-loader), also licensed | ||
under GPLv2. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# What toolchain prefix should we use | ||
# Most people who want to build this will have failkit already | ||
CROSS ?= $(DEVKITPPC)/bin/powerpc-eabi- | ||
|
||
# Set CC, LD, OBJCOPY based on CROSS, unless they are set already | ||
ifeq ($(origin CC), default) | ||
CC := $(CROSS)gcc -m32 | ||
endif | ||
ifeq ($(origin LD), default) | ||
LD := $(CROSS)ld | ||
endif | ||
OBJCOPY ?= $(CROSS)objcopy | ||
|
||
CFLAGS := -Wall -W -O1 -ffreestanding -mno-eabi -mno-sdata -fno-asynchronous-unwind-tables -mcpu=750 | ||
Q := | ||
|
||
SOURCES := memcard_loader.c | ||
OBJS := $(SOURCES:.c=.o) | ||
|
||
.PHONY: usa eur | ||
all: usa eur | ||
|
||
usa: robohaxx-USA.bin | ||
|
||
eur: robohaxx-EUR.bin | ||
|
||
robohaxx-USA.bin: robohaxx-USA.elf | ||
@echo " OBJCOPY $@" | ||
$(Q)$(OBJCOPY) -Obinary $< $@ | ||
|
||
robohaxx-USA.elf: $(OBJS) | ||
@echo " LINK $@" | ||
$(Q)$(LD) -T robohaxx-USA.ld $^ -o $@ | ||
|
||
robohaxx-EUR.bin: robohaxx-EUR.elf | ||
@echo " OBJCOPY $@" | ||
$(Q)$(OBJCOPY) -Obinary $< $@ | ||
|
||
robohaxx-EUR.elf: $(OBJS) | ||
@echo " LINK $@" | ||
$(Q)$(LD) -T robohaxx-EUR.ld $^ -o $@ | ||
|
||
$(OBJS): $(SOURCES) | ||
@echo " COMPILE $@" | ||
$(Q)$(CC) $(CFLAGS) -c $< -o $@ | ||
|
||
clean: | ||
@echo " CLEAN" | ||
@-rm -f $(OBJS) robohaxx-EUR.elf robohaxx-EUR.bin robohaxx-USA.elf robohaxx-USA.bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
Compiled version of FIX94's gc-exploit-common-loader DOL loading code. | ||
Source code is included within "loader.tar.gz". Also available on GitHub: | ||
https://github.com/FIX94/gc-exploit-common-loader | ||
Licensed under the GNU GPL version 2: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | ||
*/ | ||
|
||
#define loader_size 0x4bc | ||
|
||
const unsigned char loader[] = { | ||
0x7C, 0x60, 0x00, 0xA6, 0x54, 0x63, 0x04, 0x5E, 0x60, 0x63, 0x20, 0x00, 0x7C, 0x60, 0x01, 0x24, | ||
0x4C, 0x00, 0x01, 0x2C, 0x3C, 0x20, 0x80, 0x00, 0x38, 0x21, 0x26, 0xC0, 0x38, 0x00, 0x00, 0x00, | ||
0x94, 0x01, 0xFF, 0xC0, 0x3C, 0x60, 0x80, 0x00, 0x38, 0x63, 0x1C, 0xBC, 0x38, 0x80, 0x00, 0x00, | ||
0x3C, 0xA0, 0x80, 0x00, 0x38, 0xA5, 0x1E, 0xC0, 0x7C, 0xA3, 0x28, 0x50, 0x48, 0x00, 0x00, 0xAD, | ||
0x48, 0x00, 0x02, 0xB0, 0x39, 0x44, 0x00, 0x1F, 0x7D, 0x4A, 0x1A, 0x14, 0x55, 0x4A, 0x00, 0x34, | ||
0x54, 0x69, 0x00, 0x34, 0x7D, 0x29, 0x50, 0x50, 0x55, 0x29, 0xD9, 0x7F, 0x41, 0x82, 0x00, 0x1C, | ||
0x7D, 0x29, 0x03, 0xA6, 0x7C, 0x00, 0x18, 0x6C, 0x7C, 0x00, 0x1F, 0xAC, 0x38, 0x63, 0x00, 0x20, | ||
0x39, 0x29, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF0, 0x7C, 0x00, 0x04, 0xAC, 0x4C, 0x00, 0x01, 0x2C, | ||
0x4E, 0x80, 0x00, 0x20, 0x54, 0x8A, 0x84, 0x3E, 0x3D, 0x20, 0xCC, 0x00, 0x61, 0x29, 0x50, 0x20, | ||
0xB1, 0x49, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0x89, 0x00, 0x00, 0x54, 0xAA, 0x84, 0x3E, | ||
0x39, 0x29, 0x00, 0x02, 0xB1, 0x49, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0xA9, 0x00, 0x00, | ||
0x54, 0x63, 0x78, 0x20, 0x54, 0xC9, 0x84, 0x3E, 0x7C, 0x63, 0x4B, 0x78, 0x3D, 0x20, 0xCC, 0x00, | ||
0x61, 0x29, 0x50, 0x28, 0xB0, 0x69, 0x00, 0x00, 0x39, 0x29, 0x00, 0x02, 0xB0, 0xC9, 0x00, 0x00, | ||
0x3D, 0x40, 0xCC, 0x00, 0x61, 0x4A, 0x50, 0x0A, 0xA1, 0x2A, 0x00, 0x00, 0x71, 0x29, 0x02, 0x00, | ||
0x40, 0x82, 0xFF, 0xF8, 0x4E, 0x80, 0x00, 0x20, 0x2C, 0x05, 0x00, 0x00, 0x4D, 0x82, 0x00, 0x20, | ||
0x39, 0x23, 0xFF, 0xFF, 0x7C, 0xA9, 0x03, 0xA6, 0x9C, 0x89, 0x00, 0x01, 0x38, 0xA5, 0xFF, 0xFF, | ||
0x42, 0x00, 0xFF, 0xF8, 0x4E, 0x80, 0x00, 0x20, 0x2C, 0x05, 0x00, 0x00, 0x4D, 0x82, 0x00, 0x20, | ||
0x38, 0x84, 0xFF, 0xFF, 0x39, 0x23, 0xFF, 0xFF, 0x7C, 0xA9, 0x03, 0xA6, 0x8D, 0x44, 0x00, 0x01, | ||
0x9D, 0x49, 0x00, 0x01, 0x38, 0xA5, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x4E, 0x80, 0x00, 0x20, | ||
0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0x7D, 0x80, 0x00, 0x26, | ||
0x93, 0x61, 0x00, 0x1C, 0x93, 0x81, 0x00, 0x20, 0x93, 0xA1, 0x00, 0x24, 0x93, 0xC1, 0x00, 0x28, | ||
0x93, 0xE1, 0x00, 0x2C, 0x91, 0x81, 0x00, 0x0C, 0x7C, 0x7D, 0x1B, 0x78, 0x7C, 0x9E, 0x23, 0x78, | ||
0x54, 0xBC, 0x00, 0x2C, 0x70, 0xBB, 0x01, 0xFF, 0x40, 0x82, 0x00, 0x40, 0x2C, 0x1E, 0x00, 0x00, | ||
0x41, 0x82, 0x01, 0x54, 0x93, 0x01, 0x00, 0x10, 0x93, 0x21, 0x00, 0x14, 0x93, 0x41, 0x00, 0x18, | ||
0x3F, 0x40, 0x80, 0x00, 0x3B, 0x5A, 0x1C, 0xC0, 0x3B, 0x7A, 0x02, 0x1F, 0x57, 0x7B, 0x00, 0x34, | ||
0x7F, 0x7A, 0xD8, 0x50, 0x57, 0x7B, 0xD9, 0x7E, 0x2E, 0x1B, 0x00, 0x00, 0x3F, 0x00, 0x80, 0x00, | ||
0x7F, 0x59, 0xD3, 0x78, 0x48, 0x00, 0x00, 0xC8, 0x7C, 0xBF, 0x2B, 0x78, 0x3C, 0x80, 0x80, 0x00, | ||
0x38, 0x84, 0x1C, 0xC0, 0x39, 0x44, 0x02, 0x1F, 0x55, 0x4A, 0x00, 0x34, 0x7D, 0x44, 0x50, 0x50, | ||
0x55, 0x4A, 0xD9, 0x7F, 0x41, 0x82, 0x00, 0x1C, 0x7C, 0x89, 0x23, 0x78, 0x7D, 0x49, 0x03, 0xA6, | ||
0x7C, 0x00, 0x48, 0xAC, 0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, | ||
0x7C, 0x00, 0x04, 0xAC, 0x38, 0xC0, 0x02, 0x00, 0x7F, 0x85, 0xE3, 0x78, 0x38, 0x60, 0x00, 0x01, | ||
0x4B, 0xFF, 0xFE, 0x95, 0x7F, 0xC9, 0xF3, 0x78, 0x28, 0x1E, 0x02, 0x00, 0x40, 0x81, 0x00, 0x08, | ||
0x39, 0x20, 0x02, 0x00, 0x7F, 0xFF, 0xE0, 0x50, 0x7F, 0xE9, 0xFA, 0x14, 0x7F, 0xE5, 0xFB, 0x78, | ||
0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0, 0x7C, 0x84, 0xDA, 0x14, 0x7F, 0xA3, 0xEB, 0x78, | ||
0x4B, 0xFF, 0xFE, 0xE9, 0x7F, 0xE4, 0xFB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFE, 0x19, | ||
0x3B, 0x9C, 0x02, 0x00, 0x7F, 0xBD, 0xFA, 0x14, 0x7F, 0xDF, 0xF0, 0x50, 0x4B, 0xFF, 0xFF, 0x30, | ||
0x7F, 0xE5, 0xFB, 0x78, 0x7F, 0x24, 0xCB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFE, 0xBD, | ||
0x7F, 0xE4, 0xFB, 0x78, 0x7F, 0xA3, 0xEB, 0x78, 0x4B, 0xFF, 0xFD, 0xED, 0x3B, 0x9C, 0x02, 0x00, | ||
0x7F, 0xBD, 0xFA, 0x14, 0x7F, 0xDF, 0xF0, 0x51, 0x41, 0x82, 0x00, 0x50, 0x41, 0x92, 0x00, 0x20, | ||
0x7F, 0x6A, 0xDB, 0x78, 0x39, 0x38, 0x1C, 0xC0, 0x7F, 0x69, 0x03, 0xA6, 0x7C, 0x00, 0x48, 0xAC, | ||
0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x7C, 0x00, 0x04, 0xAC, | ||
0x38, 0xC0, 0x02, 0x00, 0x7F, 0x85, 0xE3, 0x78, 0x7F, 0x44, 0xD3, 0x78, 0x38, 0x60, 0x00, 0x01, | ||
0x4B, 0xFF, 0xFD, 0xE5, 0x7F, 0xDF, 0xF3, 0x78, 0x28, 0x1E, 0x02, 0x00, 0x40, 0xA1, 0xFF, 0x94, | ||
0x3B, 0xE0, 0x02, 0x00, 0x4B, 0xFF, 0xFF, 0x8C, 0x83, 0x01, 0x00, 0x10, 0x83, 0x21, 0x00, 0x14, | ||
0x83, 0x41, 0x00, 0x18, 0x80, 0x01, 0x00, 0x34, 0x81, 0x81, 0x00, 0x0C, 0x7C, 0x08, 0x03, 0xA6, | ||
0x83, 0x61, 0x00, 0x1C, 0x83, 0x81, 0x00, 0x20, 0x83, 0xA1, 0x00, 0x24, 0x83, 0xC1, 0x00, 0x28, | ||
0x83, 0xE1, 0x00, 0x2C, 0x7D, 0x80, 0x81, 0x20, 0x38, 0x21, 0x00, 0x30, 0x4E, 0x80, 0x00, 0x20, | ||
0x94, 0x21, 0xFE, 0xF0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x01, 0x14, 0x93, 0xA1, 0x01, 0x04, | ||
0x93, 0xC1, 0x01, 0x08, 0x93, 0xE1, 0x01, 0x0C, 0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0, | ||
0x39, 0x44, 0x02, 0x1F, 0x55, 0x4A, 0x00, 0x34, 0x7D, 0x44, 0x50, 0x50, 0x55, 0x4A, 0xD9, 0x7F, | ||
0x41, 0x82, 0x00, 0x1C, 0x7C, 0x89, 0x23, 0x78, 0x7D, 0x49, 0x03, 0xA6, 0x7C, 0x00, 0x48, 0xAC, | ||
0x39, 0x29, 0x00, 0x20, 0x39, 0x4A, 0xFF, 0xFF, 0x42, 0x00, 0xFF, 0xF4, 0x7C, 0x00, 0x04, 0xAC, | ||
0x38, 0xC0, 0x02, 0x00, 0x38, 0xA0, 0x00, 0x00, 0x38, 0x60, 0x00, 0x01, 0x4B, 0xFF, 0xFD, 0x39, | ||
0x38, 0xA0, 0x00, 0xE4, 0x3C, 0x80, 0x80, 0x00, 0x38, 0x84, 0x1C, 0xC0, 0x38, 0x61, 0x00, 0x08, | ||
0x4B, 0xFF, 0xFD, 0xA9, 0x3B, 0xE1, 0x00, 0x08, 0x7F, 0xFE, 0xFB, 0x78, 0x3B, 0xA0, 0x00, 0x07, | ||
0x48, 0x00, 0x00, 0x10, 0x3B, 0xDE, 0x00, 0x04, 0x37, 0xBD, 0xFF, 0xFF, 0x41, 0x82, 0x00, 0x28, | ||
0x80, 0x9E, 0x00, 0x90, 0x2C, 0x04, 0x00, 0x00, 0x41, 0xA2, 0xFF, 0xEC, 0x80, 0x7E, 0x00, 0x48, | ||
0x28, 0x03, 0x00, 0xFF, 0x40, 0xA1, 0xFF, 0xE0, 0x80, 0xBE, 0x00, 0x00, 0x4B, 0xFF, 0xFD, 0x95, | ||
0x4B, 0xFF, 0xFF, 0xD4, 0x3B, 0xC0, 0x00, 0x0B, 0x48, 0x00, 0x00, 0x10, 0x3B, 0xFF, 0x00, 0x04, | ||
0x37, 0xDE, 0xFF, 0xFF, 0x41, 0x82, 0x00, 0x28, 0x80, 0x9F, 0x00, 0xAC, 0x2C, 0x04, 0x00, 0x00, | ||
0x41, 0xA2, 0xFF, 0xEC, 0x80, 0x7F, 0x00, 0x64, 0x28, 0x03, 0x00, 0xFF, 0x40, 0xA1, 0xFF, 0xE0, | ||
0x80, 0xBF, 0x00, 0x1C, 0x4B, 0xFF, 0xFD, 0x5D, 0x4B, 0xFF, 0xFF, 0xD4, 0x81, 0x21, 0x00, 0xE8, | ||
0x7D, 0x28, 0x03, 0xA6, 0x4E, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, | ||
0x01, 0x7A, 0x52, 0x00, 0x04, 0x7C, 0x41, 0x01, 0x1B, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, | ||
0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0xFC, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2C, 0xFF, 0xFF, 0xFC, 0x6C, 0x00, 0x00, 0x00, 0x64, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0xFF, 0xFF, 0xFC, 0xBC, | ||
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x54, | ||
0xFF, 0xFF, 0xFC, 0xC8, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, | ||
0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFC, 0xDC, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x41, 0x0E, 0x30, | ||
0x49, 0x11, 0x41, 0x7F, 0x9B, 0x05, 0x9C, 0x04, 0x9D, 0x03, 0x9E, 0x02, 0x9F, 0x01, 0x05, 0x46, | ||
0x09, 0x48, 0x0A, 0x98, 0x08, 0x41, 0x99, 0x07, 0x41, 0x9A, 0x06, 0x4A, 0x0B, 0x66, 0x98, 0x08, | ||
0x99, 0x07, 0x9A, 0x06, 0x5F, 0xD8, 0x41, 0xD9, 0x41, 0xDA, 0x42, 0x09, 0x46, 0x0C, 0x41, 0x06, | ||
0x41, 0x46, 0x06, 0x46, 0x41, 0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1C, | ||
0x00, 0x00, 0x00, 0xB8, 0xFF, 0xFF, 0xFE, 0x4C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x41, 0x0E, 0x90, | ||
0x02, 0x45, 0x11, 0x41, 0x7F, 0x9D, 0x03, 0x9E, 0x02, 0x9F, 0x01, 0x00 | ||
}; |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
memcard_loader, a memory card boot.dol loader payload, for the robohaxx exploit | ||
Copyright 2023 Emma / InvoxiPlayGames | ||
This code is licensed to you under the terms of the GNU GPL, version 2; | ||
see file LICENSE or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | ||
*/ | ||
|
||
#include "loader.h" | ||
|
||
#define WORK_ADDR 0x80001800 | ||
#define VirtToPhys(x) (x & 0x017FFFFF) | ||
|
||
#define CARD_A 0 | ||
#define CARD_B 1 | ||
|
||
typedef unsigned int u32; | ||
typedef unsigned short u16; | ||
typedef unsigned char u8; | ||
typedef volatile unsigned int vu32; | ||
typedef volatile unsigned short vu16; | ||
|
||
// structure for an opened file from the card | ||
typedef struct _CARDFileInfo { | ||
int channel; | ||
int file_num; | ||
int offset; | ||
int length; | ||
u16 block; | ||
} CARDFileInfo; | ||
// structure for the file status returned by CARDGetStatus | ||
typedef struct _CARDFileStatus { | ||
char name[0x20]; | ||
int length; | ||
char unk[0x2C]; | ||
} CARDFileStatus; | ||
|
||
// funcs from the game that we need | ||
extern u32 OSDisableInterrupts(void); | ||
extern void __OSStopAudioSystem(void); | ||
extern void GXDrawDone(void); | ||
extern u32 DCFlushRange(void *address, u32 size); | ||
extern int CARDGetStatus(int card, int file_num, CARDFileStatus *status); | ||
extern int CARDFastOpen(int card, int file_num, CARDFileInfo *info); | ||
extern int CARDRead(CARDFileInfo *info, void *address, int length, int offset); | ||
extern int CARDClose(CARDFileInfo *info); | ||
extern int CARDUnmount(int card); | ||
extern void *_memcpy(void *dest, void *src, u32 size); | ||
extern int _memcmp(void *buf1, void *buf2, u32 len); | ||
|
||
// DMA to ARAM, this is inlined just to make my life easier | ||
// it's only used in one loop, should be fine | ||
static inline void ARAM_DMA(u32 direction, u32 mram, u32 aram, u32 len) { | ||
*(vu16 *)0xCC005020 = (mram >> 16); | ||
*(vu16 *)0xCC005022 = (mram & 0xFFFF); | ||
*(vu16 *)0xCC005024 = (aram >> 16); | ||
*(vu16 *)0xCC005026 = (aram & 0xFFFF); | ||
*(vu16 *)0xCC005028 = (direction << 15) | (direction >> 16); | ||
*(vu16 *)0xCC00502A = (len & 0xFFFF); | ||
while (*(vu16 *)0xCC00500A & 0x200); | ||
} | ||
|
||
void _start() { | ||
CARDFileInfo fileInfo; | ||
CARDFileStatus fileStatus; | ||
u32 readOffset = 0; | ||
int i = 0; | ||
|
||
// get game to shut up | ||
OSDisableInterrupts(); | ||
__OSStopAudioSystem(); | ||
GXDrawDone(); | ||
|
||
// set gameid in RAM to DOLX00 so we can load the boot.dol save | ||
*(vu32 *)0x80000000 = 0x444F4C58; | ||
*(vu16 *)0x80000004 = 0x3030; | ||
DCFlushRange((void*)0x80000000, 0x20); | ||
|
||
// find boot.dol on the memory card and open it | ||
for (i = 0; i < 127; i++) { | ||
if (CARDGetStatus(CARD_A, i, &fileStatus) != 0) | ||
continue; | ||
if (_memcmp(fileStatus.name, "boot.dol", 9) == 0) | ||
break; | ||
} | ||
CARDFastOpen(CARD_A, i, &fileInfo); | ||
// continually read it until we get an error, copying into ARAM | ||
while (CARDRead(&fileInfo, (void*)WORK_ADDR, 0x200, readOffset) == 0) { | ||
DCFlushRange((void*)WORK_ADDR, 0x200); | ||
ARAM_DMA(0, VirtToPhys(WORK_ADDR), readOffset, 0x200); | ||
readOffset += 0x200; | ||
} | ||
// unmount the card, we're done | ||
CARDClose(&fileInfo); | ||
CARDUnmount(CARD_A); | ||
|
||
// copy the DOL loader into the spare interrupt vectors | ||
_memcpy((void*)WORK_ADDR, (void*)loader, loader_size); | ||
DCFlushRange((void*)WORK_ADDR, loader_size); | ||
// jump! (if WORK_ADDR is changed, change this too) | ||
__asm__ volatile( | ||
"lis 3, 0x8000\n" | ||
"ori 3, 3, 0x1800\n" | ||
"mtlr 3\n" | ||
"blr\n" | ||
); | ||
|
||
// gcc, we shouldn't be here | ||
__builtin_unreachable(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
OUTPUT_FORMAT("elf32-powerpc") | ||
OUTPUT_ARCH(powerpc:common) | ||
|
||
SECTIONS { | ||
/* Game functions (GRBP6S) */ | ||
OSDisableInterrupts = 0x80026c6c; | ||
__OSStopAudioSystem = 0x80024958; | ||
GXDrawDone = 0x8001c8cc; | ||
DCFlushRange = 0x80024a70; | ||
CARDGetStatus = 0x80012ca4; | ||
CARDFastOpen = 0x80011b4c; | ||
CARDRead = 0x800124d0; | ||
CARDClose = 0x80011cac; | ||
CARDUnmount = 0x8001118c; | ||
_memcpy = 0x80003490; | ||
_memcmp = 0x80032350; | ||
|
||
/* Space right after profile name in memory after save file is loaded. */ | ||
. = 0x80E37750; | ||
.robohaxx 0x80E37750+0 : | ||
{ | ||
*.o(.start) | ||
*(.text) | ||
*(.rodata .rodata.*) | ||
*(.data) | ||
*(.bss) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
OUTPUT_FORMAT("elf32-powerpc") | ||
OUTPUT_ARCH(powerpc:common) | ||
|
||
SECTIONS { | ||
/* Game functions (GRBE6S) */ | ||
OSDisableInterrupts = 0x800255B0; | ||
__OSStopAudioSystem = 0x80023574; | ||
GXDrawDone = 0x8001AD28; | ||
DCFlushRange = 0x80023690; | ||
CARDGetStatus = 0x80011920; | ||
CARDFastOpen = 0x800107C8; | ||
CARDRead = 0x8001114C; | ||
CARDClose = 0x80010928; | ||
CARDUnmount = 0x8000FDFC; | ||
_memcpy = 0x80003490; | ||
_memcmp = 0x8002F4FC; | ||
|
||
/* Space right after profile name in memory after save file is loaded. */ | ||
. = 0x80E20370; | ||
.robohaxx 0x80E20370+0 : | ||
{ | ||
*.o(.start) | ||
*(.text) | ||
*(.rodata .rodata.*) | ||
*(.data) | ||
*(.bss) | ||
} | ||
} |
Oops, something went wrong.