Skip to content

Commit

Permalink
extra patches for OriginClientService and EALink just to be safe
Browse files Browse the repository at this point in the history
  • Loading branch information
p0358 committed Jun 24, 2023
1 parent 2e7e2d4 commit 5846780
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 1 deletion.
41 changes: 41 additions & 0 deletions src/main/ealink_exe_patches.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Patches for EALink.exe

#include "pch.hpp"
#include "main.hpp"

namespace EALinkExePatches
{
// Origin::Services::readSetting
void* (__cdecl* readSetting_org)(void*, void*, int, void*);
void* __cdecl readSetting_hook(void* out_qv, void* setting, int a3, void* a4)
{
static auto QVariant_QVariant_from_bool = GetExport<void* (__thiscall*)(void*, bool)>(Qt5Core, "??0QVariant@@QAE@_N@Z");
static auto SETTING_MigrationDisabled = GetExport<void*>(EALinkExe, "?SETTING_MigrationDisabled@Services@Origin@@3VSetting@12@A");
if (!SETTING_MigrationDisabled)
SETTING_MigrationDisabled = GetExport<void*>(EALinkExe, "?SETTING_MigrationDisabled@Services@Origin@@3VSetting@12@B");
if (!QVariant_QVariant_from_bool || !SETTING_MigrationDisabled) [[unlikely]]
MessageBoxA(nullptr, ("Error in Origin::Services::readSetting: one of the functions could not have been resolved, we will crash\n"
"\nQVariant_QVariant_from_bool: " + std::to_string(uintptr_t(QVariant_QVariant_from_bool))
+ "\nSETTING_MigrationDisabled: " + std::to_string(uintptr_t(SETTING_MigrationDisabled))
).c_str(),
ERROR_MSGBOX_CAPTION, MB_ICONERROR);

if (setting == SETTING_MigrationDisabled)
{
// override to true
char qv[16] = { 0 };
QVariant_QVariant_from_bool(out_qv, true); // caller will destruct this
return out_qv;
}

return readSetting_org(out_qv, setting, a3, a4);
}
}

void DoEALinkExePatches()
{
using namespace EALinkExePatches;
// checked in Origin::Services::OriginConfigService::init
// seems to set the boolean on the object and also fire a delayed QTimer to `1downloadConfig()` if migration isn't disabled
CreateHookNamed(nullptr, "?readSetting@Services@Origin@@YA?AVVariant@12@ABVSetting@12@V?$QSharedPointer@VAbstractSession@Session@Services@Origin@@@@@Z", readSetting_hook, reinterpret_cast<LPVOID*>(&readSetting_org));
}
2 changes: 2 additions & 0 deletions src/main/function_hooking.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ inline MH_STATUS WINAPI CreateHook(DWORD64 baseAddress, unsigned int offset, LPV
inline MH_STATUS WINAPI CreateHookNamed(const char* moduleName, const char* procName, LPVOID pDetour, LPVOID* ppOriginal)
{
HMODULE hModule = GetModuleHandleA(moduleName);
if (!moduleName)
moduleName = "<exe>";
if (!hModule) [[unlikely]]
{
auto err = GetLastError();
Expand Down
15 changes: 15 additions & 0 deletions src/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
CModule OriginExe;
CModule OriginClientServiceExe;
CModule OriginClient;
CModule EALinkExe;

CMemory OriginExeAdr;
CMemory OriginClientServiceExeAdr;
CMemory OriginClientAdr;
CMemory EALinkExeAdr;

CModule Qt5Core;

Expand Down Expand Up @@ -51,12 +53,15 @@ void InternalSetup()
auto exe_name = GetExeName();
bool isOriginExe = exe_name == "Origin.exe";
bool isOriginClientServiceExe = exe_name == "OriginClientService.exe";
bool isEALinkExe = exe_name == "EALink.exe";

OriginExe = CModule("Origin.exe", uintptr_t(GetModuleHandleA(nullptr)));
OriginClientServiceExe = CModule("OriginClientService.exe", uintptr_t(GetModuleHandleA(nullptr)));
EALinkExe = CModule("EALinkExe.exe", uintptr_t(GetModuleHandleA(nullptr)));

OriginExeAdr = CMemory(OriginExe.GetModuleBase());
OriginClientServiceExeAdr = CMemory(OriginClientServiceExe.GetModuleBase());
EALinkExeAdr = CMemory(EALinkExe.GetModuleBase());

if (isOriginExe)
{
Expand All @@ -65,8 +70,18 @@ void InternalSetup()
}
else if (isOriginClientServiceExe)
{
// statically imported by OriginClientService.exe
Qt5Core = CModule("Qt5Core.dll");

DoOriginClientServiceExePatches();
}
else if (isEALinkExe)
{
// statically imported by EALinkExe.exe
Qt5Core = CModule("Qt5Core.dll");

DoEALinkExePatches();
}
else
{
// WARN: loaded into unrecognized program!
Expand Down
3 changes: 3 additions & 0 deletions src/main/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
extern CModule OriginExe;
extern CModule OriginClientServiceExe;
extern CModule OriginClient;
extern CModule EALinkExe;

extern CMemory OriginExeAdr;
extern CMemory OriginClientServiceExeAdr;
extern CMemory OriginClientAdr;
extern CMemory EALinkExeAdr;

extern CModule Qt5Core;

extern void DoOriginExePatches();
extern void DoOriginClientServiceExePatches();
extern void DoOriginClientDllPatches();
extern void DoEALinkExePatches();

#define ERROR_MSGBOX_CAPTION "\"Fuck off EA App\"'s fatal error"
#define ERROR_MSGBOX_CAPTION_L L"\"Fuck off EA App\"'s fatal error"
Expand Down
34 changes: 33 additions & 1 deletion src/main/origin_client_service_exe_patches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,39 @@
#include "pch.hpp"
#include "main.hpp"

namespace OriginClientServiceExePatches
{
// Origin::Services::readSetting
void* (__cdecl* readSetting_org)(void*, void*, int, void*);
void* __cdecl readSetting_hook(void* out_qv, void* setting, int a3, void* a4)
{
static auto QVariant_QVariant_from_bool = GetExport<void* (__thiscall*)(void*, bool)>(Qt5Core, "??0QVariant@@QAE@_N@Z");
static auto SETTING_MigrationDisabled = GetExport<void*>(OriginClientServiceExe, "?SETTING_MigrationDisabled@Services@Origin@@3VSetting@12@A");
if (!SETTING_MigrationDisabled)
SETTING_MigrationDisabled = GetExport<void*>(OriginClientServiceExe, "?SETTING_MigrationDisabled@Services@Origin@@3VSetting@12@B");
if (!QVariant_QVariant_from_bool || !SETTING_MigrationDisabled) [[unlikely]]
MessageBoxA(nullptr, ("Error in Origin::Services::readSetting: one of the functions could not have been resolved, we will crash\n"
"\nQVariant_QVariant_from_bool: " + std::to_string(uintptr_t(QVariant_QVariant_from_bool))
+ "\nSETTING_MigrationDisabled: " + std::to_string(uintptr_t(SETTING_MigrationDisabled))
).c_str(),
ERROR_MSGBOX_CAPTION, MB_ICONERROR);

if (setting == SETTING_MigrationDisabled)
{
// override to true
char qv[16] = { 0 };
QVariant_QVariant_from_bool(out_qv, true); // caller will destruct this
return out_qv;
}

return readSetting_org(out_qv, setting, a3, a4);
}
}

void DoOriginClientServiceExePatches()
{
// no patches required in this exe currently
using namespace OriginClientServiceExePatches;
// checked in Origin::Services::OriginConfigService::init
// seems to set the boolean on the object and also fire a delayed QTimer to `1downloadConfig()` if migration isn't disabled
CreateHookNamed(nullptr, "?readSetting@Services@Origin@@YA?AVVariant@12@ABVSetting@12@V?$QSharedPointer@VAbstractSession@Session@Services@Origin@@@@@Z", readSetting_hook, reinterpret_cast<LPVOID*>(&readSetting_org));
}

0 comments on commit 5846780

Please sign in to comment.