Skip to content

Commit

Permalink
Add PoC switch homebrew build and minor clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
3096 committed Aug 6, 2018
1 parent 3c84b8e commit 82f8056
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 10 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@
*.lib

# Executables
splatsave
*.exe
*.out
*.app

# Switch
build/
*.elf
*.nacp
*.nro
*.nso
*.pfs0

# Test files
*.dat
*.enc
*.dec
194 changes: 191 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,198 @@
main : main.cpp
g++ main.cpp -o splatsave -std=c++11 -lmbedcrypto -lz
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------

TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/libnx/switch_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
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
# ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
#
# NO_ICON: if set to anything, do not use icon.
# NO_NACP: if set to anything, no .nacp file is generated.
# APP_TITLE is the name of the app stored in the .nacp file (Optional)
# APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
# APP_VERSION is the version of the app stored in the .nacp file (Optional)
# APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
# ICON is the filename of the icon (.jpg), relative to the project folder.
# If not set, it attempts to use one of the following (in this order):
# - <Project name>.jpg
# - icon.jpg
# - <libnx folder>/default_icon.jpg
#---------------------------------------------------------------------------------
TARGET := splatsave
BUILD := build
SOURCES := .
DATA := data
INCLUDES := include
EXEFS_SRC := exefs_src
#ROMFS := romfs

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE

CFLAGS := -g -Wall -O2 -ffunction-sections \
$(ARCH) $(DEFINES)

CFLAGS += $(INCLUDE) -D__SWITCH__

CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11

ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)

LIBS := -lmbedcrypto -lz -lnx

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(LIBNX)


#---------------------------------------------------------------------------------
# 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_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
export HFILES_BIN := $(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)

export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)

ifeq ($(strip $(ICON)),)
icons := $(wildcard *.jpg)
ifneq (,$(findstring $(TARGET).jpg,$(icons)))
export APP_ICON := $(TOPDIR)/$(TARGET).jpg
else
ifneq (,$(findstring icon.jpg,$(icons)))
export APP_ICON := $(TOPDIR)/icon.jpg
endif
endif
else
export APP_ICON := $(TOPDIR)/$(ICON)
endif

ifeq ($(strip $(NO_ICON)),)
export NROFLAGS += --icon=$(APP_ICON)
endif

ifeq ($(strip $(NO_NACP)),)
export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
endif

ifneq ($(APP_TITLEID),)
export NACPFLAGS += --titleid=$(APP_TITLEID)
endif

ifneq ($(ROMFS),)
export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
endif

.PHONY: $(BUILD) clean switch bin win
#---------------------------------------------------------------------------------
bin: main.cpp
g++ main.cpp -o splatsave -std=c++11 -lmbedcrypto -lz
#---------------------------------------------------------------------------------
# Windows rule to use with mingw, mingw openssl pre-built binary: https://wiki.openssl.org/index.php/Binaries
win: main.cpp
g++ main.cpp -o splatsave.exe -std=c++11 -lmbedcrypto -static-libstdc++ -static-libgcc
g++ main.cpp -o splatsave.exe -std=c++11 -lmbedcrypto -lz -static-libstdc++ -static-libgcc

#---------------------------------------------------------------------------------
switch: $(BUILD)

$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).pfs0 $(TARGET).nso $(TARGET).nro $(TARGET).nacp $(TARGET).elf
$(RM) splatsave
$(RM) splatsave.exe


#---------------------------------------------------------------------------------
else
.PHONY: switch

DEPENDS := $(OFILES:.o=.d)

#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
switch : $(OUTPUT).pfs0 $(OUTPUT).nro

$(OUTPUT).pfs0 : $(OUTPUT).nso

$(OUTPUT).nso : $(OUTPUT).elf

ifeq ($(strip $(NO_NACP)),)
$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp
else
$(OUTPUT).nro : $(OUTPUT).elf
endif

$(OUTPUT).elf : $(OFILES)

$(OFILES_SRC) : $(HFILES_BIN)

#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
66 changes: 59 additions & 7 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include <mbedtls/ctr_drbg.h>
#include <zlib.h>

#ifdef __SWITCH__
#include <switch.h>
#endif

const int FILE_SIZE[4] = {0x483B0, 0x483B0, 0x86840, 0x88D90};

const int BODY_SIZE[4] = {0x483A0, 0x483A0, 0x86800, 0x88D50};
Expand Down Expand Up @@ -122,21 +126,28 @@ int calcAes128Cmac(uint8_t* msg, size_t msg_len, uint8_t* key, uint8_t* mac) {
}

int rand_bytes(uint8_t* output, size_t output_len) {
int ret;
#ifndef __SWITCH__
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);

std::string pers = "Flow best waifu";

int ret;
if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(unsigned char*)pers.c_str(), pers.size())) != 0) {
return ret;
}
if((ret = mbedtls_ctr_drbg_random(&ctr_drbg, output, output_len)) != 0) {
ret = mbedtls_ctr_drbg_random(&ctr_drbg, output, output_len);
#else
if((ret = csrngInitialize()) != 0) {
return ret;
}
ret = csrngGetRandomBytes(output, output_len);
csrngExit();
#endif
return ret;
}

SaveFooter encryptBody(uint8_t* save_file, const uint32_t* crypt_tab,
Expand Down Expand Up @@ -193,7 +204,7 @@ int decryptBody(uint8_t* save_file, const uint32_t* crypt_tab,
return 0;
}

int main(int argc, char const *argv[]) {
int splatsave(int argc, char const *argv[]) {
std::string path;
if (argc < 2)
path = "save.dat";
Expand All @@ -204,8 +215,20 @@ int main(int argc, char const *argv[]) {
std::streamsize size = fileis.tellg();
fileis.seekg(0, std::ios::beg);

uint8_t save_file[size];
if (!fileis.read((char*)save_file, size)) {
uint8_t* save_file;
bool fileis_error = false;
if(size > -1) {
save_file = new uint8_t[size];
if(!fileis.read((char*)save_file, size)) {
delete[] save_file;
fileis_error = true;
}
} else {
fileis_error = true;
}

if (fileis_error) {
fileis.close();

std::cout << "Could not open " << path << std::endl;
std::cout << "Usage: " << std::endl;
Expand All @@ -219,6 +242,7 @@ int main(int argc, char const *argv[]) {
<< std::endl;
return -1;
}
fileis.close();

uint32_t vers = *(uint32_t*)save_file;

Expand Down Expand Up @@ -257,7 +281,7 @@ int main(int argc, char const *argv[]) {
else
out_path = argv[2];

uint8_t new_body[BODY_SIZE[vers]];
uint8_t* new_body = new uint8_t[BODY_SIZE[vers]];
SaveFooter footer;

if(isEncrypt) {
Expand All @@ -278,6 +302,8 @@ int main(int argc, char const *argv[]) {

std::ofstream fileos(out_path, std::fstream::binary);
if(!fileos) {
fileos.close();
delete[] new_body;
std::cout << "Could not open " << out_path << std::endl;
return -2;
}
Expand All @@ -291,6 +317,32 @@ int main(int argc, char const *argv[]) {
} else {
std::cout << "Decrypted " << path << " to " << out_path << "!"
<< std::endl;
}
}

fileos.close();
delete[] save_file;
delete[] new_body;

return 0;
}

int main(int argc, char const *argv[]) {
#ifdef __SWITCH__
gfxInitDefault();
consoleInit(NULL);
#endif

int ret = splatsave(argc, argv);

#ifdef __SWITCH__
std::cout << "Press + to exit..." << std::endl;
while(appletMainLoop()) {
hidScanInput(); u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
if (kDown & KEY_PLUS) break;
gfxFlushBuffers(); gfxSwapBuffers(); gfxWaitForVsync();
}
gfxExit();
#endif

return ret;
}

0 comments on commit 82f8056

Please sign in to comment.