mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-03 01:36:58 +02:00
143 lines
5.4 KiB
C++
143 lines
5.4 KiB
C++
#include "common.h"
|
|
#include "thumbInstructions.h"
|
|
#include "../PatchContext.h"
|
|
#include "../FunctionSignature.h"
|
|
#include "CardiReadRomIdCorePatchAsm.h"
|
|
#include "CardiReadRomIdCorePatch.h"
|
|
|
|
static constexpr auto sSignaturesArm = std::to_array<const FunctionSignature>
|
|
({
|
|
{ (const u32[]) { 0xE92D4000u, 0xE24DD004u, 0xE3A0032Eu, 0xE3A01000u }, 0x02004F50, 0x04017531 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFF0Bu }, 0x03007532, 0x03017531 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFF08u }, 0x03017530, 0x03017534 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFF07u }, 0x03027530, 0x04007531 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFEF2u }, 0x04007531, 0x04007531 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFEFDu }, 0x04007532, 0x04007532 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFEFBu }, 0x04017530, 0x04027539 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A0032Eu, 0xE3A01000u, 0xEBFFFEE6u }, 0x04017533, 0x04017533 },
|
|
{ (const u32[]) { 0xE92D4010u, 0xE3A04000u, 0xE1A01004u, 0xE3A0032Eu }, 0x04027537, 0x04027539 }
|
|
});
|
|
|
|
static constexpr auto sSignaturesThumb = std::to_array<const FunctionSignature>
|
|
({
|
|
{ (const u32[]) { 0xB081B500u, 0x2100480Bu, 0xF98AF000u, 0x6801480Au }, 0x03007530, 0x03012776 },
|
|
{ (const u32[]) { 0xB081B500u, 0x2100480Bu, 0xF990F000u, 0x6801480Au }, 0x03007532, 0x03007532 },
|
|
{ (const u32[]) { 0x202EB508u, 0x21000680u, 0xFE8CF7FFu, 0x68014809u }, 0x03017531, 0x03017531 },
|
|
{ (const u32[]) { 0xB081B500u, 0x2100480Bu, 0xF98EF000u, 0x6801480Au }, 0x03017531, 0x03017534 },
|
|
{ (const u32[]) { 0xB081B500u, 0x2100480Cu, 0xF992F000u, 0x6800480Bu }, 0x03027530, 0x03027532 },
|
|
{ (const u32[]) { 0x202EB508u, 0x21000680u, 0xFE8AF7FFu, 0x6800480Au }, 0x03027530, 0x04007531 },
|
|
{ (const u32[]) { 0x202EB508u, 0x21000680u, 0xFE74F7FFu, 0x6800480Au }, 0x04017530, 0x04027539 },
|
|
{ (const u32[]) { 0x202EB508u, 0x21000680u, 0xFE62F7FFu, 0x6800480Au }, 0x04027531, 0x04027531 },
|
|
{ (const u32[]) { 0x202EB508u, 0x21000680u, 0xFE56F7FFu, 0x6800480Au }, 0x04027537, 0x04027537 }
|
|
});
|
|
|
|
static constexpr auto sSignaturesArmSdk5 = std::to_array<const FunctionSignature>
|
|
({
|
|
{ (const u32[]) { 0xE92D4010u, 0xE3A040B8u, 0xEBFFFFD6u, 0xE3500000u }, 0x0500753B, 0x05027534 },
|
|
{ (const u32[]) { 0xE92D4008u, 0xE3A000B8u, 0xE3A01000u, 0xEBFFFFCEu }, 0x05017536, 0x05047531 },
|
|
{ (const u32[]) { 0xE92D4038u, 0xE3A050B8u, 0xEBFFFFD7u, 0xE3500000u }, 0x05017537, 0x05057535 },
|
|
{ (const u32[]) { 0xE92D4010u, 0xE3A04000u, 0xE1A01004u, 0xE3A000B8u }, 0x05037531, 0x05057535 }
|
|
});
|
|
|
|
static constexpr auto sSignaturesThumbSdk5 = std::to_array<const FunctionSignature>
|
|
({
|
|
{ (const u32[]) { 0x24B8B510u, 0xFFC4F7FFu, 0xD0002800u, 0x1C202490u }, 0x05007538, 0x05017537 },
|
|
{ (const u32[]) { 0x20B8B508u, 0xF7FF2100u, 0x480AFFABu, 0x480A6801u }, 0x05017537, 0x05057535 },
|
|
{ (const u32[]) { 0x24B8B510u, 0xFFC6F7FFu, 0xD0002800u, 0x1C202490u }, 0x05037531, 0x05057534 }
|
|
});
|
|
|
|
bool CardiReadRomIdCorePatch::FindPatchTarget(PatchContext& patchContext)
|
|
{
|
|
if (patchContext.GetSdkVersion().IsTwlSdk())
|
|
{
|
|
for (const auto& signature : sSignaturesArmSdk5)
|
|
{
|
|
if (CheckSignature(patchContext, signature))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!_cardiReadRomIdCore)
|
|
{
|
|
for (const auto& signature : sSignaturesThumbSdk5)
|
|
{
|
|
if (CheckSignature(patchContext, signature))
|
|
{
|
|
_thumb = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (const auto& signature : sSignaturesArm)
|
|
{
|
|
if (CheckSignature(patchContext, signature))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!_cardiReadRomIdCore)
|
|
{
|
|
for (const auto& signature : sSignaturesThumb)
|
|
{
|
|
if (CheckSignature(patchContext, signature))
|
|
{
|
|
_thumb = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!_cardiReadRomIdCore)
|
|
{
|
|
LOG_WARNING("CARDi_ReadRomIDCore not found\n");
|
|
}
|
|
|
|
return true; //_cardiReadRomIdCore != nullptr;
|
|
}
|
|
|
|
void CardiReadRomIdCorePatch::ApplyPatch(PatchContext& patchContext)
|
|
{
|
|
if (!_cardiReadRomIdCore)
|
|
return;
|
|
|
|
auto patchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<CardiReadRomIdCorePatchCode>
|
|
(
|
|
patchContext.GetPatchHeap(),
|
|
(const void*)(patchContext.GetSdkVersion().IsTwlSdk() ? 0x02FFFC00 : 0x027FFC00)
|
|
);
|
|
|
|
if (_thumb)
|
|
{
|
|
((u16*)_cardiReadRomIdCore)[0] = 0x4800;
|
|
((u16*)_cardiReadRomIdCore)[1] = 0x4700;
|
|
}
|
|
else
|
|
{
|
|
_cardiReadRomIdCore[0] = 0xE51FF004;
|
|
}
|
|
|
|
_cardiReadRomIdCore[1] = (u32)patchCode->GetCardiReadRomIdCoreFunction();
|
|
}
|
|
|
|
bool CardiReadRomIdCorePatch::CheckSignature(const PatchContext& patchContext, const FunctionSignature& signature)
|
|
{
|
|
if (patchContext.GetSdkVersion() >= signature.GetMinimumSdkVersion() &&
|
|
patchContext.GetSdkVersion() <= signature.GetMaximumSdkVersion())
|
|
{
|
|
_cardiReadRomIdCore = patchContext.FindPattern32(signature.GetPattern(), 16);
|
|
if (_cardiReadRomIdCore)
|
|
{
|
|
LOG_DEBUG("Found CARDi_ReadRomIDCore at %p\n", _cardiReadRomIdCore);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|