mirror of
https://github.com/pret/pokeheartgold.git
synced 2026-03-21 17:25:33 -05:00
Address review comments
- all local vars to camelcase - header include guards with lib name - comments for preprocessor directives - asm defs back to respective .inc files - /lib/dsprot/tools/ merged to /tools/ - unprefixed globals prefixed - sdk defs consolidated to sdk include - lsf lib split to objects
This commit is contained in:
parent
6ed1d7eb09
commit
008118b6b3
2
Makefile
2
Makefile
|
|
@ -26,7 +26,7 @@ BANNER_SPEC := $(buildname)/banner.bsf
|
|||
ICON_PNG := $(buildname)/icon.png
|
||||
HEADER_TEMPLATE := $(buildname)/rom_header_template.sbin
|
||||
|
||||
.PHONY: main sub libsyscall sdk sdk9 sdk7
|
||||
.PHONY: main sub dsprot libsyscall sdk sdk9 sdk7
|
||||
.PRECIOUS: $(ROM)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
|
|
|||
|
|
@ -213,3 +213,7 @@
|
|||
.public ov01_02208BFC
|
||||
.public ov02_0224F864
|
||||
.public ov02_0224F8F4
|
||||
.public DSProt_DetectFlashcart
|
||||
.public DSProt_DetectDummy
|
||||
.public DSProt_DetectNotFlashcart
|
||||
.public DSProt_DetectNotEmulator
|
||||
|
|
|
|||
|
|
@ -292,3 +292,6 @@
|
|||
.public ov18_021F89D0
|
||||
.public ov18_021F95AC
|
||||
.public ov18_021F95F8
|
||||
.public DSProt_DetectFlashcart
|
||||
.public DSProt_DetectEmulator
|
||||
.public DSProt_DetectNotDummy
|
||||
|
|
|
|||
|
|
@ -164,3 +164,6 @@
|
|||
.public ov27_0225C398
|
||||
.public ov27_0225C418
|
||||
.public ov27_0225C41C
|
||||
.public DSProt_DetectFlashcart
|
||||
.public DSProt_DetectNotEmulator
|
||||
.public DSProt_DetectNotDummy
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include "constants/items.h"
|
||||
#include "msgdata/msg/msg_0096_D31R0201.h"
|
||||
#include "msgdata/msg/msg_0066_D23R0102.h"
|
||||
#include "dsprot.h"
|
||||
.include "asm/macros.inc"
|
||||
.include "overlay_01_021E5900.inc"
|
||||
.include "global.inc"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include "dsprot.h"
|
||||
.include "asm/macros.inc"
|
||||
.include "overlay_18.inc"
|
||||
.include "global.inc"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include "dsprot.h"
|
||||
.include "asm/macros.inc"
|
||||
.include "overlay_27.inc"
|
||||
.include "global.inc"
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ MSGENC := $(TOOLSDIR)/msgenc/msgenc$(EXE)
|
|||
ASPATCH := $(TOOLSDIR)/mwasmarm_patcher/mwasmarm_patcher$(EXE)
|
||||
CSV2BIN := $(TOOLSDIR)/csv2bin/csv2bin$(EXE)
|
||||
MKFXCONST := $(TOOLSDIR)/gen_fx_consts/gen_fx_consts$(EXE)
|
||||
ELFCODER := $(TOOLSDIR)/elfcoder/elfcoder$(EXE)
|
||||
|
||||
# Decompiled NitroSDK tools
|
||||
COMPSTATIC := $(TOOLSDIR)/compstatic/compstatic$(EXE)
|
||||
|
|
@ -70,7 +71,8 @@ NATIVE_TOOLS := \
|
|||
$(ASPATCH) \
|
||||
$(CSV2BIN) \
|
||||
$(MKFXCONST) \
|
||||
$(COMPSTATIC)
|
||||
$(COMPSTATIC) \
|
||||
$(ELFCODER)
|
||||
|
||||
TOOLDIRS := $(foreach tool,$(NATIVE_TOOLS),$(dir $(tool)))
|
||||
|
||||
|
|
|
|||
7
lib/dsprot/.gitignore
vendored
7
lib/dsprot/.gitignore
vendored
|
|
@ -1,8 +1 @@
|
|||
**/build/**
|
||||
tools/mwccarm/**
|
||||
*.exe
|
||||
*.dll
|
||||
*.o
|
||||
*.so
|
||||
*.a
|
||||
*.d
|
||||
|
|
|
|||
|
|
@ -2,44 +2,36 @@
|
|||
# See doc/BUILD_OVERVIEW.TXT for a clearer outline of this build process
|
||||
# ===================================================================
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
# Need GLB_DEFINES and CLI_DEFINES from config
|
||||
include ../../config.mk
|
||||
|
||||
# Undef this from config.mk so common.mk knows this is not building a linked elf
|
||||
ELFNAME :=
|
||||
|
||||
MWCCVER := 2.0/sp2p3
|
||||
|
||||
# Relevant directories
|
||||
BUILD_DIR := ./build
|
||||
C_OBJ_DIR := $(BUILD_DIR)/src
|
||||
SRC_DIR := ./src
|
||||
INC_DIR := ./include
|
||||
TOOL_DIR := ./tools
|
||||
BUILD_DIR := ./build
|
||||
C_OBJ_DIR := $(BUILD_DIR)/src
|
||||
SRC_DIR := ./src
|
||||
INC_DIR := ./include
|
||||
SYSINC_DIR := ../include
|
||||
|
||||
include ../../common.mk
|
||||
|
||||
ifeq ($(NODEP),)
|
||||
DEP_PARAM := -gccdep -MD
|
||||
include $(wildcard $(C_OBJ_DIR)/*.d)
|
||||
else
|
||||
DEP_PARAM :=
|
||||
endif
|
||||
|
||||
INSTALL_PREFIX ?= ./install
|
||||
INSTALL_LIBDIR := $(INSTALL_PREFIX)/lib
|
||||
|
||||
ELFCODER_DIR := $(TOOL_DIR)/elfcoder
|
||||
|
||||
# Tools
|
||||
ELFCODER := $(ELFCODER_DIR)/build/elfcoder$(EXE)
|
||||
INSTALL_LIBDIR := $(INSTALL_PREFIX)/lib/dsprot
|
||||
|
||||
# C / ASM compilation parameters
|
||||
CC_PARAM := -O4,p -enum int -proc arm946E -gccext,on -fp soft -lang c99 -char signed -inline on,noauto -Cpp_exceptions off -interworking -i $(INC_DIR) -c
|
||||
ASM_PARAM := -proc arm5TE -i $(INC_DIR)
|
||||
LIB_PARAM := -nostdlib -library
|
||||
|
||||
CC_PARAM := -O4,p -enum int -proc arm946E -gccext,on -fp soft -lang c99 -char signed -inline on,noauto -Cpp_exceptions off -interworking -gccinc -i $(INC_DIR) -I$(SYSINC_DIR) -c $(GLB_DEFINES) $(CLI_DEFINES)
|
||||
CC_PARAM += -W all -W pedantic -W noimpl_signedunsigned -W noimplicitconv -W nounusedarg -W nomissingreturn -W error
|
||||
|
||||
# Output library file
|
||||
LIBRARY_NAME := dsprot.a
|
||||
LIBRARY := $(BUILD_DIR)/$(LIBRARY_NAME)
|
||||
ASM_PARAM := -proc arm5TE -i $(INC_DIR)
|
||||
|
||||
# Files (in this specific order) that will go into the library
|
||||
LIBRARY_FILES := \
|
||||
|
|
@ -62,36 +54,24 @@ LIBRARY_FILES := \
|
|||
$(BUILD_DIR)/rc4_encoded.o \
|
||||
$(BUILD_DIR)/rc4_decoder.o
|
||||
|
||||
# Encryption keys
|
||||
KEY_DSPROT_MAIN := 6AB2
|
||||
KEY_INTEGRITY := 9785
|
||||
KEY_CORE_TESTS := 0982
|
||||
|
||||
.PHONY: all clean tidy tools dsprot install
|
||||
.DELETE_ON_ERROR:
|
||||
.NOTPARALLEL:
|
||||
.SECONDARY: none
|
||||
|
||||
all:
|
||||
$(MAKE) tools
|
||||
$(MAKE) dsprot
|
||||
all: dsprot
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(ELFCODER_DIR) clean
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
tidy: clean
|
||||
|
||||
tools:
|
||||
$(MAKE) -C $(ELFCODER_DIR)
|
||||
dsprot: $(LIBRARY_FILES)
|
||||
|
||||
dsprot:
|
||||
$(MAKE) $(LIBRARY)
|
||||
|
||||
install:
|
||||
$(MAKE) all
|
||||
install: all
|
||||
$(shell mkdir -p $(INSTALL_LIBDIR))
|
||||
cp $(LIBRARY) $(INSTALL_LIBDIR)
|
||||
cp $(LIBRARY_FILES) $(INSTALL_LIBDIR)
|
||||
|
||||
|
||||
# Assembly assembling
|
||||
|
|
@ -105,65 +85,101 @@ $(C_OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
|||
@$(call fixdep,$(@:.o=.d))
|
||||
|
||||
|
||||
# Library output
|
||||
$(LIBRARY): $(LIBRARY_FILES)
|
||||
$(WINE) $(MWLD) $(LIB_PARAM) $^ -o $@
|
||||
|
||||
|
||||
# Main module function encoding
|
||||
KEY_DSPROT_MAIN := 6AB2
|
||||
|
||||
DSPROT_MAIN_ENCRYPTION_REPLACE_PREFIX := DSProtInternal_
|
||||
DSPROT_MAIN_ENCRYPTION_PREFIX := DSProt_
|
||||
DSPROT_MAIN_ENCRYPTED_FUNCTIONS := \
|
||||
DSProtInternal_DetectFlashcart \
|
||||
DSProtInternal_DetectNotFlashcart \
|
||||
DSProtInternal_DetectEmulator \
|
||||
DSProtInternal_DetectNotEmulator \
|
||||
DSProtInternal_DetectDummy \
|
||||
DSProtInternal_DetectNotDummy
|
||||
|
||||
DSPROT_MAIN_ADDED_REF := DSProt_Garbage
|
||||
DSPROT_MAIN_ENCODED_FUNCTIONS := \
|
||||
DSProt_DetectFlashcart \
|
||||
DSProt_DetectNotFlashcart \
|
||||
DSProt_DetectEmulator \
|
||||
DSProt_DetectNotEmulator \
|
||||
DSProt_DetectDummy \
|
||||
DSProt_DetectNotDummy
|
||||
|
||||
$(BUILD_DIR)/dsprot_main_decrypter_encoded.o \
|
||||
$(BUILD_DIR)/dsprot_main_decrypter_decoder.s: $(BUILD_DIR)/dsprot_main_decrypter.o $(ELFCODER)
|
||||
cp $(BUILD_DIR)/dsprot_main_decrypter.o $(BUILD_DIR)/dsprot_main_decrypter_encoded.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/dsprot_main_decrypter_encoded.o -o $(BUILD_DIR)/dsprot_main_decrypter_decoder.s -g Garbage -f \
|
||||
DSProt_DetectFlashcart \
|
||||
DSProt_DetectNotFlashcart \
|
||||
DSProt_DetectEmulator \
|
||||
DSProt_DetectNotEmulator \
|
||||
DSProt_DetectDummy \
|
||||
DSProt_DetectNotDummy
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/dsprot_main_decrypter_encoded.o -o $(BUILD_DIR)/dsprot_main_decrypter_decoder.s -g $(DSPROT_MAIN_ADDED_REF) -f $(DSPROT_MAIN_ENCODED_FUNCTIONS)
|
||||
|
||||
$(BUILD_DIR)/dsprot_main_encrypted.o \
|
||||
$(BUILD_DIR)/dsprot_main_decrypter.s: $(C_OBJ_DIR)/dsprot_main.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/dsprot_main.o $(BUILD_DIR)/dsprot_main_encrypted.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/dsprot_main_encrypted.o -o $(BUILD_DIR)/dsprot_main_decrypter.s -k $(KEY_DSPROT_MAIN) -p DSProt_ -f \
|
||||
DetectFlashcart \
|
||||
DetectNotFlashcart \
|
||||
DetectEmulator \
|
||||
DetectNotEmulator \
|
||||
DetectDummy \
|
||||
DetectNotDummy
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/dsprot_main_encrypted.o -o $(BUILD_DIR)/dsprot_main_decrypter.s -k $(KEY_DSPROT_MAIN) -p $(DSPROT_MAIN_ENCRYPTION_PREFIX) -r $(DSPROT_MAIN_ENCRYPTION_REPLACE_PREFIX) -f $(DSPROT_MAIN_ENCRYPTED_FUNCTIONS)
|
||||
|
||||
|
||||
# Integrity module function encoding
|
||||
KEY_INTEGRITY := 9785
|
||||
|
||||
# Default prefix (RunEncrypted_)
|
||||
INTEGRITY_ENCRYPTED_FUNCTIONS := \
|
||||
Integrity_MACOwner_IsBad \
|
||||
Integrity_MACOwner_IsGood \
|
||||
Integrity_ROMTest_IsBad \
|
||||
Integrity_ROMTest_IsGood
|
||||
|
||||
INTEGRITY_ENCODED_FUNCTIONS := \
|
||||
RunEncrypted_Integrity_MACOwner_IsBad \
|
||||
RunEncrypted_Integrity_MACOwner_IsGood \
|
||||
RunEncrypted_Integrity_ROMTest_IsBad \
|
||||
RunEncrypted_Integrity_ROMTest_IsGood
|
||||
|
||||
$(BUILD_DIR)/integrity_decrypter_encoded.o \
|
||||
$(BUILD_DIR)/integrity_decrypter_decoder.s: $(BUILD_DIR)/integrity_decrypter.o $(ELFCODER)
|
||||
cp $(BUILD_DIR)/integrity_decrypter.o $(BUILD_DIR)/integrity_decrypter_encoded.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/integrity_decrypter_encoded.o -o $(BUILD_DIR)/integrity_decrypter_decoder.s -f \
|
||||
RunEncrypted_Integrity_MACOwner_IsBad \
|
||||
RunEncrypted_Integrity_MACOwner_IsGood \
|
||||
RunEncrypted_Integrity_ROMTest_IsBad \
|
||||
RunEncrypted_Integrity_ROMTest_IsGood
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/integrity_decrypter_encoded.o -o $(BUILD_DIR)/integrity_decrypter_decoder.s -f $(INTEGRITY_ENCODED_FUNCTIONS)
|
||||
|
||||
$(BUILD_DIR)/integrity_encrypted.o \
|
||||
$(BUILD_DIR)/integrity_decrypter.s: $(C_OBJ_DIR)/integrity.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/integrity.o $(BUILD_DIR)/integrity_encrypted.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/integrity_encrypted.o -o $(BUILD_DIR)/integrity_decrypter.s -k $(KEY_INTEGRITY) -f \
|
||||
Integrity_MACOwner_IsBad \
|
||||
Integrity_MACOwner_IsGood \
|
||||
Integrity_ROMTest_IsBad \
|
||||
Integrity_ROMTest_IsGood
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/integrity_encrypted.o -o $(BUILD_DIR)/integrity_decrypter.s -k $(KEY_INTEGRITY) -f $(INTEGRITY_ENCRYPTED_FUNCTIONS)
|
||||
|
||||
|
||||
# Encryptor module function encoding
|
||||
ENCRYPTOR_ENCODED_FUNCTIONS := \
|
||||
Encryptor_EncryptFunction \
|
||||
Encryptor_DecryptFunction
|
||||
|
||||
$(BUILD_DIR)/encryptor_encoded.o \
|
||||
$(BUILD_DIR)/encryptor_decoder.s: $(C_OBJ_DIR)/encryptor.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/encryptor.o $(BUILD_DIR)/encryptor_encoded.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/encryptor_encoded.o -o $(BUILD_DIR)/encryptor_decoder.s -f \
|
||||
Encryptor_EncryptFunction \
|
||||
Encryptor_DecryptFunction
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/encryptor_encoded.o -o $(BUILD_DIR)/encryptor_decoder.s -f $(ENCRYPTOR_ENCODED_FUNCTIONS)
|
||||
|
||||
|
||||
# Core tests module: MAC/Owner, ROM utilities, ROM tests function encoding
|
||||
KEY_CORE_TESTS := 0982
|
||||
|
||||
# Default prefix (RunEncrypted_)
|
||||
MACOWNER_ENCRYPTED_FUNCTIONS := \
|
||||
MACOwner_IsBad \
|
||||
MACOwner_IsGood
|
||||
|
||||
ROMUTIL_ENCRYPTED_FUNCTIONS := \
|
||||
ROMUtil_Read \
|
||||
ROMUtil_CRC32
|
||||
|
||||
ROMTEST_ENCRYPTED_FUNCTIONS := \
|
||||
ROMTest_IsBad \
|
||||
ROMTest_IsGood
|
||||
|
||||
CORETESTS_ENCODED_FUNCTIONS := \
|
||||
RunEncrypted_ROMTest_IsBad \
|
||||
RunEncrypted_ROMTest_IsGood \
|
||||
RunEncrypted_MACOwner_IsBad \
|
||||
RunEncrypted_MACOwner_IsGood \
|
||||
RunEncrypted_ROMUtil_Read \
|
||||
RunEncrypted_ROMUtil_CRC32
|
||||
|
||||
$(BUILD_DIR)/mac_owner_decrypter_encoded.o \
|
||||
$(BUILD_DIR)/rom_util_decrypter_encoded.o \
|
||||
$(BUILD_DIR)/rom_test_decrypter_encoded.o \
|
||||
|
|
@ -171,45 +187,35 @@ $(BUILD_DIR)/coretests_decrypter_decoder.s: $(BUILD_DIR)/mac_owner_decrypter.o $
|
|||
cp $(BUILD_DIR)/mac_owner_decrypter.o $(BUILD_DIR)/mac_owner_decrypter_encoded.o
|
||||
cp $(BUILD_DIR)/rom_util_decrypter.o $(BUILD_DIR)/rom_util_decrypter_encoded.o
|
||||
cp $(BUILD_DIR)/rom_test_decrypter.o $(BUILD_DIR)/rom_test_decrypter_encoded.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/mac_owner_decrypter_encoded.o $(BUILD_DIR)/rom_util_decrypter_encoded.o $(BUILD_DIR)/rom_test_decrypter_encoded.o -o $(BUILD_DIR)/coretests_decrypter_decoder.s -f \
|
||||
RunEncrypted_ROMTest_IsBad \
|
||||
RunEncrypted_ROMTest_IsGood \
|
||||
RunEncrypted_MACOwner_IsBad \
|
||||
RunEncrypted_MACOwner_IsGood \
|
||||
RunEncrypted_ROMUtil_Read \
|
||||
RunEncrypted_ROMUtil_CRC32
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/mac_owner_decrypter_encoded.o $(BUILD_DIR)/rom_util_decrypter_encoded.o $(BUILD_DIR)/rom_test_decrypter_encoded.o -o $(BUILD_DIR)/coretests_decrypter_decoder.s -f $(CORETESTS_ENCODED_FUNCTIONS)
|
||||
|
||||
$(BUILD_DIR)/mac_owner_encrypted.o \
|
||||
$(BUILD_DIR)/mac_owner_decrypter.s: $(C_OBJ_DIR)/mac_owner.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/mac_owner.o $(BUILD_DIR)/mac_owner_encrypted.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/mac_owner_encrypted.o -o $(BUILD_DIR)/mac_owner_decrypter.s -k $(KEY_CORE_TESTS) -f \
|
||||
MACOwner_IsBad \
|
||||
MACOwner_IsGood
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/mac_owner_encrypted.o -o $(BUILD_DIR)/mac_owner_decrypter.s -k $(KEY_CORE_TESTS) -f $(MACOWNER_ENCRYPTED_FUNCTIONS)
|
||||
|
||||
$(BUILD_DIR)/rom_util_encrypted.o \
|
||||
$(BUILD_DIR)/rom_util_decrypter.s: $(C_OBJ_DIR)/rom_util.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/rom_util.o $(BUILD_DIR)/rom_util_encrypted.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rom_util_encrypted.o -o $(BUILD_DIR)/rom_util_decrypter.s -k $(KEY_CORE_TESTS) -f \
|
||||
ROMUtil_Read \
|
||||
ROMUtil_CRC32
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rom_util_encrypted.o -o $(BUILD_DIR)/rom_util_decrypter.s -k $(KEY_CORE_TESTS) -f $(ROMUTIL_ENCRYPTED_FUNCTIONS)
|
||||
|
||||
$(BUILD_DIR)/rom_test_encrypted.o \
|
||||
$(BUILD_DIR)/rom_test_decrypter.s: $(C_OBJ_DIR)/rom_test.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/rom_test.o $(BUILD_DIR)/rom_test_encrypted.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rom_test_encrypted.o -o $(BUILD_DIR)/rom_test_decrypter.s -k $(KEY_CORE_TESTS) -f \
|
||||
ROMTest_IsBad \
|
||||
ROMTest_IsGood
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rom_test_encrypted.o -o $(BUILD_DIR)/rom_test_decrypter.s -k $(KEY_CORE_TESTS) -f $(ROMTEST_ENCRYPTED_FUNCTIONS)
|
||||
|
||||
|
||||
# RC4 module function encoding
|
||||
RC4_ENCODED_FUNCTIONS := \
|
||||
RC4_Init \
|
||||
RC4_Byte \
|
||||
RC4_InitSBox \
|
||||
RC4_EncryptInstructions \
|
||||
RC4_DecryptInstructions \
|
||||
RC4_InitAndEncryptInstructions \
|
||||
RC4_InitAndDecryptInstructions
|
||||
|
||||
$(BUILD_DIR)/rc4_encoded.o \
|
||||
$(BUILD_DIR)/rc4_decoder.s: $(C_OBJ_DIR)/rc4.o $(ELFCODER)
|
||||
cp $(C_OBJ_DIR)/rc4.o $(BUILD_DIR)/rc4_encoded.o
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rc4_encoded.o -o $(BUILD_DIR)/rc4_decoder.s -f \
|
||||
RC4_Init \
|
||||
RC4_Byte \
|
||||
RC4_InitSBox \
|
||||
RC4_EncryptInstructions \
|
||||
RC4_DecryptInstructions \
|
||||
RC4_InitAndEncryptInstructions \
|
||||
RC4_InitAndDecryptInstructions
|
||||
$(ELFCODER) -e -i $(BUILD_DIR)/rc4_encoded.o -o $(BUILD_DIR)/rc4_decoder.s -f $(RC4_ENCODED_FUNCTIONS)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
Module 1 (main):
|
||||
Functions:
|
||||
DetectFlashcart
|
||||
DetectNotFlashcart
|
||||
DetectEmulator
|
||||
DetectNotEmulator
|
||||
DetectDummy
|
||||
DetectNotDummy
|
||||
DSProtInternal_DetectFlashcart
|
||||
DSProtInternal_DetectNotFlashcart
|
||||
DSProtInternal_DetectEmulator
|
||||
DSProtInternal_DetectNotEmulator
|
||||
DSProtInternal_DetectDummy
|
||||
DSProtInternal_DetectNotDummy
|
||||
|
||||
Encrypt and create decryption wrappers (key=0x6AB2, prefix=DSProt_):
|
||||
DetectFlashcart
|
||||
DetectNotFlashcart
|
||||
DetectEmulator
|
||||
DetectNotEmulator
|
||||
DetectDummy
|
||||
DetectNotDummy
|
||||
Encrypt and create decryption wrappers (key=0x6AB2, replace_prefix=DSProtInternal_, prefix=DSProt_):
|
||||
DSProtInternal_DetectFlashcart
|
||||
DSProtInternal_DetectNotFlashcart
|
||||
DSProtInternal_DetectEmulator
|
||||
DSProtInternal_DetectNotEmulator
|
||||
DSProtInternal_DetectDummy
|
||||
DSProtInternal_DetectNotDummy
|
||||
|
||||
Encode and create decoder function:
|
||||
DSProt_DetectFlashcart
|
||||
|
|
|
|||
|
|
@ -19,7 +19,15 @@
|
|||
.endm
|
||||
|
||||
|
||||
.public BSS
|
||||
.macro sinit sinit_func
|
||||
.type NitroStaticInit_, @object
|
||||
NitroStaticInit_:
|
||||
.word \sinit_func
|
||||
.size NitroStaticInit_, .-NitroStaticInit_
|
||||
.endm
|
||||
|
||||
|
||||
.public DSProt_BSS
|
||||
.public Encryptor_DecryptFunction
|
||||
.public Encryptor_EncryptFunction
|
||||
|
||||
|
|
@ -51,11 +59,11 @@
|
|||
str pc, storage_\@ ; Store `pc` in its place, presumably just to overwrite the return address.
|
||||
bx lr ; Return with return value from inner function.
|
||||
storage_\@:
|
||||
.word BSS + 1
|
||||
.word DSProt_BSS + 1
|
||||
length_\@:
|
||||
.word BSS + \length + ENC_VAL_1
|
||||
.word DSProt_BSS + \length + ENC_VAL_1
|
||||
key_\@:
|
||||
.word BSS + \key + ENC_VAL_1
|
||||
.word DSProt_BSS + \key + ENC_VAL_1
|
||||
func_\@:
|
||||
.word \func + ENC_VAL_1
|
||||
.endm
|
||||
|
|
@ -71,7 +79,7 @@ func_\@:
|
|||
.endm
|
||||
|
||||
.macro func_table_entry func, size
|
||||
.word \func + ENC_VAL_1, BSS + \size + ENC_VAL_1
|
||||
.word \func + ENC_VAL_1, DSProt_BSS + \size + ENC_VAL_1
|
||||
.endm
|
||||
|
||||
.macro func_table_end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef BSS_H
|
||||
#define BSS_H
|
||||
#ifndef DSPROT_BSS_H
|
||||
#define DSPROT_BSS_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
extern u8 BSS[4];
|
||||
extern u8 DSProt_BSS[4];
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_BSS_H
|
||||
|
|
|
|||
14
lib/dsprot/include/dsprot_main.h
Normal file
14
lib/dsprot/include/dsprot_main.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef DSPROT_MAIN_H
|
||||
#define DSPROT_MAIN_H
|
||||
|
||||
#include "sdk.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 DSProtInternal_DetectFlashcart(void *callback);
|
||||
u32 DSProtInternal_DetectNotFlashcart(void *callback);
|
||||
u32 DSProtInternal_DetectEmulator(void *callback);
|
||||
u32 DSProtInternal_DetectNotEmulator(void *callback);
|
||||
u32 DSProtInternal_DetectDummy(void *callback);
|
||||
u32 DSProtInternal_DetectNotDummy(void *callback);
|
||||
|
||||
#endif // DSPROT_MAIN_H
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
#ifndef ENCODING_CONSTANTS_H
|
||||
#define ENCODING_CONSTANTS_H
|
||||
#ifndef DSPROT_ENCODING_CONSTANTS_H
|
||||
#define DSPROT_ENCODING_CONSTANTS_H
|
||||
|
||||
#define INS_OPCODE_LINKBIT (0x01)
|
||||
#define INS_OPCODE_MASK (0xFF000000)
|
||||
#define INS_OPCODE_SHIFT (24)
|
||||
#define INS_OPERANDS_MASK (0x00FFFFFF)
|
||||
|
||||
#ifndef SDK_ASM
|
||||
#define ADDR_PLUS_ADDEND(ref, addend) ((u32)(&ref + ((addend) / sizeof(ref))))
|
||||
#endif // SDK_ASM
|
||||
|
||||
#define ENC_VAL_1 (0x1300)
|
||||
#define ENC_VAL_2 ((ENC_VAL_1 >> 2) + 2)
|
||||
|
|
@ -18,4 +20,4 @@
|
|||
|
||||
#define ENC_SBOX_XOR (0x01)
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_ENCODING_CONSTANTS_H
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
#ifndef ENCRYPTOR_H
|
||||
#define ENCRYPTOR_H
|
||||
#ifndef DSPROT_ENCRYPTOR_H
|
||||
#define DSPROT_ENCRYPTOR_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
typedef struct {
|
||||
u32 obfs_addr;
|
||||
u32 obfs_size;
|
||||
typedef struct FuncInfo {
|
||||
u32 obfsAddr;
|
||||
u32 obfsSize;
|
||||
} FuncInfo;
|
||||
|
||||
enum {
|
||||
typedef enum InsType {
|
||||
INS_TYPE_OTHER = 0,
|
||||
INS_TYPE_BLXIMM,
|
||||
INS_TYPE_BL,
|
||||
INS_TYPE_B
|
||||
};
|
||||
} InsType;
|
||||
|
||||
u32 Encryptor_CategorizeInstruction(u32 instruction);
|
||||
InsType Encryptor_CategorizeInstruction(u32 instruction);
|
||||
void Encryptor_DecodeFunctionTable(FuncInfo *functions);
|
||||
void *Encryptor_DecryptFunction(u32 key, u32 func_addr, u32 size);
|
||||
u32 Encryptor_EncryptFunction(u32 key, u32 func_addr, u32 size);
|
||||
void *Encryptor_DecryptFunction(u32 key, u32 funcAddr, u32 size);
|
||||
u32 Encryptor_EncryptFunction(u32 key, u32 funcAddr, u32 size);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_ENCRYPTOR_H
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef GARBAGE_H
|
||||
#define GARBAGE_H
|
||||
#ifndef DSPROT_GARBAGE_H
|
||||
#define DSPROT_GARBAGE_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
extern const u32 Garbage[6];
|
||||
extern const u32 DSProt_Garbage[6];
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_GARBAGE_H
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
#ifndef INTEGRITY_H
|
||||
#define INTEGRITY_H
|
||||
#ifndef DSPROT_INTEGRITY_H
|
||||
#define DSPROT_INTEGRITY_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 Integrity_MACOwner_IsBad(void);
|
||||
u32 Integrity_MACOwner_IsGood(void);
|
||||
u32 Integrity_ROMTest_IsBad(void);
|
||||
u32 Integrity_ROMTest_IsGood(void);
|
||||
|
||||
// Assembly decryption wrappers
|
||||
extern u32 RunEncrypted_Integrity_MACOwner_IsBad(void);
|
||||
|
|
@ -9,4 +15,4 @@ extern u32 RunEncrypted_Integrity_MACOwner_IsGood(void);
|
|||
extern u32 RunEncrypted_Integrity_ROMTest_IsBad(void);
|
||||
extern u32 RunEncrypted_Integrity_ROMTest_IsGood(void);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_INTEGRITY_H
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#ifndef MAC_OWNER_H
|
||||
#define MAC_OWNER_H
|
||||
#ifndef DSPROT_MAC_OWNER_H
|
||||
#define DSPROT_MAC_OWNER_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 MACOwner_IsBad(void);
|
||||
u32 MACOwner_IsGood(void);
|
||||
|
||||
// Assembly decryption wrappers
|
||||
extern u32 RunEncrypted_MACOwner_IsBad(void);
|
||||
extern u32 RunEncrypted_MACOwner_IsGood(void);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_MAC_OWNER_H
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef NITRO_CARD_H
|
||||
#define NITRO_CARD_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
|
||||
// <nitro/card.h>
|
||||
#define CARD_ROM_PAGE_SIZE (0x200)
|
||||
|
||||
extern void CARD_LockRom(u16 lock_id);
|
||||
extern void CARD_UnlockRom(u16 lock_id);
|
||||
|
||||
// Not available in all Nitro versions
|
||||
#define CARDMST_ENABLE (0x80)
|
||||
|
||||
#define CARD_DATA_READY (0x00800000)
|
||||
#define CARD_COMMAND_PAGE (0x01000000)
|
||||
#define CARD_COMMAND_MASK (0x07000000)
|
||||
#define CARD_RESET_HI (0x20000000)
|
||||
#define CARD_READ_MODE (0x00000000)
|
||||
#define CARD_START (0x80000000)
|
||||
|
||||
#define MROMOP_G_READ_PAGE (0xB7000000)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef NITRO_IO_REG_H
|
||||
#define NITRO_IO_REG_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
|
||||
// <nitro/hw/io_reg.h>
|
||||
#define HW_REG_BASE (0x04000000)
|
||||
|
||||
#define REG_EXMEMCNT_OFFSET (0x204)
|
||||
#define reg_MI_EXMEMCNT (*(REGType16v *)(HW_REG_BASE + REG_EXMEMCNT_OFFSET))
|
||||
#define REG_MI_EXMEMCNT_MP_MASK (0x800)
|
||||
#define REG_MI_EXMEMCNT_MP_SHIFT (11)
|
||||
|
||||
#define REG_A9ROM_OFFSET (0x4000)
|
||||
#define REG_SCFG_A9ROM_SEC_MASK (0x01)
|
||||
|
||||
#define MI_PROCESSOR_ARM9 (0)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef NITRO_OS_H
|
||||
#define NITRO_OS_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
|
||||
// <nitro/os.h>
|
||||
typedef struct {
|
||||
u8 language;
|
||||
u8 favoriteColor;
|
||||
struct {
|
||||
u8 month;
|
||||
u8 day;
|
||||
} birthday;
|
||||
u16 nickName[11];
|
||||
u16 nickNameLength;
|
||||
u16 comment[27];
|
||||
u16 commentLength;
|
||||
} OSOwnerInfo;
|
||||
|
||||
extern s32 OS_GetLockID(void);
|
||||
extern void OS_ReleaseLockID(u16 lock_id);
|
||||
extern void OS_GetMacAddress(u8 *mac_addr);
|
||||
extern void OS_GetOwnerInfo(OSOwnerInfo *info);
|
||||
extern void DC_FlushRange(const void *start_addr, u32 num_bytes);
|
||||
extern void IC_InvalidateRange(void *start_addr, u32 num_bytes);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef NITRO_TYPES_H
|
||||
#define NITRO_TYPES_H
|
||||
|
||||
// <nitro/types.h>
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short int u16;
|
||||
typedef unsigned long u32;
|
||||
typedef unsigned long long int u64;
|
||||
typedef signed char s8;
|
||||
typedef signed short int s16;
|
||||
typedef signed long s32;
|
||||
typedef signed long long int s64;
|
||||
typedef float f32;
|
||||
|
||||
typedef volatile u8 vu8;
|
||||
typedef volatile u16 vu16;
|
||||
typedef volatile u32 vu32;
|
||||
typedef volatile u64 vu64;
|
||||
typedef volatile s8 vs8;
|
||||
typedef volatile s16 vs16;
|
||||
typedef volatile s32 vs32;
|
||||
typedef volatile s64 vs64;
|
||||
typedef volatile f32 vf32;
|
||||
|
||||
typedef u8 REGType8;
|
||||
typedef u16 REGType16;
|
||||
typedef u32 REGType32;
|
||||
typedef u64 REGType64;
|
||||
typedef vu8 REGType8v;
|
||||
typedef vu16 REGType16v;
|
||||
typedef vu32 REGType32v;
|
||||
typedef vu64 REGType64v;
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
#define TRUE (1)
|
||||
#define FALSE (0)
|
||||
|
||||
#define NULL ((void *)0)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,9 +1,20 @@
|
|||
#ifndef RC4_H
|
||||
#define RC4_H
|
||||
#ifndef DSPROT_RC4_H
|
||||
#define DSPROT_RC4_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
#define RC4_KEY_SIZE (16)
|
||||
|
||||
typedef struct RC4_Ctx RC4_Ctx;
|
||||
|
||||
// Functions to be encoded (cannot be static)
|
||||
void RC4_Init(RC4_Ctx *ctx, const void *key, u32 keyLen);
|
||||
u8 RC4_Byte(RC4_Ctx *ctx);
|
||||
u32 RC4_InitSBox(u8 *sbox);
|
||||
u32 RC4_EncryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size);
|
||||
u32 RC4_DecryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size);
|
||||
|
||||
u32 RC4_InitAndEncryptInstructions(void *key, void *dst, void *src, u32 size);
|
||||
u32 RC4_InitAndDecryptInstructions(void *key, void *dst, void *src, u32 size);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_RC4_H
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#ifndef ROM_TEST_H
|
||||
#define ROM_TEST_H
|
||||
#ifndef DSPROT_ROM_TEST_H
|
||||
#define DSPROT_ROM_TEST_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 ROMTest_IsBad(void);
|
||||
u32 ROMTest_IsGood(void);
|
||||
|
||||
// Assembly decryption wrappers
|
||||
extern u32 RunEncrypted_ROMTest_IsBad(void);
|
||||
extern u32 RunEncrypted_ROMTest_IsGood(void);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_ROM_TEST_H
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#ifndef ROM_UTIL_H
|
||||
#define ROM_UTIL_H
|
||||
#ifndef DSPROT_ROM_UTIL_H
|
||||
#define DSPROT_ROM_UTIL_H
|
||||
|
||||
#include "nitro_types.h"
|
||||
#include "sdk.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
void ROMUtil_Read(void *dest, u32 addr, s32 numBytes);
|
||||
u32 ROMUtil_CRC32(void *buf, u32 size);
|
||||
|
||||
// Assembly decryption wrappers
|
||||
extern void RunEncrypted_ROMUtil_Read(void *dest, u32 addr, s32 num_bytes);
|
||||
extern void RunEncrypted_ROMUtil_Read(void *dest, u32 addr, s32 numBytes);
|
||||
extern u32 RunEncrypted_ROMUtil_CRC32(void *buf, u32 size);
|
||||
|
||||
#endif
|
||||
#endif // DSPROT_ROM_UTIL_H
|
||||
|
|
|
|||
60
lib/dsprot/include/sdk.h
Normal file
60
lib/dsprot/include/sdk.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef DSPROT_SDK_H
|
||||
#define DSPROT_SDK_H
|
||||
|
||||
#ifdef SDK_TWL
|
||||
|
||||
// Use Twl SDK if available
|
||||
#include <twl.h>
|
||||
|
||||
#else // SDK_TWL
|
||||
|
||||
// Else use Nitro and add back in the needed Twl SDK defs
|
||||
#include <nitro.h>
|
||||
|
||||
// Twl SDK only
|
||||
#ifndef REG_A9ROM_OFFSET
|
||||
#define REG_A9ROM_OFFSET (0x4000)
|
||||
#endif // REG_A9ROM_OFFSET
|
||||
|
||||
#ifndef REG_SCFG_A9ROM_SEC_MASK
|
||||
#define REG_SCFG_A9ROM_SEC_MASK (0x01)
|
||||
#endif // REG_SCFG_A9ROM_SEC_MASK
|
||||
|
||||
#endif // SDK_TWL
|
||||
|
||||
|
||||
// Not included in all SDK versions, regardless of Nitro/Twl
|
||||
// Ensure they are defined
|
||||
#ifndef CARDMST_ENABLE
|
||||
#define CARDMST_ENABLE (0x80)
|
||||
#endif // CARDMST_ENABLE
|
||||
|
||||
#ifndef CARD_DATA_READY
|
||||
#define CARD_DATA_READY (0x00800000)
|
||||
#endif // CARD_DATA_READY
|
||||
|
||||
#ifndef CARD_COMMAND_PAGE
|
||||
#define CARD_COMMAND_PAGE (0x01000000)
|
||||
#endif // CARD_COMMAND_PAGE
|
||||
|
||||
#ifndef CARD_COMMAND_MASK
|
||||
#define CARD_COMMAND_MASK (0x07000000)
|
||||
#endif // CARD_COMMAND_MASK
|
||||
|
||||
#ifndef CARD_RESET_HI
|
||||
#define CARD_RESET_HI (0x20000000)
|
||||
#endif // CARD_RESET_HI
|
||||
|
||||
#ifndef CARD_READ_MODE
|
||||
#define CARD_READ_MODE (0x00000000)
|
||||
#endif // CARD_READ_MODE
|
||||
|
||||
#ifndef CARD_START
|
||||
#define CARD_START (0x80000000)
|
||||
#endif // CARD_START
|
||||
|
||||
#ifndef MROMOP_G_READ_PAGE
|
||||
#define MROMOP_G_READ_PAGE (0xB7000000)
|
||||
#endif // MROMOP_G_READ_PAGE
|
||||
|
||||
#endif // DSPROT_SDK_H
|
||||
|
|
@ -1,19 +1,10 @@
|
|||
/* No dedicated header */
|
||||
#include "dsprot_main.h"
|
||||
|
||||
#include "encoding_constants.h"
|
||||
#include "integrity.h"
|
||||
#include "mac_owner.h"
|
||||
#include "nitro_types.h"
|
||||
#include "rom_test.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 DetectFlashcart(void *callback);
|
||||
u32 DetectNotFlashcart(void *callback);
|
||||
u32 DetectEmulator(void *callback);
|
||||
u32 DetectNotEmulator(void *callback);
|
||||
u32 DetectDummy(void *callback);
|
||||
u32 DetectNotDummy(void *callback);
|
||||
|
||||
#define DSP_OBFS_OFFSET (0x320)
|
||||
|
||||
#define FUNC_QUEUE_END (0)
|
||||
|
|
@ -21,33 +12,33 @@ u32 DetectNotDummy(void *callback);
|
|||
typedef u32 (*TaskFunc)(void);
|
||||
typedef void (*CallbackFunc)(void);
|
||||
|
||||
enum {
|
||||
typedef enum ExpectedResult {
|
||||
EXPECT_FALSE,
|
||||
EXPECT_TRUE
|
||||
};
|
||||
} ExpectedResult;
|
||||
|
||||
// This was likely not originally an inline, but an inline is able to match here nicely
|
||||
static inline u32 dsprotMain(u32 *func_queue, int expected_result, void *callback) {
|
||||
static inline u32 dsprotMain(u32 *funcQueue, ExpectedResult expectedResult, void *callback) {
|
||||
// These two bit arrays must be signed to match
|
||||
s32 compare_sum = 0;
|
||||
s32 compareSum = 0;
|
||||
u32 i;
|
||||
s32 func_result_sum = 0;
|
||||
s32 funcResultSum = 0;
|
||||
|
||||
for (i = 0; func_queue[i] != FUNC_QUEUE_END; i++) {
|
||||
BOOL func_result = ((TaskFunc)(func_queue[i] - ENC_VAL_1 - DSP_OBFS_OFFSET))() != 0;
|
||||
for (i = 0; funcQueue[i] != FUNC_QUEUE_END; i++) {
|
||||
BOOL funcResult = ((TaskFunc)(funcQueue[i] - ENC_VAL_1 - DSP_OBFS_OFFSET))() != 0;
|
||||
|
||||
func_result_sum += func_result;
|
||||
func_result_sum <<= 1;
|
||||
funcResultSum += funcResult;
|
||||
funcResultSum <<= 1;
|
||||
|
||||
compare_sum += TRUE;
|
||||
compare_sum <<= 1;
|
||||
compareSum += TRUE;
|
||||
compareSum <<= 1;
|
||||
}
|
||||
|
||||
BOOL ret;
|
||||
if (expected_result == EXPECT_TRUE) {
|
||||
ret = (func_result_sum >> 1) == (compare_sum >> 1);
|
||||
if (expectedResult == EXPECT_TRUE) {
|
||||
ret = (funcResultSum >> 1) == (compareSum >> 1);
|
||||
} else {
|
||||
ret = ((func_result_sum & compare_sum) >> 1) != 0;
|
||||
ret = ((funcResultSum & compareSum) >> 1) != 0;
|
||||
}
|
||||
|
||||
if (callback != NULL && ret) {
|
||||
|
|
@ -57,60 +48,60 @@ static inline u32 dsprotMain(u32 *func_queue, int expected_result, void *callbac
|
|||
return (u32)ret;
|
||||
}
|
||||
|
||||
u32 DetectFlashcart(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectFlashcart(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
func_queue[2] = FUNC_QUEUE_END;
|
||||
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[2] = FUNC_QUEUE_END;
|
||||
funcQueue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_FALSE, callback);
|
||||
}
|
||||
|
||||
u32 DetectNotFlashcart(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectNotFlashcart(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
func_queue[2] = FUNC_QUEUE_END;
|
||||
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[2] = FUNC_QUEUE_END;
|
||||
funcQueue[0] = ADDR_PLUS_ADDEND(RunEncrypted_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_ROMTest_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_TRUE, callback);
|
||||
}
|
||||
|
||||
u32 DetectEmulator(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectEmulator(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
func_queue[2] = FUNC_QUEUE_END;
|
||||
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[2] = FUNC_QUEUE_END;
|
||||
funcQueue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsBad, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_FALSE, callback);
|
||||
}
|
||||
|
||||
u32 DetectNotEmulator(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectNotEmulator(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
func_queue[2] = FUNC_QUEUE_END;
|
||||
func_queue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
func_queue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[2] = FUNC_QUEUE_END;
|
||||
funcQueue[0] = ADDR_PLUS_ADDEND(RunEncrypted_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
funcQueue[1] = ADDR_PLUS_ADDEND(RunEncrypted_Integrity_MACOwner_IsGood, ENC_VAL_1) + DSP_OBFS_OFFSET;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_TRUE, callback);
|
||||
}
|
||||
|
||||
u32 DetectDummy(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectDummy(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
// Prevent optimization of the function queue processing
|
||||
*(u32 *)&func_queue[0] = FUNC_QUEUE_END;
|
||||
*(u32 *)&funcQueue[0] = FUNC_QUEUE_END;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_FALSE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_FALSE, callback);
|
||||
}
|
||||
|
||||
u32 DetectNotDummy(void *callback) {
|
||||
u32 func_queue[32];
|
||||
u32 DSProtInternal_DetectNotDummy(void *callback) {
|
||||
u32 funcQueue[32];
|
||||
|
||||
// Prevent optimization of the function queue processing
|
||||
*(u32 *)&func_queue[0] = FUNC_QUEUE_END;
|
||||
*(u32 *)&funcQueue[0] = FUNC_QUEUE_END;
|
||||
|
||||
return dsprotMain(&func_queue[0], EXPECT_TRUE, callback);
|
||||
return dsprotMain(&funcQueue[0], EXPECT_TRUE, callback);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,18 @@
|
|||
|
||||
#include "bss.h"
|
||||
#include "encoding_constants.h"
|
||||
#include "nitro_os.h"
|
||||
#include "rc4.h"
|
||||
|
||||
#define ROTL(x, a) ((a) == 0 ? (x) : (((x) << (a)) | ((x) >> (32 - (a)))))
|
||||
|
||||
static void clearDataAndInstructionCache(void *start_addr, u32 num_bytes);
|
||||
static void clearDataAndInstructionCache(void *startAddr, u32 numBytes);
|
||||
|
||||
static void clearDataAndInstructionCache(void *start_addr, u32 num_bytes) {
|
||||
DC_FlushRange(start_addr, num_bytes);
|
||||
IC_InvalidateRange(start_addr, num_bytes);
|
||||
static void clearDataAndInstructionCache(void *startAddr, u32 numBytes) {
|
||||
DC_FlushRange(startAddr, numBytes);
|
||||
IC_InvalidateRange(startAddr, numBytes);
|
||||
}
|
||||
|
||||
u32 Encryptor_CategorizeInstruction(u32 instruction) {
|
||||
InsType Encryptor_CategorizeInstruction(u32 instruction) {
|
||||
u8 opcode = instruction >> INS_OPCODE_SHIFT;
|
||||
|
||||
// Branch instruction
|
||||
|
|
@ -40,18 +39,18 @@ void Encryptor_DecodeFunctionTable(FuncInfo *functions) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (; functions->obfs_addr != 0; functions++) {
|
||||
u32 *addr = (u32 *)functions->obfs_addr;
|
||||
u32 size = functions->obfs_size - (u32)&BSS - ENC_VAL_1;
|
||||
for (; functions->obfsAddr != 0; functions++) {
|
||||
u32 *addr = (u32 *)functions->obfsAddr;
|
||||
u32 size = functions->obfsSize - (u32)&DSProt_BSS - ENC_VAL_1;
|
||||
|
||||
if (addr == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
addr = (void *)addr - ENC_VAL_1;
|
||||
u32 *end_addr = addr + (size / 4);
|
||||
u32 *endAddr = addr + (size / 4);
|
||||
|
||||
for (; addr < end_addr; addr++) {
|
||||
for (; addr < endAddr; addr++) {
|
||||
switch (Encryptor_CategorizeInstruction(*addr)) {
|
||||
case INS_TYPE_BLXIMM:
|
||||
case INS_TYPE_BL: {
|
||||
|
|
@ -59,67 +58,70 @@ void Encryptor_DecodeFunctionTable(FuncInfo *functions) {
|
|||
u32 operands = ((*addr & INS_OPERANDS_MASK) - ENC_VAL_1) & INS_OPERANDS_MASK;
|
||||
|
||||
*addr = opcode | operands;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case INS_TYPE_B: {
|
||||
u32 opcode = (*addr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*addr & INS_OPERANDS_MASK) - ENC_VAL_2) & INS_OPERANDS_MASK;
|
||||
|
||||
*addr = opcode | operands;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
u8 *addr_bytes = (u8 *)addr;
|
||||
*addr = (addr_bytes[0] ^ ENC_BYTE_A) | ((addr_bytes[1] ^ ENC_BYTE_B) << 8) | ((addr_bytes[2] ^ ENC_BYTE_C) << 16) | ((addr_bytes[3] ^ ENC_BYTE_D) << 24);
|
||||
} break;
|
||||
u8 *addrBytes = (u8 *)addr;
|
||||
*addr = (addrBytes[0] ^ ENC_BYTE_A) | ((addrBytes[1] ^ ENC_BYTE_B) << 8) | ((addrBytes[2] ^ ENC_BYTE_C) << 16) | ((addrBytes[3] ^ ENC_BYTE_D) << 24);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clearDataAndInstructionCache((void *)(functions->obfs_addr - ENC_VAL_1), size);
|
||||
clearDataAndInstructionCache((void *)(functions->obfsAddr - ENC_VAL_1), size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void expandRC4Key(u32 seed_key, u32 size, u32 *expanded_key) {
|
||||
expanded_key[0] = ROTL(seed_key, 0) ^ size;
|
||||
expanded_key[1] = ROTL(seed_key, 8) ^ size;
|
||||
expanded_key[2] = ROTL(seed_key, 16) ^ size;
|
||||
expanded_key[3] = ROTL(seed_key, 24) ^ size;
|
||||
static inline void expandRC4Key(u32 seedKey, u32 size, u32 *expandedKey) {
|
||||
expandedKey[0] = ROTL(seedKey, 0) ^ size;
|
||||
expandedKey[1] = ROTL(seedKey, 8) ^ size;
|
||||
expandedKey[2] = ROTL(seedKey, 16) ^ size;
|
||||
expandedKey[3] = ROTL(seedKey, 24) ^ size;
|
||||
}
|
||||
|
||||
void *Encryptor_DecryptFunction(u32 key, u32 func_addr, u32 size) {
|
||||
void *Encryptor_DecryptFunction(u32 key, u32 funcAddr, u32 size) {
|
||||
// Deobfuscate arguments
|
||||
size -= (u32)&BSS + ENC_VAL_1;
|
||||
size -= (u32)&DSProt_BSS + ENC_VAL_1;
|
||||
|
||||
key -= (u32)&BSS + ENC_VAL_1;
|
||||
key -= (u32)&DSProt_BSS + ENC_VAL_1;
|
||||
|
||||
void *func_ptr = (void *)func_addr;
|
||||
func_ptr -= ENC_VAL_1;
|
||||
void *funcPtr = (void *)funcAddr;
|
||||
funcPtr -= ENC_VAL_1;
|
||||
|
||||
u32 expanded_key[4];
|
||||
expandRC4Key(key, size, &expanded_key[0]);
|
||||
RC4_InitAndDecryptInstructions(&expanded_key[0], func_ptr, func_ptr, size);
|
||||
clearDataAndInstructionCache(func_ptr, size);
|
||||
u32 expandedKey[4];
|
||||
expandRC4Key(key, size, &expandedKey[0]);
|
||||
RC4_InitAndDecryptInstructions(&expandedKey[0], funcPtr, funcPtr, size);
|
||||
clearDataAndInstructionCache(funcPtr, size);
|
||||
|
||||
return func_ptr;
|
||||
return funcPtr;
|
||||
}
|
||||
|
||||
u32 Encryptor_EncryptFunction(u32 key, u32 func_addr, u32 size) {
|
||||
u32 Encryptor_EncryptFunction(u32 key, u32 funcAddr, u32 size) {
|
||||
// Deobfuscate arguments and change key
|
||||
size -= (u32)&BSS + ENC_VAL_1;
|
||||
size -= (u32)&DSProt_BSS + ENC_VAL_1;
|
||||
|
||||
key -= (u32)&BSS + ENC_VAL_1;
|
||||
key += func_addr >> 20;
|
||||
key -= (u32)&DSProt_BSS + ENC_VAL_1;
|
||||
key += funcAddr >> 20;
|
||||
|
||||
void *func_ptr = (void *)func_addr;
|
||||
func_ptr -= ENC_VAL_1;
|
||||
void *funcPtr = (void *)funcAddr;
|
||||
funcPtr -= ENC_VAL_1;
|
||||
|
||||
u32 expanded_key[4];
|
||||
expandRC4Key(key, size, &expanded_key[0]);
|
||||
RC4_InitAndEncryptInstructions(&expanded_key[0], func_ptr, func_ptr, size);
|
||||
clearDataAndInstructionCache(func_ptr, size);
|
||||
u32 expandedKey[4];
|
||||
expandRC4Key(key, size, &expandedKey[0]);
|
||||
RC4_InitAndEncryptInstructions(&expandedKey[0], funcPtr, funcPtr, size);
|
||||
clearDataAndInstructionCache(funcPtr, size);
|
||||
|
||||
// Re-obfuscate key
|
||||
key += (u32)&BSS + ENC_VAL_1;
|
||||
key += (u32)&DSProt_BSS + ENC_VAL_1;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#include "bss.h"
|
||||
#include "garbage.h"
|
||||
|
||||
u8 BSS[4];
|
||||
u8 DSProt_BSS[4];
|
||||
|
||||
const u32 Garbage[6] = {
|
||||
const u32 DSProt_Garbage[6] = {
|
||||
0xEBAA0113,
|
||||
0xE4064EC7,
|
||||
0xEF013596,
|
||||
|
|
|
|||
|
|
@ -4,16 +4,10 @@
|
|||
#include "mac_owner.h"
|
||||
#include "rom_test.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 Integrity_MACOwner_IsBad(void);
|
||||
u32 Integrity_MACOwner_IsGood(void);
|
||||
u32 Integrity_ROMTest_IsBad(void);
|
||||
u32 Integrity_ROMTest_IsGood(void);
|
||||
|
||||
#define INTEGRITY_OBFS_OFFSET (ENC_VAL_1 & ~0xFFF)
|
||||
|
||||
// This was likely not originally an inline, but an inline is able to match here nicely
|
||||
static inline u32 checkDecryptionWrapper(u8 *addr, u32 match_ret, u32 mismatch_ret) {
|
||||
static inline u32 checkDecryptionWrapper(u8 *addr, u32 matchRet, u32 mismatchRet) {
|
||||
addr += INTEGRITY_OBFS_OFFSET;
|
||||
u32 offset = ENC_VAL_1 - INTEGRITY_OBFS_OFFSET;
|
||||
|
||||
|
|
@ -23,58 +17,58 @@ static inline u32 checkDecryptionWrapper(u8 *addr, u32 match_ret, u32 mismatch_r
|
|||
// e8bd00f0 ldmfd sp!, {r4-r7}
|
||||
// e59f103c ldr r1, [pc, #60]
|
||||
if (addr[offset++] != 0xF0) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x00) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x2D) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0xE9) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
|
||||
if (addr[offset++] != 0x0F) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x00) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x2D) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0xE9) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
|
||||
if (addr[offset++] != 0xF0) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x00) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0xBD) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0xE8) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
|
||||
if (addr[offset++] != 0x60) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x10) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0x9F) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
if (addr[offset++] != 0xE5) {
|
||||
return mismatch_ret;
|
||||
return mismatchRet;
|
||||
}
|
||||
|
||||
return match_ret;
|
||||
return matchRet;
|
||||
}
|
||||
|
||||
u32 Integrity_MACOwner_IsBad(void) {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,10 @@
|
|||
#include "mac_owner.h"
|
||||
|
||||
#include "nitro_os.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 MACOwner_IsBad(void);
|
||||
u32 MACOwner_IsGood(void);
|
||||
|
||||
#define MAC_ADDR_SIZE (6)
|
||||
|
||||
#define ENC_MAC_ADDR_BYTE (0xFF)
|
||||
|
||||
static const u8 bad_mac_addr[MAC_ADDR_SIZE] = {
|
||||
static const u8 badMacAddr[MAC_ADDR_SIZE] = {
|
||||
0x00 ^ ENC_MAC_ADDR_BYTE,
|
||||
0x09 ^ ENC_MAC_ADDR_BYTE,
|
||||
0xBF ^ ENC_MAC_ADDR_BYTE,
|
||||
|
|
@ -19,34 +13,34 @@ static const u8 bad_mac_addr[MAC_ADDR_SIZE] = {
|
|||
0x31 ^ ENC_MAC_ADDR_BYTE
|
||||
};
|
||||
|
||||
static inline u32 testMACOwner(u32 pass_ret, u32 fail_ret) {
|
||||
u8 mac_addr[MAC_ADDR_SIZE];
|
||||
OS_GetMacAddress(&mac_addr[0]);
|
||||
static inline u32 testMACOwner(u32 passRet, u32 failRet) {
|
||||
u8 macAddr[MAC_ADDR_SIZE];
|
||||
OS_GetMacAddress(&macAddr[0]);
|
||||
|
||||
s32 i;
|
||||
for (i = 0; i < MAC_ADDR_SIZE; i++) {
|
||||
if (bad_mac_addr[i] != (mac_addr[i] ^ ENC_MAC_ADDR_BYTE)) {
|
||||
if (badMacAddr[i] != (macAddr[i] ^ ENC_MAC_ADDR_BYTE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSOwnerInfo owner_info;
|
||||
OS_GetOwnerInfo(&owner_info);
|
||||
OSOwnerInfo ownerInfo;
|
||||
OS_GetOwnerInfo(&ownerInfo);
|
||||
|
||||
u32 ret;
|
||||
if (i == MAC_ADDR_SIZE && owner_info.birthday.month == 1 && owner_info.birthday.day == 1 && owner_info.nickNameLength == 0) {
|
||||
ret = fail_ret;
|
||||
if (i == MAC_ADDR_SIZE && ownerInfo.birthday.month == 1 && ownerInfo.birthday.day == 1 && ownerInfo.nickNameLength == 0) {
|
||||
ret = failRet;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAC_ADDR_SIZE; i++) {
|
||||
if (mac_addr[i] != 0x00) {
|
||||
ret = pass_ret;
|
||||
if (macAddr[i] != 0x00) {
|
||||
ret = passRet;
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = fail_ret;
|
||||
ret = failRet;
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -3,22 +3,13 @@
|
|||
#include "encoding_constants.h"
|
||||
#include "encryptor.h"
|
||||
|
||||
#define RC4_KEY_SIZE (16)
|
||||
|
||||
typedef struct {
|
||||
struct RC4_Ctx {
|
||||
int i;
|
||||
int j;
|
||||
u8 S[256];
|
||||
} RC4_Ctx;
|
||||
};
|
||||
|
||||
// Functions to be encoded (cannot be static)
|
||||
void RC4_Init(RC4_Ctx *ctx, const void *key, u32 key_len);
|
||||
u8 RC4_Byte(RC4_Ctx *ctx);
|
||||
u32 RC4_InitSBox(u8 *sbox);
|
||||
u32 RC4_EncryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size);
|
||||
u32 RC4_DecryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size);
|
||||
|
||||
void RC4_Init(RC4_Ctx *ctx, const void *key, u32 key_len) {
|
||||
void RC4_Init(RC4_Ctx *ctx, const void *key, u32 keyLen) {
|
||||
s32 Ki = 0;
|
||||
u8 Si = 0;
|
||||
|
||||
|
|
@ -41,7 +32,7 @@ void RC4_Init(RC4_Ctx *ctx, const void *key, u32 key_len) {
|
|||
ctx->S[i] = tmp2;
|
||||
|
||||
Ki++;
|
||||
if (Ki >= key_len) {
|
||||
if (Ki >= keyLen) {
|
||||
Ki = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -75,44 +66,46 @@ u32 RC4_EncryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
u8 *src_bytes = (u8 *)src;
|
||||
u8 *dst_bytes = (u8 *)dst;
|
||||
u8 *srcBytes = (u8 *)src;
|
||||
u8 *dstBytes = (u8 *)dst;
|
||||
|
||||
u8 sbox[256];
|
||||
RC4_InitSBox(&sbox[0]);
|
||||
|
||||
for (u32 offset = 0; offset < size; offset += 4) {
|
||||
switch (Encryptor_CategorizeInstruction(*(u32 *)(src_bytes + offset))) {
|
||||
switch (Encryptor_CategorizeInstruction(*(u32 *)(srcBytes + offset))) {
|
||||
case INS_TYPE_BLXIMM:
|
||||
case INS_TYPE_BL: {
|
||||
u32 *src_addr = (u32 *)(src_bytes + offset);
|
||||
u32 *dst_addr = (u32 *)(dst_bytes + offset);
|
||||
u32 *srcAddr = (u32 *)(srcBytes + offset);
|
||||
u32 *dstAddr = (u32 *)(dstBytes + offset);
|
||||
|
||||
*dst_addr = *src_addr;
|
||||
*dstAddr = *srcAddr;
|
||||
|
||||
u32 opcode = (*dst_addr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dst_addr & INS_OPERANDS_MASK) + ENC_VAL_2) & INS_OPERANDS_MASK;
|
||||
u32 opcode = (*dstAddr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dstAddr & INS_OPERANDS_MASK) + ENC_VAL_2) & INS_OPERANDS_MASK;
|
||||
|
||||
*dst_addr = opcode | operands;
|
||||
} break;
|
||||
*dstAddr = opcode | operands;
|
||||
}
|
||||
break;
|
||||
|
||||
case INS_TYPE_B: {
|
||||
u32 *src_addr = (u32 *)(src_bytes + offset);
|
||||
u32 *dst_addr = (u32 *)(dst_bytes + offset);
|
||||
u32 *srcAddr = (u32 *)(srcBytes + offset);
|
||||
u32 *dstAddr = (u32 *)(dstBytes + offset);
|
||||
|
||||
*dst_addr = *src_addr;
|
||||
*dstAddr = *srcAddr;
|
||||
|
||||
u32 opcode = (*dst_addr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dst_addr & INS_OPERANDS_MASK) + ENC_VAL_1) & INS_OPERANDS_MASK;
|
||||
u32 opcode = (*dstAddr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dstAddr & INS_OPERANDS_MASK) + ENC_VAL_1) & INS_OPERANDS_MASK;
|
||||
|
||||
*dst_addr = opcode | operands;
|
||||
} break;
|
||||
*dstAddr = opcode | operands;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dst_bytes[offset] = src_bytes[offset] ^ RC4_Byte(ctx);
|
||||
dst_bytes[offset + 1] = src_bytes[offset + 1] ^ RC4_Byte(ctx);
|
||||
dst_bytes[offset + 2] = sbox[src_bytes[offset + 2]];
|
||||
dst_bytes[offset + 3] = src_bytes[offset + 3];
|
||||
dstBytes[offset] = srcBytes[offset] ^ RC4_Byte(ctx);
|
||||
dstBytes[offset + 1] = srcBytes[offset + 1] ^ RC4_Byte(ctx);
|
||||
dstBytes[offset + 2] = sbox[srcBytes[offset + 2]];
|
||||
dstBytes[offset + 3] = srcBytes[offset + 3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -125,44 +118,46 @@ u32 RC4_DecryptInstructions(RC4_Ctx *ctx, void *src, void *dst, u32 size) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
u8 *src_bytes = (u8 *)src;
|
||||
u8 *dst_bytes = (u8 *)dst;
|
||||
u8 *srcBytes = (u8 *)src;
|
||||
u8 *dstBytes = (u8 *)dst;
|
||||
|
||||
u8 sbox[256];
|
||||
RC4_InitSBox(&sbox[0]);
|
||||
|
||||
for (u32 offset = 0; offset < size; offset += 4) {
|
||||
switch (Encryptor_CategorizeInstruction(*(u32 *)(src_bytes + offset))) {
|
||||
switch (Encryptor_CategorizeInstruction(*(u32 *)(srcBytes + offset))) {
|
||||
case INS_TYPE_BLXIMM:
|
||||
case INS_TYPE_BL: {
|
||||
u32 *src_addr = (u32 *)(src_bytes + offset);
|
||||
u32 *dst_addr = (u32 *)(dst_bytes + offset);
|
||||
u32 *srcAddr = (u32 *)(srcBytes + offset);
|
||||
u32 *dstAddr = (u32 *)(dstBytes + offset);
|
||||
|
||||
*dst_addr = *src_addr;
|
||||
*dstAddr = *srcAddr;
|
||||
|
||||
u32 opcode = (*dst_addr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dst_addr & INS_OPERANDS_MASK) - ENC_VAL_1) & INS_OPERANDS_MASK;
|
||||
u32 opcode = (*dstAddr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dstAddr & INS_OPERANDS_MASK) - ENC_VAL_1) & INS_OPERANDS_MASK;
|
||||
|
||||
*dst_addr = opcode | operands;
|
||||
} break;
|
||||
*dstAddr = opcode | operands;
|
||||
}
|
||||
break;
|
||||
|
||||
case INS_TYPE_B: {
|
||||
u32 *src_addr = (u32 *)(src_bytes + offset);
|
||||
u32 *dst_addr = (u32 *)(dst_bytes + offset);
|
||||
u32 *srcAddr = (u32 *)(srcBytes + offset);
|
||||
u32 *dstAddr = (u32 *)(dstBytes + offset);
|
||||
|
||||
*dst_addr = *src_addr;
|
||||
*dstAddr = *srcAddr;
|
||||
|
||||
u32 opcode = (*dst_addr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dst_addr & INS_OPERANDS_MASK) - ENC_VAL_2) & INS_OPERANDS_MASK;
|
||||
u32 opcode = (*dstAddr & INS_OPCODE_MASK) ^ (INS_OPCODE_LINKBIT << INS_OPCODE_SHIFT);
|
||||
u32 operands = ((*dstAddr & INS_OPERANDS_MASK) - ENC_VAL_2) & INS_OPERANDS_MASK;
|
||||
|
||||
*dst_addr = opcode | operands;
|
||||
} break;
|
||||
*dstAddr = opcode | operands;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dst_bytes[offset] = src_bytes[offset] ^ RC4_Byte(ctx);
|
||||
dst_bytes[offset + 1] = src_bytes[offset + 1] ^ RC4_Byte(ctx);
|
||||
dst_bytes[offset + 2] = sbox[src_bytes[offset + 2]];
|
||||
dst_bytes[offset + 3] = src_bytes[offset + 3];
|
||||
dstBytes[offset] = srcBytes[offset] ^ RC4_Byte(ctx);
|
||||
dstBytes[offset + 1] = srcBytes[offset + 1] ^ RC4_Byte(ctx);
|
||||
dstBytes[offset + 2] = sbox[srcBytes[offset + 2]];
|
||||
dstBytes[offset + 3] = srcBytes[offset + 3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,27 @@
|
|||
#include "rom_test.h"
|
||||
|
||||
#include "nitro_card.h"
|
||||
#include "rom_util.h"
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
u32 ROMTest_IsBad(void);
|
||||
u32 ROMTest_IsGood(void);
|
||||
|
||||
#define ROM_BLOCK_SIZE CARD_ROM_PAGE_SIZE
|
||||
|
||||
static inline u32 testROM(u32 pass_ret, u32 fail_ret) {
|
||||
static inline u32 testROM(u32 passRet, u32 failRet) {
|
||||
// Extra CRC entry is required to match
|
||||
u32 crcs[7];
|
||||
u8 rom_buf[ROM_BLOCK_SIZE];
|
||||
u8 romBuf[ROM_BLOCK_SIZE];
|
||||
s32 i;
|
||||
|
||||
u32 rom_addr = 0x1000;
|
||||
u32 romAddr = 0x1000;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
RunEncrypted_ROMUtil_Read(&rom_buf[0], rom_addr, ROM_BLOCK_SIZE);
|
||||
crcs[i] = RunEncrypted_ROMUtil_CRC32(&rom_buf[0], ROM_BLOCK_SIZE);
|
||||
RunEncrypted_ROMUtil_Read(&romBuf[0], romAddr, ROM_BLOCK_SIZE);
|
||||
crcs[i] = RunEncrypted_ROMUtil_CRC32(&romBuf[0], ROM_BLOCK_SIZE);
|
||||
|
||||
if (i == 2) {
|
||||
// Has to be like this to match
|
||||
rom_addr = 1;
|
||||
rom_addr <<= 15;
|
||||
romAddr = 1;
|
||||
romAddr <<= 15;
|
||||
} else {
|
||||
rom_addr += ROM_BLOCK_SIZE;
|
||||
romAddr += ROM_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,22 +32,22 @@ static inline u32 testROM(u32 pass_ret, u32 fail_ret) {
|
|||
u32 ret;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (crcs[i] != crcs[3]) {
|
||||
ret = fail_ret;
|
||||
ret = failRet;
|
||||
goto EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (crcs[3] == crcs[4] && crcs[3] == crcs[5]) {
|
||||
ret = fail_ret;
|
||||
ret = failRet;
|
||||
} else {
|
||||
ret = pass_ret;
|
||||
ret = passRet;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
// Erasing read buffer
|
||||
u8 *buf_ptr = &rom_buf[0];
|
||||
u8 *bufPtr = &romBuf[0];
|
||||
for (i = 0; i < ROM_BLOCK_SIZE; i++) {
|
||||
*buf_ptr++ = 0;
|
||||
*bufPtr++ = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,12 @@
|
|||
#include "rom_util.h"
|
||||
|
||||
#include "nitro_card.h"
|
||||
#include "nitro_io_reg.h"
|
||||
#include "nitro_os.h"
|
||||
|
||||
// Custom defs not provided by Nitro
|
||||
// Custom defs not provided by SDK
|
||||
#define REG_CARD_MASTER_CNT_OFFSET (0x1A1)
|
||||
#define REG_CARDCNT_OFFSET (0x1A4)
|
||||
#define REG_CARD_CMD_OFFSET (0x1A8)
|
||||
#define REG_CARD_DATA_OFFSET (0x100010)
|
||||
|
||||
// Functions to be encrypted (cannot be called directly)
|
||||
void ROMUtil_Read(void *dest, u32 addr, s32 num_bytes);
|
||||
u32 ROMUtil_CRC32(void *buf, u32 size);
|
||||
|
||||
void ROMUtil_Read(void *dest, u32 addr, s32 num_bytes) {
|
||||
void ROMUtil_Read(void *dest, u32 addr, s32 numBytes) {
|
||||
// This function is executing an obfuscated manual cartridge ROM read.
|
||||
// Nitro SDK usually does this for you with CARD_ReadRom* and friends.
|
||||
//
|
||||
|
|
@ -24,105 +16,105 @@ void ROMUtil_Read(void *dest, u32 addr, s32 num_bytes) {
|
|||
// Some of the comment documentation may be inaccurate here.
|
||||
|
||||
u8 buffer[8];
|
||||
u8 *buf_ptr;
|
||||
u8 *bufPtr;
|
||||
REGType8v *vnull;
|
||||
u32 register_base_1;
|
||||
REGType8v *register_base_2;
|
||||
u32 card_ctrl_13;
|
||||
s32 addr_offset;
|
||||
u16 lock_id;
|
||||
u16 ext_mem_register_val_original;
|
||||
u32 registerBase1;
|
||||
REGType8v *registerBase2;
|
||||
u32 cardCtrl13;
|
||||
s32 addrOffset;
|
||||
u16 lockID;
|
||||
u16 extMemRegisterValOriginal;
|
||||
u32 output;
|
||||
s32 card_ctrl_cmd;
|
||||
s32 cardCtrlCmd;
|
||||
s32 i;
|
||||
|
||||
lock_id = OS_GetLockID();
|
||||
CARD_LockRom(lock_id);
|
||||
lockID = OS_GetLockID();
|
||||
CARD_LockRom(lockID);
|
||||
|
||||
// Alias for volatile null pointer
|
||||
vnull = (REGType8v *)NULL;
|
||||
|
||||
// Alias for register base (0x04000000)
|
||||
register_base_1 = 1;
|
||||
register_base_1 <<= 26;
|
||||
registerBase1 = 1;
|
||||
registerBase1 <<= 26;
|
||||
|
||||
// Another alias for register base (0x04000000)
|
||||
register_base_2 = (REGType8v *)HW_REG_BASE;
|
||||
registerBase2 = (REGType8v *)HW_REG_BASE;
|
||||
|
||||
// External memory control register (0x04000204)
|
||||
// Save value to rewrite later
|
||||
ext_mem_register_val_original = reg_MI_EXMEMCNT;
|
||||
extMemRegisterValOriginal = reg_MI_EXMEMCNT;
|
||||
|
||||
// Set current processor accessing the gamecard bus to the ARM9
|
||||
reg_MI_EXMEMCNT = (reg_MI_EXMEMCNT & ~REG_MI_EXMEMCNT_MP_MASK) | (MI_PROCESSOR_ARM9 << REG_MI_EXMEMCNT_MP_SHIFT);
|
||||
|
||||
// Obfuscated, create address 0x027FFE60
|
||||
// This is an address in the ROM header: port 0x040001A4 / setting for normal commands
|
||||
card_ctrl_13 = 5;
|
||||
card_ctrl_13 <<= 18;
|
||||
card_ctrl_13 -= 13;
|
||||
cardCtrl13 = 5;
|
||||
cardCtrl13 <<= 18;
|
||||
cardCtrl13 -= 13;
|
||||
|
||||
// Detect if the system is in DSi mode. If so, change the address to 0x02FFFE60
|
||||
if (*(REGType8v *)(register_base_1 + REG_A9ROM_OFFSET) & REG_SCFG_A9ROM_SEC_MASK) {
|
||||
card_ctrl_13 |= 0x40000;
|
||||
if (*(REGType8v *)(registerBase1 + REG_A9ROM_OFFSET) & REG_SCFG_A9ROM_SEC_MASK) {
|
||||
cardCtrl13 |= 0x40000;
|
||||
}
|
||||
|
||||
card_ctrl_13 <<= 5;
|
||||
cardCtrl13 <<= 5;
|
||||
|
||||
// Read port setting and set page read flags
|
||||
card_ctrl_cmd = (*(vs32 *)card_ctrl_13 & ~CARD_COMMAND_MASK) | (CARD_COMMAND_PAGE | CARD_READ_MODE | CARD_START | CARD_RESET_HI);
|
||||
cardCtrlCmd = (*(vs32 *)cardCtrl13 & ~CARD_COMMAND_MASK) | (CARD_COMMAND_PAGE | CARD_READ_MODE | CARD_START | CARD_RESET_HI);
|
||||
|
||||
// Calculate offset to round back to nearest 0x200-byte block.
|
||||
// E.G. if we want to read starting from 0x1208, we actually need to
|
||||
// request the block at 0x1200 and then ignore the first 8 bytes of the result.
|
||||
// This would set `addr_offset` to -8.
|
||||
addr_offset = 0 - (addr & (CARD_ROM_PAGE_SIZE - 1));
|
||||
// This would set `addrOffset` to -8.
|
||||
addrOffset = 0 - (addr & (CARD_ROM_PAGE_SIZE - 1));
|
||||
|
||||
// Wait for card to not be busy
|
||||
while (*(REGType32v *)(register_base_1 + REG_CARDCNT_OFFSET) & CARD_START) {
|
||||
while (*(REGType32v *)(registerBase1 + REG_CARDCNT_OFFSET) & CARD_START) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Write enable flag to card ROM and SPI control register
|
||||
*(REGType8v *)(register_base_1 + REG_CARD_MASTER_CNT_OFFSET) = CARDMST_ENABLE;
|
||||
*(REGType8v *)(registerBase1 + REG_CARD_MASTER_CNT_OFFSET) = CARDMST_ENABLE;
|
||||
|
||||
// Read 8-byte command out from gamecard bus, write this back later
|
||||
buf_ptr = &buffer[0];
|
||||
bufPtr = &buffer[0];
|
||||
for (i = 0; i < 8; i++) {
|
||||
*buf_ptr++ = *(vnull + HW_REG_BASE + REG_CARD_CMD_OFFSET + i);
|
||||
*bufPtr++ = *(vnull + HW_REG_BASE + REG_CARD_CMD_OFFSET + i);
|
||||
}
|
||||
|
||||
addr += addr_offset;
|
||||
addr += addrOffset;
|
||||
|
||||
while (addr_offset < num_bytes) {
|
||||
while (addrOffset < numBytes) {
|
||||
// Read a 0x200-byte data block from ROM
|
||||
|
||||
// Write 8-byte command to registers
|
||||
// B7XXXXXXXX000000 -> 0x200-byte encrypted data read from address XXXXXXXX
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 0] = MROMOP_G_READ_PAGE >> 24;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 1] = addr >> 24;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 2] = addr >> 16;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 3] = addr >> 8;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 4] = addr;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 5] = 0x00;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 6] = 0x00;
|
||||
register_base_2[REG_CARD_CMD_OFFSET + 7] = 0x00;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 0] = MROMOP_G_READ_PAGE >> 24;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 1] = addr >> 24;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 2] = addr >> 16;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 3] = addr >> 8;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 4] = addr;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 5] = 0x00;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 6] = 0x00;
|
||||
registerBase2[REG_CARD_CMD_OFFSET + 7] = 0x00;
|
||||
|
||||
// Submit command
|
||||
*(REGType32v *)(register_base_1 + REG_CARDCNT_OFFSET) = card_ctrl_cmd;
|
||||
*(REGType32v *)(registerBase1 + REG_CARDCNT_OFFSET) = cardCtrlCmd;
|
||||
|
||||
// Copy the output into the destination buffer, within the bounds of num_bytes
|
||||
// Copy the output into the destination buffer, within the bounds of numBytes
|
||||
// (Must read the output out of the I/O register regardless)
|
||||
do {
|
||||
if (*(REGType32v *)(register_base_1 + REG_CARDCNT_OFFSET) & CARD_DATA_READY) {
|
||||
output = *(REGType32v *)(register_base_1 + REG_CARD_DATA_OFFSET);
|
||||
if (addr_offset >= 0 && addr_offset < num_bytes) {
|
||||
*(u32 *)(dest + addr_offset) = output;
|
||||
if (*(REGType32v *)(registerBase1 + REG_CARDCNT_OFFSET) & CARD_DATA_READY) {
|
||||
output = *(REGType32v *)(registerBase1 + REG_CARD_DATA_OFFSET);
|
||||
if (addrOffset >= 0 && addrOffset < numBytes) {
|
||||
*(u32 *)(dest + addrOffset) = output;
|
||||
}
|
||||
|
||||
addr_offset += 4;
|
||||
addrOffset += 4;
|
||||
}
|
||||
} while (*(REGType32v *)(register_base_1 + REG_CARDCNT_OFFSET) & CARD_START);
|
||||
} while (*(REGType32v *)(registerBase1 + REG_CARDCNT_OFFSET) & CARD_START);
|
||||
|
||||
// Advance address to next block
|
||||
addr += CARD_ROM_PAGE_SIZE;
|
||||
|
|
@ -131,25 +123,25 @@ void ROMUtil_Read(void *dest, u32 addr, s32 num_bytes) {
|
|||
// Done reading, restore everything how it was before
|
||||
|
||||
// Write original command back to gamecard bus
|
||||
buf_ptr = &buffer[0];
|
||||
bufPtr = &buffer[0];
|
||||
for (i = 0; i < 8; i++) {
|
||||
*(vnull + HW_REG_BASE + REG_CARD_CMD_OFFSET + i) = *buf_ptr++;
|
||||
*(vnull + HW_REG_BASE + REG_CARD_CMD_OFFSET + i) = *bufPtr++;
|
||||
}
|
||||
|
||||
// Write original value back to to external memory control register
|
||||
*(REGType16v *)(register_base_1 + REG_EXMEMCNT_OFFSET) = ext_mem_register_val_original;
|
||||
*(REGType16v *)(registerBase1 + REG_EXMEMCNT_OFFSET) = extMemRegisterValOriginal;
|
||||
|
||||
CARD_UnlockRom(lock_id);
|
||||
OS_ReleaseLockID(lock_id);
|
||||
CARD_UnlockRom(lockID);
|
||||
OS_ReleaseLockID(lockID);
|
||||
}
|
||||
|
||||
u32 ROMUtil_CRC32(void *buf, u32 size) {
|
||||
s32 i;
|
||||
u8 *byte_ptr = (u8 *)buf;
|
||||
u8 *bytePtr = (u8 *)buf;
|
||||
u32 crc = 0xFFFFFFFF;
|
||||
u32 poly = 0xEDB88320;
|
||||
while (size-- != 0) {
|
||||
crc ^= *byte_ptr++;
|
||||
crc ^= *bytePtr++;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (crc & 1) {
|
||||
crc = (crc >> 1);
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
SRC_DIR := ./src
|
||||
INC_DIR := ./include
|
||||
BUILD_DIR := ./build
|
||||
|
||||
$(shell mkdir -p $(BUILD_DIR))
|
||||
|
||||
CFLAGS := -O3 -Wno-unused-result -I $(INC_DIR)
|
||||
|
||||
C_FILES := $(wildcard $(SRC_DIR)/*.c)
|
||||
H_FILES := $(wildcard $(INC_DIR)/*.h)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
$(BUILD_DIR)/elfcoder: $(C_FILES) $(H_FILES)
|
||||
$(CC) $(CFLAGS) $(C_FILES) -o $(BUILD_DIR)/elfcoder
|
||||
|
||||
clean:
|
||||
$(RM) $(BUILD_DIR)/elfcoder
|
||||
|
|
@ -8,13 +8,11 @@
|
|||
* Version 1.23
|
||||
*/
|
||||
|
||||
#ifndef SDK_ASM
|
||||
|
||||
#include <nitro/types.h> // For u32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
* u32 DSProt_DetectFlashcart(void *callback)
|
||||
|
|
@ -84,17 +82,6 @@ extern u32 DSProt_DetectNotDummy(void *callback);
|
|||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __cplusplus
|
||||
|
||||
#else /* SDK_ASM */
|
||||
|
||||
.public DSProt_DetectFlashcart
|
||||
.public DSProt_DetectNotFlashcart
|
||||
.public DSProt_DetectEmulator
|
||||
.public DSProt_DetectNotEmulator
|
||||
.public DSProt_DetectDummy
|
||||
.public DSProt_DetectNotDummy
|
||||
|
||||
#endif /* SDK_ASM */
|
||||
|
||||
#endif /* DSPROT_H */
|
||||
#endif // DSPROT_H
|
||||
|
|
|
|||
19
main.lsf
19
main.lsf
|
|
@ -1303,7 +1303,24 @@ Overlay voltorb_flip
|
|||
Overlay ds_protect
|
||||
{
|
||||
After OVY_31
|
||||
Library dsprot.a
|
||||
Object lib/dsprot/dsprot_main_encrypted.o
|
||||
Object lib/dsprot/dsprot_main_decrypter_encoded.o
|
||||
Object lib/dsprot/dsprot_main_decrypter_decoder.o
|
||||
Object lib/dsprot/extra.o
|
||||
Object lib/dsprot/integrity_encrypted.o
|
||||
Object lib/dsprot/integrity_decrypter_encoded.o
|
||||
Object lib/dsprot/integrity_decrypter_decoder.o
|
||||
Object lib/dsprot/encryptor_encoded.o
|
||||
Object lib/dsprot/encryptor_decoder.o
|
||||
Object lib/dsprot/mac_owner_encrypted.o
|
||||
Object lib/dsprot/mac_owner_decrypter_encoded.o
|
||||
Object lib/dsprot/rom_util_encrypted.o
|
||||
Object lib/dsprot/rom_util_decrypter_encoded.o
|
||||
Object lib/dsprot/rom_test_encrypted.o
|
||||
Object lib/dsprot/rom_test_decrypter_encoded.o
|
||||
Object lib/dsprot/coretests_decrypter_decoder.o
|
||||
Object lib/dsprot/rc4_encoded.o
|
||||
Object lib/dsprot/rc4_decoder.o
|
||||
}
|
||||
Overlay OVY_124
|
||||
{
|
||||
|
|
|
|||
17
tools/elfcoder/Makefile
Normal file
17
tools/elfcoder/Makefile
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
CC := gcc
|
||||
|
||||
CFLAGS := -O3 -Wno-unused-result
|
||||
|
||||
C_FILES := $(wildcard *.c)
|
||||
H_FILES := $(wildcard *.h)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: elfcoder
|
||||
@:
|
||||
|
||||
elfcoder: $(C_FILES) $(H_FILES)
|
||||
$(CC) $(CFLAGS) $(C_FILES) -o elfcoder
|
||||
|
||||
clean:
|
||||
$(RM) elfcoder
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "asmwriter.h"
|
||||
#include "encoder.h"
|
||||
|
||||
static int parseKey(const char *key_text, uint32_t *out_key) {
|
||||
|
|
@ -50,6 +51,7 @@ static void printUsage(const char *self_name) {
|
|||
" -f, --functions [func1, [func2, [ ... ]]] List of functions to encode/decode.\n"
|
||||
" -k, --key [key] Optional encryption key. \n"
|
||||
" -p, --prefix [prefix = RunEncrypted_] Prefix for decryption wrappers. \n"
|
||||
" -r, --replace-prefix [prefix] Remove prefix from input functions.\n"
|
||||
" -g --garbage [symbol] Optional added garbage reference. \n"
|
||||
" -v, --verbose Print encoding progress. \n",
|
||||
self_name);
|
||||
|
|
@ -73,6 +75,7 @@ int ArgParse_CreateTask(EncodingTask *task, char **argv) {
|
|||
task->key_mode = MODE_UNKEYED;
|
||||
task->symbols = NULL;
|
||||
task->wrapper_prefix = NULL;
|
||||
task->replace_prefix = NULL;
|
||||
task->garbage = NULL;
|
||||
task->key = 0;
|
||||
task->verbose = 0;
|
||||
|
|
@ -199,6 +202,25 @@ int ArgParse_CreateTask(EncodingTask *task, char **argv) {
|
|||
task->wrapper_prefix = next_arg;
|
||||
arg_idx++;
|
||||
|
||||
} else if (argCompare(curr_arg, 'r', "--replace-prefix")) {
|
||||
if (next_arg == NULL || next_arg[0] == '-') {
|
||||
printf("Error: %s but no prefix string provided\n", curr_arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (task->replace_prefix != NULL) {
|
||||
printf("Error: multiple prefix strings provided\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!isValidIdentifier(next_arg)) {
|
||||
printf("Error: invalid identifier: %s\n", next_arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
task->replace_prefix = next_arg;
|
||||
arg_idx++;
|
||||
|
||||
} else if (argCompare(curr_arg, 'g', "--garbage")) {
|
||||
if (next_arg == NULL || next_arg[0] == '-') {
|
||||
printf("Error: %s but no reference provided\n", curr_arg);
|
||||
|
|
@ -291,6 +313,14 @@ int ArgParse_CreateTask(EncodingTask *task, char **argv) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (task->replace_prefix != NULL && task->encoding_type == ENC_ENCODE && task->key_mode == MODE_KEYED) {
|
||||
if ((task->wrapper_prefix == NULL && strcmp(task->replace_prefix, DEFAULT_ADDED_PREFIX) == 0) ||
|
||||
(task->wrapper_prefix != NULL && strcmp(task->wrapper_prefix, task->replace_prefix) == 0)) {
|
||||
printf("Error: replaced prefix and added prefix cannot be the same\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (task->output_fname != NULL && task->encoding_type == ENC_DECODE) {
|
||||
printf("Warning: output file name provided, but no output will be generated for decoding\n");
|
||||
task->output_fname = NULL;
|
||||
|
|
@ -301,6 +331,11 @@ int ArgParse_CreateTask(EncodingTask *task, char **argv) {
|
|||
task->wrapper_prefix = NULL;
|
||||
}
|
||||
|
||||
if (task->replace_prefix != NULL && !(task->encoding_type == ENC_ENCODE && task->key_mode == MODE_KEYED)) {
|
||||
printf("Warning: replaced prefix provided, but will not be used unless encoding with key\n");
|
||||
task->replace_prefix = NULL;
|
||||
}
|
||||
|
||||
if (task->garbage != NULL && task->encoding_type == ENC_DECODE) {
|
||||
printf("Warning: garbage reference provided, but will not be used for decoding\n");
|
||||
task->garbage = NULL;
|
||||
|
|
@ -3,10 +3,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ASM_COMMON_INCLUDE "asm_macro.inc"
|
||||
|
||||
char *default_prefix = "RunEncrypted_";
|
||||
|
||||
static int *allocSizeArray(char **first_symbol) {
|
||||
int symbol_count = 0;
|
||||
while (*first_symbol++ != NULL) {
|
||||
|
|
@ -56,7 +52,21 @@ static void writeAssembly(ASMWriter_Ctx *asmw, FILE *output) {
|
|||
"\n");
|
||||
|
||||
if (asmw->key_mode == MODE_KEYED) {
|
||||
int replace_prefix_len = 0;
|
||||
if (asmw->replace_prefix != NULL) {
|
||||
replace_prefix_len = strlen(asmw->replace_prefix);
|
||||
}
|
||||
|
||||
for (int symbol_idx = 0; asmw->symbols[symbol_idx] != NULL; symbol_idx++) {
|
||||
int prefix_skip = 0;
|
||||
|
||||
// Skip over replace prefix, if the base symbol name starts with it
|
||||
if (asmw->replace_prefix != NULL) {
|
||||
if (strncmp(asmw->symbols[symbol_idx], asmw->replace_prefix, replace_prefix_len) == 0) {
|
||||
prefix_skip = replace_prefix_len;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output,
|
||||
"\tarm_func_start %s%s\n"
|
||||
"%s%s:\n"
|
||||
|
|
@ -64,14 +74,14 @@ static void writeAssembly(ASMWriter_Ctx *asmw, FILE *output) {
|
|||
"\tarm_func_end %s%s\n"
|
||||
"\n",
|
||||
asmw->wrapper_prefix,
|
||||
asmw->symbols[symbol_idx],
|
||||
asmw->symbols[symbol_idx] + prefix_skip,
|
||||
asmw->wrapper_prefix,
|
||||
asmw->symbols[symbol_idx],
|
||||
asmw->symbols[symbol_idx] + prefix_skip,
|
||||
asmw->symbols[symbol_idx],
|
||||
asmw->symbol_sizes[symbol_idx],
|
||||
asmw->key,
|
||||
asmw->wrapper_prefix,
|
||||
asmw->symbols[symbol_idx]);
|
||||
asmw->symbols[symbol_idx] + prefix_skip);
|
||||
}
|
||||
|
||||
if (asmw->garbage != NULL) {
|
||||
|
|
@ -109,7 +119,7 @@ static void writeAssembly(ASMWriter_Ctx *asmw, FILE *output) {
|
|||
|
||||
fprintf(output,
|
||||
"\t.section .sinit, 4\n"
|
||||
"\t.word NitroStaticInit\n"
|
||||
"\tsinit NitroStaticInit\n"
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -118,12 +128,13 @@ void ASMWriter_Init(ASMWriter_Ctx *asmw, EncodingTask *task) {
|
|||
asmw->key = task->key;
|
||||
asmw->key_mode = task->key_mode;
|
||||
asmw->output_fname = task->output_fname;
|
||||
asmw->replace_prefix = task->replace_prefix;
|
||||
asmw->symbols = task->symbols;
|
||||
asmw->garbage = task->garbage;
|
||||
asmw->valid = 1;
|
||||
|
||||
if (task->wrapper_prefix == NULL) {
|
||||
asmw->wrapper_prefix = default_prefix;
|
||||
asmw->wrapper_prefix = DEFAULT_ADDED_PREFIX;
|
||||
} else {
|
||||
asmw->wrapper_prefix = task->wrapper_prefix;
|
||||
}
|
||||
|
|
@ -5,10 +5,15 @@
|
|||
|
||||
#include "encoder.h"
|
||||
|
||||
#define ASM_COMMON_INCLUDE "asm_macro.inc"
|
||||
|
||||
#define DEFAULT_ADDED_PREFIX "RunEncrypted_"
|
||||
|
||||
typedef struct {
|
||||
char *output_fname;
|
||||
char **symbols;
|
||||
char *wrapper_prefix;
|
||||
char *replace_prefix;
|
||||
char *garbage;
|
||||
int *symbol_sizes;
|
||||
int key_mode;
|
||||
|
|
@ -7,7 +7,22 @@
|
|||
// S[i] = i ^ 1
|
||||
// Incredibly secure S-Box.
|
||||
static const uint8_t SBox[256] = {
|
||||
0x01, 0x00, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06, 0x09, 0x08, 0x0B, 0x0A, 0x0D, 0x0C, 0x0F, 0x0E, 0x11, 0x10, 0x13, 0x12, 0x15, 0x14, 0x17, 0x16, 0x19, 0x18, 0x1B, 0x1A, 0x1D, 0x1C, 0x1F, 0x1E, 0x21, 0x20, 0x23, 0x22, 0x25, 0x24, 0x27, 0x26, 0x29, 0x28, 0x2B, 0x2A, 0x2D, 0x2C, 0x2F, 0x2E, 0x31, 0x30, 0x33, 0x32, 0x35, 0x34, 0x37, 0x36, 0x39, 0x38, 0x3B, 0x3A, 0x3D, 0x3C, 0x3F, 0x3E, 0x41, 0x40, 0x43, 0x42, 0x45, 0x44, 0x47, 0x46, 0x49, 0x48, 0x4B, 0x4A, 0x4D, 0x4C, 0x4F, 0x4E, 0x51, 0x50, 0x53, 0x52, 0x55, 0x54, 0x57, 0x56, 0x59, 0x58, 0x5B, 0x5A, 0x5D, 0x5C, 0x5F, 0x5E, 0x61, 0x60, 0x63, 0x62, 0x65, 0x64, 0x67, 0x66, 0x69, 0x68, 0x6B, 0x6A, 0x6D, 0x6C, 0x6F, 0x6E, 0x71, 0x70, 0x73, 0x72, 0x75, 0x74, 0x77, 0x76, 0x79, 0x78, 0x7B, 0x7A, 0x7D, 0x7C, 0x7F, 0x7E, 0x81, 0x80, 0x83, 0x82, 0x85, 0x84, 0x87, 0x86, 0x89, 0x88, 0x8B, 0x8A, 0x8D, 0x8C, 0x8F, 0x8E, 0x91, 0x90, 0x93, 0x92, 0x95, 0x94, 0x97, 0x96, 0x99, 0x98, 0x9B, 0x9A, 0x9D, 0x9C, 0x9F, 0x9E, 0xA1, 0xA0, 0xA3, 0xA2, 0xA5, 0xA4, 0xA7, 0xA6, 0xA9, 0xA8, 0xAB, 0xAA, 0xAD, 0xAC, 0xAF, 0xAE, 0xB1, 0xB0, 0xB3, 0xB2, 0xB5, 0xB4, 0xB7, 0xB6, 0xB9, 0xB8, 0xBB, 0xBA, 0xBD, 0xBC, 0xBF, 0xBE, 0xC1, 0xC0, 0xC3, 0xC2, 0xC5, 0xC4, 0xC7, 0xC6, 0xC9, 0xC8, 0xCB, 0xCA, 0xCD, 0xCC, 0xCF, 0xCE, 0xD1, 0xD0, 0xD3, 0xD2, 0xD5, 0xD4, 0xD7, 0xD6, 0xD9, 0xD8, 0xDB, 0xDA, 0xDD, 0xDC, 0xDF, 0xDE, 0xE1, 0xE0, 0xE3, 0xE2, 0xE5, 0xE4, 0xE7, 0xE6, 0xE9, 0xE8, 0xEB, 0xEA, 0xED, 0xEC, 0xEF, 0xEE, 0xF1, 0xF0, 0xF3, 0xF2, 0xF5, 0xF4, 0xF7, 0xF6, 0xF9, 0xF8, 0xFB, 0xFA, 0xFD, 0xFC, 0xFF, 0xFE
|
||||
0x01, 0x00, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06, 0x09, 0x08, 0x0B, 0x0A, 0x0D, 0x0C, 0x0F, 0x0E,
|
||||
0x11, 0x10, 0x13, 0x12, 0x15, 0x14, 0x17, 0x16, 0x19, 0x18, 0x1B, 0x1A, 0x1D, 0x1C, 0x1F, 0x1E,
|
||||
0x21, 0x20, 0x23, 0x22, 0x25, 0x24, 0x27, 0x26, 0x29, 0x28, 0x2B, 0x2A, 0x2D, 0x2C, 0x2F, 0x2E,
|
||||
0x31, 0x30, 0x33, 0x32, 0x35, 0x34, 0x37, 0x36, 0x39, 0x38, 0x3B, 0x3A, 0x3D, 0x3C, 0x3F, 0x3E,
|
||||
0x41, 0x40, 0x43, 0x42, 0x45, 0x44, 0x47, 0x46, 0x49, 0x48, 0x4B, 0x4A, 0x4D, 0x4C, 0x4F, 0x4E,
|
||||
0x51, 0x50, 0x53, 0x52, 0x55, 0x54, 0x57, 0x56, 0x59, 0x58, 0x5B, 0x5A, 0x5D, 0x5C, 0x5F, 0x5E,
|
||||
0x61, 0x60, 0x63, 0x62, 0x65, 0x64, 0x67, 0x66, 0x69, 0x68, 0x6B, 0x6A, 0x6D, 0x6C, 0x6F, 0x6E,
|
||||
0x71, 0x70, 0x73, 0x72, 0x75, 0x74, 0x77, 0x76, 0x79, 0x78, 0x7B, 0x7A, 0x7D, 0x7C, 0x7F, 0x7E,
|
||||
0x81, 0x80, 0x83, 0x82, 0x85, 0x84, 0x87, 0x86, 0x89, 0x88, 0x8B, 0x8A, 0x8D, 0x8C, 0x8F, 0x8E,
|
||||
0x91, 0x90, 0x93, 0x92, 0x95, 0x94, 0x97, 0x96, 0x99, 0x98, 0x9B, 0x9A, 0x9D, 0x9C, 0x9F, 0x9E,
|
||||
0xA1, 0xA0, 0xA3, 0xA2, 0xA5, 0xA4, 0xA7, 0xA6, 0xA9, 0xA8, 0xAB, 0xAA, 0xAD, 0xAC, 0xAF, 0xAE,
|
||||
0xB1, 0xB0, 0xB3, 0xB2, 0xB5, 0xB4, 0xB7, 0xB6, 0xB9, 0xB8, 0xBB, 0xBA, 0xBD, 0xBC, 0xBF, 0xBE,
|
||||
0xC1, 0xC0, 0xC3, 0xC2, 0xC5, 0xC4, 0xC7, 0xC6, 0xC9, 0xC8, 0xCB, 0xCA, 0xCD, 0xCC, 0xCF, 0xCE,
|
||||
0xD1, 0xD0, 0xD3, 0xD2, 0xD5, 0xD4, 0xD7, 0xD6, 0xD9, 0xD8, 0xDB, 0xDA, 0xDD, 0xDC, 0xDF, 0xDE,
|
||||
0xE1, 0xE0, 0xE3, 0xE2, 0xE5, 0xE4, 0xE7, 0xE6, 0xE9, 0xE8, 0xEB, 0xEA, 0xED, 0xEC, 0xEF, 0xEE,
|
||||
0xF1, 0xF0, 0xF3, 0xF2, 0xF5, 0xF4, 0xF7, 0xF6, 0xF9, 0xF8, 0xFB, 0xFA, 0xFD, 0xFC, 0xFF, 0xFE
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -26,6 +26,7 @@ typedef struct {
|
|||
int key_mode;
|
||||
char **symbols;
|
||||
char *wrapper_prefix;
|
||||
char *replace_prefix;
|
||||
char *garbage;
|
||||
uint32_t key;
|
||||
int verbose;
|
||||
Loading…
Reference in New Issue
Block a user