EOS support & fix 24.20 latest CL

This commit is contained in:
Sarah
2025-02-14 09:58:14 -05:00
parent 7b0757d31f
commit 397d389644
9 changed files with 136 additions and 40 deletions
+7
View File
@@ -4,11 +4,18 @@
namespace Starfall {
namespace Globals {
void* buf;
void* EOSBuf;
void* tbuf;
size_t tsize;
void* rbuf;
size_t rsize;
void* EOSTextBuf;
size_t EOSTextSize;
void* EOSRDataBuf;
size_t EOSRDataSize;
}
};
+8
View File
@@ -6,12 +6,20 @@ namespace Starfall {
namespace Globals {
extern void* buf;
//extern size_t size;
extern void* EOSBuf;
extern void* tbuf;
extern size_t tsize;
extern void* rbuf;
extern size_t rsize;
extern void* EOSTextBuf;
extern size_t EOSTextSize;
extern void* EOSRDataBuf;
extern size_t EOSRDataSize;
}
using namespace Globals;
};
+23 -7
View File
@@ -26,18 +26,34 @@ namespace Starfall {
}
buf = *(void**)(__readgsqword(0x60) + 0x10);
EOSBuf = GetModuleHandleA("EOSSDK-Win64-Shipping.dll");
if (!EOSBuf)
EOSBuf = LoadLibraryA("EOSSDK-Win64-Shipping.dll");
auto section = pe_get_section((char*)buf, ".text");
auto rsection = pe_get_section((char*)buf, ".rdata");
{
auto section = pe_get_section((char*)buf, ".text");
auto rsection = pe_get_section((char*)buf, ".rdata");
tbuf = (void*)(__int64(buf) + section->virtualAddress);
tsize = section->virtualSize;
tbuf = (void*)(__int64(buf) + section->virtualAddress);
tsize = section->virtualSize;
rbuf = (void*)(__int64(buf) + rsection->virtualAddress);
rsize = rsection->virtualSize;
rbuf = (void*)(__int64(buf) + rsection->virtualAddress);
rsize = rsection->virtualSize;
}
if (EOSBuf) {
auto section = pe_get_section((char*)EOSBuf, ".text");
auto rsection = pe_get_section((char*)EOSBuf, ".rdata");
EOSTextBuf = (void*)(__int64(EOSBuf) + section->virtualAddress);
EOSTextSize = section->virtualSize;
EOSRDataBuf = (void*)(__int64(EOSBuf) + rsection->virtualAddress);
EOSRDataSize = rsection->virtualSize;
}
FindProcessRequest();
if (Game == Fortnite) FindPushWidget();
//if (Game == Fortnite) FindPushWidget();
return;
}
+4
View File
@@ -25,6 +25,7 @@ namespace Starfall {
namespace Callbacks {
bool RequestExitWithStatusCallback(struct pf_patch_t* patch, void* stream) {
AsmHook(stream, Hooks::RequestExitWithStatusHook);
AsmHook((void*)(uint64_t(buf) + 0x221a404), Hooks::RequestExitWithStatusHook);
return true;
}
@@ -85,6 +86,9 @@ namespace Starfall {
constexpr static struct pf_patchset_t patchset = pf_construct_patchset(patches, sizeof(patches) / sizeof(struct pf_patch_t), (bool (*)(void*, size_t, pf_patchset_t))pf_find_maskmatch);
pf_patchset_emit(tbuf, tsize, patchset);
//AsmHook((void*)(uint64_t(buf) + 0x221a404), Hooks::RequestExitWithStatusHook);
//AsmHook((void*)(uint64_t(buf) + 0x221a438), Hooks::RequestExitWithStatusHook);
//AsmHook((void*)(uint64_t(buf) + 0x48830b0), Hooks::UnsafeEnvironmentPopupHook);
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include "ue.h"
constexpr bool Console = false; // if the console window should be created
constexpr bool Console = true; // if the console window should be created
constexpr StarfallURLSet URLSet = Default;
constexpr inline FString Backend = L"http://127.0.0.1:3551"; // your backend url
constexpr UEGame Game = Fortnite; // use Generic for any UE game other than fortnite
+1 -2
View File
@@ -94,8 +94,7 @@ namespace Starfall {
};
enum UEGame {
Generic,
Fortnite,
Generic427 // found in latest EGL
Fortnite
};
}
using namespace Types;
+1
View File
@@ -41,6 +41,7 @@ namespace Starfall {
L"on.epicgames.com",
L"game-social.epicgames.com",
L"ak.epicgames.com",
L"epicgames.dev"
//L"cdn2.unrealengine.com" // only needed if you have fixed friend images in friends list
};
+90 -28
View File
@@ -14,13 +14,13 @@
namespace Unreal {
FString FCurlHttpRequest::GetURL()
{
return GetURLFunc(this, FString());
return ((FString&(*)(FCurlHttpRequest*, FString)) VTable[0])(this, FString());
}
void FCurlHttpRequest::SetURL(URL& URL)
{
FString str = URL;
SetURLFunc(this, str);
((void (*)(FCurlHttpRequest*, FString)) VTable[SetURLIdx])(this, str);
free(str.String);
}
}
@@ -28,9 +28,8 @@ namespace Unreal {
namespace Starfall {
bool setupMemLeak = false;
void SetupRequest(FCurlHttpRequest* Request) {
if (FCurlHttpRequest::SetURLFunc == nullptr) {
if (FCurlHttpRequest::SetURLIdx == 0) {
void* GetFunc = *Request->VTable;
FCurlHttpRequest::GetURLFunc = (decltype(FCurlHttpRequest::GetURLFunc)) *Request->VTable;
uint32_t URLOffset = 0;
for (int i = 0; i < 100; i++) {
// this is only needed for latest
@@ -46,14 +45,14 @@ namespace Starfall {
for (int j = 0; j < 100; j++) {
if (CheckBytes<0x48, 0x81, 0xC1>(func, j)) {
if (*(uint32_t*)(__int64(func) + j + 3) == URLOffset) {
FCurlHttpRequest::SetURLFunc = (void (*)(FCurlHttpRequest*, FString)) Request->VTable[i];
FCurlHttpRequest::SetURLIdx = i;
return;
}
}
}
}
def:
FCurlHttpRequest::SetURLFunc = (void (*)(FCurlHttpRequest*, FString)) Request->VTable[10];
FCurlHttpRequest::SetURLIdx = 10;
}
// this works bc the first request is a datarouter request, and the second request should be after engine init
else if (!setupMemLeak && Game == Fortnite) {
@@ -74,15 +73,16 @@ def:
namespace Hooks {
bool (*ProcessRequestOG)(FCurlHttpRequest* Request);
bool ProcessRequestHook(FCurlHttpRequest* Request) {
bool (*EOSProcessRequestOG)(FCurlHttpRequest* Request);
bool InternalProcessRequest(FCurlHttpRequest* Request) {
SetupRequest(Request);
auto urlS = Request->GetURL();
auto url = (URL *) malloc(sizeof(URL));
auto url = (URL*)malloc(sizeof(URL));
if (!url) return false;
__stosb((uint8_t*)url, 0, sizeof(URL));
url->Construct(urlS);
Log(Display, "URL: %ls\n", static_cast<wchar_t *>(urlS));
Log(Display, "URL: %ls\n", static_cast<wchar_t*>(urlS));
if (shouldRedirect(url)) {
if (UseBackendParam)
url->SetHost(backend);
@@ -98,8 +98,17 @@ def:
}
free(url);
return true;
}
bool ProcessRequestHook(FCurlHttpRequest* Request) {
if (!InternalProcessRequest(Request)) return false;
return ProcessRequestOG(Request);
}
bool EOSProcessRequestHook(FCurlHttpRequest* Request) {
if (!InternalProcessRequest(Request)) return false;
return EOSProcessRequestOG(Request);
}
}
namespace Callbacks {
@@ -110,10 +119,28 @@ def:
return true;
}
bool EOSPtrCallback(struct pf_patch_t* patch, void* stream) {
VTHook((void**)stream, EOSProcessRequestHook, (void**)&EOSProcessRequestOG);
return true;
}
constexpr static char ptrMasks[] = {
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff
};
bool StringCallback(struct pf_patch_t* patch, void* stream) {
void* saddr = (void*)((__int64(stream) + 7) + *(int32_t*)(__int64(stream) + 3));
if (__int64(saddr) >= __int64(rbuf) && __int64(saddr) < (__int64(rbuf) + (int64_t)rsize)) {
if (wcscmp((wchar_t*)saddr, Game == Generic427 ? L"Could not perform game thread setup, processing HTTP request failed. Increase verbosity for additional information." : L"Could not set libcurl options for easy handle, processing HTTP request failed. Increase verbosity for additional information.") == 0) {
if (wcscmp((wchar_t*)saddr, L"ProcessRequest failed. URL '%s' is not using a whitelisted domain. %p") == 0) {
for (int i = 0; i < 2048; i++) {
if (CheckBytes<0x48, 0x81, 0xEC>(stream, i, true)) {
for (int x = 0; x < 50; x++) {
@@ -144,7 +171,9 @@ setStream:
Log(Display, "Found using UE 4.25, 4.26 & 5.4+ method\n");
stream = (uint8_t*)stream - i - x;
goto HookVT;
} else if (CheckBytes<0x4C, 0x8B, 0xDC>(stream, i + x, true) || CheckBytes<0x4C, 0x8B, 0xC4>(stream, i + x, true)) break;
}
else if (CheckBytes<0x4C, 0x8B, 0xDC>(stream, i + x, true) || CheckBytes<0x48, 0x8B, 0xC4>(stream, i + x, true))
break;
}
}
}
@@ -155,17 +184,6 @@ setStream:
Log(Display, "ProcessRequest: 0x%llx\n", __int64(stream) - __int64(buf));
char* ptrMatches = (char*)&stream;
constexpr static char ptrMasks[] = {
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff,
(char)0xff
};
auto patch2 = pf_construct_patch(ptrMatches, (void*)ptrMasks, 8, PtrCallback);
struct pf_patch_t patches2[] = {
@@ -176,6 +194,36 @@ setStream:
while (!pf_patchset_emit(rbuf, rsize, patchset2));
return true;
}
bool EOSStringCallback(struct pf_patch_t* patch, void* stream) {
void* saddr = (void*)((__int64(stream) + 7) + *(int32_t*)(__int64(stream) + 3));
if (__int64(saddr) >= __int64(EOSRDataBuf) && __int64(saddr) < (__int64(EOSRDataBuf) + (int64_t)EOSRDataSize)) {
if (wcscmp((wchar_t*)saddr, L"ProcessRequest failed. URL '%s' is not using a whitelisted domain. %p") == 0) {
for (int i = 0; i < 2048; i++) {
if (CheckBytes<0x48, 0x89, 0x5C>(stream, i, true)) {
Log(Display, "Found EOS ProcessRequest\n");
stream = (uint8_t*)stream - i;
goto HookVT;
}
}
}
}
return false;
HookVT:
Log(Display, "EOS ProcessRequest: 0x%llx\n", __int64(stream) - __int64(EOSBuf));
char* ptrMatches = (char*)&stream;
auto patch2 = pf_construct_patch(ptrMatches, (void*)ptrMasks, 8, EOSPtrCallback);
struct pf_patch_t patches2[] = {
patch2
};
struct pf_patchset_t patchset2 = pf_construct_patchset(patches2, sizeof(patches2) / sizeof(struct pf_patch_t), (bool (*)(void*, size_t, pf_patchset_t))pf_find_maskmatch);
while (!pf_patchset_emit(EOSRDataBuf, EOSRDataSize, patchset2));
return true;
}
}
namespace Finders {
@@ -188,16 +236,30 @@ setStream:
0xfb,
0xff
};
{
constexpr static auto patch = pf_construct_patch((void*)matches.data(), (void*)masks.data(), 2, StringCallback);
constexpr static auto patch = pf_construct_patch((void*)matches.data(), (void*)masks.data(), 2, StringCallback);
constexpr static pf_patch_t patches[] = {
patch
};
constexpr static pf_patch_t patches[] = {
patch
};
constexpr static struct pf_patchset_t patchset = pf_construct_patchset(patches, sizeof(patches) / sizeof(struct pf_patch_t), pf_find_maskmatch);
constexpr static struct pf_patchset_t patchset = pf_construct_patchset(patches, sizeof(patches) / sizeof(struct pf_patch_t), pf_find_maskmatch);
while (!pf_patchset_emit(tbuf, tsize, patchset));
}
while (!pf_patchset_emit(tbuf, tsize, patchset));
if (EOSBuf) {
constexpr static auto patch = pf_construct_patch((void*)matches.data(), (void*)masks.data(), 2, EOSStringCallback);
constexpr static pf_patch_t patches[] = {
patch
};
constexpr static struct pf_patchset_t patchset = pf_construct_patchset(patches, sizeof(patches) / sizeof(struct pf_patch_t), pf_find_maskmatch);
while (!pf_patchset_emit(EOSTextBuf, EOSTextSize, patchset));
}
}
}
}
+1 -2
View File
@@ -10,8 +10,7 @@ namespace Unreal {
{
public:
void** VTable;
static inline FString& (*GetURLFunc)(FCurlHttpRequest*, FString) = nullptr;
static inline void (*SetURLFunc)(FCurlHttpRequest*, FString) = nullptr;
static inline int64_t SetURLIdx;
static inline void** ProcessRequestVT = nullptr;
FString GetURL();