Simple Rendering x64

Posts 1–6 of 6 · Page 1 of 1
Simple Rendering x64
Well, shit ton of people keep asking me how to create an internal hack because external hacks get annoying at a point. So let's begin, also this method works for x86 as long as you have the correct classes for it.

First we must hook the game's Present function, now in order to do so, we require the IDXGISwapChain pointer which leads us to the VTable itself. This pointer can be found and utilized from the game as well. The class that holds this is ScreenInfo which is held by DxRenderer:

Code:
const DWORD64 OFFSET_DXRENDERER = 0x142540BF0;

class ScreenInfo
{
public:
	BYTE pad00[0x58];				//0x00
	unsigned int m_Width;			//0x58
	unsigned int m_Height;			//0x5C
	unsigned int m_WindowWidth;			//0x60
	unsigned int m_WindowHeight;		//0x64
	BYTE pad01[0x88];				//0x68
	IDXGISwapChain* m_pSwapChain;		//0xF0
};

class DxRenderer
{
public:
	char pad_0x00[0x38];                // 0x00
	ScreenInfo* m_pScreen;                  // 0x38
	char pad_0x40[0xC0];                // 0x40
	ID3D11Device* m_pDevice;            // 0x100
	ID3D11DeviceContext* m_pContext;    // 0x108

	static DxRenderer* Singleton()
	{
		return *(DxRenderer**)OFFSET_DXRENDERER;
	}
};
Now all we need to do is to swap the vtable and initialize. The VTable function, can be easily found or made by yourself as well.

Code:
PBYTE SwapVTable(PDWORD64* pVTable, PBYTE pHook, size_t iIndex)
{
	DWORD dwOld = 0;

	VirtualProtect((PVOID)((*pVTable) + iIndex), sizeof(PDWORD64), PAGE_EXECUTE_READWRITE, &dwOld);

	PBYTE pOrig = ((PBYTE)(*pVTable)[iIndex]);
	(*pVTable)[iIndex] = (DWORD64)pHook;

	VirtualProtect((PVOID)((*pVTable) + iIndex), sizeof(PDWORD64), dwOld, &dwOld);

	return pOrig;
}
Now if the vtable is analyzed you will know that the index of Present is 8. (Not going to go in depth as that is for another time and will take too long to explain.) So all we need to do now is to figure out how to render once hooked. The class DebugRenderer will help us achieve this.

Code:
const DWORD64 OFFSET_DEBUGRENDERER = 0x140616630;
const DWORD64 OFFSET_DRAWTEXT = 0x140617BD0;
const DWORD64 OFFSET_DRAWLINE = 0x1406177A0;
const DWORD64 OFFSET_DRAWLINERECT2D = 0x140617810;
const DWORD64 OFFSET_DRAWFILLRECT = 0x1406179A0;

class DebugRenderer2
	{
	public:
		static DebugRenderer2* Singleton()
		{
			typedef EngineD3D::DebugRenderer2* (__stdcall* EngineD3D__DebugRenderManager_getThreadContext_t)(void);
			EngineD3D__DebugRenderManager_getThreadContext_t EngineD3D__DebugRenderManager_getThreadContext = (EngineD3D__DebugRenderManager_getThreadContext_t)OFFSET_DEBUGRENDERER;

			return EngineD3D__DebugRenderManager_getThreadContext();
		}

		void RenderEngineText(int x, int y, Color32 color, char* text, float scale)
		{
			typedef void(__thiscall *tdrawText)(EngineD3D::DebugRenderer2*, int, int, char*, Color32, float);
			tdrawText mdrawText = (tdrawText)OFFSET_DRAWTEXT;

			mdrawText(this, x, y, text, color, scale);
		}

		void RenderEngineTextCentered(int x, int y, Color32 color, char* text, float scale)
		{
			typedef void(__thiscall *tdrawText)(EngineD3D::DebugRenderer2*, int, int, char *, Color32, float);
			tdrawText mdrawText = (tdrawText)OFFSET_DRAWTEXT;

			mdrawText(this, x - static_cast<int>((strlen(text)) * 4.4), y, text, color, scale);
		}

		void RenderEngine2DLine(float x1, float y1, float x2, float y2, Color32 color)
		{
			Tuple2< float > minpos = Tuple2< float >(x1, y1);
			Tuple2< float > maxpos = Tuple2< float >(x2, y2);

			typedef void(__thiscall *tdrawLine2d)(EngineD3D::DebugRenderer2*, Tuple2<float>*, Tuple2<float>*, Color32);
			tdrawLine2d mdrawLine2d = (tdrawLine2d)OFFSET_DRAWLINE;

			mdrawLine2d(this, &minpos, &maxpos, color);
		}

		void RenderEngine2DLineRect(float x1, float y1, float x2, float y2, Color32 color)
		{
			Tuple2< float > minpos = Tuple2< float >(x1, y1);
			Tuple2< float > maxpos = Tuple2< float >(x2, y2);

			typedef void(__thiscall *tdrawLineRect2d)(EngineD3D::DebugRenderer2*, Tuple2<float>*, Tuple2<float>*, Color32);
			tdrawLineRect2d mdrawLineRect2d = (tdrawLineRect2d)OFFSET_DRAWLINERECT2D;

			mdrawLineRect2d(this, &minpos, &maxpos, color);
		}

		void RenderEngine2DRect(float x1, float y1, float x2, float y2, Color32 color)
		{
			Tuple2< float > minpos = Tuple2< float >(x1, y1);
			Tuple2< float > maxpos = Tuple2< float >(x2, y2);

			typedef void(__thiscall *tdrawRect2d)(EngineD3D::DebugRenderer2*, Tuple2<float>*, Tuple2<float>*, Color32);
			tdrawRect2d mdrawRect2d = (tdrawRect2d)OFFSET_DRAWFILLRECT;

			mdrawRect2d(this, &minpos, &maxpos, color);
		}
	};
Luckily we can just use the game's functions to render text, lines, shaders, etc. All that good shit, now if you want to create your own font, you can use the FW1FontWrapper whose use can be found here. NOW we can initialize. Also we're going to want to disable PB SS or else we'll get banned. Now in order to do that you can just simply null out the game's SS module as that is what PB uses to take screenshots. This will just result in a blank screen when uploaded, this can also occur naturally if there are issues with the user's graphics card which is why PB doesn't ban for this. If you wan't to get a clean screenshot, load up the ss module class in ReClass and analyze what happens when a SS is taken, from there it's pretty much common sense.

Code:
typedef HRESULT(__stdcall *D3D11PresentHook) (IDXGISwapChain* This, UINT SyncInterval, UINT Flags);
D3D11PresentHook oPresent = 0;

HRESULT __stdcall Present(IDXGISwapChain* This, UINT SyncInterval, UINT Flags)
{
	const DWORD64 OFFSET_PBSSMODULE = 0x142546278;
	*reinterpret_cast<PDWORD64*>(OFFSET_PBSSMODULE) = nullptr; //nulls out screenshot module

	EngineD3D::DebugRenderer2::Singleton()->RenderEngineText(100, 100, EngineD3D::Color32(255, 0, 0, 255), "EHRMAGERD RENDERED", 1.0f);

	return oPresent(This, SyncInterval, Flags);
}

bool _HookPresent()
{
	oPresent = reinterpret_cast<D3D11PresentHook>(SwapVTable(reinterpret_cast<PDWORD64*>(DxRenderer::Singleton()->m_pScreen->m_pSwapChain), reinterpret_cast<PBYTE>(&Present), 8));

	return true;
}
Last but not least, set the platform to x64 as well as a x64 injector. If you guys have any questions, feel free to ask. I'll probably post how to achieve entity iteration (player, weapon, vehicle, explosives, etc) if people ask for it.
I was hoping this wouldn't be fed out to everyone. Should include some anti C+P in that I would say.
Quote Originally Posted by Flengo View Post
I was hoping this wouldn't be fed out to everyone. Should include some anti C+P in that I would say.
Lol, you're acting as if this is the ONLY method to render and it has finally been released. All I literally did is simplified it into one thread. You can find any other hack base and they do it the same way. Method has been out for years, wouldn't make a difference.
Quote Originally Posted by arun823 View Post
Lol, you're acting as if this is the ONLY method to render and it has finally been released. All I literally did is simplified it into one thread. You can find any other hack base and they do it the same way. Method has been out for years, wouldn't make a difference.
No I know the method has been out. It's not the only way, but it's the most convenient way.

Code:
const DWORD64 OFFSET_DEBUGRENDERER = 0x140616630;
const DWORD64 OFFSET_DRAWTEXT = 0x140617BD0;
const DWORD64 OFFSET_DRAWLINE = 0x1406177A0;
const DWORD64 OFFSET_DRAWLINERECT2D = 0x140617810;
const DWORD64 OFFSET_DRAWFILLRECT = 0x1406179A0;
The area of concern which feeds them, since that's all that's not public available or updated.
Quote Originally Posted by Flengo View Post


No I know the method has been out. It's not the only way, but it's the most convenient way.

Code:
const DWORD64 OFFSET_DEBUGRENDERER = 0x140616630;
const DWORD64 OFFSET_DRAWTEXT = 0x140617BD0;
const DWORD64 OFFSET_DRAWLINE = 0x1406177A0;
const DWORD64 OFFSET_DRAWLINERECT2D = 0x140617810;
const DWORD64 OFFSET_DRAWFILLRECT = 0x1406179A0;
The area of concern which feeds them, since that's all that's not public available or updated.
Yes, but it is publicly available lol. Either way, a c+p wouldn't know how to get the addresses after an update.
here are some updated offsets to use this :+)

Code:
GetInstance: 0x140618210 (gather dbgrenderer2 instance by calling it)
DrawText: 0x1406195B0
DrawRect: 0x1406191F0
DrawFilledRect: 0x140619380


+

Code:
SSModule: 0x14254AFF8
Posts 1–6 of 6 · Page 1 of 1
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Talk with us