mirror of
https://github.com/wiiu-env/MochaPayload.git
synced 2024-11-21 15:39:16 +01:00
Format the code via clang-format
This commit is contained in:
parent
77c31bd0fe
commit
8015a18f24
67
.clang-format
Normal file
67
.clang-format
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# Generated from CLion C/C++ Code Style settings
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: Consecutive
|
||||||
|
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
|
||||||
|
AlignOperands: Align
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Always
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Always
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
ColumnLimit: 0
|
||||||
|
CompactNamespaces: false
|
||||||
|
ContinuationIndentWidth: 8
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MaxEmptyLinesToKeep: 2
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: false
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@ -6,8 +6,16 @@ on:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
clang-format:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: clang-format
|
||||||
|
run: |
|
||||||
|
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source
|
||||||
build-binary:
|
build-binary:
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
|
needs: clang-format
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: build binary
|
- name: build binary
|
||||||
@ -54,4 +62,4 @@ jobs:
|
|||||||
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
|
||||||
asset_path: ./${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
|
asset_path: ./${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
|
||||||
asset_name: ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
|
asset_name: ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip
|
||||||
asset_content_type: application/unknown
|
asset_content_type: application/zip
|
8
.github/workflows/pr.yml
vendored
8
.github/workflows/pr.yml
vendored
@ -3,8 +3,16 @@ name: CI-PR
|
|||||||
on: [pull_request]
|
on: [pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
clang-format:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: clang-format
|
||||||
|
run: |
|
||||||
|
docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source
|
||||||
build-binary:
|
build-binary:
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
|
needs: clang-format
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: build binary
|
- name: build binary
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
[![CI-Release](https://github.com/wiiu-env/MochaPayload/actions/workflows/ci.yml/badge.svg)](https://github.com/wiiu-env/MochaPayload/actions/workflows/ci.yml)
|
||||||
|
|
||||||
# MochaPayload - a simple custom firmware
|
# MochaPayload - a simple custom firmware
|
||||||
This a lite version of the [original mocha](https://github.com/dimok789/mocha) to be used with the [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader).
|
This a version of the [original mocha](https://github.com/dimok789/mocha) to be used with the [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
Place the `00_mocha.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader).
|
Place the `00_mocha.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the [EnvironmentLoader](https://github.com/wiiu-env/EnvironmentLoader).
|
||||||
@ -15,7 +17,6 @@ Place the `00_mocha.rpx` in the `[ENVIRONMENT]/modules/setup` folder and run the
|
|||||||
|
|
||||||
For building you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command.
|
For building you just need [wut](https://github.com/devkitPro/wut/) installed, then use the `make` command.
|
||||||
|
|
||||||
|
|
||||||
## Building using the Dockerfile
|
## Building using the Dockerfile
|
||||||
|
|
||||||
It's possible to use a docker image for building. This way you don't need anything installed on your host system.
|
It's possible to use a docker image for building. This way you don't need anything installed on your host system.
|
||||||
@ -31,6 +32,10 @@ docker run -it --rm -v ${PWD}:/project mochapayload-builder make
|
|||||||
docker run -it --rm -v ${PWD}:/project mochapayload-builder make clean
|
docker run -it --rm -v ${PWD}:/project mochapayload-builder make clean
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Format the code via docker
|
||||||
|
|
||||||
|
`docker run --rm -v ${PWD}:/src wiiuenv/clang-format:13.0.0-2 -r ./source -i`
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
dimok
|
dimok
|
||||||
Maschell
|
Maschell
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define CHECK_SIZE(Type, Size) \
|
#define CHECK_SIZE(Type, Size) \
|
||||||
static_assert(sizeof(Type) == Size, \
|
static_assert(sizeof(Type) == Size, \
|
||||||
#Type " must be " #Size " bytes")
|
#Type " must be " #Size " bytes")
|
||||||
|
|
||||||
#define CHECK_OFFSET(Type, Offset, Field) \
|
#define CHECK_OFFSET(Type, Offset, Field) \
|
||||||
static_assert(offsetof(Type, Field) == Offset, \
|
static_assert(offsetof(Type, Field) == Offset, \
|
||||||
#Type "::" #Field " must be at offset " #Offset)
|
#Type "::" #Field " must be at offset " #Offset)
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
uint64_t title_id;
|
uint64_t title_id;
|
||||||
@ -222,11 +223,11 @@ typedef struct {
|
|||||||
unsigned char unk3[0x12D8 - 0x68];
|
unsigned char unk3[0x12D8 - 0x68];
|
||||||
} MCPLoadFileRequest;
|
} MCPLoadFileRequest;
|
||||||
|
|
||||||
#define IPC_CUSTOM_START_MCP_THREAD 0xFE
|
#define IPC_CUSTOM_START_MCP_THREAD 0xFE
|
||||||
#define IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED 0xFD
|
#define IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED 0xFD
|
||||||
#define IPC_CUSTOM_LOAD_CUSTOM_RPX 0xFC
|
#define IPC_CUSTOM_LOAD_CUSTOM_RPX 0xFC
|
||||||
#define IPC_CUSTOM_META_XML_READ 0xFB
|
#define IPC_CUSTOM_META_XML_READ 0xFB
|
||||||
#define IPC_CUSTOM_START_USB_LOGGING 0xFA
|
#define IPC_CUSTOM_START_USB_LOGGING 0xFA
|
||||||
#define IPC_CUSTOM_COPY_ENVIRONMENT_PATH 0xF9
|
#define IPC_CUSTOM_COPY_ENVIRONMENT_PATH 0xF9
|
||||||
|
|
||||||
#define LOAD_FILE_TARGET_SD_CARD 0
|
#define LOAD_FILE_TARGET_SD_CARD 0
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
#ifndef KERNEL_COMMANDS_H_
|
#ifndef KERNEL_COMMANDS_H_
|
||||||
#define KERNEL_COMMANDS_H_
|
#define KERNEL_COMMANDS_H_
|
||||||
|
|
||||||
#define KERNEL_READ32 1
|
#define KERNEL_READ32 1
|
||||||
#define KERNEL_WRITE32 2
|
#define KERNEL_WRITE32 2
|
||||||
#define KERNEL_MEMCPY 3
|
#define KERNEL_MEMCPY 3
|
||||||
#define KERNEL_GET_CFW_CONFIG 4
|
#define KERNEL_GET_CFW_CONFIG 4
|
||||||
#define KERNEL_READ_OTP 5
|
#define KERNEL_READ_OTP 5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <coreinit/cache.h>
|
|
||||||
#include <coreinit/thread.h>
|
|
||||||
#include <coreinit/ios.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "ios_exploit.h"
|
#include "ios_exploit.h"
|
||||||
|
#include <coreinit/cache.h>
|
||||||
|
#include <coreinit/ios.h>
|
||||||
|
#include <coreinit/thread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||||
|
|
||||||
#define CHAIN_START 0x1016AD40
|
#define CHAIN_START 0x1016AD40
|
||||||
#define SHUTDOWN 0x1012EE4C
|
#define SHUTDOWN 0x1012EE4C
|
||||||
#define SIMPLE_RETURN 0x101014E4
|
#define SIMPLE_RETURN 0x101014E4
|
||||||
#define SOURCE (0x120000)
|
#define SOURCE (0x120000)
|
||||||
#define IOS_CREATETHREAD 0x1012EABC
|
#define IOS_CREATETHREAD 0x1012EABC
|
||||||
#define ARM_CODE_BASE 0x08135000
|
#define ARM_CODE_BASE 0x08135000
|
||||||
#define REPLACE_SYSCALL 0x081298BC
|
#define REPLACE_SYSCALL 0x081298BC
|
||||||
|
|
||||||
extern const uint8_t launch_image_tga[];
|
extern const uint8_t launch_image_tga[];
|
||||||
extern const uint32_t launch_image_tga_size;
|
extern const uint32_t launch_image_tga_size;
|
||||||
@ -24,7 +24,7 @@ static int uhs_write32(int uhs_handle, int arm_addr, int val);
|
|||||||
|
|
||||||
//!------Variables used in exploit------
|
//!------Variables used in exploit------
|
||||||
static int *pretend_root_hub = (int *) 0xF5003ABC;
|
static int *pretend_root_hub = (int *) 0xF5003ABC;
|
||||||
static int *ayylmao = (int *) 0xF4500000;
|
static int *ayylmao = (int *) 0xF4500000;
|
||||||
//!-------------------------------------
|
//!-------------------------------------
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
@ -34,271 +34,271 @@ typedef struct __attribute__((packed)) {
|
|||||||
|
|
||||||
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
|
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
|
||||||
#include "ios_kernel/ios_kernel.bin.h"
|
#include "ios_kernel/ios_kernel.bin.h"
|
||||||
#include "ios_usb/ios_usb.bin.h"
|
|
||||||
#include "ios_mcp/ios_mcp.bin.h"
|
#include "ios_mcp/ios_mcp.bin.h"
|
||||||
|
#include "ios_usb/ios_usb.bin.h"
|
||||||
|
|
||||||
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
||||||
static const int final_chain[] = {
|
static const int final_chain[] = {
|
||||||
0x101236f3, // 0x00 POP {R1-R7,PC}
|
0x101236f3, // 0x00 POP {R1-R7,PC}
|
||||||
0x0, // 0x04 arg
|
0x0, // 0x04 arg
|
||||||
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
|
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
|
||||||
0x68, // 0x0C stacksize
|
0x68, // 0x0C stacksize
|
||||||
0x10101638, // 0x10
|
0x10101638, // 0x10
|
||||||
0x0, // 0x14
|
0x0, // 0x14
|
||||||
0x0, // 0x18
|
0x0, // 0x18
|
||||||
0x0, // 0x1C
|
0x0, // 0x1C
|
||||||
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||||
0x0, // 0x24
|
0x0, // 0x24
|
||||||
0x0, // 0x28
|
0x0, // 0x28
|
||||||
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x30
|
0x0, // 0x30
|
||||||
0x0, // 0x34
|
0x0, // 0x34
|
||||||
IOS_CREATETHREAD, // 0x38
|
IOS_CREATETHREAD, // 0x38
|
||||||
0x1, // 0x3C
|
0x1, // 0x3C
|
||||||
0x2, // 0x40
|
0x2, // 0x40
|
||||||
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE92D4010, // 0x4C value: PUSH {R4,LR}
|
0xE92D4010, // 0x4C value: PUSH {R4,LR}
|
||||||
0x0, // 0x50
|
0x0, // 0x50
|
||||||
0x10123a8b, // 0x54 POP {R3,R4,PC}
|
0x10123a8b, // 0x54 POP {R3,R4,PC}
|
||||||
0x1, // 0x58 R3 must be 1 for the arbitrary write
|
0x1, // 0x58 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x5C
|
0x0, // 0x5C
|
||||||
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x64
|
0x0, // 0x64
|
||||||
0x0, // 0x68
|
0x0, // 0x68
|
||||||
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x70
|
0x0, // 0x70
|
||||||
0x0, // 0x74
|
0x0, // 0x74
|
||||||
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE1A04000, // 0x80 value: MOV R4, R0
|
0xE1A04000, // 0x80 value: MOV R4, R0
|
||||||
0x0, // 0x84
|
0x0, // 0x84
|
||||||
0x10123a8b, // 0x88 POP {R3,R4,PC}
|
0x10123a8b, // 0x88 POP {R3,R4,PC}
|
||||||
0x1, // 0x8C R3 must be 1 for the arbitrary write
|
0x1, // 0x8C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x90
|
0x0, // 0x90
|
||||||
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x98
|
0x0, // 0x98
|
||||||
0x0, // 0x9C
|
0x0, // 0x9C
|
||||||
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0xA4
|
0x0, // 0xA4
|
||||||
0x0, // 0xA8
|
0x0, // 0xA8
|
||||||
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
|
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
|
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
|
||||||
0x0, // 0xB8
|
0x0, // 0xB8
|
||||||
0x10123a8b, // 0xBC POP {R3,R4,PC}
|
0x10123a8b, // 0xBC POP {R3,R4,PC}
|
||||||
0x1, // 0xC0 R3 must be 1 for the arbitrary write
|
0x1, // 0xC0 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0xC4
|
0x0, // 0xC4
|
||||||
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0xCC
|
0x0, // 0xCC
|
||||||
0x0, // 0xD0
|
0x0, // 0xD0
|
||||||
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0xD8
|
0x0, // 0xD8
|
||||||
0x0, // 0xDC
|
0x0, // 0xDC
|
||||||
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
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)
|
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
|
||||||
0x0, // 0xEC
|
0x0, // 0xEC
|
||||||
0x10123a8b, // 0xF0 POP {R3,R4,PC}
|
0x10123a8b, // 0xF0 POP {R3,R4,PC}
|
||||||
0x1, // 0xF4 R3 must be 1 for the arbitrary write
|
0x1, // 0xF4 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0xF8
|
0x0, // 0xF8
|
||||||
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x100
|
0x0, // 0x100
|
||||||
0x0, // 0x104
|
0x0, // 0x104
|
||||||
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x10C
|
0x0, // 0x10C
|
||||||
0x0, // 0x110
|
0x0, // 0x110
|
||||||
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE1A00004, // 0x11C value: MOV R0, R4
|
0xE1A00004, // 0x11C value: MOV R0, R4
|
||||||
0x0, // 0x120
|
0x0, // 0x120
|
||||||
0x10123a8b, // 0x124 POP {R3,R4,PC}
|
0x10123a8b, // 0x124 POP {R3,R4,PC}
|
||||||
0x1, // 0x128 R3 must be 1 for the arbitrary write
|
0x1, // 0x128 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x12C
|
0x0, // 0x12C
|
||||||
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x134
|
0x0, // 0x134
|
||||||
0x0, // 0x138
|
0x0, // 0x138
|
||||||
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x140
|
0x0, // 0x140
|
||||||
0x0, // 0x144
|
0x0, // 0x144
|
||||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
|
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
|
||||||
0x0, // 0x154
|
0x0, // 0x154
|
||||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x160
|
0x0, // 0x160
|
||||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x168
|
0x0, // 0x168
|
||||||
0x0, // 0x16C
|
0x0, // 0x16C
|
||||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x174
|
0x0, // 0x174
|
||||||
0x0, // 0x178
|
0x0, // 0x178
|
||||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0x00000000, // 0x150 value: NOP
|
0x00000000, // 0x150 value: NOP
|
||||||
0x0, // 0x154
|
0x0, // 0x154
|
||||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x160
|
0x0, // 0x160
|
||||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x168
|
0x0, // 0x168
|
||||||
0x0, // 0x16C
|
0x0, // 0x16C
|
||||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x174
|
0x0, // 0x174
|
||||||
0x0, // 0x178
|
0x0, // 0x178
|
||||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
|
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
|
||||||
0x0, // 0x154
|
0x0, // 0x154
|
||||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x160
|
0x0, // 0x160
|
||||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x168
|
0x0, // 0x168
|
||||||
0x0, // 0x16C
|
0x0, // 0x16C
|
||||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x174
|
0x0, // 0x174
|
||||||
0x0, // 0x178
|
0x0, // 0x178
|
||||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0x1AFFFFFD, // 0x150 value: BNE clean_loop
|
0x1AFFFFFD, // 0x150 value: BNE clean_loop
|
||||||
0x0, // 0x154
|
0x0, // 0x154
|
||||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x160
|
0x0, // 0x160
|
||||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x168
|
0x0, // 0x168
|
||||||
0x0, // 0x16C
|
0x0, // 0x16C
|
||||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x174
|
0x0, // 0x174
|
||||||
0x0, // 0x178
|
0x0, // 0x178
|
||||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
|
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
|
||||||
0x0, // 0x154
|
0x0, // 0x154
|
||||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x160
|
0x0, // 0x160
|
||||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x168
|
0x0, // 0x168
|
||||||
0x0, // 0x16C
|
0x0, // 0x16C
|
||||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x174
|
0x0, // 0x174
|
||||||
0x0, // 0x178
|
0x0, // 0x178
|
||||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE1A03004, // 0x184 value: MOV R3, R4
|
0xE1A03004, // 0x184 value: MOV R3, R4
|
||||||
0x0, // 0x188
|
0x0, // 0x188
|
||||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x194
|
0x0, // 0x194
|
||||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x19C
|
0x0, // 0x19C
|
||||||
0x0, // 0x1A0
|
0x0, // 0x1A0
|
||||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x1A8
|
0x0, // 0x1A8
|
||||||
0x0, // 0x1AC
|
0x0, // 0x1AC
|
||||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE8BD4010, // 0x184 value: POP {R4,LR}
|
0xE8BD4010, // 0x184 value: POP {R4,LR}
|
||||||
0x0, // 0x188
|
0x0, // 0x188
|
||||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x194
|
0x0, // 0x194
|
||||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x19C
|
0x0, // 0x19C
|
||||||
0x0, // 0x1A0
|
0x0, // 0x1A0
|
||||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x1A8
|
0x0, // 0x1A8
|
||||||
0x0, // 0x1AC
|
0x0, // 0x1AC
|
||||||
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||||
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
|
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
|
||||||
0x0, // 0x1BC
|
0x0, // 0x1BC
|
||||||
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
|
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
|
||||||
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
|
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
|
||||||
0x0, // 0x1C8
|
0x0, // 0x1C8
|
||||||
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x1D0
|
0x0, // 0x1D0
|
||||||
0x0, // 0x1D4
|
0x0, // 0x1D4
|
||||||
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
|
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
|
||||||
0x0, // 0x1DC
|
0x0, // 0x1DC
|
||||||
0x0, // 0x1E0
|
0x0, // 0x1E0
|
||||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||||
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
|
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
|
||||||
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
|
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
|
||||||
0x0, // 0x1E0
|
0x0, // 0x1E0
|
||||||
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
|
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
|
||||||
0x0, // 0x1DC
|
0x0, // 0x1DC
|
||||||
0x0, // 0x1E0
|
0x0, // 0x1E0
|
||||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||||
ARM_CODE_BASE, // 0x1E8 our code destination address
|
ARM_CODE_BASE, // 0x1E8 our code destination address
|
||||||
0x0, // 0x1EC
|
0x0, // 0x1EC
|
||||||
0x0, // 0x1F0
|
0x0, // 0x1F0
|
||||||
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
|
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
|
||||||
0x0, // 0x1F8
|
0x0, // 0x1F8
|
||||||
sizeof(ios_kernel), // 0x1FC our code size
|
sizeof(ios_kernel), // 0x1FC our code size
|
||||||
0x0, // 0x200
|
0x0, // 0x200
|
||||||
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
|
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
|
||||||
0x00140000, // 0x208 our code source location
|
0x00140000, // 0x208 our code source location
|
||||||
0x08131D04, // 0x20C KERNEL_MEMCPY address
|
0x08131D04, // 0x20C KERNEL_MEMCPY address
|
||||||
0x0, // 0x210
|
0x0, // 0x210
|
||||||
0x0, // 0x214
|
0x0, // 0x214
|
||||||
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
|
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x101312D0,
|
0x101312D0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int second_chain[] = {
|
static const int second_chain[] = {
|
||||||
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
|
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
|
||||||
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
|
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
|
||||||
0x0, // 0x08
|
0x0, // 0x08
|
||||||
0x0, // 0x0C
|
0x0, // 0x0C
|
||||||
0x101063db, // 0x10 POP {R1,R2,R5,PC}
|
0x101063db, // 0x10 POP {R1,R2,R5,PC}
|
||||||
0x00130000, // 0x14 source
|
0x00130000, // 0x14 source
|
||||||
sizeof(final_chain), // 0x18 length
|
sizeof(final_chain), // 0x18 length
|
||||||
0x0, // 0x1C
|
0x0, // 0x1C
|
||||||
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
|
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
|
||||||
0x0, // 0x24
|
0x0, // 0x24
|
||||||
0x0, // 0x28
|
0x0, // 0x28
|
||||||
0x101236f3, // 0x2C POP {R1-R7,PC}
|
0x101236f3, // 0x2C POP {R1-R7,PC}
|
||||||
0x0, // 0x30 arg
|
0x0, // 0x30 arg
|
||||||
0x101001DC, // 0x34 stackptr
|
0x101001DC, // 0x34 stackptr
|
||||||
0x68, // 0x38 stacksize
|
0x68, // 0x38 stacksize
|
||||||
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
|
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
|
||||||
0x0, // 0x40
|
0x0, // 0x40
|
||||||
0x0, // 0x44
|
0x0, // 0x44
|
||||||
0x0, // 0x48
|
0x0, // 0x48
|
||||||
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||||
0x0, // 0x50
|
0x0, // 0x50
|
||||||
0x0, // 0x54
|
0x0, // 0x54
|
||||||
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||||
0x0, // 0x5C
|
0x0, // 0x5C
|
||||||
0x0, // 0x60
|
0x0, // 0x60
|
||||||
IOS_CREATETHREAD, // 0x64
|
IOS_CREATETHREAD, // 0x64
|
||||||
0x1, // 0x68 priority
|
0x1, // 0x68 priority
|
||||||
0x2, // 0x6C flags
|
0x2, // 0x6C flags
|
||||||
0x0, // 0x70
|
0x0, // 0x70
|
||||||
0x0, // 0x74
|
0x0, // 0x74
|
||||||
0x101063db, // 0x78 POP {R1,R2,R5,PC}
|
0x101063db, // 0x78 POP {R1,R2,R5,PC}
|
||||||
0x0, // 0x7C
|
0x0, // 0x7C
|
||||||
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
|
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
|
||||||
0x0, // 0x84
|
0x0, // 0x84
|
||||||
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
|
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x00110000 - 0x44, // 0x8C
|
0x00110000 - 0x44, // 0x8C
|
||||||
0x00110010, // 0x90
|
0x00110010, // 0x90
|
||||||
0x0, // 0x94
|
0x0, // 0x94
|
||||||
0x0, // 0x98
|
0x0, // 0x98
|
||||||
0x0, // 0x9C
|
0x0, // 0x9C
|
||||||
0x0, // 0xA0
|
0x0, // 0xA0
|
||||||
0x0, // 0xA4
|
0x0, // 0xA4
|
||||||
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
|
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}
|
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x1012EA68, // 0xAC stack pivot
|
0x1012EA68, // 0xAC stack pivot
|
||||||
@ -313,10 +313,10 @@ static void uhs_exploit_init(int dev_uhs_0_handle) {
|
|||||||
memcpy((char *) (0xF4140000), ios_kernel, sizeof(ios_kernel));
|
memcpy((char *) (0xF4140000), ios_kernel, sizeof(ios_kernel));
|
||||||
|
|
||||||
payload_info_t *payloads = (payload_info_t *) 0xF4148000;
|
payload_info_t *payloads = (payload_info_t *) 0xF4148000;
|
||||||
payloads->size = sizeof(ios_usb);
|
payloads->size = sizeof(ios_usb);
|
||||||
memcpy(payloads->data, ios_usb, payloads->size);
|
memcpy(payloads->data, ios_usb, payloads->size);
|
||||||
|
|
||||||
payloads = (payload_info_t *) 0xF4160000;
|
payloads = (payload_info_t *) 0xF4160000;
|
||||||
payloads->size = sizeof(ios_mcp);
|
payloads->size = sizeof(ios_mcp);
|
||||||
memcpy(payloads->data, ios_mcp, payloads->size);
|
memcpy(payloads->data, ios_mcp, payloads->size);
|
||||||
|
|
||||||
@ -331,10 +331,10 @@ static void uhs_exploit_init(int dev_uhs_0_handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) {
|
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) {
|
||||||
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
|
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)
|
DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress)
|
||||||
OSSleepTicks(0x200000); //! Improves stability
|
OSSleepTicks(0x200000); //! Improves stability
|
||||||
int request_buffer[] = {-(0xBEA2C), val}; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
|
int request_buffer[] = {-(0xBEA2C), val}; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
|
||||||
int output_buffer[32];
|
int output_buffer[32];
|
||||||
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// clang-format off
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1995, 1996, 2001, 2002
|
* Copyright (c) 1995, 1996, 2001, 2002
|
||||||
* Erik Theisen. All rights reserved.
|
* Erik Theisen. All rights reserved.
|
||||||
|
@ -21,16 +21,14 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "types.h"
|
|
||||||
#include "elf_abi.h"
|
#include "elf_abi.h"
|
||||||
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static Elf32_Phdr *get_section(u32 data, u32 vaddr) {
|
static Elf32_Phdr *get_section(u32 data, u32 vaddr) {
|
||||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
|
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
|
||||||
|
|
||||||
if (!IS_ELF (*ehdr)
|
if (!IS_ELF(*ehdr) || (ehdr->e_type != ET_EXEC) || (ehdr->e_machine != EM_ARM)) {
|
||||||
|| (ehdr->e_type != ET_EXEC)
|
|
||||||
|| (ehdr->e_machine != EM_ARM)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define ARM_B(addr, func) (0xEA000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB
|
#define ARM_B(addr, func) (0xEA000000 | ((((u32) (func) - (u32) (addr) -8) >> 2) & 0x00FFFFFF)) // +-32MB
|
||||||
#define ARM_BL(addr, func) (0xEB000000 | ((((u32)(func) - (u32)(addr) - 8) >> 2) & 0x00FFFFFF)) // +-32MB
|
#define ARM_BL(addr, func) (0xEB000000 | ((((u32) (func) - (u32) (addr) -8) >> 2) & 0x00FFFFFF)) // +-32MB
|
||||||
#define THUMB_B(addr, func) ((0xE000 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x7FF))) // +-2KB
|
#define THUMB_B(addr, func) ((0xE000 | ((((u32) (func) - (u32) (addr) -4) >> 1) & 0x7FF))) // +-2KB
|
||||||
#define THUMB_BL(addr, func) ((0xF000F800 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x0FFF)) | ((((u32)(func) - (u32)(addr) - 4) << 4) & 0x7FFF000)) // +-4MB
|
#define THUMB_BL(addr, func) ((0xF000F800 | ((((u32) (func) - (u32) (addr) -4) >> 1) & 0x0FFF)) | ((((u32) (func) - (u32) (addr) -4) << 4) & 0x7FFF000)) // +-4MB
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 address;
|
u32 address;
|
||||||
|
@ -24,13 +24,13 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define svcAlloc ((void *(*)(u32 heapid, u32 size))0x081234E4)
|
#define svcAlloc ((void *(*) (u32 heapid, u32 size)) 0x081234E4)
|
||||||
#define svcAllocAlign ((void *(*)(u32 heapid, u32 size, u32 align))0x08123464)
|
#define svcAllocAlign ((void *(*) (u32 heapid, u32 size, u32 align)) 0x08123464)
|
||||||
#define svcFree ((void *(*)(u32 heapid, void *ptr))0x08123830)
|
#define svcFree ((void *(*) (u32 heapid, void *ptr)) 0x08123830)
|
||||||
#define svcOpen ((int (*)(const char* name, int mode))0x0812940C)
|
#define svcOpen ((int (*)(const char *name, int mode)) 0x0812940C)
|
||||||
#define svcClose ((int (*)(int fd))0x08129368)
|
#define svcClose ((int (*)(int fd)) 0x08129368)
|
||||||
#define svcIoctl ((int (*)(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len))0x081290E0)
|
#define svcIoctl ((int (*)(int fd, u32 request, void *input_buffer, u32 input_buffer_len, void *output_buffer, u32 output_buffer_len)) 0x081290E0)
|
||||||
#define svcIoctlv ((int (*)(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector))0x0812903C)
|
#define svcIoctlv ((int (*)(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s *vector)) 0x0812903C)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@ -73,8 +73,8 @@ static int FSA_Close(int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int FSA_RawOpen(int fd, const char *device_path, int *outHandle) {
|
static int FSA_RawOpen(int fd, const char *device_path, int *outHandle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
kernel_strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
kernel_strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
||||||
@ -88,8 +88,8 @@ static int FSA_RawOpen(int fd, const char *device_path, int *outHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int FSA_RawClose(int fd, int device_handle) {
|
static int FSA_RawClose(int fd, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = device_handle;
|
inbuf[1] = device_handle;
|
||||||
@ -101,12 +101,12 @@ static int FSA_RawClose(int fd, int device_handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
static int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
// note : offset_bytes = blocks_offset * size_bytes
|
// note : offset_bytes = blocks_offset * size_bytes
|
||||||
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
||||||
@ -131,12 +131,12 @@ static int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_o
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
static int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
||||||
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
|
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
|
||||||
@ -218,4 +218,3 @@ int FSA_SDWriteRawSectors(const void *buffer, u32 sector, u32 num_sectors) {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,25 +26,25 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define NAND_DUMP_SIGNATURE_SECTOR 0x01
|
#define NAND_DUMP_SIGNATURE_SECTOR 0x01
|
||||||
#define NAND_MAX_DESC_TYPES 5
|
#define NAND_MAX_DESC_TYPES 5
|
||||||
|
|
||||||
#define NAND_DUMP_SIGNATURE 0x4841585844554d50ULL // HAXXDUMP
|
#define NAND_DUMP_SIGNATURE 0x4841585844554d50ULL // HAXXDUMP
|
||||||
|
|
||||||
#define NAND_DESC_TYPE_SLC 0x534c4320 // 'SLC '
|
#define NAND_DESC_TYPE_SLC 0x534c4320 // 'SLC '
|
||||||
#define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2'
|
#define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2'
|
||||||
#define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC '
|
#define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC '
|
||||||
#define NAND_DESC_TYPE_SEEPROM 0x45455052 // 'EEPR'
|
#define NAND_DESC_TYPE_SEEPROM 0x45455052 // 'EEPR'
|
||||||
#define NAND_DESC_TYPE_OTP 0x4f545020 // 'OTP '
|
#define NAND_DESC_TYPE_OTP 0x4f545020 // 'OTP '
|
||||||
|
|
||||||
typedef struct _stdio_nand_desc_t {
|
typedef struct _stdio_nand_desc_t {
|
||||||
u32 nand_type; // nand type
|
u32 nand_type; // nand type
|
||||||
u32 base_sector; // base sector of dump
|
u32 base_sector; // base sector of dump
|
||||||
u32 sector_count; // sector count in SDIO sectors
|
u32 sector_count; // sector count in SDIO sectors
|
||||||
} __attribute__((packed)) stdio_nand_desc_t;
|
} __attribute__((packed)) stdio_nand_desc_t;
|
||||||
|
|
||||||
typedef struct _sdio_nand_signature_sector_t {
|
typedef struct _sdio_nand_signature_sector_t {
|
||||||
u64 signature; // HAXXDUMP
|
u64 signature; // HAXXDUMP
|
||||||
stdio_nand_desc_t nand_descriptions[NAND_MAX_DESC_TYPES];
|
stdio_nand_desc_t nand_descriptions[NAND_MAX_DESC_TYPES];
|
||||||
} __attribute__((packed)) sdio_nand_signature_sector_t;
|
} __attribute__((packed)) sdio_nand_signature_sector_t;
|
||||||
|
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "utils.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "elf_patcher.h"
|
|
||||||
#include "kernel_patches.h"
|
|
||||||
#include "ios_mcp_patches.h"
|
|
||||||
#include "../../ios_mcp/ios_mcp_syms.h"
|
#include "../../ios_mcp/ios_mcp_syms.h"
|
||||||
|
#include "elf_patcher.h"
|
||||||
|
#include "ios_mcp_patches.h"
|
||||||
|
#include "kernel_patches.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 paddr;
|
u32 paddr;
|
||||||
@ -37,9 +37,9 @@ typedef struct {
|
|||||||
u32 cached;
|
u32 cached;
|
||||||
} ios_map_shared_info_t;
|
} ios_map_shared_info_t;
|
||||||
|
|
||||||
#define mcp_rodata_phys(addr) ((u32)(addr) - 0x05060000 + 0x08220000)
|
#define mcp_rodata_phys(addr) ((u32) (addr) -0x05060000 + 0x08220000)
|
||||||
#define mcp_data_phys(addr) ((u32)(addr) - 0x05074000 + 0x08234000)
|
#define mcp_data_phys(addr) ((u32) (addr) -0x05074000 + 0x08234000)
|
||||||
#define acp_phys(addr) ((u32)(addr) - 0xE0000000 + 0x12900000)
|
#define acp_phys(addr) ((u32) (addr) -0xE0000000 + 0x12900000)
|
||||||
|
|
||||||
void instant_patches_setup(void) {
|
void instant_patches_setup(void) {
|
||||||
// apply IOS ELF launch hook
|
// apply IOS ELF launch hook
|
||||||
@ -62,13 +62,13 @@ void instant_patches_setup(void) {
|
|||||||
*(volatile u32 *) 0x081430B4 = 1;
|
*(volatile u32 *) 0x081430B4 = 1;
|
||||||
|
|
||||||
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
||||||
*(volatile u32 *) (0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
*(volatile u32 *) (0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
||||||
|
|
||||||
kernel_memset((void *) (0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x2F00);
|
kernel_memset((void *) (0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x2F00);
|
||||||
|
|
||||||
// allow custom bootLogoTex and bootMovie.h264
|
// allow custom bootLogoTex and bootMovie.h264
|
||||||
*(volatile u32 *) (0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32 *) (0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
*(volatile u32 *) (0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32 *) (0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
|
|
||||||
// Patch update check
|
// Patch update check
|
||||||
*(volatile u32 *) (0xe22830e0 - 0xe2280000 + 0x13140000) = 0x00000000;
|
*(volatile u32 *) (0xe22830e0 - 0xe2280000 + 0x13140000) = 0x00000000;
|
||||||
@ -76,9 +76,9 @@ void instant_patches_setup(void) {
|
|||||||
*(volatile u32 *) (0xe204fb68 - 0xe2000000 + 0x12EC0000) = 0xe3a00000;
|
*(volatile u32 *) (0xe204fb68 - 0xe2000000 + 0x12EC0000) = 0xe3a00000;
|
||||||
|
|
||||||
// allow any region title launch
|
// allow any region title launch
|
||||||
*(volatile u32 *) (0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32 *) (0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
// Patch CheckTitleLaunch to ignore gamepad connected result
|
// Patch CheckTitleLaunch to ignore gamepad connected result
|
||||||
*(volatile u32 *) (0xE0030868 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32 *) (0xE0030868 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
|
|
||||||
*(volatile u32 *) (0x050254D6 - 0x05000000 + 0x081C0000) = THUMB_BL(0x050254D6, MCP_LoadFile_patch);
|
*(volatile u32 *) (0x050254D6 - 0x05000000 + 0x081C0000) = THUMB_BL(0x050254D6, MCP_LoadFile_patch);
|
||||||
*(volatile u32 *) (0x05025242 - 0x05000000 + 0x081C0000) = THUMB_BL(0x05025242, MCP_ioctl100_patch);
|
*(volatile u32 *) (0x05025242 - 0x05000000 + 0x081C0000) = THUMB_BL(0x05025242, MCP_ioctl100_patch);
|
||||||
@ -110,19 +110,19 @@ void instant_patches_setup(void) {
|
|||||||
*(volatile u32 *) (0x050BC580 - 0x05000000 + 0x081C0000) = 0;
|
*(volatile u32 *) (0x050BC580 - 0x05000000 + 0x081C0000) = 0;
|
||||||
|
|
||||||
ios_map_shared_info_t map_info;
|
ios_map_shared_info_t map_info;
|
||||||
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
|
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
|
||||||
map_info.vaddr = 0x050BD000;
|
map_info.vaddr = 0x050BD000;
|
||||||
map_info.size = 0x3000;
|
map_info.size = 0x3000;
|
||||||
map_info.domain = 1; // MCP
|
map_info.domain = 1; // MCP
|
||||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read/write
|
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read/write
|
||||||
map_info.cached = 0xFFFFFFFF;
|
map_info.cached = 0xFFFFFFFF;
|
||||||
_iosMapSharedUserExecution(&map_info); // actually a bss section but oh well it will have read/write
|
_iosMapSharedUserExecution(&map_info); // actually a bss section but oh well it will have read/write
|
||||||
|
|
||||||
map_info.paddr = 0x05116000 - 0x05100000 + 0x13D80000;
|
map_info.paddr = 0x05116000 - 0x05100000 + 0x13D80000;
|
||||||
map_info.vaddr = 0x05116000;
|
map_info.vaddr = 0x05116000;
|
||||||
map_info.size = 0x4000;
|
map_info.size = 0x4000;
|
||||||
map_info.domain = 1; // MCP
|
map_info.domain = 1; // MCP
|
||||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read write
|
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read write
|
||||||
map_info.cached = 0xFFFFFFFF;
|
map_info.cached = 0xFFFFFFFF;
|
||||||
_iosMapSharedUserExecution(&map_info);
|
_iosMapSharedUserExecution(&map_info);
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "types.h"
|
|
||||||
#include "elf_patcher.h"
|
|
||||||
#include "ios_mcp_patches.h"
|
#include "ios_mcp_patches.h"
|
||||||
#include "../../ios_mcp/ios_mcp.bin.h"
|
#include "../../ios_mcp/ios_mcp.bin.h"
|
||||||
#include "../../ios_mcp/ios_mcp_syms.h"
|
#include "../../ios_mcp/ios_mcp_syms.h"
|
||||||
|
#include "elf_patcher.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#define MCP_CODE_BASE_PHYS_ADDR (-0x05100000 + 0x13D80000)
|
#define MCP_CODE_BASE_PHYS_ADDR (-0x05100000 + 0x13D80000)
|
||||||
|
|
||||||
extern const patch_table_t mcp_patches_table[];
|
extern const patch_table_t mcp_patches_table[];
|
||||||
extern const patch_table_t mcp_patches_table_end[];
|
extern const patch_table_t mcp_patches_table_end[];
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
#ifndef _MCP_PATCHES_H_
|
#ifndef _MCP_PATCHES_H_
|
||||||
#define _MCP_PATCHES_H_
|
#define _MCP_PATCHES_H_
|
||||||
|
|
||||||
#define MCP_LAUNCH_IMG_PHYS_ADDR (0x27000000)
|
#include "types.h"
|
||||||
|
|
||||||
|
#define MCP_LAUNCH_IMG_PHYS_ADDR (0x27000000)
|
||||||
|
|
||||||
u32 mcp_get_phys_code_base(void);
|
u32 mcp_get_phys_code_base(void);
|
||||||
|
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "types.h"
|
#include "kernel_patches.h"
|
||||||
#include "../../common/kernel_commands.h"
|
#include "../../common/kernel_commands.h"
|
||||||
#include "elf_patcher.h"
|
#include "elf_patcher.h"
|
||||||
#include "ios_mcp_patches.h"
|
|
||||||
#include "kernel_patches.h"
|
|
||||||
#include "fsa.h"
|
#include "fsa.h"
|
||||||
#include "utils.h"
|
#include "ios_mcp_patches.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
extern void __KERNEL_CODE_START(void);
|
extern void __KERNEL_CODE_START(void);
|
||||||
|
|
||||||
@ -40,24 +40,24 @@ extern const patch_table_t kernel_patches_table_end[];
|
|||||||
static const u32 mcpIoMappings_patch[] =
|
static const u32 mcpIoMappings_patch[] =
|
||||||
{
|
{
|
||||||
// vaddr paddr size ? ? ?
|
// vaddr paddr size ? ? ?
|
||||||
0x0D000000, 0x0D000000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 1
|
0x0D000000, 0x0D000000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 1
|
||||||
0x0D800000, 0x0D800000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 2
|
0x0D800000, 0x0D800000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 2
|
||||||
0x0C200000, 0x0C200000, 0x00100000, 0x00000000, 0x00000003, 0x00000000 // mapping 3
|
0x0C200000, 0x0C200000, 0x00100000, 0x00000000, 0x00000003, 0x00000000 // mapping 3
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] =
|
static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] =
|
||||||
{
|
{
|
||||||
(u32) mcpIoMappings_patch, // ptr to iomapping structs
|
(u32) mcpIoMappings_patch, // ptr to iomapping structs
|
||||||
0x00000003, // number of iomappings
|
0x00000003, // number of iomappings
|
||||||
0x00000001 // pid (MCP)
|
0x00000001 // pid (MCP)
|
||||||
};
|
};
|
||||||
|
|
||||||
ThreadContext_t** currentThreadContext = (ThreadContext_t**) 0x08173ba0;
|
ThreadContext_t **currentThreadContext = (ThreadContext_t **) 0x08173ba0;
|
||||||
uint32_t* domainAccessPermissions = (uint32_t*) 0x081a4000;
|
uint32_t *domainAccessPermissions = (uint32_t *) 0x081a4000;
|
||||||
|
|
||||||
int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3) {
|
int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int level = disable_interrupts();
|
int level = disable_interrupts();
|
||||||
set_domain_register(domainAccessPermissions[0]); // 0 = KERNEL
|
set_domain_register(domainAccessPermissions[0]); // 0 = KERNEL
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
@ -78,8 +78,8 @@ int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KERNEL_READ_OTP: {
|
case KERNEL_READ_OTP: {
|
||||||
int (*read_otp_internal)(int index, void* out_buf, u32 size) = (int (*)(int, void*, u32)) 0x08120248;
|
int (*read_otp_internal)(int index, void *out_buf, u32 size) = (int (*)(int, void *, u32)) 0x08120248;
|
||||||
read_otp_internal(0, (void*)(arg1), 0x400);
|
read_otp_internal(0, (void *) (arg1), 0x400);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -98,7 +98,7 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H) {
|
|||||||
void (*kernel_launch_bootrom)(u32 launch_address, u32 L, u32 C, u32 H) = (void *) 0x0812A050;
|
void (*kernel_launch_bootrom)(u32 launch_address, u32 L, u32 C, u32 H) = (void *) 0x0812A050;
|
||||||
|
|
||||||
if (*(u32 *) (launch_address - 0x300 + 0x1AC) == 0x00DFD000) {
|
if (*(u32 *) (launch_address - 0x300 + 0x1AC) == 0x00DFD000) {
|
||||||
int level = disable_interrupts();
|
int level = disable_interrupts();
|
||||||
unsigned int control_register = disable_mmu();
|
unsigned int control_register = disable_mmu();
|
||||||
|
|
||||||
u32 ios_elf_start = launch_address + 0x804 - 0x300;
|
u32 ios_elf_start = launch_address + 0x804 - 0x300;
|
||||||
@ -129,23 +129,23 @@ void kernel_run_patches(u32 ios_elf_start) {
|
|||||||
section_write_word(ios_elf_start, 0xe22830e0, 0x00000000);
|
section_write_word(ios_elf_start, 0xe22830e0, 0x00000000);
|
||||||
section_write_word(ios_elf_start, 0xe22b2a78, 0x00000000);
|
section_write_word(ios_elf_start, 0xe22b2a78, 0x00000000);
|
||||||
section_write_word(ios_elf_start, 0xe204fb68, 0xe3a00000);
|
section_write_word(ios_elf_start, 0xe204fb68, 0xe3a00000);
|
||||||
|
|
||||||
// patch MCP syslog debug mode check
|
// patch MCP syslog debug mode check
|
||||||
section_write_word(ios_elf_start, 0x050290d8, 0x20004770);
|
section_write_word(ios_elf_start, 0x050290d8, 0x20004770);
|
||||||
|
|
||||||
// Write magic word to disable custom IPC
|
// Write magic word to disable custom IPC
|
||||||
section_write_word(ios_elf_start, 0x050290dc, 0x42424242);
|
section_write_word(ios_elf_start, 0x050290dc, 0x42424242);
|
||||||
|
|
||||||
// give us bsp::ee:read permission for PPC
|
// give us bsp::ee:read permission for PPC
|
||||||
section_write_word(ios_elf_start, 0xe6044db0, 0x000001F0);
|
section_write_word(ios_elf_start, 0xe6044db0, 0x000001F0);
|
||||||
|
|
||||||
// patch TEST debug mode check
|
// patch TEST debug mode check
|
||||||
//section_write_word(ios_elf_start, 0xe4016a78, 0xe3a00000);
|
//section_write_word(ios_elf_start, 0xe4016a78, 0xe3a00000);
|
||||||
section_write_word(ios_elf_start, 0xe4007828, 0xe3a00000);
|
section_write_word(ios_elf_start, 0xe4007828, 0xe3a00000);
|
||||||
|
|
||||||
// Patch FS to syslog everything
|
// Patch FS to syslog everything
|
||||||
section_write_word(ios_elf_start, 0x107F5720, ARM_B(0x107F5720, 0x107F0C84));
|
section_write_word(ios_elf_start, 0x107F5720, ARM_B(0x107F5720, 0x107F0C84));
|
||||||
|
|
||||||
// Patch MCP to syslog everything
|
// Patch MCP to syslog everything
|
||||||
section_write_word(ios_elf_start, 0x05055438, ARM_B(0x05055438, 0x0503dcf8));
|
section_write_word(ios_elf_start, 0x05055438, ARM_B(0x05055438, 0x0503dcf8));
|
||||||
|
|
||||||
@ -154,4 +154,3 @@ void kernel_run_patches(u32 ios_elf_start) {
|
|||||||
u32 patch_count = (u32) (((u8 *) kernel_patches_table_end) - ((u8 *) kernel_patches_table)) / sizeof(patch_table_t);
|
u32 patch_count = (u32) (((u8 *) kernel_patches_table_end) - ((u8 *) kernel_patches_table)) / sizeof(patch_table_t);
|
||||||
patch_table_entries(ios_elf_start, kernel_patches_table, patch_count);
|
patch_table_entries(ios_elf_start, kernel_patches_table, patch_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#ifndef _KERNEL_PATCHES_H
|
#ifndef _KERNEL_PATCHES_H
|
||||||
#define _KERNEL_PATCHES_H
|
#define _KERNEL_PATCHES_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
int kernel_init_otp_buffer(u32 sd_sector, int tagValid);
|
int kernel_init_otp_buffer(u32 sd_sector, int tagValid);
|
||||||
|
|
||||||
int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3);
|
int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3);
|
||||||
|
@ -21,18 +21,19 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#include "instant_patches.h"
|
||||||
|
#include "ios_mcp_patches.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "ios_mcp_patches.h"
|
|
||||||
#include "instant_patches.h"
|
|
||||||
|
|
||||||
#define USB_PHYS_CODE_BASE 0x101312D0
|
#define USB_PHYS_CODE_BASE 0x101312D0
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 size;
|
u32 size;
|
||||||
u8 data[0];
|
u8 data[0];
|
||||||
} payload_info_t;
|
} payload_info_t;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
static const char repairData_set_fault_behavior[] = {
|
static const char repairData_set_fault_behavior[] = {
|
||||||
0xE1, 0x2F, 0xFF, 0x1E, 0xE9, 0x2D, 0x40, 0x30, 0xE5, 0x93, 0x20, 0x00, 0xE1, 0xA0, 0x40, 0x00,
|
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,
|
0xE5, 0x92, 0x30, 0x54, 0xE1, 0xA0, 0x50, 0x01, 0xE3, 0x53, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x02,
|
||||||
@ -56,11 +57,12 @@ static const char repairData_usb_root_thread[] = {
|
|||||||
0xE2, 0x4D, 0xDE, 0x17, 0xEB, 0x00, 0xB9, 0x92, 0xE3, 0xA0, 0x10, 0x00, 0xE3, 0xA0, 0x20, 0x03,
|
0xE2, 0x4D, 0xDE, 0x17, 0xEB, 0x00, 0xB9, 0x92, 0xE3, 0xA0, 0x10, 0x00, 0xE3, 0xA0, 0x20, 0x03,
|
||||||
0xE5, 0x9F, 0x0E, 0x68, 0xEB, 0x00, 0xB3, 0x20,
|
0xE5, 0x9F, 0x0E, 0x68, 0xEB, 0x00, 0xB3, 0x20,
|
||||||
};
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
int _main() {
|
int _main() {
|
||||||
void (*invalidate_icache)() = (void (*)()) 0x0812DCF0;
|
void (*invalidate_icache)() = (void (*)()) 0x0812DCF0;
|
||||||
void (*invalidate_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120164;
|
void (*invalidate_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120164;
|
||||||
void (*flush_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120160;
|
void (*flush_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120160;
|
||||||
|
|
||||||
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
|
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct ThreadContext {
|
typedef struct ThreadContext {
|
||||||
uint32_t cspr;
|
uint32_t cspr;
|
||||||
uint32_t gpr[14];
|
uint32_t gpr[14];
|
||||||
uint32_t lr;
|
uint32_t lr;
|
||||||
uint32_t pc;
|
uint32_t pc;
|
||||||
struct ThreadContext* threadQueueNext;
|
struct ThreadContext *threadQueueNext;
|
||||||
uint32_t maxPriority;
|
uint32_t maxPriority;
|
||||||
uint32_t priority;
|
uint32_t priority;
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
@ -16,18 +16,18 @@ typedef struct ThreadContext {
|
|||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t exitValue;
|
uint32_t exitValue;
|
||||||
struct ThreadContext** joinQueue;
|
struct ThreadContext **joinQueue;
|
||||||
struct ThreadContext** threadQueue;
|
struct ThreadContext **threadQueue;
|
||||||
uint8_t unk1[56];
|
uint8_t unk1[56];
|
||||||
void* stackPointer;
|
void *stackPointer;
|
||||||
uint8_t unk2[8];
|
uint8_t unk2[8];
|
||||||
void* sysStackAddr;
|
void *sysStackAddr;
|
||||||
void* userStackAddr;
|
void *userStackAddr;
|
||||||
uint32_t userStackSize;
|
uint32_t userStackSize;
|
||||||
void* threadLocalStorage;
|
void *threadLocalStorage;
|
||||||
uint32_t profileCount;
|
uint32_t profileCount;
|
||||||
uint32_t profileTime;
|
uint32_t profileTime;
|
||||||
} ThreadContext_t;
|
} ThreadContext_t;
|
||||||
static_assert(sizeof(ThreadContext_t) == 0xC8, "ThreadContext_t: different size than expected");
|
static_assert(sizeof(ThreadContext_t) == 0xC8, "ThreadContext_t: different size than expected");
|
||||||
|
|
||||||
extern ThreadContext_t** currentThreadContext;
|
extern ThreadContext_t **currentThreadContext;
|
||||||
|
@ -30,7 +30,7 @@ void reverse_memcpy(void *dst, const void *src, unsigned int size) {
|
|||||||
if ((size >= 4) && !((dst - src) & 3)) {
|
if ((size >= 4) && !((dst - src) & 3)) {
|
||||||
const unsigned int *src_p32;
|
const unsigned int *src_p32;
|
||||||
unsigned int *dst_p32;
|
unsigned int *dst_p32;
|
||||||
unsigned int endDst = ((unsigned int) dst) + size;
|
unsigned int endDst = ((unsigned int) dst) + size;
|
||||||
unsigned int endRest = endDst & 3;
|
unsigned int endRest = endDst & 3;
|
||||||
|
|
||||||
if (endRest) {
|
if (endRest) {
|
||||||
|
@ -24,30 +24,37 @@
|
|||||||
#ifndef _UTILS_H
|
#ifndef _UTILS_H
|
||||||
#define _UTILS_H
|
#define _UTILS_H
|
||||||
|
|
||||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||||
|
|
||||||
#define kernel_memcpy ((void * (*)(void*, const void*, int))0x08131D04)
|
#define kernel_memcpy ((void *(*) (void *, const void *, int) ) 0x08131D04)
|
||||||
#define kernel_memset ((void *(*)(void*, int, unsigned int))0x08131DA0)
|
#define kernel_memset ((void *(*) (void *, int, unsigned int) ) 0x08131DA0)
|
||||||
#define kernel_strncpy ((char *(*)(char*, const char*, unsigned int))0x081329B8)
|
#define kernel_strncpy ((char *(*) (char *, const char *, unsigned int) ) 0x081329B8)
|
||||||
#define disable_interrupts ((int(*)())0x0812E778)
|
#define disable_interrupts ((int (*)()) 0x0812E778)
|
||||||
#define enable_interrupts ((int(*)(int))0x0812E78C)
|
#define enable_interrupts ((int (*)(int)) 0x0812E78C)
|
||||||
#define kernel_bsp_command_5 ((int (*)(const char*, int offset, const char*, int size, void *buffer))0x0812EC40)
|
#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);
|
void reverse_memcpy(void *dest, const void *src, unsigned int size);
|
||||||
|
|
||||||
static inline unsigned int disable_mmu(void) {
|
static inline unsigned int disable_mmu(void) {
|
||||||
unsigned int control_register = 0;
|
unsigned int control_register = 0;
|
||||||
asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register));
|
asm volatile("MRC p15, 0, %0, c1, c0, 0"
|
||||||
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA));
|
: "=r"(control_register));
|
||||||
|
asm volatile("MCR p15, 0, %0, c1, c0, 0"
|
||||||
|
:
|
||||||
|
: "r"(control_register & 0xFFFFEFFA));
|
||||||
return control_register;
|
return control_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void restore_mmu(unsigned int control_register) {
|
static inline void restore_mmu(unsigned int control_register) {
|
||||||
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register));
|
asm volatile("MCR p15, 0, %0, c1, c0, 0"
|
||||||
|
:
|
||||||
|
: "r"(control_register));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_domain_register(unsigned int domain_register) {
|
static inline void set_domain_register(unsigned int domain_register) {
|
||||||
asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register));
|
asm volatile("MCR p15, 0, %0, c3, c0, 0"
|
||||||
|
:
|
||||||
|
: "r"(domain_register));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "svc.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "fsa.h"
|
#include "fsa.h"
|
||||||
|
#include "imports.h"
|
||||||
|
#include "svc.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void *allocIobuf() {
|
static void *allocIobuf() {
|
||||||
void *ptr = svcAlloc(0xCAFF, 0x828);
|
void *ptr = svcAlloc(0xCAFF, 0x828);
|
||||||
@ -18,12 +18,12 @@ static void freeIobuf(void *ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_Mount(int fd, char *device_path, char *volume_path, u32 flags, char *arg_string, int arg_string_len) {
|
int FSA_Mount(int fd, char *device_path, char *volume_path, u32 flags, char *arg_string, int arg_string_len) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
strncpy((char *) &inbuf8[0x04], device_path, 0x27F);
|
strncpy((char *) &inbuf8[0x04], device_path, 0x27F);
|
||||||
strncpy((char *) &inbuf8[0x284], volume_path, 0x27F);
|
strncpy((char *) &inbuf8[0x284], volume_path, 0x27F);
|
||||||
@ -44,8 +44,8 @@ int FSA_Mount(int fd, char *device_path, char *volume_path, u32 flags, char *arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_Unmount(int fd, char *path, u32 flags) {
|
int FSA_Unmount(int fd, char *path, u32 flags) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -58,8 +58,8 @@ int FSA_Unmount(int fd, char *path, u32 flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_FlushVolume(int fd, char *volume_path) {
|
int FSA_FlushVolume(int fd, char *volume_path) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], volume_path, 0x27F);
|
strncpy((char *) &inbuf[0x01], volume_path, 0x27F);
|
||||||
@ -71,8 +71,8 @@ int FSA_FlushVolume(int fd, char *volume_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_MakeDir(int fd, char *path, u32 flags) {
|
int FSA_MakeDir(int fd, char *path, u32 flags) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -85,8 +85,8 @@ int FSA_MakeDir(int fd, char *path, u32 flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_OpenDir(int fd, char *path, int *outHandle) {
|
int FSA_OpenDir(int fd, char *path, int *outHandle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -100,8 +100,8 @@ int FSA_OpenDir(int fd, char *path, int *outHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_ReadDir(int fd, int handle, directoryEntry_s *out_data) {
|
int FSA_ReadDir(int fd, int handle, directoryEntry_s *out_data) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = handle;
|
inbuf[1] = handle;
|
||||||
@ -115,8 +115,8 @@ int FSA_ReadDir(int fd, int handle, directoryEntry_s *out_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_RewindDir(int fd, int handle) {
|
int FSA_RewindDir(int fd, int handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = handle;
|
inbuf[1] = handle;
|
||||||
@ -128,8 +128,8 @@ int FSA_RewindDir(int fd, int handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_CloseDir(int fd, int handle) {
|
int FSA_CloseDir(int fd, int handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = handle;
|
inbuf[1] = handle;
|
||||||
@ -141,8 +141,8 @@ int FSA_CloseDir(int fd, int handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_ChangeDir(int fd, char *path) {
|
int FSA_ChangeDir(int fd, char *path) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -154,8 +154,8 @@ int FSA_ChangeDir(int fd, char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_OpenFile(int fd, char *path, char *mode, int *outHandle) {
|
int FSA_OpenFile(int fd, char *path, char *mode, int *outHandle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -170,12 +170,12 @@ int FSA_OpenFile(int fd, char *path, char *mode, int *outHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _FSA_ReadWriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read) {
|
int _FSA_ReadWriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
inbuf[0x08 / 4] = size;
|
inbuf[0x08 / 4] = size;
|
||||||
inbuf[0x0C / 4] = cnt;
|
inbuf[0x0C / 4] = cnt;
|
||||||
@ -193,7 +193,8 @@ int _FSA_ReadWriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u3
|
|||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if (read) ret = svcIoctlv(fd, 0x0F, 1, 2, iovec);
|
if (read) ret = svcIoctlv(fd, 0x0F, 1, 2, iovec);
|
||||||
else ret = svcIoctlv(fd, 0x10, 2, 1, iovec);
|
else
|
||||||
|
ret = svcIoctlv(fd, 0x10, 2, 1, iovec);
|
||||||
|
|
||||||
freeIobuf(iobuf);
|
freeIobuf(iobuf);
|
||||||
return ret;
|
return ret;
|
||||||
@ -208,8 +209,8 @@ int FSA_WriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 fla
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_StatFile(int fd, int handle, fileStat_s *out_data) {
|
int FSA_StatFile(int fd, int handle, fileStat_s *out_data) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = handle;
|
inbuf[1] = handle;
|
||||||
@ -223,8 +224,8 @@ int FSA_StatFile(int fd, int handle, fileStat_s *out_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_CloseFile(int fd, int fileHandle) {
|
int FSA_CloseFile(int fd, int fileHandle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = fileHandle;
|
inbuf[1] = fileHandle;
|
||||||
@ -236,8 +237,8 @@ int FSA_CloseFile(int fd, int fileHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_SetPosFile(int fd, int fileHandle, u32 position) {
|
int FSA_SetPosFile(int fd, int fileHandle, u32 position) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = fileHandle;
|
inbuf[1] = fileHandle;
|
||||||
@ -250,8 +251,8 @@ int FSA_SetPosFile(int fd, int fileHandle, u32 position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_GetStat(int fd, char *path, fileStat_s *out_data) {
|
int FSA_GetStat(int fd, char *path, fileStat_s *out_data) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -266,8 +267,8 @@ int FSA_GetStat(int fd, char *path, fileStat_s *out_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_Remove(int fd, char *path) {
|
int FSA_Remove(int fd, char *path) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -279,8 +280,8 @@ int FSA_Remove(int fd, char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_ChangeMode(int fd, char *path, int mode) {
|
int FSA_ChangeMode(int fd, char *path, int mode) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
strncpy((char *) &inbuf[0x01], path, 0x27F);
|
||||||
@ -297,8 +298,8 @@ int FSA_ChangeMode(int fd, char *path, int mode) {
|
|||||||
// 0x08 : device size in sectors (u64)
|
// 0x08 : device size in sectors (u64)
|
||||||
// 0x10 : device sector size (u32)
|
// 0x10 : device sector size (u32)
|
||||||
int FSA_GetDeviceInfo(int fd, char *device_path, int type, u32 *out_data) {
|
int FSA_GetDeviceInfo(int fd, char *device_path, int type, u32 *out_data) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
||||||
@ -339,8 +340,8 @@ int FSA_GetDeviceInfo(int fd, char *device_path, int type, u32 *out_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_RawOpen(int fd, char *device_path, int *outHandle) {
|
int FSA_RawOpen(int fd, char *device_path, int *outHandle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
|
||||||
@ -354,8 +355,8 @@ int FSA_RawOpen(int fd, char *device_path, int *outHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_RawClose(int fd, int device_handle) {
|
int FSA_RawClose(int fd, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) &iobuf[0x520];
|
u32 *outbuf = (u32 *) &iobuf[0x520];
|
||||||
|
|
||||||
inbuf[1] = device_handle;
|
inbuf[1] = device_handle;
|
||||||
@ -368,12 +369,12 @@ int FSA_RawClose(int fd, int device_handle) {
|
|||||||
|
|
||||||
// offset in blocks of 0x1000 bytes
|
// offset in blocks of 0x1000 bytes
|
||||||
int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
// note : offset_bytes = blocks_offset * size_bytes
|
// note : offset_bytes = blocks_offset * size_bytes
|
||||||
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
||||||
@ -398,12 +399,12 @@ int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
|
||||||
u8 *iobuf = allocIobuf();
|
u8 *iobuf = allocIobuf();
|
||||||
u8 *inbuf8 = iobuf;
|
u8 *inbuf8 = iobuf;
|
||||||
u8 *outbuf8 = &iobuf[0x520];
|
u8 *outbuf8 = &iobuf[0x520];
|
||||||
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
|
||||||
u32 *inbuf = (u32 *) inbuf8;
|
u32 *inbuf = (u32 *) inbuf8;
|
||||||
u32 *outbuf = (u32 *) outbuf8;
|
u32 *outbuf = (u32 *) outbuf8;
|
||||||
|
|
||||||
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
||||||
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
|
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
#ifndef FSA_H
|
#ifndef FSA_H
|
||||||
#define FSA_H
|
#define FSA_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 flag;
|
u32 flag;
|
||||||
u32 permission;
|
u32 permission;
|
||||||
u32 owner_id;
|
u32 owner_id;
|
||||||
u32 group_id;
|
u32 group_id;
|
||||||
u32 size; // size in bytes
|
u32 size; // size in bytes
|
||||||
u32 physsize; // physical size on disk in bytes
|
u32 physsize; // physical size on disk in bytes
|
||||||
u32 unk[3];
|
u32 unk[3];
|
||||||
u32 id;
|
u32 id;
|
||||||
@ -20,10 +22,10 @@ typedef struct {
|
|||||||
char name[0x100];
|
char name[0x100];
|
||||||
} directoryEntry_s;
|
} directoryEntry_s;
|
||||||
|
|
||||||
#define DIR_ENTRY_IS_DIRECTORY 0x80000000
|
#define DIR_ENTRY_IS_DIRECTORY 0x80000000
|
||||||
|
|
||||||
#define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0)
|
#define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0)
|
||||||
#define FSA_MOUNTFLAGS_GLOBAL (1 << 1)
|
#define FSA_MOUNTFLAGS_GLOBAL (1 << 1)
|
||||||
|
|
||||||
int FSA_Open();
|
int FSA_Open();
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#ifndef IMPORTS_H
|
#ifndef IMPORTS_H
|
||||||
#define IMPORTS_H
|
#define IMPORTS_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define MCP_SVC_BASE ((void*)0x050567EC)
|
#define MCP_SVC_BASE ((void *) 0x050567EC)
|
||||||
|
|
||||||
void usleep(u32 time);
|
void usleep(u32 time);
|
||||||
|
|
||||||
|
@ -21,59 +21,58 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "imports.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
#include "svc.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
#include "wupserver.h"
|
|
||||||
#include "../../common/kernel_commands.h"
|
#include "../../common/kernel_commands.h"
|
||||||
|
#include "fsa.h"
|
||||||
|
#include "imports.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include "svc.h"
|
||||||
|
#include "wupserver.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6
|
#define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6
|
||||||
#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3
|
#define IOS_ERROR_INVALID_ARG 0xFFFFFFE3
|
||||||
#define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9
|
#define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9
|
||||||
#define IOS_ERROR_UNKNOWN 0xFFFFFFF7
|
#define IOS_ERROR_UNKNOWN 0xFFFFFFF7
|
||||||
#define IOS_ERROR_NOEXISTS 0xFFFFFFFA
|
#define IOS_ERROR_NOEXISTS 0xFFFFFFFA
|
||||||
|
|
||||||
#define IOCTL_MEM_WRITE 0x00
|
#define IOCTL_MEM_WRITE 0x00
|
||||||
#define IOCTL_MEM_READ 0x01
|
#define IOCTL_MEM_READ 0x01
|
||||||
#define IOCTL_SVC 0x02
|
#define IOCTL_SVC 0x02
|
||||||
#define IOCTL_KILL_SERVER 0x03
|
#define IOCTL_KILL_SERVER 0x03
|
||||||
#define IOCTL_MEMCPY 0x04
|
#define IOCTL_MEMCPY 0x04
|
||||||
#define IOCTL_REPEATED_WRITE 0x05
|
#define IOCTL_REPEATED_WRITE 0x05
|
||||||
#define IOCTL_KERN_READ32 0x06
|
#define IOCTL_KERN_READ32 0x06
|
||||||
#define IOCTL_KERN_WRITE32 0x07
|
#define IOCTL_KERN_WRITE32 0x07
|
||||||
#define IOCTL_READ_OTP 0x08
|
#define IOCTL_READ_OTP 0x08
|
||||||
|
|
||||||
#define IOCTL_FSA_OPEN 0x40
|
#define IOCTL_FSA_OPEN 0x40
|
||||||
#define IOCTL_FSA_CLOSE 0x41
|
#define IOCTL_FSA_CLOSE 0x41
|
||||||
#define IOCTL_FSA_MOUNT 0x42
|
#define IOCTL_FSA_MOUNT 0x42
|
||||||
#define IOCTL_FSA_UNMOUNT 0x43
|
#define IOCTL_FSA_UNMOUNT 0x43
|
||||||
#define IOCTL_FSA_GETDEVICEINFO 0x44
|
#define IOCTL_FSA_GETDEVICEINFO 0x44
|
||||||
#define IOCTL_FSA_OPENDIR 0x45
|
#define IOCTL_FSA_OPENDIR 0x45
|
||||||
#define IOCTL_FSA_READDIR 0x46
|
#define IOCTL_FSA_READDIR 0x46
|
||||||
#define IOCTL_FSA_CLOSEDIR 0x47
|
#define IOCTL_FSA_CLOSEDIR 0x47
|
||||||
#define IOCTL_FSA_MAKEDIR 0x48
|
#define IOCTL_FSA_MAKEDIR 0x48
|
||||||
#define IOCTL_FSA_OPENFILE 0x49
|
#define IOCTL_FSA_OPENFILE 0x49
|
||||||
#define IOCTL_FSA_READFILE 0x4A
|
#define IOCTL_FSA_READFILE 0x4A
|
||||||
#define IOCTL_FSA_WRITEFILE 0x4B
|
#define IOCTL_FSA_WRITEFILE 0x4B
|
||||||
#define IOCTL_FSA_STATFILE 0x4C
|
#define IOCTL_FSA_STATFILE 0x4C
|
||||||
#define IOCTL_FSA_CLOSEFILE 0x4D
|
#define IOCTL_FSA_CLOSEFILE 0x4D
|
||||||
#define IOCTL_FSA_SETFILEPOS 0x4E
|
#define IOCTL_FSA_SETFILEPOS 0x4E
|
||||||
#define IOCTL_FSA_GETSTAT 0x4F
|
#define IOCTL_FSA_GETSTAT 0x4F
|
||||||
#define IOCTL_FSA_REMOVE 0x50
|
#define IOCTL_FSA_REMOVE 0x50
|
||||||
#define IOCTL_FSA_REWINDDIR 0x51
|
#define IOCTL_FSA_REWINDDIR 0x51
|
||||||
#define IOCTL_FSA_CHDIR 0x52
|
#define IOCTL_FSA_CHDIR 0x52
|
||||||
#define IOCTL_FSA_RENAME 0x53
|
#define IOCTL_FSA_RENAME 0x53
|
||||||
#define IOCTL_FSA_RAW_OPEN 0x54
|
#define IOCTL_FSA_RAW_OPEN 0x54
|
||||||
#define IOCTL_FSA_RAW_READ 0x55
|
#define IOCTL_FSA_RAW_READ 0x55
|
||||||
#define IOCTL_FSA_RAW_WRITE 0x56
|
#define IOCTL_FSA_RAW_WRITE 0x56
|
||||||
#define IOCTL_FSA_RAW_CLOSE 0x57
|
#define IOCTL_FSA_RAW_CLOSE 0x57
|
||||||
#define IOCTL_FSA_CHANGEMODE 0x58
|
#define IOCTL_FSA_CHANGEMODE 0x58
|
||||||
#define IOCTL_FSA_FLUSHVOLUME 0x59
|
#define IOCTL_FSA_FLUSHVOLUME 0x59
|
||||||
|
|
||||||
static int ipcNodeKilled;
|
static int ipcNodeKilled;
|
||||||
static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
|
static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
|
||||||
@ -102,7 +101,7 @@ static int ipc_ioctl(ipcmessage *message) {
|
|||||||
if ((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) {
|
if ((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) {
|
||||||
res = IOS_ERROR_INVALID_SIZE;
|
res = IOS_ERROR_INVALID_SIZE;
|
||||||
} else {
|
} else {
|
||||||
int svc_id = message->ioctl.buffer_in[0];
|
int svc_id = message->ioctl.buffer_in[0];
|
||||||
int size_arguments = message->ioctl.length_in - 4;
|
int size_arguments = message->ioctl.length_in - 4;
|
||||||
|
|
||||||
u32 arguments[8];
|
u32 arguments[8];
|
||||||
@ -110,8 +109,8 @@ static int ipc_ioctl(ipcmessage *message) {
|
|||||||
memcpy(arguments, message->ioctl.buffer_in + 1, (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
|
memcpy(arguments, message->ioctl.buffer_in + 1, (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
|
||||||
|
|
||||||
// return error code as data
|
// return error code as data
|
||||||
message->ioctl.buffer_io[0] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32)) (MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4],
|
message->ioctl.buffer_io[0] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4],
|
||||||
arguments[5], arguments[6], arguments[7]);
|
arguments[5], arguments[6], arguments[7]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -132,10 +131,10 @@ static int ipc_ioctl(ipcmessage *message) {
|
|||||||
if (message->ioctl.length_in < 12) {
|
if (message->ioctl.length_in < 12) {
|
||||||
res = IOS_ERROR_INVALID_SIZE;
|
res = IOS_ERROR_INVALID_SIZE;
|
||||||
} else {
|
} else {
|
||||||
u32 *dst = (u32 *) message->ioctl.buffer_in[0];
|
u32 *dst = (u32 *) message->ioctl.buffer_in[0];
|
||||||
u32 *cache_range = (u32 *) (message->ioctl.buffer_in[0] & ~0xFF);
|
u32 *cache_range = (u32 *) (message->ioctl.buffer_in[0] & ~0xFF);
|
||||||
u32 value = message->ioctl.buffer_in[1];
|
u32 value = message->ioctl.buffer_in[1];
|
||||||
u32 n = message->ioctl.buffer_in[2];
|
u32 n = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
u32 old = *dst;
|
u32 old = *dst;
|
||||||
int i;
|
int i;
|
||||||
@ -190,68 +189,68 @@ static int ipc_ioctl(ipcmessage *message) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_CLOSE: {
|
case IOCTL_FSA_CLOSE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
message->ioctl.buffer_io[0] = svcClose(fd);
|
message->ioctl.buffer_io[0] = svcClose(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_MOUNT: {
|
case IOCTL_FSA_MOUNT: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
char *volume_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
|
char *volume_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
|
||||||
u32 flags = message->ioctl.buffer_in[3];
|
u32 flags = message->ioctl.buffer_in[3];
|
||||||
char *arg_string = (message->ioctl.buffer_in[4] > 0) ? (((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[4]) : 0;
|
char *arg_string = (message->ioctl.buffer_in[4] > 0) ? (((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[4]) : 0;
|
||||||
int arg_string_len = message->ioctl.buffer_in[5];
|
int arg_string_len = message->ioctl.buffer_in[5];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_Mount(fd, device_path, volume_path, flags, arg_string, arg_string_len);
|
message->ioctl.buffer_io[0] = FSA_Mount(fd, device_path, volume_path, flags, arg_string, arg_string_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_UNMOUNT: {
|
case IOCTL_FSA_UNMOUNT: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
u32 flags = message->ioctl.buffer_in[2];
|
u32 flags = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags);
|
message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_GETDEVICEINFO: {
|
case IOCTL_FSA_GETDEVICEINFO: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
int type = message->ioctl.buffer_in[2];
|
int type = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1);
|
message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_OPENDIR: {
|
case IOCTL_FSA_OPENDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int *) message->ioctl.buffer_io + 1);
|
message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int *) message->ioctl.buffer_io + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_READDIR: {
|
case IOCTL_FSA_READDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int handle = message->ioctl.buffer_in[1];
|
int handle = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s *) (message->ioctl.buffer_io + 1));
|
message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s *) (message->ioctl.buffer_io + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_CLOSEDIR: {
|
case IOCTL_FSA_CLOSEDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int handle = message->ioctl.buffer_in[1];
|
int handle = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle);
|
message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_MAKEDIR: {
|
case IOCTL_FSA_MAKEDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
u32 flags = message->ioctl.buffer_in[2];
|
u32 flags = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags);
|
message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_OPENFILE: {
|
case IOCTL_FSA_OPENFILE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
char *mode = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
|
char *mode = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
@ -259,119 +258,119 @@ static int ipc_ioctl(ipcmessage *message) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_READFILE: {
|
case IOCTL_FSA_READFILE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
u32 size = message->ioctl.buffer_in[1];
|
u32 size = message->ioctl.buffer_in[1];
|
||||||
u32 cnt = message->ioctl.buffer_in[2];
|
u32 cnt = message->ioctl.buffer_in[2];
|
||||||
int fileHandle = message->ioctl.buffer_in[3];
|
int fileHandle = message->ioctl.buffer_in[3];
|
||||||
u32 flags = message->ioctl.buffer_in[4];
|
u32 flags = message->ioctl.buffer_in[4];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags);
|
message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_WRITEFILE: {
|
case IOCTL_FSA_WRITEFILE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
u32 size = message->ioctl.buffer_in[1];
|
u32 size = message->ioctl.buffer_in[1];
|
||||||
u32 cnt = message->ioctl.buffer_in[2];
|
u32 cnt = message->ioctl.buffer_in[2];
|
||||||
int fileHandle = message->ioctl.buffer_in[3];
|
int fileHandle = message->ioctl.buffer_in[3];
|
||||||
u32 flags = message->ioctl.buffer_in[4];
|
u32 flags = message->ioctl.buffer_in[4];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags);
|
message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_STATFILE: {
|
case IOCTL_FSA_STATFILE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int fileHandle = message->ioctl.buffer_in[1];
|
int fileHandle = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s *) (message->ioctl.buffer_io + 1));
|
message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s *) (message->ioctl.buffer_io + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_CLOSEFILE: {
|
case IOCTL_FSA_CLOSEFILE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int fileHandle = message->ioctl.buffer_in[1];
|
int fileHandle = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle);
|
message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_SETFILEPOS: {
|
case IOCTL_FSA_SETFILEPOS: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int fileHandle = message->ioctl.buffer_in[1];
|
int fileHandle = message->ioctl.buffer_in[1];
|
||||||
u32 position = message->ioctl.buffer_in[2];
|
u32 position = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_SetPosFile(fd, fileHandle, position);
|
message->ioctl.buffer_io[0] = FSA_SetPosFile(fd, fileHandle, position);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_GETSTAT: {
|
case IOCTL_FSA_GETSTAT: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s *) (message->ioctl.buffer_io + 1));
|
message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s *) (message->ioctl.buffer_io + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_REMOVE: {
|
case IOCTL_FSA_REMOVE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_Remove(fd, path);
|
message->ioctl.buffer_io[0] = FSA_Remove(fd, path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_REWINDDIR: {
|
case IOCTL_FSA_REWINDDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int dirFd = message->ioctl.buffer_in[1];
|
int dirFd = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd);
|
message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_CHDIR: {
|
case IOCTL_FSA_CHDIR: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path);
|
message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_RAW_OPEN: {
|
case IOCTL_FSA_RAW_OPEN: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_RawOpen(fd, path, (int *) (message->ioctl.buffer_io + 1));
|
message->ioctl.buffer_io[0] = FSA_RawOpen(fd, path, (int *) (message->ioctl.buffer_io + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_RAW_READ: {
|
case IOCTL_FSA_RAW_READ: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
u32 block_size = message->ioctl.buffer_in[1];
|
u32 block_size = message->ioctl.buffer_in[1];
|
||||||
u32 cnt = message->ioctl.buffer_in[2];
|
u32 cnt = message->ioctl.buffer_in[2];
|
||||||
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
|
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
|
||||||
int deviceHandle = message->ioctl.buffer_in[5];
|
int deviceHandle = message->ioctl.buffer_in[5];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle);
|
message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_RAW_WRITE: {
|
case IOCTL_FSA_RAW_WRITE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
u32 block_size = message->ioctl.buffer_in[1];
|
u32 block_size = message->ioctl.buffer_in[1];
|
||||||
u32 cnt = message->ioctl.buffer_in[2];
|
u32 cnt = message->ioctl.buffer_in[2];
|
||||||
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
|
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
|
||||||
int deviceHandle = message->ioctl.buffer_in[5];
|
int deviceHandle = message->ioctl.buffer_in[5];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle);
|
message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_RAW_CLOSE: {
|
case IOCTL_FSA_RAW_CLOSE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
int deviceHandle = message->ioctl.buffer_in[1];
|
int deviceHandle = message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle);
|
message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_CHANGEMODE: {
|
case IOCTL_FSA_CHANGEMODE: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
int mode = message->ioctl.buffer_in[2];
|
int mode = message->ioctl.buffer_in[2];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode);
|
message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_FSA_FLUSHVOLUME: {
|
case IOCTL_FSA_FLUSHVOLUME: {
|
||||||
int fd = message->ioctl.buffer_in[0];
|
int fd = message->ioctl.buffer_in[0];
|
||||||
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
|
||||||
|
|
||||||
message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path);
|
message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path);
|
||||||
@ -451,5 +450,4 @@ void ipc_deinit(void) {
|
|||||||
svcIoctl(fd, IOCTL_KILL_SERVER, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
|
svcIoctl(fd, IOCTL_KILL_SERVER, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
|
||||||
svcClose(fd);
|
svcClose(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,21 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define IOS_COMMAND_INVALID 0x00
|
#define IOS_COMMAND_INVALID 0x00
|
||||||
#define IOS_OPEN 0x01
|
#define IOS_OPEN 0x01
|
||||||
#define IOS_CLOSE 0x02
|
#define IOS_CLOSE 0x02
|
||||||
#define IOS_READ 0x03
|
#define IOS_READ 0x03
|
||||||
#define IOS_WRITE 0x04
|
#define IOS_WRITE 0x04
|
||||||
#define IOS_SEEK 0x05
|
#define IOS_SEEK 0x05
|
||||||
#define IOS_IOCTL 0x06
|
#define IOS_IOCTL 0x06
|
||||||
#define IOS_IOCTLV 0x07
|
#define IOS_IOCTLV 0x07
|
||||||
#define IOS_REPLY 0x08
|
#define IOS_REPLY 0x08
|
||||||
#define IOS_IPC_MSG0 0x09
|
#define IOS_IPC_MSG0 0x09
|
||||||
#define IOS_IPC_MSG1 0x0A
|
#define IOS_IPC_MSG1 0x0A
|
||||||
#define IOS_IPC_MSG2 0x0B
|
#define IOS_IPC_MSG2 0x0B
|
||||||
#define IOS_SUSPEND 0x0C
|
#define IOS_SUSPEND 0x0C
|
||||||
#define IOS_RESUME 0x0D
|
#define IOS_RESUME 0x0D
|
||||||
#define IOS_SVCMSG 0x0E
|
#define IOS_SVCMSG 0x0E
|
||||||
|
|
||||||
|
|
||||||
/* IPC message */
|
/* IPC message */
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
#include <stdarg.h>
|
#include "logger.h"
|
||||||
#include <string.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "logger.h"
|
#include "types.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef LOG_IP
|
#ifdef LOG_IP
|
||||||
static int log_socket = 0;
|
static int log_socket = 0;
|
||||||
|
|
||||||
int log_init(unsigned int ipAddress){
|
int log_init(unsigned int ipAddress) {
|
||||||
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (log_socket < 0){
|
if (log_socket < 0) {
|
||||||
return log_socket;
|
return log_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in connect_addr;
|
struct sockaddr_in connect_addr;
|
||||||
memset(&connect_addr, 0, sizeof(connect_addr));
|
memset(&connect_addr, 0, sizeof(connect_addr));
|
||||||
connect_addr.sin_family = AF_INET;
|
connect_addr.sin_family = AF_INET;
|
||||||
connect_addr.sin_port = 4405;
|
connect_addr.sin_port = 4405;
|
||||||
connect_addr.sin_addr.s_addr = ipAddress;
|
connect_addr.sin_addr.s_addr = ipAddress;
|
||||||
|
|
||||||
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
|
if (connect(log_socket, (struct sockaddr *) &connect_addr, sizeof(connect_addr)) < 0) {
|
||||||
{
|
|
||||||
closesocket(log_socket);
|
closesocket(log_socket);
|
||||||
log_socket = -1;
|
log_socket = -1;
|
||||||
}
|
}
|
||||||
@ -29,25 +28,22 @@ int log_init(unsigned int ipAddress){
|
|||||||
return log_socket;
|
return log_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_deinit()
|
void log_deinit() {
|
||||||
{
|
if (log_socket >= 0) {
|
||||||
if(log_socket >= 0)
|
|
||||||
{
|
|
||||||
closesocket(log_socket);
|
closesocket(log_socket);
|
||||||
log_socket = -1;
|
log_socket = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_print(const char *str, int len)
|
static void log_print(const char *str, int len) {
|
||||||
{
|
if (log_socket < 0) {
|
||||||
if(log_socket < 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int ret;
|
int ret;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
|
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
|
||||||
ret = send(log_socket, str, block, 0);
|
ret = send(log_socket, str, block, 0);
|
||||||
if(ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
len -= ret;
|
len -= ret;
|
||||||
@ -55,9 +51,8 @@ static void log_print(const char *str, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_printf(const char *format, ...)
|
void log_printf(const char *format, ...) {
|
||||||
{
|
if (log_socket < 0) {
|
||||||
if(log_socket < 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,9 @@ void log_printf(const char *format, ...);
|
|||||||
#define log_printf(x, ...)
|
#define log_printf(x, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
|
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
|
||||||
log_printf("[%23s]%30s@L%04d: " FMT "",__FILE__,__FUNCTION__, __LINE__, ## ARGS); \
|
do { \
|
||||||
|
log_printf("[%23s]%30s@L%04d: " FMT "", __FILE__, __FUNCTION__, __LINE__, ##ARGS); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "wupserver.h"
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
#include "wupserver.h"
|
||||||
|
|
||||||
static int threadsStarted = 0;
|
static int threadsStarted = 0;
|
||||||
|
|
||||||
|
@ -16,31 +16,31 @@
|
|||||||
* - each request routes here where we can do whatever
|
* - each request routes here where we can do whatever
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "ipc_types.h"
|
|
||||||
#include "../../common/ipc_defs.h"
|
#include "../../common/ipc_defs.h"
|
||||||
#include "fsa.h"
|
#include "fsa.h"
|
||||||
|
#include "ipc_types.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int (*const real_MCP_LoadFile)(ipcmessage *msg) = (void *) 0x0501CAA8 + 1; //+1 for thumb
|
int (*const real_MCP_LoadFile)(ipcmessage *msg) = (void *) 0x0501CAA8 + 1; //+1 for thumb
|
||||||
int (*const MCP_DoLoadFile)(const char *path, const char *path2, void *outputBuffer, uint32_t outLength, uint32_t pos, int *bytesRead, uint32_t unk) = (void *) 0x05017248 + 1;
|
int (*const MCP_DoLoadFile)(const char *path, const char *path2, void *outputBuffer, uint32_t outLength, uint32_t pos, int *bytesRead, uint32_t unk) = (void *) 0x05017248 + 1;
|
||||||
|
|
||||||
static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffset, void *out_buffer, int buffer_len, int pos);
|
static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffset, void *out_buffer, int buffer_len, int pos);
|
||||||
|
|
||||||
static bool replace_valid = false;
|
static bool replace_valid = false;
|
||||||
static bool skipPPCSetup = false;
|
static bool skipPPCSetup = false;
|
||||||
static bool doWantReplaceRPX = false;
|
static bool doWantReplaceRPX = false;
|
||||||
static bool replace_target_device = 0;
|
static bool replace_target_device = 0;
|
||||||
static uint32_t rep_filesize = 0;
|
static uint32_t rep_filesize = 0;
|
||||||
static uint32_t rep_fileoffset = 0;
|
static uint32_t rep_fileoffset = 0;
|
||||||
static char rpxpath[256];
|
static char rpxpath[256];
|
||||||
|
|
||||||
#define log(fmt, ...) log_printf("%s: " fmt, __FUNCTION__, __VA_ARGS__)
|
#define log(fmt, ...) log_printf("%s: " fmt, __FUNCTION__, __VA_ARGS__)
|
||||||
#define FAIL_ON(cond, val) \
|
#define FAIL_ON(cond, val) \
|
||||||
if (cond) { \
|
if (cond) { \
|
||||||
log(#cond " (%08X)", val); \
|
log(#cond " (%08X)", val); \
|
||||||
return -29; \
|
return -29; \
|
||||||
}
|
}
|
||||||
|
|
||||||
int _MCP_LoadFile_patch(ipcmessage *msg) {
|
int _MCP_LoadFile_patch(ipcmessage *msg) {
|
||||||
@ -56,10 +56,10 @@ int _MCP_LoadFile_patch(ipcmessage *msg) {
|
|||||||
//DEBUG_FUNCTION_LINE("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
//DEBUG_FUNCTION_LINE("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
||||||
//DEBUG_FUNCTION_LINE("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
//DEBUG_FUNCTION_LINE("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
||||||
|
|
||||||
int replace_target = replace_target_device;
|
int replace_target = replace_target_device;
|
||||||
int replace_filesize = rep_filesize;
|
int replace_filesize = rep_filesize;
|
||||||
int replace_fileoffset = rep_fileoffset;
|
int replace_fileoffset = rep_fileoffset;
|
||||||
char *replace_path = rpxpath;
|
char *replace_path = rpxpath;
|
||||||
|
|
||||||
if (strlen(request->name) > 1 && request->name[strlen(request->name) - 1] == 'x') {
|
if (strlen(request->name) > 1 && request->name[strlen(request->name) - 1] == 'x') {
|
||||||
if (strncmp(request->name, "safe.rpx", strlen("safe.rpx")) != 0) {
|
if (strncmp(request->name, "safe.rpx", strlen("safe.rpx")) != 0) {
|
||||||
@ -81,28 +81,28 @@ int _MCP_LoadFile_patch(ipcmessage *msg) {
|
|||||||
// The replacement may restart the application to execute a kernel exploit.
|
// The replacement may restart the application to execute a kernel exploit.
|
||||||
// The men.rpx is hooked until the "IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED" command is passed to IOCTL 0x100.
|
// The men.rpx is hooked until the "IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED" command is passed to IOCTL 0x100.
|
||||||
// If the loading of the replacement file fails, the Wii U Menu is loaded normally.
|
// If the loading of the replacement file fails, the Wii U Menu is loaded normally.
|
||||||
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
||||||
replace_filesize = 0; // unknown
|
replace_filesize = 0; // unknown
|
||||||
replace_fileoffset = 0;
|
replace_fileoffset = 0;
|
||||||
} else if (strncmp(request->name, "safe.rpx", strlen("safe.rpx")) == 0) {
|
} else if (strncmp(request->name, "safe.rpx", strlen("safe.rpx")) == 0) {
|
||||||
// if we don't explicitly replace files, we do want replace the Health and Safety app with the HBL
|
// if we don't explicitly replace files, we do want replace the Health and Safety app with the HBL
|
||||||
if (request->pos == 0 && !doWantReplaceRPX) {
|
if (request->pos == 0 && !doWantReplaceRPX) {
|
||||||
replace_path = "wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
|
replace_path = "wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
|
||||||
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
||||||
//doWantReplaceXML = false;
|
//doWantReplaceXML = false;
|
||||||
doWantReplaceRPX = true;
|
doWantReplaceRPX = true;
|
||||||
replace_filesize = 0; // unknown
|
replace_filesize = 0; // unknown
|
||||||
replace_fileoffset = 0;
|
replace_fileoffset = 0;
|
||||||
}
|
}
|
||||||
} else if (!doWantReplaceRPX) {
|
} else if (!doWantReplaceRPX) {
|
||||||
doWantReplaceRPX = false; // Only replace it once.
|
doWantReplaceRPX = false; // Only replace it once.
|
||||||
replace_path = NULL;
|
replace_path = NULL;
|
||||||
return real_MCP_LoadFile(msg);
|
return real_MCP_LoadFile(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replace_path != NULL && strlen(replace_path) > 0) {
|
if (replace_path != NULL && strlen(replace_path) > 0) {
|
||||||
doWantReplaceRPX = false; // Only replace it once.
|
doWantReplaceRPX = false; // Only replace it once.
|
||||||
int result = MCP_LoadCustomFile(replace_target, replace_path, replace_filesize, replace_fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos);
|
int result = MCP_LoadCustomFile(replace_target, replace_path, replace_filesize, replace_fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos);
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
return result;
|
return result;
|
||||||
@ -126,7 +126,7 @@ static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffs
|
|||||||
|
|
||||||
if (target == LOAD_FILE_TARGET_SD_CARD) {
|
if (target == LOAD_FILE_TARGET_SD_CARD) {
|
||||||
char mountpath[] = "/vol/storage_iosu_homebrew";
|
char mountpath[] = "/vol/storage_iosu_homebrew";
|
||||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||||
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
|
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
|
||||||
svcClose(fsa_h);
|
svcClose(fsa_h);
|
||||||
strncpy(filepath, mountpath, sizeof(filepath) - 1);
|
strncpy(filepath, mountpath, sizeof(filepath) - 1);
|
||||||
@ -143,7 +143,7 @@ static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffs
|
|||||||
|
|
||||||
/* TODO: If this fails, try last argument as 1 */
|
/* TODO: If this fails, try last argument as 1 */
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
int result = MCP_DoLoadFile(filepath, NULL, buffer_out, buffer_len, pos + fileoffset, &bytesRead, 0);
|
int result = MCP_DoLoadFile(filepath, NULL, buffer_out, buffer_len, pos + fileoffset, &bytesRead, 0);
|
||||||
//log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, pos + fileoffset);
|
//log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, pos + fileoffset);
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
@ -161,7 +161,7 @@ static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffs
|
|||||||
}
|
}
|
||||||
|
|
||||||
int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlData) {
|
int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlData) {
|
||||||
int (*const real_MCP_ReadCOSXml_patch)(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlData) = (void *) 0x050024ec + 1; //+1 for thumb
|
int (*const real_MCP_ReadCOSXml_patch)(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo * xmlData) = (void *) 0x050024ec + 1; //+1 for thumb
|
||||||
|
|
||||||
int res = real_MCP_ReadCOSXml_patch(u1, u2, xmlData);
|
int res = real_MCP_ReadCOSXml_patch(u1, u2, xmlData);
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlDat
|
|||||||
if (xmlData->titleId != 0x000500001010DC00 && // Mass Effect 3 Special Edition USA
|
if (xmlData->titleId != 0x000500001010DC00 && // Mass Effect 3 Special Edition USA
|
||||||
xmlData->titleId != 0x000500001010F500 && // Mass Effect 3 Special Edition EUR
|
xmlData->titleId != 0x000500001010F500 && // Mass Effect 3 Special Edition EUR
|
||||||
xmlData->titleId != 0x0005000010113000) { // Mass Effect 3 Special Edition JPN
|
xmlData->titleId != 0x0005000010113000) { // Mass Effect 3 Special Edition JPN
|
||||||
|
|
||||||
// Give all titles permission to use ACP
|
// Give all titles permission to use ACP
|
||||||
xmlData->permissions[10].mask = 0xFFFFFFFFFFFFFFFF;
|
xmlData->permissions[10].mask = 0xFFFFFFFFFFFFFFFF;
|
||||||
}
|
}
|
||||||
@ -185,11 +185,11 @@ int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlDat
|
|||||||
xmlData->titleId == 0x000500101004E200) {
|
xmlData->titleId == 0x000500101004E200) {
|
||||||
xmlData->codegen_size = 0x02000000;
|
xmlData->codegen_size = 0x02000000;
|
||||||
xmlData->codegen_core = 0x80000001;
|
xmlData->codegen_core = 0x80000001;
|
||||||
xmlData->max_size = 0x40000000;
|
xmlData->max_size = 0x40000000;
|
||||||
|
|
||||||
// Set maximum codesize to 64 MiB
|
// Set maximum codesize to 64 MiB
|
||||||
xmlData->max_codesize = 0x04000000;
|
xmlData->max_codesize = 0x04000000;
|
||||||
xmlData->avail_size = 0;
|
xmlData->avail_size = 0;
|
||||||
xmlData->overlay_arena = 0;
|
xmlData->overlay_arena = 0;
|
||||||
|
|
||||||
// Give us full permissions everywhere
|
// Give us full permissions everywhere
|
||||||
@ -197,9 +197,9 @@ int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo *xmlDat
|
|||||||
xmlData->permissions[i].mask = 0xFFFFFFFFFFFFFFFF;
|
xmlData->permissions[i].mask = 0xFFFFFFFFFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlData->default_stack0_size = 0;
|
xmlData->default_stack0_size = 0;
|
||||||
xmlData->default_stack1_size = 0;
|
xmlData->default_stack1_size = 0;
|
||||||
xmlData->default_stack2_size = 0;
|
xmlData->default_stack2_size = 0;
|
||||||
xmlData->default_redzone0_size = 0;
|
xmlData->default_redzone0_size = 0;
|
||||||
xmlData->default_redzone1_size = 0;
|
xmlData->default_redzone1_size = 0;
|
||||||
xmlData->default_redzone2_size = 0;
|
xmlData->default_redzone2_size = 0;
|
||||||
@ -260,16 +260,16 @@ int _MCP_ioctl100_patch(ipcmessage *msg) {
|
|||||||
DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOAD_CUSTOM_RPX\n");
|
DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOAD_CUSTOM_RPX\n");
|
||||||
|
|
||||||
if (msg->ioctl.length_in >= 0x110) {
|
if (msg->ioctl.length_in >= 0x110) {
|
||||||
int target = msg->ioctl.buffer_in[0x04 / 0x04];
|
int target = msg->ioctl.buffer_in[0x04 / 0x04];
|
||||||
int filesize = msg->ioctl.buffer_in[0x08 / 0x04];
|
int filesize = msg->ioctl.buffer_in[0x08 / 0x04];
|
||||||
int fileoffset = msg->ioctl.buffer_in[0x0C / 0x04];
|
int fileoffset = msg->ioctl.buffer_in[0x0C / 0x04];
|
||||||
char *str_ptr = (char *) &msg->ioctl.buffer_in[0x10 / 0x04];
|
char *str_ptr = (char *) &msg->ioctl.buffer_in[0x10 / 0x04];
|
||||||
memset(rpxpath, 0, sizeof(rpxpath));
|
memset(rpxpath, 0, sizeof(rpxpath));
|
||||||
|
|
||||||
strncpy(rpxpath, str_ptr, 256 - 1);
|
strncpy(rpxpath, str_ptr, 256 - 1);
|
||||||
|
|
||||||
rep_filesize = filesize;
|
rep_filesize = filesize;
|
||||||
rep_fileoffset = fileoffset;
|
rep_fileoffset = fileoffset;
|
||||||
doWantReplaceRPX = true;
|
doWantReplaceRPX = true;
|
||||||
//doWantReplaceXML = true;
|
//doWantReplaceXML = true;
|
||||||
replace_valid = true;
|
replace_valid = true;
|
||||||
@ -309,8 +309,8 @@ int _MCP_ioctl100_patch(ipcmessage *msg) {
|
|||||||
|
|
||||||
// Kill existing syslogs to avoid long catch up
|
// Kill existing syslogs to avoid long catch up
|
||||||
uint32_t *bufferPtr = (uint32_t *) (*(uint32_t *) 0x05095ecc);
|
uint32_t *bufferPtr = (uint32_t *) (*(uint32_t *) 0x05095ecc);
|
||||||
bufferPtr[0] = 0;
|
bufferPtr[0] = 0;
|
||||||
bufferPtr[1] = 0;
|
bufferPtr[1] = 0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "net_ifmgr_ncl.h"
|
#include "net_ifmgr_ncl.h"
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static int ifmgrncl_handle = 0;
|
static int ifmgrncl_handle = 0;
|
||||||
|
|
||||||
@ -40,9 +40,9 @@ static void freeIobuf(void *ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16 *out_status) {
|
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16 *out_status) {
|
||||||
u8 *iobuf1 = allocIobuf(0x2);
|
u8 *iobuf1 = allocIobuf(0x2);
|
||||||
u16 *inbuf = (u16 *) iobuf1;
|
u16 *inbuf = (u16 *) iobuf1;
|
||||||
u8 *iobuf2 = allocIobuf(0x8);
|
u8 *iobuf2 = allocIobuf(0x8);
|
||||||
u16 *outbuf = (u16 *) iobuf2;
|
u16 *outbuf = (u16 *) iobuf2;
|
||||||
|
|
||||||
inbuf[0] = interface_id;
|
inbuf[0] = interface_id;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "svc.h"
|
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
|
#include "svc.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static int socket_handle = 0;
|
static int socket_handle = 0;
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ static void freeIobuf(void *ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int socket(int domain, int type, int protocol) {
|
int socket(int domain, int type, int protocol) {
|
||||||
u8 *iobuf = allocIobuf(0xC);
|
u8 *iobuf = allocIobuf(0xC);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = domain;
|
inbuf[0] = domain;
|
||||||
@ -55,7 +55,7 @@ int socket(int domain, int type, int protocol) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int closesocket(int sockfd) {
|
int closesocket(int sockfd) {
|
||||||
u8 *iobuf = allocIobuf(0x4);
|
u8 *iobuf = allocIobuf(0x4);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -67,8 +67,8 @@ int closesocket(int sockfd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||||
u8 *iobuf = allocIobuf(0x18);
|
u8 *iobuf = allocIobuf(0x18);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
u32 *outbuf = (u32 *) inbuf;
|
u32 *outbuf = (u32 *) inbuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -97,7 +97,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
|||||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
if (addrlen != 0x10) return -1;
|
if (addrlen != 0x10) return -1;
|
||||||
|
|
||||||
u8 *iobuf = allocIobuf(0x18);
|
u8 *iobuf = allocIobuf(0x18);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -113,7 +113,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
if (addrlen != 0x10) return -1;
|
if (addrlen != 0x10) return -1;
|
||||||
|
|
||||||
u8 *iobuf = allocIobuf(0x18);
|
u8 *iobuf = allocIobuf(0x18);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -127,7 +127,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int listen(int sockfd, int backlog) {
|
int listen(int sockfd, int backlog) {
|
||||||
u8 *iobuf = allocIobuf(0x8);
|
u8 *iobuf = allocIobuf(0x8);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -140,7 +140,7 @@ int listen(int sockfd, int backlog) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int shutdown(int sockfd, int how) {
|
int shutdown(int sockfd, int how) {
|
||||||
u8 *iobuf = allocIobuf(0x8);
|
u8 *iobuf = allocIobuf(0x8);
|
||||||
u32 *inbuf = (u32 *) iobuf;
|
u32 *inbuf = (u32 *) iobuf;
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
@ -159,9 +159,9 @@ int recv(int sockfd, void *buf, size_t len, int flags) {
|
|||||||
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
|
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
|
||||||
if (!data_buf) return -100;
|
if (!data_buf) return -100;
|
||||||
|
|
||||||
u8 *iobuf = allocIobuf(0x38);
|
u8 *iobuf = allocIobuf(0x38);
|
||||||
iovec_s *iovec = (iovec_s *) iobuf;
|
iovec_s *iovec = (iovec_s *) iobuf;
|
||||||
u32 *inbuf = (u32 *) &iobuf[0x30];
|
u32 *inbuf = (u32 *) &iobuf[0x30];
|
||||||
|
|
||||||
inbuf[0] = sockfd;
|
inbuf[0] = sockfd;
|
||||||
inbuf[1] = flags;
|
inbuf[1] = flags;
|
||||||
@ -189,9 +189,9 @@ int send(int sockfd, const void *buf, size_t len, int flags) {
|
|||||||
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
|
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
|
||||||
if (!data_buf) return -100;
|
if (!data_buf) return -100;
|
||||||
|
|
||||||
u8 *iobuf = allocIobuf(0x38);
|
u8 *iobuf = allocIobuf(0x38);
|
||||||
iovec_s *iovec = (iovec_s *) iobuf;
|
iovec_s *iovec = (iovec_s *) iobuf;
|
||||||
u32 *inbuf = (u32 *) &iobuf[0x30];
|
u32 *inbuf = (u32 *) &iobuf[0x30];
|
||||||
|
|
||||||
memcpy(data_buf, buf, len);
|
memcpy(data_buf, buf, len);
|
||||||
|
|
||||||
|
@ -5,70 +5,70 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define SOL_SOCKET 0xFFFF
|
#define SOL_SOCKET 0xFFFF
|
||||||
|
|
||||||
#define PF_UNSPEC 0
|
#define PF_UNSPEC 0
|
||||||
#define PF_INET 2
|
#define PF_INET 2
|
||||||
#define PF_INET6 10
|
#define PF_INET6 10
|
||||||
|
|
||||||
#define AF_UNSPEC PF_UNSPEC
|
#define AF_UNSPEC PF_UNSPEC
|
||||||
#define AF_INET PF_INET
|
#define AF_INET PF_INET
|
||||||
#define AF_INET6 PF_INET6
|
#define AF_INET6 PF_INET6
|
||||||
|
|
||||||
#define SOCK_STREAM 1
|
#define SOCK_STREAM 1
|
||||||
#define SOCK_DGRAM 2
|
#define SOCK_DGRAM 2
|
||||||
|
|
||||||
#define MSG_CTRUNC 0x01000000
|
#define MSG_CTRUNC 0x01000000
|
||||||
#define MSG_DONTROUTE 0x02000000
|
#define MSG_DONTROUTE 0x02000000
|
||||||
#define MSG_EOR 0x04000000
|
#define MSG_EOR 0x04000000
|
||||||
#define MSG_OOB 0x08000000
|
#define MSG_OOB 0x08000000
|
||||||
#define MSG_PEEK 0x10000000
|
#define MSG_PEEK 0x10000000
|
||||||
#define MSG_TRUNC 0x20000000
|
#define MSG_TRUNC 0x20000000
|
||||||
#define MSG_WAITALL 0x40000000
|
#define MSG_WAITALL 0x40000000
|
||||||
|
|
||||||
#define SHUT_RD 0
|
#define SHUT_RD 0
|
||||||
#define SHUT_WR 1
|
#define SHUT_WR 1
|
||||||
#define SHUT_RDWR 2
|
#define SHUT_RDWR 2
|
||||||
|
|
||||||
#define SO_DEBUG 0x0001
|
#define SO_DEBUG 0x0001
|
||||||
#define SO_ACCEPTCONN 0x0002
|
#define SO_ACCEPTCONN 0x0002
|
||||||
#define SO_REUSEADDR 0x0004
|
#define SO_REUSEADDR 0x0004
|
||||||
#define SO_KEEPALIVE 0x0008
|
#define SO_KEEPALIVE 0x0008
|
||||||
#define SO_DONTROUTE 0x0010
|
#define SO_DONTROUTE 0x0010
|
||||||
#define SO_BROADCAST 0x0020
|
#define SO_BROADCAST 0x0020
|
||||||
#define SO_USELOOPBACK 0x0040
|
#define SO_USELOOPBACK 0x0040
|
||||||
#define SO_LINGER 0x0080
|
#define SO_LINGER 0x0080
|
||||||
#define SO_OOBINLINE 0x0100
|
#define SO_OOBINLINE 0x0100
|
||||||
#define SO_REUSEPORT 0x0200
|
#define SO_REUSEPORT 0x0200
|
||||||
#define SO_SNDBUF 0x1001
|
#define SO_SNDBUF 0x1001
|
||||||
#define SO_RCVBUF 0x1002
|
#define SO_RCVBUF 0x1002
|
||||||
#define SO_SNDLOWAT 0x1003
|
#define SO_SNDLOWAT 0x1003
|
||||||
#define SO_RCVLOWAT 0x1004
|
#define SO_RCVLOWAT 0x1004
|
||||||
#define SO_SNDTIMEO 0x1005
|
#define SO_SNDTIMEO 0x1005
|
||||||
#define SO_RCVTIMEO 0x1006
|
#define SO_RCVTIMEO 0x1006
|
||||||
#define SO_ERROR 0x1007
|
#define SO_ERROR 0x1007
|
||||||
#define SO_TYPE 0x1008
|
#define SO_TYPE 0x1008
|
||||||
|
|
||||||
#define INADDR_ANY 0x00000000
|
#define INADDR_ANY 0x00000000
|
||||||
#define INADDR_BROADCAST 0xFFFFFFFF
|
#define INADDR_BROADCAST 0xFFFFFFFF
|
||||||
#define INADDR_NONE 0xFFFFFFFF
|
#define INADDR_NONE 0xFFFFFFFF
|
||||||
|
|
||||||
#define INET_ADDRSTRLEN 16
|
#define INET_ADDRSTRLEN 16
|
||||||
|
|
||||||
#define INADDR_LOOPBACK 0x7f000001
|
#define INADDR_LOOPBACK 0x7f000001
|
||||||
#define INADDR_ANY 0x00000000
|
#define INADDR_ANY 0x00000000
|
||||||
#define INADDR_BROADCAST 0xFFFFFFFF
|
#define INADDR_BROADCAST 0xFFFFFFFF
|
||||||
#define INADDR_NONE 0xFFFFFFFF
|
#define INADDR_NONE 0xFFFFFFFF
|
||||||
|
|
||||||
#define INET_ADDRSTRLEN 16
|
#define INET_ADDRSTRLEN 16
|
||||||
|
|
||||||
#define IPPROTO_IP 0 /* dummy for IP */
|
#define IPPROTO_IP 0 /* dummy for IP */
|
||||||
#define IPPROTO_UDP 17 /* user datagram protocol */
|
#define IPPROTO_UDP 17 /* user datagram protocol */
|
||||||
#define IPPROTO_TCP 6 /* tcp */
|
#define IPPROTO_TCP 6 /* tcp */
|
||||||
|
|
||||||
#define IP_TOS 7
|
#define IP_TOS 7
|
||||||
#define IP_TTL 8
|
#define IP_TTL 8
|
||||||
#define IP_MULTICAST_LOOP 9
|
#define IP_MULTICAST_LOOP 9
|
||||||
#define IP_MULTICAST_TTL 10
|
#define IP_MULTICAST_TTL 10
|
||||||
#define IP_ADD_MEMBERSHIP 11
|
#define IP_ADD_MEMBERSHIP 11
|
||||||
#define IP_DROP_MEMBERSHIP 12
|
#define IP_DROP_MEMBERSHIP 12
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
#ifndef TYPES_H
|
#ifndef TYPES_H
|
||||||
#define TYPES_H
|
#define TYPES_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define U64_MAX UINT64_MAX
|
#define U64_MAX UINT64_MAX
|
||||||
|
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#include <stdlib.h>
|
#include "fsa.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "imports.h"
|
#include "imports.h"
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "net_ifmgr_ncl.h"
|
#include "net_ifmgr_ncl.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "fsa.h"
|
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
#include "logger.h"
|
#include <stdio.h>
|
||||||
#include "ipc.h"
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static int serverKilled;
|
static int serverKilled;
|
||||||
static int serverSocket;
|
static int serverSocket;
|
||||||
@ -24,84 +24,84 @@ static int serverCommandHandler(u32 *command_buffer, u32 length) {
|
|||||||
case 0:
|
case 0:
|
||||||
// write
|
// write
|
||||||
// [cmd_id][addr]
|
// [cmd_id][addr]
|
||||||
{
|
{
|
||||||
void *dst = (void *) command_buffer[1];
|
void *dst = (void *) command_buffer[1];
|
||||||
|
|
||||||
memcpy(dst, &command_buffer[2], length - 8);
|
memcpy(dst, &command_buffer[2], length - 8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// read
|
// read
|
||||||
// [cmd_id][addr][length]
|
// [cmd_id][addr][length]
|
||||||
{
|
{
|
||||||
void *src = (void *) command_buffer[1];
|
void *src = (void *) command_buffer[1];
|
||||||
length = command_buffer[2];
|
length = command_buffer[2];
|
||||||
|
|
||||||
memcpy(&command_buffer[1], src, length);
|
memcpy(&command_buffer[1], src, length);
|
||||||
out_length = length + 4;
|
out_length = length + 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// svc
|
// svc
|
||||||
// [cmd_id][svc_id]
|
// [cmd_id][svc_id]
|
||||||
{
|
{
|
||||||
int svc_id = command_buffer[1];
|
int svc_id = command_buffer[1];
|
||||||
int size_arguments = length - 8;
|
int size_arguments = length - 8;
|
||||||
|
|
||||||
u32 arguments[8];
|
u32 arguments[8];
|
||||||
memset(arguments, 0x00, sizeof(arguments));
|
memset(arguments, 0x00, sizeof(arguments));
|
||||||
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
|
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
|
||||||
|
|
||||||
// return error code as data
|
// return error code as data
|
||||||
out_length = 8;
|
out_length = 8;
|
||||||
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32)) (MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5],
|
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5],
|
||||||
arguments[6], arguments[7]);
|
arguments[6], arguments[7]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// kill
|
// kill
|
||||||
// [cmd_id]
|
// [cmd_id]
|
||||||
{
|
{
|
||||||
serverKilled = 1;
|
serverKilled = 1;
|
||||||
ipc_deinit();
|
ipc_deinit();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// memcpy
|
// memcpy
|
||||||
// [dst][src][size]
|
// [dst][src][size]
|
||||||
{
|
{
|
||||||
void *dst = (void *) command_buffer[1];
|
void *dst = (void *) command_buffer[1];
|
||||||
void *src = (void *) command_buffer[2];
|
void *src = (void *) command_buffer[2];
|
||||||
int size = command_buffer[3];
|
int size = command_buffer[3];
|
||||||
|
|
||||||
memcpy(dst, src, size);
|
memcpy(dst, src, size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// repeated-write
|
// repeated-write
|
||||||
// [address][value][n]
|
// [address][value][n]
|
||||||
{
|
{
|
||||||
u32 *dst = (u32 *) command_buffer[1];
|
u32 *dst = (u32 *) command_buffer[1];
|
||||||
u32 *cache_range = (u32 *) (command_buffer[1] & ~0xFF);
|
u32 *cache_range = (u32 *) (command_buffer[1] & ~0xFF);
|
||||||
u32 value = command_buffer[2];
|
u32 value = command_buffer[2];
|
||||||
u32 n = command_buffer[3];
|
u32 n = command_buffer[3];
|
||||||
|
|
||||||
u32 old = *dst;
|
u32 old = *dst;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
if (*dst != old) {
|
if (*dst != old) {
|
||||||
if (*dst == 0x0) old = *dst;
|
if (*dst == 0x0) old = *dst;
|
||||||
else {
|
else {
|
||||||
*dst = value;
|
*dst = value;
|
||||||
svcFlushDCache(cache_range, 0x100);
|
svcFlushDCache(cache_range, 0x100);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
svcInvalidateDCache(cache_range, 0x100);
|
||||||
|
usleep(50);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
svcInvalidateDCache(cache_range, 0x100);
|
|
||||||
usleep(50);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// unknown command
|
// unknown command
|
||||||
@ -141,8 +141,8 @@ static void serverListenClients() {
|
|||||||
|
|
||||||
memset(&server, 0x00, sizeof(server));
|
memset(&server, 0x00, sizeof(server));
|
||||||
|
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
server.sin_port = 1337;
|
server.sin_port = 1337;
|
||||||
server.sin_addr.s_addr = 0;
|
server.sin_addr.s_addr = 0;
|
||||||
|
|
||||||
if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
|
if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
|
||||||
|
@ -5,7 +5,7 @@ void _main() {
|
|||||||
int (*reply)(int, int) = (int (*)(int, int)) 0x1012ED04;
|
int (*reply)(int, int) = (int (*)(int, int)) 0x1012ED04;
|
||||||
|
|
||||||
int saved_handle = *(volatile int *) 0x0012F000;
|
int saved_handle = *(volatile int *) 0x0012F000;
|
||||||
int myret = reply(saved_handle, 0);
|
int myret = reply(saved_handle, 0);
|
||||||
if (myret != 0)
|
if (myret != 0)
|
||||||
ios_shutdown(1);
|
ios_shutdown(1);
|
||||||
|
|
||||||
@ -19,6 +19,4 @@ void _main() {
|
|||||||
"newlr: .word 0x1012EACC\n"
|
"newlr: .word 0x1012EACC\n"
|
||||||
"newr0: .word 0x10146080\n"
|
"newr0: .word 0x10146080\n"
|
||||||
"newpc: .word 0x10111164\n");
|
"newpc: .word 0x10111164\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include <cstring>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <coreinit/ios.h>
|
#include <coreinit/ios.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <sysapp/title.h>
|
#include <sysapp/title.h>
|
||||||
|
|
||||||
#include <whb/log.h>
|
#include <whb/log.h>
|
||||||
@ -30,11 +30,11 @@ int main(int argc, char **argv) {
|
|||||||
// When the kernel exploit is set up successfully, we signal the ios to move on.
|
// When the kernel exploit is set up successfully, we signal the ios to move on.
|
||||||
int mcpFd = IOS_Open("/dev/mcp", (IOSOpenMode) 0);
|
int mcpFd = IOS_Open("/dev/mcp", (IOSOpenMode) 0);
|
||||||
if (mcpFd >= 0) {
|
if (mcpFd >= 0) {
|
||||||
int in = IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED;
|
int in = IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED;
|
||||||
int out = 0;
|
int out = 0;
|
||||||
IOS_Ioctl(mcpFd, 100, &in, sizeof(in), &out, sizeof(out));
|
IOS_Ioctl(mcpFd, 100, &in, sizeof(in), &out, sizeof(out));
|
||||||
|
|
||||||
in = IPC_CUSTOM_START_MCP_THREAD;
|
in = IPC_CUSTOM_START_MCP_THREAD;
|
||||||
out = 0;
|
out = 0;
|
||||||
IOS_Ioctl(mcpFd, 100, &in, sizeof(in), &out, sizeof(out));
|
IOS_Ioctl(mcpFd, 100, &in, sizeof(in), &out, sizeof(out));
|
||||||
IOS_Close(mcpFd);
|
IOS_Close(mcpFd);
|
||||||
|
Loading…
Reference in New Issue
Block a user