int control_module_threads(SceUID module_id, int pause) { // get an array of all threads int thread_count; if (sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, NULL, 0, &thread_count) < 0) return 0; if (thread_count < 1) return 0; SceUID thread_id[thread_count]; if (sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Thread, thread_id, thread_count, NULL) < 0) return 0; int i; SceModule* module; SceKernelThreadInfo thread_info; thread_info.size = sizeof(SceKernelThreadInfo); for (i = 0; i < thread_count; i++) { // determine if a thread is from the game if (sceKernelReferThreadStatus(thread_id[i], &thread_info)) continue; module = sceKernelFindModuleByAddress((unsigned int) thread_info.entry); if (module && module->modid == module_id) { // pause or resume the thread if (pause) sceKernelSuspendThread(thread_id[i]); else sceKernelResumeThread(thread_id[i]); } } return 1; }
/* Get a pointer to a register based on its name */ unsigned int *exceptionGetReg(const char *reg) { static unsigned int modaddr = 0; if(g_currex == NULL) { return NULL; } if(strcmp(reg, "epc") == 0) { return &g_currex->regs.epc; } else if(strcmp(reg, "fsr") == 0) { return &g_currex->regs.fsr; } else if(strcmp(reg, "mod") == 0) { SceModule *pMod; SceKernelModuleInfo mod; modaddr = 0; pMod = sceKernelFindModuleByAddress(g_currex->regs.epc); if(pMod) { memset(&mod, 0, sizeof(mod)); mod.size = sizeof(mod); enable_kprintf(0); if(!g_QueryModuleInfo(pMod->modid, &mod)) { modaddr = mod.text_addr; } enable_kprintf(1); } return &modaddr; } else { int reg_loop; for(reg_loop = 0; reg_loop < 32; reg_loop++) { if(strcmp(regName[reg_loop], reg) == 0) { return &g_currex->regs.r[reg_loop]; } } } return NULL; }
int check_game(game_info_t* game_info) { // get the game's module info SceModule* module = NULL; while (module == NULL) { sceKernelDelayThread(1000000); module = sceKernelFindModuleByAddress(0x08804000); } // set the module id and game name game_info->module_id = module->modid; strcpy(game_info->game_name, module->modname); // get the game's global pointer // NOTE: the SceModule structure is incorrect, text_addr is actually the gp_value unsigned int module_gp = module->text_addr; // add the offset to the global pointer, add the offset to the character pointer, // set the size and file name based on the game name if (strcmp("MonsterHunterPSP", game_info->game_name) == 0) { module_gp -= 0x6e60; game_info->character = (char *) 648; game_info->size = 0x46a0; strcat(game_info->file_name, "mhp.bin"); } else if (strcmp("MonsterHunterPortable2nd", game_info->game_name) == 0) { module_gp -= 0x7e5c; game_info->character = (char *) 1060; game_info->size = 0x13ef4; strcat(game_info->file_name, "mhp2.bin"); } else if (strcmp("MonsterHunterPortable2ndG", game_info->game_name) == 0) { module_gp -= 0x7648; game_info->character = (char *) 1184; game_info->size = 0x6a938; strcat(game_info->file_name, "mhp2g.bin"); } else if (strcmp("MonsterHunterPortable3rd", game_info->game_name) == 0) { module_gp += 0x88fc0; game_info->character = (char *) 2140; game_info->size = 0x5f378; strcat(game_info->file_name, "mhp3.bin"); } else { return 0; } // wait for the global pointer to be filled while (*((unsigned int *) module_gp) == 0) sceKernelDelayThread(1000000); // set the character pointer game_info->character += *((unsigned int *) module_gp); // check if a save file already exists SceIoStat stat; if (sceIoGetstat(game_info->file_name, &stat) < 0) game_info->file_exists = 0; else game_info->file_exists = 1; return 1; }