From dfd922318d3e0b0600a741308ce8863e2cd3b7e3 Mon Sep 17 00:00:00 2001 From: Pablomf6 Date: Sat, 24 Nov 2018 18:45:10 +0100 Subject: [PATCH] OnionFS 2.0 ready for release --- 3ds.ld | 12 +- Includes/csvc.h | 266 +++++++++++++++++++++------------------- OnionFS.vcxproj | 51 +++++++- OnionFS.vcxproj.filters | 141 +++++++++++++++++++++ Sources/bootloader.s | 58 ++------- Sources/main.cpp | 4 +- Sources/save.cpp | 5 +- 7 files changed, 348 insertions(+), 189 deletions(-) diff --git a/3ds.ld b/3ds.ld index ca8e209..55c34a8 100644 --- a/3ds.ld +++ b/3ds.ld @@ -13,7 +13,7 @@ PHDRS SECTIONS { /* =========== CODE section =========== */ - . = 0x00100000; + . = 0x07000100; __start__ = . ; .text ALIGN(0x4) : { @@ -123,16 +123,6 @@ SECTIONS KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } : data - - .rel.plt ALIGN(4): - { - *(.__rel_dyn_start) - *(.rel*) - *(.rel.*) - *(.rel.dyn) - *(.__rel_dyn_end) - } : data - .bss ALIGN(4): { *(.__bss_start) diff --git a/Includes/csvc.h b/Includes/csvc.h index 2c6862e..c79f358 100644 --- a/Includes/csvc.h +++ b/Includes/csvc.h @@ -16,135 +16,149 @@ #pragma once -#include - -// For accessing physmem uncached (and directly) -#define PA_PTR(addr) (void *)((u32)(addr) | 1 << 31) -#ifndef PA_FROM_VA_PTR -#define PA_FROM_VA_PTR(addr) PA_PTR(svcConvertVAToPA((const void *)(addr), false)) -#endif - #ifdef __cplusplus extern "C" { #endif - /// Operations for svcControlService - typedef enum ServiceOp - { - SERVICEOP_STEAL_CLIENT_SESSION = 0, ///< Steal a client session given a service or global port name - SERVICEOP_GET_NAME, ///< Get the name of a service or global port given a client or session handle - } ServiceOp; - - /** - * @brief Executes a function in supervisor mode, using the supervisor-mode stack. - * @param func Function to execute. - * @param ... Function parameters, up to 3 registers. - */ - Result svcCustomBackdoor(void *func, ...); - - ///@name I/O - ///@{ - /** - * @brief Gives the physical address corresponding to a virtual address. - * @param VA Virtual address. - * @param writeCheck whether to check if the VA is writable in supervisor mode - * @return The corresponding physical address, or NULL. - */ - u32 svcConvertVAToPA(const void *VA, bool writeCheck); - - /** - * @brief Flushes a range of the data cache (L2C included). - * @param addr Start address. - * @param len Length of the range. - */ - void svcFlushDataCacheRange(void *addr, u32 len); - - /** - * @brief Flushes the data cache entirely (L2C included). - */ - void svcFlushEntireDataCache(void); - - /** - * @brief Invalidates a range of the instruction cache. - * @param addr Start address. - * @param len Length of the range. - */ - void svcInvalidateInstructionCacheRange(void *addr, u32 len); - - /** - * @brief Invalidates the data cache entirely. - */ - void svcInvalidateEntireInstructionCache(void); - ///@} - - ///@name Memory management - ///@{ - /** - * @brief Maps a block of process memory. - * @param process Handle of the process. - * @param destAddress Address of the mapped block in the current process. - * @param srcAddress Address of the mapped block in the source process. - * @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes). - */ - Result svcMapProcessMemoryEx(Handle process, u32 destAddr, u32 srcAddr, u32 size); - - /** - * @brief Unmaps a block of process memory. - * @param process Handle of the process. - * @param destAddress Address of the block of memory to unmap, in the current (destination) process. - * @param size Size of the block of memory to unmap (truncated to a multiple of 0x1000 bytes). - */ - Result svcUnmapProcessMemoryEx(Handle process, u32 destAddress, u32 size); - - /** - * @brief Controls memory mapping, with the choice to use region attributes or not. - * @param[out] addr_out The virtual address resulting from the operation. Usually the same as addr0. - * @param addr0 The virtual address to be used for the operation. - * @param addr1 The virtual address to be (un)mirrored by @p addr0 when using @ref MEMOP_MAP or @ref MEMOP_UNMAP. - * It has to be pointing to a RW memory. - * Use NULL if the operation is @ref MEMOP_FREE or @ref MEMOP_ALLOC. - * @param size The requested size for @ref MEMOP_ALLOC and @ref MEMOP_ALLOC_LINEAR. - * @param op Operation flags. See @ref MemOp. - * @param perm A combination of @ref MEMPERM_READ and @ref MEMPERM_WRITE. Using MEMPERM_EXECUTE will return an error. - * Value 0 is used when unmapping memory. - * @param isLoader Whether to use the region attributes - * If a memory is mapped for two or more addresses, you have to use MEMOP_UNMAP before being able to MEMOP_FREE it. - * MEMOP_MAP will fail if @p addr1 was already mapped to another address. - * - * @sa svcControlMemory - */ - Result svcControlMemoryEx(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader); - ///@} - - ///@name System - ///@{ - /** - * @brief Performs actions related to services or global handles. - * @param op The operation to perform, see @ref ServiceOp. - * - * Examples: - * svcControlService(SERVICEOP_GET_NAME, (char [12])outName, (Handle)clientOrSessionHandle); - * svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, (Handle *)&outHandle, (const char *)name); - */ - Result svcControlService(ServiceOp op, ...); - - /** - * @brief Copy a handle from a process to another one. - * @param[out] out The output handle. - * @param outProcess Handle of the process of the output handle. - * @param in The input handle. Pseudo-handles are not accepted. - * @param inProcess Handle of the process of the input handle. - */ - Result svcCopyHandle(Handle *out, Handle outProcess, Handle in, Handle inProcess); - - /** - * @brief Get the address and class name of the underlying kernel object corresponding to a handle. - * @param[out] outKAddr The output kernel address. - * @param[out] outName Output class name. The buffer should be large enough to contain it. - * @param in The input handle. - */ - Result svcTranslateHandle(u32 *outKAddr, char *outClassName, Handle in); - ///@} +#include "types.h" + +#define PA_RWX(add) (add == 0 ? 0 : (add < 0x30000000 ? (u32)((add) | (1u << 31)) : add)) +#define PA_FROM_VA(addr) PA_RWX(svcConvertVAToPA((void *)addr, false)) + +/// Operations for svcControlService +typedef enum ServiceOp +{ + SERVICEOP_STEAL_CLIENT_SESSION = 0, ///< Steal a client session given a service or global port name + SERVICEOP_GET_NAME, ///< Get the name of a service or global port given a client or session handle +} ServiceOp; + +/** + * @brief Executes a function in supervisor mode, using the supervisor-mode stack. + * @param func Function to execute. + * @param ... Function parameters, up to 3 registers. +*/ +Result svcCustomBackdoor(void *func, ...); + +///@name I/O +///@{ +/** + * @brief Gives the physical address corresponding to a virtual address. + * @param VA Virtual address. + * @param writeCheck whether to check if the VA is writable in supervisor mode + * @return The corresponding physical address, or NULL. +*/ +u32 svcConvertVAToPA(const void *VA, bool writeCheck); + +/** + * @brief Flushes a range of the data cache (L2C included). + * @param addr Start address. + * @param len Length of the range. +*/ +void svcFlushDataCacheRange(void *addr, u32 len); + +/** + * @brief Flushes the data cache entirely (L2C included). +*/ +void svcFlushEntireDataCache(void); + +/** + * @brief Invalidates a range of the instruction cache. + * @param addr Start address. + * @param len Length of the range. +*/ +void svcInvalidateInstructionCacheRange(void *addr, u32 len); + +/** + * @brief Invalidates the data cache entirely. +*/ +void svcInvalidateEntireInstructionCache(void); +///@} + +///@name Memory management +///@{ +/** + * @brief Maps a block of process memory. + * @param process Handle of the process. + * @param destAddress Address of the mapped block in the current process. + * @param srcAddress Address of the mapped block in the source process. + * @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes). +*/ +Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); + +/** + * @brief Unmaps a block of process memory. + * @param process Handle of the process. + * @param destAddress Address of the block of memory to unmap, in the current (destination) process. + * @param size Size of the block of memory to unmap (truncated to a multiple of 0x1000 bytes). + */ +Result svcUnmapProcessMemoryEx(Handle process, u32 destAddress, u32 size); + +/** + * @brief Controls memory mapping, with the choice to use region attributes or not. + * @param[out] addr_out The virtual address resulting from the operation. Usually the same as addr0. + * @param addr0 The virtual address to be used for the operation. + * @param addr1 The virtual address to be (un)mirrored by @p addr0 when using @ref MEMOP_MAP or @ref MEMOP_UNMAP. + * It has to be pointing to a RW memory. + * Use NULL if the operation is @ref MEMOP_FREE or @ref MEMOP_ALLOC. + * @param size The requested size for @ref MEMOP_ALLOC and @ref MEMOP_ALLOC_LINEAR. + * @param op Operation flags. See @ref MemOp. + * @param perm A combination of @ref MEMPERM_READ and @ref MEMPERM_WRITE. Using MEMPERM_EXECUTE will return an error. + * Value 0 is used when unmapping memory. + * @param isLoader Whether to use the region attributes + * If a memory is mapped for two or more addresses, you have to use MEMOP_UNMAP before being able to MEMOP_FREE it. + * MEMOP_MAP will fail if @p addr1 was already mapped to another address. + * + * @sa svcControlMemory + */ +Result svcControlMemoryEx(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader); +///@} + +///@name System +///@{ +/** + * @brief Performs actions related to services or global handles. + * @param op The operation to perform, see @ref ServiceOp. + * + * Examples: + * svcControlService(SERVICEOP_GET_NAME, (char [12])outName, (Handle)clientOrSessionHandle); + * svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, (Handle *)&outHandle, (const char *)name); + */ +Result svcControlService(ServiceOp op, ...); + +/** + * @brief Copy a handle from a process to another one. + * @param[out] out The output handle. + * @param outProcess Handle of the process of the output handle. + * @param in The input handle. Pseudo-handles are not accepted. + * @param inProcess Handle of the process of the input handle. +*/ +Result svcCopyHandle(Handle *out, Handle outProcess, Handle in, Handle inProcess); + +/** + * @brief Get the address and class name of the underlying kernel object corresponding to a handle. + * @param[out] outKAddr The output kernel address. + * @param[out] outName Output class name. The buffer should be large enough to contain it. + * @param in The input handle. +*/ +Result svcTranslateHandle(u32 *outKAddr, char *outClassName, Handle in); +///@} + +/// Operations for svcControlProcess +typedef enum ProcessOp +{ + PROCESSOP_GET_ALL_HANDLES, ///< List all handles of the process, varg3 can be either 0 to fetch all handles, or token of the type to fetch + ///< svcControlProcess(handle, PROCESSOP_GET_ALL_HANDLES, (u32)&outBuf, 0) + PROCESSOP_SET_MMU_TO_RWX, ///< Set the whole memory of the process with rwx access + ///< svcControlProcess(handle, PROCESSOP_SET_MMU_TO_RWX, 0, 0) + PROCESSOP_GET_ON_MEMORY_CHANGE_EVENT, + PROCESSOP_GET_ON_EXIT_EVENT, + PROCESSOP_GET_PA_FROM_VA, ///< Get the physical address of the va within the process + ///< svcControlProcess(handle, PROCESSOP_GET_PA_FROM_VA, (u32)&outPa, va) + PROCESSOP_SCHEDULE_THREADS, +} ProcessOp; + +Result svcControlProcess(Handle process, ProcessOp op, u32 varg2, u32 varg3); + #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/OnionFS.vcxproj b/OnionFS.vcxproj index f21e5a1..c1daa36 100644 --- a/OnionFS.vcxproj +++ b/OnionFS.vcxproj @@ -68,7 +68,7 @@ make re WIN32;_DEBUG;$(NMakePreprocessorDefinitions) $(NMakeForcedIncludes) - D:\Documentos\3dshack\OnionFS\v2\Includes;$(NMakeIncludeSearchPath) + D:\Documentos\3dshack\OnionFS\Includes;$(NMakeIncludeSearchPath) make @@ -103,6 +103,9 @@ + + + @@ -121,10 +124,14 @@ + + + + @@ -137,7 +144,9 @@ + + @@ -148,36 +157,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OnionFS.vcxproj.filters b/OnionFS.vcxproj.filters index 2ee096b..0e33ca4 100644 --- a/OnionFS.vcxproj.filters +++ b/OnionFS.vcxproj.filters @@ -245,10 +245,151 @@ Archivos de encabezado + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + Archivos de encabezado + + + + \ No newline at end of file diff --git a/Sources/bootloader.s b/Sources/bootloader.s index 52b6573..859506d 100644 --- a/Sources/bootloader.s +++ b/Sources/bootloader.s @@ -3,49 +3,21 @@ .section .text .global _start _start: -stmfd sp!, {r0-r12, lr} -mrs r0, cpsr -stmfd sp!, {r0} + stmfd sp!, {r0-r12, lr} + mrs r0, cpsr + stmfd sp!, {r0} -ldr r6, =_start -adr r5, _start -sub r5, r5, r6 /* r5 = realAddress - baseAddress */ -ldr r6, = __rel_dyn_start -ldr r7, = __rel_dyn_end -add r6, r6, r5 -add r7, r7, r5 -relocNotFinished: -ldmia r6!, {r3, r4} -cmp r4, #0x17 -bne notRelativeEntry -add r3, r3, r5 -ldr r4, [r3] -add r4, r4, r5 -str r4, [r3] -notRelativeEntry: -cmp r6, r7 -bcc relocNotFinished -ldr r0, =0xffff8001 -adr r1, _start -ldr r2, =__rel_dyn_end -sub r2, r2, r1 /* r2 = codesize */ -svc 0x54 /* flush instruction cache */ -nop -nop + @ Clear the BSS section + ldr r0, = __c_bss_start + ldr r1, = __c_bss_end + sub r1, r1, r0 + bl ClearMem -skip: -@ Clear the BSS section -ldr r0, = __c_bss_start -ldr r1, = __c_bss_end -sub r1, r1, r0 -bl ClearMem + bl LaunchMainThread -bl LaunchMainThread - -ldmfd sp!, {r0} -msr cpsr, r0 -ldmfd sp!, {r0-r12, pc} -bx lr + ldmfd sp!, {r0} + msr cpsr, r0 + ldmfd sp!, {r0-r12, pc} @--------------------------------------------------------------------------------- @ Clear memory to 0x00 if length != 0 @@ -66,12 +38,6 @@ ClrLoop: bne ClrLoop bx lr -.section .__rel_dyn_start -__rel_dyn_start: - -.section .__rel_dyn_end -__rel_dyn_end: - .section .__bss_start .global __c_bss_start __c_bss_start: diff --git a/Sources/main.cpp b/Sources/main.cpp index 89b57f3..ae3d431 100644 --- a/Sources/main.cpp +++ b/Sources/main.cpp @@ -58,7 +58,7 @@ namespace CTRPluginFramework DEBUG(", svcGetProcessInfo 0x10002 returned: 0x%08X, aborting.\n", res); customBreak(0xAB047, 1, 0); } - res = svcMapProcessMemoryEx(prochand, 0x08000000, (u32)addr, (u32)info); + res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x08000000, prochand, (u32)addr, (u32)info); if (res) { DEBUG(", svcMapProcessMemoryEx returned: 0x%08X, aborting.\n", res); customBreak(0xAB047, 1, 0); @@ -92,7 +92,7 @@ namespace CTRPluginFramework for (u32 *addrRest : backup) *addrRest = 0x121004; svcInvalidateEntireInstructionCache(); - svcUnmapProcessMemoryEx(prochand, 0x08000000, (u32)info); + svcUnmapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x08000000, (u32)info); svcCloseHandle(prochand); } if (out) { diff --git a/Sources/save.cpp b/Sources/save.cpp index a3cf757..f8628d7 100644 --- a/Sources/save.cpp +++ b/Sources/save.cpp @@ -98,10 +98,9 @@ namespace CTRPluginFramework { } *dst = '\0'; } - +#define PA_PTR(addr) void OnionSave::initDebug() { - Controller::Update(); - if (Controller::IsKeysDown(Key::DPadUp)) { + if ((((*(vu32 *)((u32)(0x10146000) | 1 << 31))) ^ 0xFFF) & Key::DPadUp) { ENABLE_DEBUG = true; } if (ENABLE_DEBUG) {