2020-04-15 06:00:48 +09:00
|
|
|
/*Credits to riidefi for hook code, cache asm, and teaching me C*/
|
2020-04-15 05:48:58 +09:00
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
#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))
|
2020-04-15 05:48:58 +09:00
|
|
|
|
|
|
|
typedef unsigned int u32;
|
|
|
|
typedef unsigned short u16;
|
|
|
|
typedef unsigned char u8;
|
|
|
|
typedef int BOOL;
|
|
|
|
typedef u32 unk32;
|
2020-04-15 08:10:46 +09:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
FALSE,
|
|
|
|
TRUE
|
|
|
|
};
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
NULL
|
|
|
|
};
|
2020-04-15 05:48:58 +09:00
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
struct Info
|
|
|
|
{
|
2020-04-15 06:02:48 +09:00
|
|
|
u32 allocsize;
|
|
|
|
u32 _loaderSize;
|
|
|
|
u32 _loaderFullSize;
|
2020-04-15 08:10:46 +09:00
|
|
|
struct CodeList *_codelistPointer;
|
2020-04-15 05:48:58 +09:00
|
|
|
u32 _wiiVIHook[4];
|
|
|
|
u32 _gcnVIHook[8];
|
|
|
|
};
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
struct CodeList
|
|
|
|
{
|
2020-04-15 05:48:58 +09:00
|
|
|
u16 mBaseASM;
|
|
|
|
u16 mUpperBase;
|
|
|
|
u16 mOffsetASM;
|
|
|
|
u16 mLowerOffset;
|
|
|
|
};
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
struct DiscInfo
|
|
|
|
{
|
2020-04-15 06:00:48 +09:00
|
|
|
u8 mDiscID;
|
|
|
|
u16 mGameCode;
|
|
|
|
u8 mRegionCode;
|
|
|
|
u16 mMakerCode;
|
|
|
|
u8 mDiscNumber;
|
|
|
|
u8 mDiscVersion;
|
|
|
|
u8 mAudioStreaming;
|
|
|
|
u8 mStreamBufferSize;
|
|
|
|
u8 mUnknown[12];
|
|
|
|
u32 mWiiMagic;
|
|
|
|
u32 mGCNMagic;
|
|
|
|
u32 mUnknown2[2];
|
|
|
|
u32 mRAMSize;
|
|
|
|
u32 mUnknown3[2];
|
2020-04-15 08:10:46 +09:00
|
|
|
u32 *mHeapPointer;
|
2020-04-15 06:00:48 +09:00
|
|
|
u32 mHeapMirror;
|
|
|
|
u32 mFstSize;
|
|
|
|
u32 mData[(0x3110 - 0x40) / 4];
|
|
|
|
u32 mWiiHeap;
|
2020-04-15 05:48:58 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Info gInfo = {
|
2020-04-15 08:10:46 +09:00
|
|
|
.allocsize = 0,
|
|
|
|
._loaderSize = 0,
|
|
|
|
._loaderFullSize = 0,
|
|
|
|
._codelistPointer = (struct CodeList *)0x800018F8,
|
|
|
|
._wiiVIHook = {0x7CE33B78, 0x38870034, 0x38A70038, 0x38C7004C},
|
|
|
|
._gcnVIHook = {0x7C030034, 0x38830020, 0x5485083C, 0x7C7F2A14, 0xA0030000, 0x7C7D2A14, 0x20A4003F, 0xB0030000},
|
2020-04-15 05:48:58 +09:00
|
|
|
};
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
static inline void flushAddr(void *addr)
|
2020-04-15 05:48:58 +09:00
|
|
|
{
|
2020-04-15 08:10:46 +09:00
|
|
|
dcbf(addr);
|
|
|
|
icbi(addr);
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
static inline void directWrite(u32 *addr, u32 ptr)
|
|
|
|
{
|
|
|
|
addr[0] = ptr;
|
|
|
|
flushAddr(addr);
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
static inline void directBranchEx(void *addr, void *ptr, BOOL link)
|
|
|
|
{
|
|
|
|
directWrite((u32 *)(addr), ((((u32)(ptr) - (u32)(addr)) & 0x3ffffff) | 0x48000000 | !!link));
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
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;
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
void hookFunction(u32 *start, u32 hookInstruction, u32 hookTo)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
while (start[i] != hookInstruction)
|
|
|
|
{
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
directBranchEx((u32 *)(&start[i]), (void *)(hookTo), FALSE);
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
static inline void overwriteValue(u32 *addr, u32 newValue)
|
|
|
|
{
|
2020-04-15 05:48:58 +09:00
|
|
|
addr[0] = newValue;
|
|
|
|
flushAddr(&addr[0]);
|
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-15 05:48:58 +09:00
|
|
|
}
|
|
|
|
|
2020-04-15 08:10:46 +09:00
|
|
|
int main()
|
|
|
|
{
|
|
|
|
struct DiscInfo *baseAddress = (struct DiscInfo *)0x80000000;
|
|
|
|
if (baseAddress->mWiiMagic || baseAddress->mGCNMagic)
|
|
|
|
{
|
|
|
|
initMods(baseAddress);
|
|
|
|
(*_codeHandler)();
|
2020-04-15 06:02:48 +09:00
|
|
|
}
|
2020-04-15 08:10:46 +09:00
|
|
|
(*_init_registers)();
|
2020-04-15 06:00:48 +09:00
|
|
|
}
|