Skip to content

Commit

Permalink
Attempt to add memory access validation through rc_runtime_invalidate…
Browse files Browse the repository at this point in the history
…_address
  • Loading branch information
hrydgard committed Jun 20, 2023
1 parent 475016e commit cb0d65f
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 3 deletions.
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ static const ConfigSetting achievementSettings[] = {
ConfigSetting("AchievementsChallengeMode", &g_Config.bAchievementsChallengeMode, false, CfgFlag::DEFAULT),
ConfigSetting("AchievementsSoundEffects", &g_Config.bAchievementsSoundEffects, 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.
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ struct Config {
bool bAchievementsChallengeMode;
bool bAchievementsSoundEffects;
bool bAchievementsNotifications;
bool bAchievementsLogBadMemReads;

// 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.
Expand Down
3 changes: 2 additions & 1 deletion UI/RetroAchievementScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ void RetroAchievementsSettingsScreen::CreateSettingsTab(UI::ViewGroup *viewGroup
using namespace UI;
viewGroup->Add(new ItemHeader(ac->T("Settings")));
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
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode")));
Expand Down
34 changes: 32 additions & 2 deletions UI/RetroAchievements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ static void DeactivateAchievement(Achievement *achievement);
static void UnlockAchievement(u32 achievement_id, bool add_notification = true);
static void AchievementPrimed(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 SendPing();
static void SendPlaying();
Expand Down Expand Up @@ -245,6 +246,8 @@ static u64 g_badMemoryAccessCount = 0;
const std::string g_gameIconCachePrefix = "game:";
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
// download them as we go.

Expand Down Expand Up @@ -1171,6 +1174,10 @@ void Achievements::GetUserUnlocks()
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,
Common::HTTPDownloader::Request::Data data)
{
Expand Down Expand Up @@ -1318,6 +1325,9 @@ void Achievements::GetPatchesCallback(s32 status_code, std::string content_type,
{
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,
Expand Down Expand Up @@ -1962,6 +1972,19 @@ void Achievements::AchievementUnprimed(u32 achievement_id)
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> result;
Expand Down Expand Up @@ -2037,6 +2060,10 @@ void Achievements::CheevosEventHandler(const rc_runtime_event_t *runtime_event)
AchievementUnprimed(runtime_event->id);
break;

case RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED:
AchievementDisabled(runtime_event->id);
break;

case RC_RUNTIME_EVENT_LBOARD_TRIGGERED:
SubmitLeaderboard(runtime_event->id, runtime_event->value);
break;
Expand All @@ -2048,13 +2075,16 @@ void Achievements::CheevosEventHandler(const rc_runtime_event_t *runtime_event)

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.
address += 0x08000000;
address += PSP_MEMORY_OFFSET;

if (!Memory::IsValidAddress(address)) {
// Some achievement packs are really, really spammy.
// So we'll just count the bad accesses.
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;
}

Expand Down
1 change: 1 addition & 0 deletions UI/RetroAchievements.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct Achievement
bool locked;
bool active;
bool primed;
bool disabled; // due to bad memory access, presumably
};

struct Leaderboard
Expand Down

0 comments on commit cb0d65f

Please sign in to comment.