Merge pull request #6506 from unknownbrackets/replace-funcs

Detect Peace Walker's anti-cheat hash func
This commit is contained in:
Henrik Rydgård 2014-07-18 09:34:46 +02:00
commit 06f058de54
3 changed files with 47 additions and 6 deletions

View File

@ -458,6 +458,37 @@ static int Replace_dl_write_matrix() {
return 60;
}
static int Replace_peacewalker_codehash() {
u32 srcPtr = PARAM(1);
const u32 size = PARAM(2);
const u32 *table = (const u32 *)Memory::GetPointer(PARAM(3));
const u32 salt = PARAM(4);
// Note: this seems like an anti-cheat device, makes sure code doesn't get modified.
// It detects emuhacks being modified, so we override it here.
// We could clear the jit, but this is called a ton, and that wouldn't fix replacements.
// We need it aligned to read behind the emuhacks.
u32 offset = srcPtr & 3;
u32 srcOffset = srcPtr & ~3;
u32 sizeOffset = offset + size;
u32 hash = ~PARAM(0);
for (u32 i = 0; i < sizeOffset; i += 4) {
union { u32 w; u8 b[4]; } word;
word.w = Memory::Read_Instruction(srcOffset + i, true).encoding;
const u32 remaining = std::min(4U, size - i);
for (u32 j = offset; j < remaining; ++j) {
const u8 index = (word.b[j] ^ hash) & 0xFF;
hash = table[index] ^ salt ^ (hash >> 8);
}
offset = 0;
}
RETURN(~hash);
return 9 + 13 * size;
}
static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) {
const MIPSOpcode upper = Memory::Read_Instruction(currentMIPS->pc + lui_offset, true);
if (upper != MIPS_MAKE_LUI(MIPS_GET_RT(upper), upper & 0xffff)) {
@ -586,6 +617,7 @@ static const ReplacementTableEntry entries[] = {
{ "topx_create_saveicon", &Hook_topx_create_saveicon, 0, REPFLAG_HOOKENTER, 0x34},
{ "ff1_battle_effect", &Hook_ff1_battle_effect, 0, REPFLAG_HOOKENTER},
{ "dissidia_recordframe_avi", &Hook_dissidia_recordframe_avi, 0, REPFLAG_HOOKENTER},
{ "peacewalker_codehash", &Replace_peacewalker_codehash, 0, 0},
{}
};

View File

@ -201,7 +201,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0x52d5141545a75eda, 60, "dl_write_clutformat", },
{ 0x530cbe1ce9b45d58, 108, "dl_write_light_vector", },
{ 0x53c9aa23504a630f, 96, "vmmul_q_5", },
{ 0x54015ccbcbc75374, 24, "strlen", },
{ 0x54015ccbcbc75374, 24, "strlen", }, // Metal Gear Solid: Peace Walker demo
{ 0x5550d87a851c218c, 168, "dl_write_viewport", },
{ 0x55c1294280bfade0, 88, "dl_write_blend_fixed", },
{ 0x56c9929e8c8c5768, 24, "fabsf", },
@ -299,6 +299,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0xa2bcef60a550a3ef, 92, "matrix_rot_z", },
{ 0xa373f55c65cd757a, 312, "memcpy_swizzled" }, // God Eater Burst Demo
{ 0xa41989db0f9bf97e, 1304, "pow", },
{ 0xa4984da0a704cd67, 72, "peacewalker_codehash" }, // Metal Gear Solid: Peace Walker demo
{ 0xa46cc6ea720d5775, 44, "dl_write_cull", },
{ 0xa54967288afe8f26, 600, "ceil", },
{ 0xa5ddbbc688e89a4d, 56, "isinf", },
@ -413,7 +414,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0xfb4253a1d9d9df9f, 20, "isnanf", },
{ 0xfd34a9ad94fa6241, 76, "__extendsfdf2", },
{ 0xfe4f0280240008e9, 28, "vavg_q", },
{ 0xfe5dd338ab862291, 216, "memset", },
{ 0xfe5dd338ab862291, 216, "memset", }, // Metal Gear Solid: Peace Walker demo
{ 0xffc8f5f8f946152c, 192, "dl_write_light_color", },
};
@ -755,6 +756,9 @@ skip:
closestJumpbackTarget = target;
}
}
if (aheadOp == MIPS_MAKE_JR_RA()) {
break;
}
}
if (closestJumpbackAddr != INVALIDTARGET && furthestJumpbackAddr == INVALIDTARGET) {
@ -846,7 +850,8 @@ skip:
}
// A jump later. Probably tail, but let's check if it jumps back.
u32 knownEnd = furthestBranch == 0 ? addr : furthestBranch;
// We use + 8 here in case it jumps right back to the delay slot. We'll consider that inside the func.
u32 knownEnd = furthestBranch == 0 ? addr + 8 : furthestBranch;
u32 jumpback = ScanAheadForJumpback(sureTarget, currentFunction.start, knownEnd);
if (jumpback != INVALIDTARGET && jumpback > addr && jumpback > knownEnd) {
furthestBranch = jumpback;

View File

@ -315,9 +315,10 @@ void System_Wake() {
static bool pspIsInited = false;
static bool pspIsIniting = false;
static bool pspIsQuiting = false;
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
if (pspIsIniting) {
if (pspIsIniting || pspIsQuiting) {
return false;
}
@ -394,12 +395,12 @@ bool PSP_IsIniting() {
}
bool PSP_IsInited() {
return pspIsInited;
return pspIsInited && !pspIsQuiting;
}
void PSP_Shutdown() {
// Do nothing if we never inited.
if (!pspIsInited && !pspIsIniting) {
if (!pspIsInited && !pspIsIniting && !pspIsQuiting) {
return;
}
@ -409,6 +410,8 @@ void PSP_Shutdown() {
}
#endif
// Make sure things know right away that PSP memory, etc. is going away.
pspIsQuiting = true;
if (coreState == CORE_RUNNING)
Core_UpdateState(CORE_ERROR);
Core_NotifyShutdown();
@ -426,6 +429,7 @@ void PSP_Shutdown() {
currentMIPS = 0;
pspIsInited = false;
pspIsIniting = false;
pspIsQuiting = false;
}
void PSP_RunLoopUntil(u64 globalticks) {