mirror of
https://github.com/wiiu-env/libmocha.git
synced 2024-11-13 23:45:05 +01:00
Add features of libiosuhax
This commit is contained in:
parent
e16878d7d7
commit
1bcb7649ac
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <coreinit/filesystem.h>
|
#include <coreinit/filesystem.h>
|
||||||
#include <mocha/commands.h>
|
#include <mocha/commands.h>
|
||||||
|
#include <mocha/otp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -12,6 +12,7 @@ typedef enum MochaUtilsStatus {
|
|||||||
MOCHA_RESULT_SUCCESS = 0,
|
MOCHA_RESULT_SUCCESS = 0,
|
||||||
MOCHA_RESULT_INVALID_ARGUMENT = -0x01,
|
MOCHA_RESULT_INVALID_ARGUMENT = -0x01,
|
||||||
MOCHA_RESULT_MAX_CLIENT = -0x02,
|
MOCHA_RESULT_MAX_CLIENT = -0x02,
|
||||||
|
MOCHA_RESULT_OUT_OF_MEMORY = -0x03,
|
||||||
MOCHA_RESULT_NOT_FOUND = -0x06,
|
MOCHA_RESULT_NOT_FOUND = -0x06,
|
||||||
MOCHA_RESULT_UNSUPPORTED_API_VERSION = -0x10,
|
MOCHA_RESULT_UNSUPPORTED_API_VERSION = -0x10,
|
||||||
MOCHA_RESULT_UNSUPPORTED_COMMAND = -0x11,
|
MOCHA_RESULT_UNSUPPORTED_COMMAND = -0x11,
|
||||||
@ -26,7 +27,11 @@ typedef enum MochaUtilsStatus {
|
|||||||
*/
|
*/
|
||||||
MochaUtilsStatus Mocha_InitLibrary();
|
MochaUtilsStatus Mocha_InitLibrary();
|
||||||
|
|
||||||
MochaUtilsStatus Mocha_DeInitLibrary();
|
/**
|
||||||
|
* Deinitializes the mocha lib
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_DeinitLibrary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the API Version of the running mocha.
|
* Retrieves the API Version of the running mocha.
|
||||||
@ -39,6 +44,87 @@ MochaUtilsStatus Mocha_DeInitLibrary();
|
|||||||
*/
|
*/
|
||||||
MochaUtilsStatus Mocha_CheckAPIVersion(uint32_t *outVersion);
|
MochaUtilsStatus Mocha_CheckAPIVersion(uint32_t *outVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies data within IOSU with kernel permission.
|
||||||
|
* @param dst - Destination address
|
||||||
|
* @param src - Source address
|
||||||
|
* @param size - Bytes to copy.
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The data has been copied successfully<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid version pointer<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Unknown error<br>
|
||||||
|
* MOCHA_RESULT_UNSUPPORTED_API_VERSION: Failed to get the API version caused by an outdated mocha version.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelMemcpy(uint32_t dst, uint32_t src, uint32_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes data to a given address with kernel permission.
|
||||||
|
* @param address - Address where the data will be written to.
|
||||||
|
* @param buffer - Pointer to the data which should be written.
|
||||||
|
* @param size - Bytes to write.
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The data has been written successfully<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid version pointer<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Unknown error<br>
|
||||||
|
* MOCHA_RESULT_UNSUPPORTED_API_VERSION: Failed to get the API version caused by an outdated mocha version.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelWrite(uint32_t address, const uint8_t *buffer, uint32_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads data from a given address with kernel permission.
|
||||||
|
* @param address - Address where the data will be read from.
|
||||||
|
* @param buffer - Pointer to the buffer where the read will be stored
|
||||||
|
* @param size - Bytes to read.
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The data has been read successfully<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid version pointer<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Unknown error<br>
|
||||||
|
* MOCHA_RESULT_UNSUPPORTED_API_VERSION: Failed to get the API version caused by an outdated mocha version.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelRead(uint32_t address, uint8_t *out_buffer, uint32_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write 4 bytes with IOSU kernel permission
|
||||||
|
* @param address Address where the value will be written.
|
||||||
|
* @param value Value that will be written to address.
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The data has been written successfully<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid version pointer<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Unknown error<br>
|
||||||
|
* MOCHA_RESULT_UNSUPPORTED_API_VERSION: Failed to get the API version caused by an outdated mocha version.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelWrite32(uint32_t address, uint32_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads 4 bytes with IOSU kernel permission
|
||||||
|
* @param address Address from which the data will be read.
|
||||||
|
* @param out_buffer Pointer where the result will be stored
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The data has been read successfully<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid version pointer<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Unknown error<br>
|
||||||
|
* MOCHA_RESULT_UNSUPPORTED_API_VERSION: Failed to get the API version caused by an outdated mocha version.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelRead32(uint32_t address, uint32_t *out_buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the consoles OTP into the given buffer.
|
||||||
|
*
|
||||||
|
* @param out_buffer Buffer where the result will be stored.
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The OTP has been read into the buffer<br>
|
||||||
|
* MOCHA_RESULT_INVALID_ARGUMENT: invalid environmentPathBuffer pointer or bufferLen \< 0x100<br>
|
||||||
|
* MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR: Failed to retrieve the environment path.
|
||||||
|
*/
|
||||||
|
MochaUtilsStatus Mocha_ReadOTP(WiiUConsoleOTP *out_buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls an iosu SVC.
|
||||||
|
* @param svc_id
|
||||||
|
* @param args array of argument with the length arg_cnt
|
||||||
|
* @param arg_cnt number of arguments
|
||||||
|
* @param outResult
|
||||||
|
* @return MOCHA_RESULT_SUCCESS: The SVC has been called successfully, the result has been stored in outResult.<br>
|
||||||
|
* MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.<br>
|
||||||
|
* MOCHA_RESULT_UNKNOWN_ERROR
|
||||||
|
*/
|
||||||
|
int Mocha_IOSUCallSVC(uint32_t svc_id, uint32_t *args, uint32_t arg_cnt, int32_t *outResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the path of the currently loaded environment
|
* Returns the path of the currently loaded environment
|
||||||
* @param environmentPathBuffer: buffer where the result will be stored
|
* @param environmentPathBuffer: buffer where the result will be stored
|
||||||
|
193
include/mocha/otp.h
Normal file
193
include/mocha/otp.h
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <wut.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct WiiUConsoleOTP WiiUConsoleOTP;
|
||||||
|
typedef struct OTPWiiBank OTPWiiBank;
|
||||||
|
typedef struct OTPWiiUBank OTPWiiUBank;
|
||||||
|
typedef struct OTPWiiUNGBank OTPWiiUNGBank;
|
||||||
|
typedef struct OTPWiiUCertBank OTPWiiUCertBank;
|
||||||
|
typedef struct OTPWiiCertBank OTPWiiCertBank;
|
||||||
|
typedef struct OTPMiscBank OTPMiscBank;
|
||||||
|
|
||||||
|
typedef uint32_t OTPJTAGStatus;
|
||||||
|
typedef uint32_t OTPSecurityLevel;
|
||||||
|
|
||||||
|
typedef enum OTPSecurityLevelFlags {
|
||||||
|
SECURITY_FLAG_UNKNOWN = 0x40000000, // Unknown, causes error in boot0
|
||||||
|
SECURITY_FLAG_CONSOLE_PROGRAMMED = 0x80000000, // Console type has been programmed
|
||||||
|
SECURITY_FLAG_USE_DEBUG_KEY_IMAGE = 0x08000000, // Use first RSA key and debug ancast images in boot0
|
||||||
|
SECURITY_FLAG_USE_RETAIL_KEY_IMAGE = 0x10000000 // Use second RSA key and retail ancast images in boot0
|
||||||
|
} OTPSecurityLevelFlags;
|
||||||
|
|
||||||
|
typedef enum OTPIOStrength {
|
||||||
|
IO_HW_IOSTRCTRL0 = 0x00008000,
|
||||||
|
IO_HW_IOSTRCTRL1_3 = 0x00002000,
|
||||||
|
IO_HW_IOSTRCTRL1_2 = 0x00000800,
|
||||||
|
IO_HW_IOSTRCTRL1_1 = 0x00000080,
|
||||||
|
IO_HW_IOSTRCTRL1_0 = 0x00000008,
|
||||||
|
IO_NONE = 0x00000000
|
||||||
|
} OTPIOStrength;
|
||||||
|
|
||||||
|
typedef enum OTPPulseLength {
|
||||||
|
PULSE_BOOT0 = 0x0000002F,
|
||||||
|
PULSE_NONE = 0x00000000
|
||||||
|
} OTPPulseLength;
|
||||||
|
|
||||||
|
typedef enum OTPJTAGMask {
|
||||||
|
JTAG_MASK_DISABLED = 0x80
|
||||||
|
} OTPJTAGMask;
|
||||||
|
|
||||||
|
struct OTPWiiBank {
|
||||||
|
uint8_t boot1SHA1Hash[0x14];
|
||||||
|
uint8_t commonKey[0x10];
|
||||||
|
uint32_t ngId;
|
||||||
|
uint8_t ngPrivateKey[0x1C];
|
||||||
|
uint8_t nandHMAC[0x14];
|
||||||
|
uint8_t nandKey[0x10];
|
||||||
|
uint8_t rngKey[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x08);
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPWiiBank, 0x80);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x00, boot1SHA1Hash);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x14, commonKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x24, ngId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x28, ngPrivateKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x44, nandHMAC);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x58, nandKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiBank, 0x68, rngKey);
|
||||||
|
|
||||||
|
struct OTPWiiUBank {
|
||||||
|
OTPSecurityLevel securityLevel;
|
||||||
|
OTPIOStrength ioStrength;
|
||||||
|
OTPPulseLength pulseLength;
|
||||||
|
uint32_t signature;
|
||||||
|
uint8_t starbuckAncastKey[0x10];
|
||||||
|
uint8_t seepromKey[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
uint8_t vWiiCommonKey[0x10];
|
||||||
|
uint8_t wiiUCommonKey[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
uint8_t sslRSAKey[0x10];
|
||||||
|
uint8_t usbStorageSeedsKey[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
uint8_t xorKey[0x10];
|
||||||
|
uint8_t rngKey[0x10];
|
||||||
|
uint8_t slcKey[0x10];
|
||||||
|
uint8_t mlcKey[0x10];
|
||||||
|
uint8_t sshdKey[0x10];
|
||||||
|
uint8_t drhWLAN[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x30);
|
||||||
|
uint8_t slcHmac[0x14];
|
||||||
|
WUT_UNKNOWN_BYTES(0x0C);
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPWiiUBank, 0x180);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x00, securityLevel);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x04, ioStrength);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x08, pulseLength);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x10, starbuckAncastKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x20, seepromKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x50, vWiiCommonKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x60, wiiUCommonKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0xA0, sslRSAKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0xB0, usbStorageSeedsKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0xD0, xorKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0xE0, rngKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0xF0, slcKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x100, mlcKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x110, sshdKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x120, drhWLAN);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUBank, 0x160, slcHmac);
|
||||||
|
|
||||||
|
struct OTPWiiUNGBank {
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
WUT_UNKNOWN_BYTES(0x0C);
|
||||||
|
uint32_t ngId;
|
||||||
|
uint8_t ngPrivateKey[0x20];
|
||||||
|
uint8_t privateNSSDeviceCertKey[0x20];
|
||||||
|
uint8_t otpRNGSeed[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPWiiUNGBank, 0x80);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUNGBank, 0x1C, ngId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUNGBank, 0x20, ngPrivateKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUNGBank, 0x40, privateNSSDeviceCertKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUNGBank, 0x60, otpRNGSeed);
|
||||||
|
|
||||||
|
struct OTPWiiUCertBank {
|
||||||
|
uint32_t rootCertMSId;
|
||||||
|
uint32_t rootCertCAId;
|
||||||
|
uint32_t rootCertNGKeyId;
|
||||||
|
uint8_t rootCertNGSignature[0x3C];
|
||||||
|
WUT_UNKNOWN_BYTES(0x18);
|
||||||
|
WUT_UNKNOWN_BYTES(0x20);
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPWiiUCertBank, 0x80);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUCertBank, 0x00, rootCertMSId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUCertBank, 0x04, rootCertCAId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUCertBank, 0x08, rootCertNGKeyId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiUCertBank, 0x0C, rootCertNGSignature);
|
||||||
|
|
||||||
|
struct OTPWiiCertBank {
|
||||||
|
uint32_t rootCertMSId;
|
||||||
|
uint32_t rootCertCAId;
|
||||||
|
uint32_t rootCertNGKeyId;
|
||||||
|
uint8_t rootCertNGSignature[0x3C];
|
||||||
|
uint8_t koreanKey[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x08);
|
||||||
|
uint8_t privateNSSDeviceCertKey[0x20];
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPWiiCertBank, 0x80);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x00, rootCertMSId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x04, rootCertCAId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x08, rootCertNGKeyId);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x0C, rootCertNGSignature);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x48, koreanKey);
|
||||||
|
WUT_CHECK_OFFSET(OTPWiiCertBank, 0x60, privateNSSDeviceCertKey);
|
||||||
|
|
||||||
|
struct OTPMiscBank {
|
||||||
|
WUT_UNKNOWN_BYTES(0x20);
|
||||||
|
uint8_t boot1Key_protected[0x10];
|
||||||
|
WUT_UNKNOWN_BYTES(0x10);
|
||||||
|
WUT_UNKNOWN_BYTES(0x20);
|
||||||
|
WUT_UNKNOWN_BYTES(0x04);
|
||||||
|
uint32_t otpVersionAndRevision;
|
||||||
|
uint64_t otpDateCode;
|
||||||
|
char otpVersionName[0x08];
|
||||||
|
WUT_UNKNOWN_BYTES(0x04);
|
||||||
|
OTPJTAGStatus jtagStatus;
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(OTPMiscBank, 0x80);
|
||||||
|
WUT_CHECK_OFFSET(OTPMiscBank, 0x20, boot1Key_protected);
|
||||||
|
WUT_CHECK_OFFSET(OTPMiscBank, 0x64, otpVersionAndRevision);
|
||||||
|
WUT_CHECK_OFFSET(OTPMiscBank, 0x68, otpDateCode);
|
||||||
|
WUT_CHECK_OFFSET(OTPMiscBank, 0x70, otpVersionName);
|
||||||
|
WUT_CHECK_OFFSET(OTPMiscBank, 0x7C, jtagStatus);
|
||||||
|
|
||||||
|
struct WiiUConsoleOTP {
|
||||||
|
OTPWiiBank wiiBank;
|
||||||
|
OTPWiiUBank wiiUBank;
|
||||||
|
OTPWiiUNGBank wiiUNGBank;
|
||||||
|
OTPWiiUCertBank wiiUCertBank;
|
||||||
|
OTPWiiCertBank wiiCertBank;
|
||||||
|
OTPMiscBank miscBank;
|
||||||
|
};
|
||||||
|
WUT_CHECK_SIZE(WiiUConsoleOTP, 0x400);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x00, wiiBank);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x80, wiiUBank);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x200, wiiUNGBank);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x280, wiiUCertBank);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x300, wiiCertBank);
|
||||||
|
WUT_CHECK_OFFSET(WiiUConsoleOTP, 0x380, miscBank);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
23
source/logger.h
Normal file
23
source/logger.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <coreinit/debug.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#define __FILENAME__ ({ \
|
||||||
|
const char *__filename = __FILE__; \
|
||||||
|
const char *__pos = strrchr(__filename, '/'); \
|
||||||
|
if (!__pos) __pos = strrchr(__filename, '\\'); \
|
||||||
|
__pos ? __pos + 1 : __filename; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define LOG_APP_TYPE "L"
|
||||||
|
#define LOG_APP_NAME "libmocha"
|
||||||
|
|
||||||
|
#define LOG_EX(FILENAME, FUNCTION, LINE, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) \
|
||||||
|
do { \
|
||||||
|
LOG_FUNC("[(%s)%18s][%23s]%30s@L%04d: " LOG_LEVEL "" FMT "" LINE_END, LOG_APP_TYPE, LOG_APP_NAME, FILENAME, FUNCTION, LINE, ##ARGS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LOG_EX_DEFAULT(LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) LOG_EX(__FILENAME__, __FUNCTION__, __LINE__, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ##ARGS)
|
||||||
|
|
||||||
|
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
|
||||||
|
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##WARNING## ", "\n", FMT, ##ARGS)
|
176
source/utils.cpp
176
source/utils.cpp
@ -1,21 +1,48 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "mocha/commands.h"
|
#include "mocha/commands.h"
|
||||||
#include "mocha/mocha.h"
|
#include "mocha/mocha.h"
|
||||||
|
#include "mocha/otp.h"
|
||||||
#include <coreinit/ios.h>
|
#include <coreinit/ios.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <malloc.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sysapp/launch.h>
|
#include <sysapp/launch.h>
|
||||||
#include <sysapp/title.h>
|
#include <sysapp/title.h>
|
||||||
|
|
||||||
|
int iosuhaxHandle = -1;
|
||||||
int mochaInitDone = 0;
|
int mochaInitDone = 0;
|
||||||
uint32_t mochaApiVersion = 0;
|
uint32_t mochaApiVersion = 0;
|
||||||
|
|
||||||
|
#define IOCTL_MEM_WRITE 0x00
|
||||||
|
#define IOCTL_MEM_READ 0x01
|
||||||
|
#define IOCTL_SVC 0x02
|
||||||
|
#define IOCTL_MEMCPY 0x04
|
||||||
|
#define IOCTL_REPEATED_WRITE 0x05
|
||||||
|
#define IOCTL_KERN_READ32 0x06
|
||||||
|
#define IOCTL_KERN_WRITE32 0x07
|
||||||
|
#define IOCTL_READ_OTP 0x08
|
||||||
MochaUtilsStatus Mocha_InitLibrary() {
|
MochaUtilsStatus Mocha_InitLibrary() {
|
||||||
|
if (mochaInitDone) {
|
||||||
|
return MOCHA_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iosuhaxHandle < 0) {
|
||||||
|
int haxHandle = IOS_Open((char *) ("/dev/iosuhax"), static_cast<IOSOpenMode>(0));
|
||||||
|
if (haxHandle < 0) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to open /dev/iosuhax");
|
||||||
|
return MOCHA_RESULT_UNSUPPORTED_COMMAND;
|
||||||
|
}
|
||||||
|
iosuhaxHandle = haxHandle;
|
||||||
|
}
|
||||||
|
|
||||||
mochaInitDone = 1;
|
mochaInitDone = 1;
|
||||||
mochaApiVersion = 0;
|
mochaApiVersion = 0;
|
||||||
uint32_t version = 0;
|
uint32_t version = 0;
|
||||||
if (Mocha_CheckAPIVersion(&version) != MOCHA_RESULT_SUCCESS) {
|
if (Mocha_CheckAPIVersion(&version) != MOCHA_RESULT_SUCCESS) {
|
||||||
return MOCHA_RESULT_SUCCESS;
|
IOS_Close(iosuhaxHandle);
|
||||||
|
iosuhaxHandle = -1;
|
||||||
|
return MOCHA_RESULT_UNSUPPORTED_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
mochaApiVersion = version;
|
mochaApiVersion = version;
|
||||||
@ -23,10 +50,14 @@ MochaUtilsStatus Mocha_InitLibrary() {
|
|||||||
return MOCHA_RESULT_SUCCESS;
|
return MOCHA_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
MochaUtilsStatus Mocha_DeInitLibrary() {
|
MochaUtilsStatus Mocha_DeinitLibrary() {
|
||||||
mochaInitDone = 0;
|
mochaInitDone = 0;
|
||||||
mochaApiVersion = 0;
|
mochaApiVersion = 0;
|
||||||
|
|
||||||
|
if (iosuhaxHandle >= 0) {
|
||||||
|
IOS_Close(iosuhaxHandle);
|
||||||
|
}
|
||||||
|
|
||||||
return MOCHA_RESULT_SUCCESS;
|
return MOCHA_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,11 +68,11 @@ MochaUtilsStatus Mocha_CheckAPIVersion(uint32_t *version) {
|
|||||||
MochaUtilsStatus res = MOCHA_RESULT_UNKNOWN_ERROR;
|
MochaUtilsStatus res = MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
int mcpFd = IOS_Open("/dev/mcp", IOS_OPEN_READ);
|
int mcpFd = IOS_Open("/dev/mcp", IOS_OPEN_READ);
|
||||||
if (mcpFd >= 0) {
|
if (mcpFd >= 0) {
|
||||||
ALIGN_0x40 uint32_t io_buffer[0x100 / 4];
|
ALIGN_0x40 uint32_t io_buffer[0x40 / 4];
|
||||||
io_buffer[0] = IPC_CUSTOM_GET_MOCHA_API_VERSION;
|
io_buffer[0] = IPC_CUSTOM_GET_MOCHA_API_VERSION;
|
||||||
|
|
||||||
if (IOS_Ioctl(mcpFd, 100, io_buffer, 4, io_buffer, 4) == IOS_ERROR_OK) {
|
if (IOS_Ioctl(mcpFd, 100, io_buffer, 4, io_buffer, 8) == IOS_ERROR_OK && io_buffer[0] == 0xCAFEBABE) {
|
||||||
*version = io_buffer[0];
|
*version = io_buffer[1];
|
||||||
res = MOCHA_RESULT_SUCCESS;
|
res = MOCHA_RESULT_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
res = MOCHA_RESULT_UNSUPPORTED_API_VERSION;
|
res = MOCHA_RESULT_UNSUPPORTED_API_VERSION;
|
||||||
@ -55,6 +86,138 @@ MochaUtilsStatus Mocha_CheckAPIVersion(uint32_t *version) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelMemcpy(uint32_t dst, uint32_t src, uint32_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
return MOCHA_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (dst == 0 || src == 0) {
|
||||||
|
return MOCHA_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (!mochaInitDone || iosuhaxHandle < 0) {
|
||||||
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIGN_0x40 uint32_t io_buf[0x40 >> 2];
|
||||||
|
io_buf[0] = dst;
|
||||||
|
io_buf[1] = src;
|
||||||
|
io_buf[2] = size;
|
||||||
|
|
||||||
|
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEMCPY, io_buf, 3 * sizeof(uint32_t), nullptr, 0);
|
||||||
|
return res >= 0 ? MOCHA_RESULT_SUCCESS : MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelWrite(uint32_t address, const uint8_t *buffer, uint32_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
return MOCHA_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (address == 0 || buffer == nullptr) {
|
||||||
|
return MOCHA_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (!mochaInitDone || iosuhaxHandle < 0) {
|
||||||
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *io_buf = (uint32_t *) memalign(0x40, ROUNDUP(size + 4, 0x40));
|
||||||
|
if (!io_buf) {
|
||||||
|
return MOCHA_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_buf[0] = address;
|
||||||
|
memcpy(io_buf + 1, buffer, size);
|
||||||
|
|
||||||
|
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_WRITE, io_buf, size + 4, nullptr, 0);
|
||||||
|
|
||||||
|
free(io_buf);
|
||||||
|
return res >= 0 ? MOCHA_RESULT_SUCCESS : MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelRead(uint32_t address, uint8_t *out_buffer, uint32_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
return MOCHA_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (address == 0 || out_buffer == nullptr) {
|
||||||
|
return MOCHA_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (!mochaInitDone || iosuhaxHandle < 0) {
|
||||||
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIGN_0x40 uint32_t io_buf[0x40 >> 2];
|
||||||
|
io_buf[0] = address;
|
||||||
|
|
||||||
|
void *tmp_buf = nullptr;
|
||||||
|
|
||||||
|
if (((uintptr_t) out_buffer & 0x3F) || (size & 0x3F)) {
|
||||||
|
tmp_buf = (uint32_t *) memalign(0x40, ROUNDUP(size, 0x40));
|
||||||
|
if (!tmp_buf) {
|
||||||
|
return MOCHA_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_MEM_READ, io_buf, sizeof(address), tmp_buf ? tmp_buf : out_buffer, size);
|
||||||
|
|
||||||
|
if (res >= 0 && tmp_buf) {
|
||||||
|
memcpy(out_buffer, tmp_buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp_buf);
|
||||||
|
return res >= 0 ? MOCHA_RESULT_SUCCESS : MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelWrite32(uint32_t address, uint32_t value) {
|
||||||
|
return Mocha_IOSUKernelWrite(address, reinterpret_cast<const uint8_t *>(&value), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_IOSUKernelRead32(uint32_t address, uint32_t *out_buffer) {
|
||||||
|
return Mocha_IOSUKernelRead(address, reinterpret_cast<uint8_t *>(out_buffer), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
MochaUtilsStatus Mocha_ReadOTP(WiiUConsoleOTP *out_buffer) {
|
||||||
|
if (out_buffer == nullptr) {
|
||||||
|
return MOCHA_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (!mochaInitDone || iosuhaxHandle < 0) {
|
||||||
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIGN_0x40 uint32_t io_buf[0x400 >> 2];
|
||||||
|
|
||||||
|
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_READ_OTP, nullptr, 0, io_buf, 0x400);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
return MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
memcpy(out_buffer, io_buf, 0x400);
|
||||||
|
|
||||||
|
return MOCHA_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mocha_IOSUCallSVC(uint32_t svc_id, uint32_t *args, uint32_t arg_cnt, int32_t *outResult) {
|
||||||
|
if (!mochaInitDone || iosuhaxHandle < 0) {
|
||||||
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIGN_0x40 uint32_t arguments[0x40 >> 2];
|
||||||
|
arguments[0] = svc_id;
|
||||||
|
|
||||||
|
if (args && arg_cnt) {
|
||||||
|
if (arg_cnt > 8) {
|
||||||
|
arg_cnt = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(arguments + 1, args, arg_cnt * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIGN_0x40 int result[0x40 >> 2];
|
||||||
|
int res = IOS_Ioctl(iosuhaxHandle, IOCTL_SVC, arguments, (1 + arg_cnt) * 4, result, 4);
|
||||||
|
|
||||||
|
if (res >= 0 && outResult) {
|
||||||
|
*outResult = *result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res >= 0 ? MOCHA_RESULT_SUCCESS : MOCHA_RESULT_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
MochaUtilsStatus Mocha_GetEnvironmentPath(char *environmentPathBuffer, uint32_t bufferLen) {
|
MochaUtilsStatus Mocha_GetEnvironmentPath(char *environmentPathBuffer, uint32_t bufferLen) {
|
||||||
if (!mochaInitDone) {
|
if (!mochaInitDone) {
|
||||||
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
return MOCHA_RESULT_LIB_UNINITIALIZED;
|
||||||
@ -73,7 +236,8 @@ MochaUtilsStatus Mocha_GetEnvironmentPath(char *environmentPathBuffer, uint32_t
|
|||||||
|
|
||||||
if (IOS_Ioctl(mcpFd, 100, io_buffer, 4, io_buffer, 0x100) == IOS_ERROR_OK) {
|
if (IOS_Ioctl(mcpFd, 100, io_buffer, 4, io_buffer, 0x100) == IOS_ERROR_OK) {
|
||||||
memcpy(environmentPathBuffer, reinterpret_cast<const char *>(io_buffer), 0xFF);
|
memcpy(environmentPathBuffer, reinterpret_cast<const char *>(io_buffer), 0xFF);
|
||||||
res = MOCHA_RESULT_SUCCESS;
|
environmentPathBuffer[bufferLen - 1] = 0;
|
||||||
|
res = MOCHA_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
IOS_Close(mcpFd);
|
IOS_Close(mcpFd);
|
||||||
|
Loading…
Reference in New Issue
Block a user