Impressive. Yesterday I also worked out routines at 0x00000360 and 0x000002B4. Apparently the fix in Chinese version is in routine 0x00000360 (OK it may be in other places as well but I don't know).
But I would never figure out how it works coz I just don't know existence of rebootex which hides itself in data segment.
May I ask how you noticed rebootex.bin and found where to locate it?
I was really depressed when yesterday I found that 0x00000360 just call some random functions and place value in arbitrary addresses, which just doesn't make sense to me. But now I feel much better coz your code explains some of the mysterious functions.
And besides, could you please try to compile it till the first jalr in main, and see how it works?
That is, with this code, how far does it go (see below). Coz I'm confused why my code always stops at func_unknown1(0x08080000);
Is it because I use PSP_MODULE_INFO("hen", 0, 1, 0); while you use PSP_MODULE_INFO("hen", 0, 1, 1);
Or it could be some other issue, like wrong Makefile?
- Code: Select all
int main() // sub_004B0
pspDebugScreenInit(); // sub_00F4C
memset(&htmlParam, 0, sizeof(pspUtilityHtmlViewerParam)); // sub_01020
htmlParam.base.size = sizeof(pspUtilityHtmlViewerParam); // = 0x000000A8
htmlParam.base.accessThread = 0x13;
SceUID loadResult = sceUtilityHtmlViewerInitStart(&htmlParam); //sceUtility_CDC3AA41
if (loadResult < 0)
pspDebugScreenPrintf("Error: %s.", "Could not load module");
// Search through all of user memory to find the values 0x56656373 0x56486873 = "sceVshHV" (from "sceVshHVUtility_Module")
// Note: this performs the same function, it is not transcribed verbatim
unsigned int* address_low = (unsigned int*)0x08800000;
unsigned int* address_high = (unsigned int*)0x08800004;
while (address_high < (unsigned int*)0x0A000000)
if ((*address_low == 0x56656373) && (*address_high == 0x56486873))
// String not found
if (address_high == (unsigned int*)0x0A000000)
pspDebugScreenPrintf("Error: %s.", "Could not find module address"); // sub_00F6C(0x0000B428, 0x0000B464)
// Zero out a good chunk of the lower end of user memory
memset((void*)0x08800000, 0, 0x100000); // sub_01020
// Make function pointer from address_low and invalidate the cache
int (*func_unknown1)(int) = (void*)((unsigned int)address_low - 0x288);
// Call the function
henClearCache(); // sub_00494