diff --git a/loader.c b/loader.c index eec560d..d0d19d5 100644 --- a/loader.c +++ b/loader.c @@ -1,34 +1,44 @@ /*Credits to riidefi for hook code, cache asm, and teaching me C*/ -#define dcbst(_val) asm volatile("dcbst 0, %0" : : "r" (_val)) -#define dcbf(_val) asm volatile("dcbf 0, %0" : : "r" (_val)) -#define icbi(_val) asm volatile("icbi 0, %0" : : "r" (_val)) +#define dcbst(_val) asm volatile("dcbst 0, %0" : : "r"(_val)) +#define dcbf(_val) asm volatile("dcbf 0, %0" : : "r"(_val)) +#define icbi(_val) asm volatile("icbi 0, %0" : : "r"(_val)) typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; typedef int BOOL; typedef u32 unk32; -enum { FALSE, TRUE }; -enum { NULL }; +enum +{ + FALSE, + TRUE +}; +enum +{ + NULL +}; -struct Info { +struct Info +{ u32 allocsize; u32 _loaderSize; u32 _loaderFullSize; - struct CodeList* _codelistPointer; + struct CodeList *_codelistPointer; u32 _wiiVIHook[4]; u32 _gcnVIHook[8]; }; -struct CodeList { +struct CodeList +{ u16 mBaseASM; u16 mUpperBase; u16 mOffsetASM; u16 mLowerOffset; }; -struct DiscInfo { +struct DiscInfo +{ u8 mDiscID; u16 mGameCode; u8 mRegionCode; @@ -43,7 +53,7 @@ struct DiscInfo { u32 mUnknown2[2]; u32 mRAMSize; u32 mUnknown3[2]; - u32* mHeapPointer; + u32 *mHeapPointer; u32 mHeapMirror; u32 mFstSize; u32 mData[(0x3110 - 0x40) / 4]; @@ -51,109 +61,125 @@ struct DiscInfo { }; struct Info gInfo = { - .allocsize = 0, //Set to ASCII HEAP in bin file after compiling if using main.py - ._loaderSize = 0, //Set to ASCII LSIZ in bin file after compiling if using main.py - ._loaderFullSize = 0, //Set to ASCII FSIZ in bin file after compiling if using main.py - ._codelistPointer = (struct CodeList*)0x800018F8, - ._wiiVIHook = {0x7CE33B78, 0x38870034, - 0x38A70038, 0x38C7004C}, - ._gcnVIHook = {0x7C030034, 0x38830020, - 0x5485083C, 0x7C7F2A14, - 0xA0030000, 0x7C7D2A14, - 0x20A4003F, 0xB0030000}, + .allocsize = 0, + ._loaderSize = 0, + ._loaderFullSize = 0, + ._codelistPointer = (struct CodeList *)0x800018F8, + ._wiiVIHook = {0x7CE33B78, 0x38870034, 0x38A70038, 0x38C7004C}, + ._gcnVIHook = {0x7C030034, 0x38830020, 0x5485083C, 0x7C7F2A14, 0xA0030000, 0x7C7D2A14, 0x20A4003F, 0xB0030000}, }; -static inline void flushAddr(void* addr) +static inline void flushAddr(void *addr) { - dcbf(addr); - icbi(addr); + dcbf(addr); + icbi(addr); } -static inline void directWrite(u32* addr, u32 ptr) { - addr[0] = ptr; - flushAddr(addr); +static inline void directWrite(u32 *addr, u32 ptr) +{ + addr[0] = ptr; + flushAddr(addr); } -static inline void directBranchEx(void* addr, void* ptr, BOOL lk) { - directWrite((u32*)(addr), - ((((u32)(ptr) - (u32)(addr)) & 0x3ffffff) | 0x48000000 | !!lk)); +static inline void directBranchEx(void *addr, void *ptr, BOOL link) +{ + directWrite((u32 *)(addr), ((((u32)(ptr) - (u32)(addr)) & 0x3ffffff) | 0x48000000 | !!link)); } -void (*_init_registers)(void) = &gInfo; //Set to game entry address. ASCII HEAP in bin file after compiling if using main.py -void (*_codeHandler)(void) = &gInfo; //Set to codehandler entry address. Set to 800018A8 in bin file after compiling +void (*_init_registers)(void) = &gInfo; +void (*_codeHandler)(void) = &gInfo; -static inline u32* findFunction(u32* hookData, u32* start, u32 end, u32 arrayLength) { - u32 index = 0; - for (u32 i = 0; (u32)&start[i] < end; ++i) { - if (start[i] == hookData[index]) index = index + 1; - else index = 0; - if (index >= (arrayLength - 1)) { - if ((u32)&start[i] < &gInfo || (u32)&start[i] > (u32)&gInfo + 0x100){ - return &start[i]; - } - } - } - return NULL; +static inline u32 *findFunction(u32 *hookData, u32 *start, u32 end, u32 arrayLength) +{ + u32 index = 0; + for (u32 i = 0; (u32)&start[i] < end; ++i) + { + if (start[i] == hookData[index]) + index = index + 1; + else + index = 0; + if (index >= (arrayLength - 1)) + { + if ((u32)&start[i] < &gInfo || (u32)&start[i] > (u32)&gInfo + 0x100) + { + return &start[i]; + } + } + } + return NULL; } -void hookFunction(u32* start, u32 hookInstruction, u32 hookTo) { - int i = 0; - while (start[i] != hookInstruction) { - ++i; - } - directBranchEx((u32*)(&start[i]), (void*)(hookTo), FALSE); +void hookFunction(u32 *start, u32 hookInstruction, u32 hookTo) +{ + int i = 0; + while (start[i] != hookInstruction) + { + ++i; + } + directBranchEx((u32 *)(&start[i]), (void *)(hookTo), FALSE); } -static inline void overwriteValue(u32* addr, u32 newValue) { +static inline void overwriteValue(u32 *addr, u32 newValue) +{ addr[0] = newValue; flushAddr(&addr[0]); } -void initMods(struct DiscInfo* baseAddress) { +void initMods(struct DiscInfo *baseAddress) +{ + struct Info *infoPointer = &gInfo; + const u32 *geckoPointerInit = (u32 *)(u32)baseAddress + 0x18F8; + u32 sizeDiff = infoPointer->_loaderFullSize - infoPointer->_loaderSize; + const u32 *sourcePointer = (u32 *)(infoPointer); - struct Info* infoPointer = &gInfo; - const u32* geckoPointerInit = (u32*)(u32)baseAddress + 0x18F8; - u32 sizeDiff = infoPointer->_loaderFullSize - infoPointer->_loaderSize; - const u32* sourcePointer = (u32*)(infoPointer); + if (infoPointer->_codelistPointer) + { + if (baseAddress->mWiiMagic) + { + baseAddress->mHeapPointer = (u32)baseAddress->mWiiHeap - infoPointer->allocsize; + baseAddress->mWiiHeap = (u32)baseAddress->mHeapPointer; + } + else if (baseAddress->mGCNMagic) + { + baseAddress->mHeapPointer = (u32)baseAddress->mHeapPointer - infoPointer->allocsize; + } - if (infoPointer->_codelistPointer) { - if (baseAddress->mWiiMagic) { - baseAddress->mHeapPointer = (u32)baseAddress->mWiiHeap - infoPointer->allocsize; - baseAddress->mWiiHeap = (u32)baseAddress->mHeapPointer; - } - else if(baseAddress->mGCNMagic) { - baseAddress->mHeapPointer = (u32)baseAddress->mHeapPointer - infoPointer->allocsize; - } + if (infoPointer->_loaderFullSize > 0 && infoPointer->_loaderSize > 0) + { + while (sizeDiff > 0) + { + sizeDiff = sizeDiff - 4; + baseAddress->mHeapPointer[sizeDiff / 4] = sourcePointer[sizeDiff / 4]; + } + infoPointer->_codelistPointer->mUpperBase = ((u32)baseAddress->mHeapPointer >> 16) & 0xFFFF; + infoPointer->_codelistPointer->mLowerOffset = (u32)(baseAddress->mHeapPointer) & 0xFFFF; + flushAddr(&infoPointer->_codelistPointer->mUpperBase); + flushAddr(&infoPointer->_codelistPointer->mLowerOffset); - if (infoPointer->_loaderFullSize > 0 && infoPointer->_loaderSize > 0) { - while (sizeDiff > 0) { - sizeDiff = sizeDiff - 4; - baseAddress->mHeapPointer[sizeDiff / 4] = sourcePointer[sizeDiff / 4]; - } - infoPointer->_codelistPointer->mUpperBase = ((u32)baseAddress->mHeapPointer >> 16) & 0xFFFF; - infoPointer->_codelistPointer->mLowerOffset = (u32)(baseAddress->mHeapPointer) & 0xFFFF; - flushAddr(&infoPointer->_codelistPointer->mUpperBase); - flushAddr(&infoPointer->_codelistPointer->mLowerOffset); - - u32* functionAddr; - if (baseAddress->mWiiMagic) { - functionAddr = findFunction((u32*)infoPointer->_wiiVIHook, (u32*)baseAddress, 0x817FFF00, 0x4); - } - else { - functionAddr = findFunction((u32*)infoPointer->_gcnVIHook, (u32*)baseAddress, 0x817FFF00, 0x8); - } - if (functionAddr) { - hookFunction(functionAddr, 0x4E800020, 0x800018A8); - } - } - } -} - -int main() { - struct DiscInfo* baseAddress = (struct DiscInfo*)0x80000000; - if (baseAddress->mWiiMagic || baseAddress->mGCNMagic) { - initMods(baseAddress); - (*_codeHandler)(); //Call codehandler + u32 *functionAddr; + if (baseAddress->mWiiMagic) + { + functionAddr = findFunction((u32 *)infoPointer->_wiiVIHook, (u32 *)baseAddress, 0x817FFF00, 0x4); + } + else + { + functionAddr = findFunction((u32 *)infoPointer->_gcnVIHook, (u32 *)baseAddress, 0x817FFF00, 0x8); + } + if (functionAddr) + { + hookFunction(functionAddr, 0x4E800020, 0x800018A8); + } + } } - (*_init_registers)(); //Call game entry "_init_registers" +} + +int main() +{ + struct DiscInfo *baseAddress = (struct DiscInfo *)0x80000000; + if (baseAddress->mWiiMagic || baseAddress->mGCNMagic) + { + initMods(baseAddress); + (*_codeHandler)(); + } + (*_init_registers)(); }