ProcessEvent Hook for almost all UE game, Hook + Rendering

04/27/2024 13:02 MRx86™#1
Hi Folkz!

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:

[Only registered and activated users can see links. Click Here To Register...]

[Only registered and activated users can see links. Click Here To Register...]

[Only registered and activated users can see links. Click Here To Register...]

[Only registered and activated users can see links. Click Here To Register...]

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.

:p
04/30/2024 20:49 Gipha#2
#moved