mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Attempt to add memory access validation through rc_runtime_invalidate_address
This commit is contained in:
parent
da36d78d4f
commit
3218422a69
5 changed files with 37 additions and 3 deletions
|
@ -273,6 +273,7 @@ static const ConfigSetting achievementSettings[] = {
|
||||||
ConfigSetting("AchievementsChallengeMode", &g_Config.bAchievementsChallengeMode, false, CfgFlag::DEFAULT),
|
ConfigSetting("AchievementsChallengeMode", &g_Config.bAchievementsChallengeMode, false, CfgFlag::DEFAULT),
|
||||||
ConfigSetting("AchievementsSoundEffects", &g_Config.bAchievementsSoundEffects, true, CfgFlag::DEFAULT),
|
ConfigSetting("AchievementsSoundEffects", &g_Config.bAchievementsSoundEffects, true, CfgFlag::DEFAULT),
|
||||||
ConfigSetting("AchievementsNotifications", &g_Config.bAchievementsNotifications, true, CfgFlag::DEFAULT),
|
ConfigSetting("AchievementsNotifications", &g_Config.bAchievementsNotifications, true, CfgFlag::DEFAULT),
|
||||||
|
ConfigSetting("AchievementsLogBadMemReads", &g_Config.bAchievementsLogBadMemReads, false, CfgFlag::DEFAULT),
|
||||||
|
|
||||||
// Achievements login info. Note that password is NOT stored, only a login token.
|
// Achievements login info. Note that password is NOT stored, only a login token.
|
||||||
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
|
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
|
||||||
|
|
|
@ -492,6 +492,7 @@ public:
|
||||||
bool bAchievementsChallengeMode;
|
bool bAchievementsChallengeMode;
|
||||||
bool bAchievementsSoundEffects;
|
bool bAchievementsSoundEffects;
|
||||||
bool bAchievementsNotifications;
|
bool bAchievementsNotifications;
|
||||||
|
bool bAchievementsLogBadMemReads;
|
||||||
|
|
||||||
// Achivements login info. Note that password is NOT stored, only a login token.
|
// Achivements login info. Note that password is NOT stored, only a login token.
|
||||||
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
|
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
|
||||||
|
|
|
@ -104,7 +104,8 @@ void RetroAchievementsSettingsScreen::CreateSettingsTab(UI::ViewGroup *viewGroup
|
||||||
using namespace UI;
|
using namespace UI;
|
||||||
viewGroup->Add(new ItemHeader(ac->T("Settings")));
|
viewGroup->Add(new ItemHeader(ac->T("Settings")));
|
||||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsRichPresence, ac->T("Rich Presence")));
|
viewGroup->Add(new CheckBox(&g_Config.bAchievementsRichPresence, ac->T("Rich Presence")));
|
||||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects")));
|
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects"))); // not yet implemented
|
||||||
|
viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")));
|
||||||
|
|
||||||
// Not yet fully implemented
|
// Not yet fully implemented
|
||||||
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode")));
|
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode")));
|
||||||
|
|
|
@ -173,6 +173,7 @@ static void DeactivateAchievement(Achievement *achievement);
|
||||||
static void UnlockAchievement(u32 achievement_id, bool add_notification = true);
|
static void UnlockAchievement(u32 achievement_id, bool add_notification = true);
|
||||||
static void AchievementPrimed(u32 achievement_id);
|
static void AchievementPrimed(u32 achievement_id);
|
||||||
static void AchievementUnprimed(u32 achievement_id);
|
static void AchievementUnprimed(u32 achievement_id);
|
||||||
|
static void AchievementDisabled(u32 achievement_id);
|
||||||
static void SubmitLeaderboard(u32 leaderboard_id, int value);
|
static void SubmitLeaderboard(u32 leaderboard_id, int value);
|
||||||
static void SendPing();
|
static void SendPing();
|
||||||
static void SendPlaying();
|
static void SendPlaying();
|
||||||
|
@ -245,6 +246,8 @@ static u64 g_badMemoryAccessCount = 0;
|
||||||
const std::string g_gameIconCachePrefix = "game:";
|
const std::string g_gameIconCachePrefix = "game:";
|
||||||
const std::string g_iconCachePrefix = "badge:";
|
const std::string g_iconCachePrefix = "badge:";
|
||||||
|
|
||||||
|
#define PSP_MEMORY_OFFSET 0x08000000
|
||||||
|
|
||||||
// TODO: Add an icon cache as a string map. We won't cache achievement icons across sessions, let's just
|
// TODO: Add an icon cache as a string map. We won't cache achievement icons across sessions, let's just
|
||||||
// download them as we go.
|
// download them as we go.
|
||||||
|
|
||||||
|
@ -1171,6 +1174,10 @@ void Achievements::GetUserUnlocks()
|
||||||
request.Send(GetUserUnlocksCallback);
|
request.Send(GetUserUnlocksCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ValidateAddress(unsigned address) {
|
||||||
|
return Memory::IsValidAddress(address + PSP_MEMORY_OFFSET) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Achievements::GetPatchesCallback(s32 status_code, std::string content_type,
|
void Achievements::GetPatchesCallback(s32 status_code, std::string content_type,
|
||||||
Common::HTTPDownloader::Request::Data data)
|
Common::HTTPDownloader::Request::Data data)
|
||||||
{
|
{
|
||||||
|
@ -1318,6 +1325,9 @@ void Achievements::GetPatchesCallback(s32 status_code, std::string content_type,
|
||||||
{
|
{
|
||||||
ClearGameInfo();
|
ClearGameInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hook up memory validation (doesn't seem to do much though?)
|
||||||
|
rc_runtime_validate_addresses(&s_rcheevos_runtime, &Achievements::CheevosEventHandler, &ValidateAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::GetLbInfoCallback(s32 status_code, std::string content_type,
|
void Achievements::GetLbInfoCallback(s32 status_code, std::string content_type,
|
||||||
|
@ -1962,6 +1972,19 @@ void Achievements::AchievementUnprimed(u32 achievement_id)
|
||||||
s_primed_achievement_count.fetch_sub(std::memory_order_acq_rel);
|
s_primed_achievement_count.fetch_sub(std::memory_order_acq_rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Achievements::AchievementDisabled(u32 achievement_id)
|
||||||
|
{
|
||||||
|
std::unique_lock lock(s_achievements_mutex);
|
||||||
|
Achievement *achievement = GetMutableAchievementByID(achievement_id);
|
||||||
|
if (!achievement)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Have not seen this trigger yet, despite games doing bad memory accesses.
|
||||||
|
INFO_LOG(ACHIEVEMENTS, "Achievement disabled due to invalid memory access: %s", achievement->title);
|
||||||
|
|
||||||
|
achievement->disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<u32, u32> Achievements::GetAchievementProgress(const Achievement &achievement)
|
std::pair<u32, u32> Achievements::GetAchievementProgress(const Achievement &achievement)
|
||||||
{
|
{
|
||||||
std::pair<u32, u32> result;
|
std::pair<u32, u32> result;
|
||||||
|
@ -2037,6 +2060,10 @@ void Achievements::CheevosEventHandler(const rc_runtime_event_t *runtime_event)
|
||||||
AchievementUnprimed(runtime_event->id);
|
AchievementUnprimed(runtime_event->id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED:
|
||||||
|
AchievementDisabled(runtime_event->id);
|
||||||
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_LBOARD_TRIGGERED:
|
case RC_RUNTIME_EVENT_LBOARD_TRIGGERED:
|
||||||
SubmitLeaderboard(runtime_event->id, runtime_event->value);
|
SubmitLeaderboard(runtime_event->id, runtime_event->value);
|
||||||
break;
|
break;
|
||||||
|
@ -2048,13 +2075,16 @@ void Achievements::CheevosEventHandler(const rc_runtime_event_t *runtime_event)
|
||||||
|
|
||||||
unsigned Achievements::PeekMemory(unsigned address, unsigned num_bytes, void *ud) {
|
unsigned Achievements::PeekMemory(unsigned address, unsigned num_bytes, void *ud) {
|
||||||
// Unclear why achievements are defined with this offset, but they are and it can't be changed now, so we roll with it.
|
// Unclear why achievements are defined with this offset, but they are and it can't be changed now, so we roll with it.
|
||||||
address += 0x08000000;
|
address += PSP_MEMORY_OFFSET;
|
||||||
|
|
||||||
if (!Memory::IsValidAddress(address)) {
|
if (!Memory::IsValidAddress(address)) {
|
||||||
// Some achievement packs are really, really spammy.
|
// Some achievement packs are really, really spammy.
|
||||||
// So we'll just count the bad accesses.
|
// So we'll just count the bad accesses.
|
||||||
g_badMemoryAccessCount++;
|
g_badMemoryAccessCount++;
|
||||||
// WARN_LOG(G3D, "RetroAchievements PeekMemory: Bad address %08x (%d bytes)", address, num_bytes);
|
|
||||||
|
if (g_Config.bAchievementsLogBadMemReads) {
|
||||||
|
WARN_LOG(G3D, "RetroAchievements PeekMemory: Bad address %08x (%d bytes)", address, num_bytes);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct Achievement
|
||||||
bool locked;
|
bool locked;
|
||||||
bool active;
|
bool active;
|
||||||
bool primed;
|
bool primed;
|
||||||
|
bool disabled; // due to bad memory access, presumably
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Leaderboard
|
struct Leaderboard
|
||||||
|
|
Loading…
Add table
Reference in a new issue