From c4d6f5961b13364fcae5f615eed6e01eb2e6a807 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 6 Jun 2020 22:20:11 +0200 Subject: [PATCH] first commit --- .gitignore | 8 + Makefile | 163 +++++++++++++++++++ README.md | 3 + include/function_patcher/fpatching_defines.h | 127 +++++++++++++++ include/function_patcher/function_patching.h | 14 ++ source/patching.def | 4 + 6 files changed, 319 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 include/function_patcher/fpatching_defines.h create mode 100644 include/function_patcher/function_patching.h create mode 100644 source/patching.def diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a2fa80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/*.a +/build +*.bz2 +release/ +lib/ +CMakeLists.txt +.idea/ +cmake-build-debug/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8ed0750 --- /dev/null +++ b/Makefile @@ -0,0 +1,163 @@ +#------------------------------------------------------------------------------- +.SUFFIXES: +#------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") +endif + +TOPDIR ?= $(CURDIR) + +include $(DEVKITPRO)/wut/share/wut_rules + +export VER_MAJOR := 1 +export VER_MINOR := 0 +export VER_PATCH := 0 + +VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH) + +#------------------------------------------------------------------------------- +# 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 +DATA := data +INCLUDES := source \ + include \ + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -Wall -Werror -save-temps \ + -ffunction-sections -fdata-sections \ + $(MACHDEP) \ + $(BUILD_CFLAGS) + +CFLAGS += $(INCLUDE) -D__WIIU__ + +CXXFLAGS := $(CFLAGS) -std=gnu++17 + +ASFLAGS := $(MACHDEP) + +LDFLAGS = $(ARCH) -Wl,--gc-sections + + +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) + +#--------------------------------------------------------------------------------- +# 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 TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +DEFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.def))) +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 := $(DEFFILES:.def=.o) $(SFILES:.s=.o) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I. + +.PHONY: all dist-bin dist-src dist install clean + +#--------------------------------------------------------------------------------- +all: lib/libfunctionpatcher.a + +dist-bin: all + @tar --exclude=*~ -cjf libfunctionpatcher-$(VERSION).tar.bz2 include lib + +dist-src: + @tar --exclude=*~ -cjf libfunctionpatcher-src-$(VERSION).tar.bz2 include source Makefile + +dist: dist-src dist-bin + +install: dist-bin + mkdir -p $(DESTDIR)$(DEVKITPRO)/wums + bzip2 -cd libfunctionpatcher-$(VERSION).tar.bz2 | tar -xf - -C $(DESTDIR)$(DEVKITPRO)/wums + +lib: + @[ -d $@ ] || mkdir -p $@ + +release: + @[ -d $@ ] || mkdir -p $@ + +lib/libfunctionpatcher.a :$(SOURCES) $(INCLUDES) | lib release + @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ + BUILD_CFLAGS="-DNDEBUG=1 -O2 -s" \ + DEPSDIR=$(CURDIR)/release \ + --no-print-directory -C release \ + -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -rf release lib + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT) : $(OFILES) + +$(OFILES_SRC) : $(HFILES) + +#--------------------------------------------------------------------------------- +%.o: %.def + $(SILENTMSG) $(notdir $<) + $(SILENTCMD)rplimportgen $< $*.s --forceSingleSection $(ERROR_FILTER) + $(SILENTCMD)$(CC) -x assembler-with-cpp $(ASFLAGS) -c $*.s -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%_bin.h %.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..a5d65e6 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Requires the [FunctionPatcherModule](https://github.com/Maschell/FunctionPatcherModule) to be running via [SetupPayload](https://github.com/wiiu-env/SetupPayload). +Requires [wut](https://github.com/decaf-emu/wut) for building. +Install via `make install`. \ No newline at end of file diff --git a/include/function_patcher/fpatching_defines.h b/include/function_patcher/fpatching_defines.h new file mode 100644 index 0000000..58a375f --- /dev/null +++ b/include/function_patcher/fpatching_defines.h @@ -0,0 +1,127 @@ +#pragma once + +#include + +typedef enum function_replacement_library_type_t { + LIBRARY_AVM, + LIBRARY_CAMERA, + LIBRARY_COREINIT, + LIBRARY_DC, + LIBRARY_DMAE, + LIBRARY_DRMAPP, + LIBRARY_ERREULA, + LIBRARY_GX2, + LIBRARY_H264, + LIBRARY_LZMA920, + LIBRARY_MIC, + LIBRARY_NFC, + LIBRARY_NIO_PROF, + LIBRARY_NLIBCURL, + LIBRARY_NLIBNSS, + LIBRARY_NLIBNSS2, + LIBRARY_NN_AC, + LIBRARY_NN_ACP, + LIBRARY_NN_ACT, + LIBRARY_NN_AOC, + LIBRARY_NN_BOSS, + LIBRARY_NN_CCR, + LIBRARY_NN_CMPT, + LIBRARY_NN_DLP, + LIBRARY_NN_EC, + LIBRARY_NN_FP, + LIBRARY_NN_HAI, + LIBRARY_NN_HPAD, + LIBRARY_NN_IDBE, + LIBRARY_NN_NDM, + LIBRARY_NN_NETS2, + LIBRARY_NN_NFP, + LIBRARY_NN_NIM, + LIBRARY_NN_OLV, + LIBRARY_NN_PDM, + LIBRARY_NN_SAVE, + LIBRARY_NN_SL, + LIBRARY_NN_SPM, + LIBRARY_NN_TEMP, + LIBRARY_NN_UDS, + LIBRARY_NN_VCTL, + LIBRARY_NSYSCCR, + LIBRARY_NSYSHID, + LIBRARY_NSYSKBD, + LIBRARY_NSYSNET, + LIBRARY_NSYSUHS, + LIBRARY_NSYSUVD, + LIBRARY_NTAG, + LIBRARY_PADSCORE, + LIBRARY_PROC_UI, + LIBRARY_SND_CORE, + LIBRARY_SND_USER, + LIBRARY_SNDCORE2, + LIBRARY_SNDUSER2, + LIBRARY_SWKBD, + LIBRARY_SYSAPP, + LIBRARY_TCL, + LIBRARY_TVE, + LIBRARY_UAC, + LIBRARY_UAC_RPL, + LIBRARY_USB_MIC, + LIBRARY_UVC, + LIBRARY_UVD, + LIBRARY_VPAD, + LIBRARY_VPADBASE, + LIBRARY_ZLIB125, + LIBRARY_OTHER, +} function_replacement_library_type_t; + +#define MAXIMUM_FUNCTION_NAME_LENGTH 100 +#define FUNCTION_PATCHER_METHOD_STORE_SIZE 20 + +#define STATIC_FUNCTION 0 +#define DYNAMIC_FUNCTION 1 + +typedef struct function_replacement_data_t { + uint32_t physicalAddr; /* [needs to be filled] */ + uint32_t virtualAddr; /* [needs to be filled] */ + uint32_t replaceAddr; /* [needs to be filled] Address of our replacement function */ + uint32_t replaceCall; /* [needs to be filled] Address to access the real_function */ + function_replacement_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */ + char function_name[MAXIMUM_FUNCTION_NAME_LENGTH]; /* [needs to be filled] name of the function we want to replace */ + uint32_t realAddr; /* [will be filled] Address of the real function we want to replace. */ + volatile uint32_t replace_data [FUNCTION_PATCHER_METHOD_STORE_SIZE]; /* [will be filled] Space for us to store some jump instructions */ + uint32_t restoreInstruction; /* [will be filled] Copy of the instruction we replaced to jump to our code. */ + uint8_t functionType; /* [will be filled] */ + uint8_t alreadyPatched; /* [will be filled] */ +} function_replacement_data_t; + +#define REPLACE_FUNCTION(x, lib, function_name) \ + { \ + 0, \ + 0, \ + (uint32_t) my_ ## x, \ + (uint32_t) &real_ ## x, \ + lib, \ + # function_name, \ + 0, \ + {}, \ + 0, \ + STATIC_FUNCTION, \ + 0 \ + } + +#define REPLACE_FUNCTION_VIA_ADDRESS(x, physicalAddress, effectiveAddress) \ + { \ + physicalAddress, \ + effectiveAddress, \ + (uint32_t) my_ ## x, \ + (uint32_t) &real_ ## x, \ + LIBRARY_OTHER, \ + # x, \ + 0, \ + {}, \ + 0, \ + STATIC_FUNCTION, \ + 0 \ + } + +#define DECL_FUNCTION(res, name, ...) \ + res (* real_ ## name)(__VA_ARGS__) __attribute__((section(".data"))); \ + res my_ ## name(__VA_ARGS__) diff --git a/include/function_patcher/function_patching.h b/include/function_patcher/function_patching.h new file mode 100644 index 0000000..478ba71 --- /dev/null +++ b/include/function_patcher/function_patching.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "fpatching_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void FunctionPatcherPatchFunction(function_replacement_data_t *replacements, uint32_t size); + +#ifdef __cplusplus +} +#endif diff --git a/source/patching.def b/source/patching.def new file mode 100644 index 0000000..ba834f8 --- /dev/null +++ b/source/patching.def @@ -0,0 +1,4 @@ +:NAME homebrew_functionpatcher + +:TEXT +FunctionPatcherPatchFunction \ No newline at end of file