This just an example for Unreal Engine 3 x86. Exactly Special Force 2( back the past ). but this should work for any UE version
According to the code. recently i saw.
STEP 1: Lets identify Process Event Function look screenshot below-
Jobs:
Intercept memcpy from Process Event and wait for exactly returnaddress into ProcessEvent, + retrive from stack all parametar for Process Event.
According to UE to code analysis they call memcpy into ProcessEvent UE3/UE4/UE5 :coolmaninthetoilet:

Code:
UGameViewportClient_eventPostRender_Parms* BlaBla;
ASFPlayerController* PlayerController = nullptr;
ASFWeapon* sfweapon = nullptr;
void PostRender ( UGameViewportClient_eventPostRender_Parms * asd )
{
if (asd && asd->Canvas)
{
asd->Canvas->SetPos(10,10,0);
asd->Canvas->DrawTextA(L"GHTheBoss D3D", FALSE, 1.0f, 1.0f, 0);
}
}
void* (__cdecl* omemcpy) (void* dest, const void* src, size_t count);
void* __cdecl nmemcpy(void* dest, const void* src, size_t count)
{
static DWORD hReturnProcessEvent = NULL;
__asm pushad
__asm mov eax, [ebp + 0x4]
__asm mov hReturnProcessEvent, eax
if (hReturnProcessEvent == 0x45442E || hReturnProcessEvent == 0x4542C6/*0x454D96*/)
{
UFunction * pFunction = nullptr;
__asm mov ecx,dword ptr[ebp-0x20] // UFunction
__asm mov pFunction, ecx
if (engine->ValidPointer(pFunction))
{
const char* szName = pFunction->GetFullName();
if (strlen((char*)szName))
{
static DWORD pObject = NULL; //pobject
__asm mov ecx, dword ptr[ebp-0xC]
__asm mov pObject, ecx
//tool->add_log("DEBUG.log", "szName %s\npFunction %x\npObject %x", szName, pFunction, pObject);
if (strcmp(szName, "Function Engine.GameViewportClient.PostRender") == 0)
{
BlaBla = (UGameViewportClient_eventPostRender_Parms*)(src);
PostRender(BlaBla);
}
if ( strcmp(szName,"Function SFGame.SFPlayerController.PlayerTick") == 0 )
{
PlayerController = (ASFPlayerController*)(pObject);
}
if ( strcmp(szName,"Function SFGame.SFPlayerController.Destroyed") == 0 )
{
PlayerController = nullptr;
}
}
}
}// ReturnAddress
__asm popad
return omemcpy(dest, src, count);
}
DWORD WINAPI InitHook()
{
DWORD dwBack;
VirtualProtect((void*)0x136D5A0/*0x0136C5A0*/, 4, PAGE_READWRITE, &dwBack);
IatHook(0x136D5A0/*0x0136C5A0*/, omemcpy, nmemcpy);
VirtualProtect((void*)0x136D5A0/*0x0136C5A0*/, 4, dwBack, &dwBack);
return 0;
}
just a few precautions need to be taken when swap memcpy, make sure you point it into a legit module.






