106
Reversing / [ Reversing ] [ Reversing ] Find GetRenderContext in Source Engine for Chams
« on: January 01, 2023, 09:24:22 PM »
In Dx9 hacks you can get advanced DrawIndexedPrimitive chams using the engines CMaterialSystem GetRenderContext method.
in the source code you can find this refrence
and this is what it looks like in ida:
(search for the strings sub_10341DF0("cl_software_cursor"); sub_10341030(Buffer, 0x100u, "mat_setvideomode %i %i %i\n", this[128]);
from that we can see our index for render context:
RenderContext = (*(*g_pMaterialSystem + 412))(g_pMaterialSystem);
412 bytes.. divided by 4 gives us our vtable pointer index (103)
here is a class it returns.. think i found it on UC or UnstucK
and this is how you use it in DIP
in the source code you can find this refrence
Code: [Select]
void CClientVirtualReality::Deactivate()
{
if( !UseVR() )
return;
g_pSourceVR->Deactivate();
g_pMatSystemSurface->ForceScreenSizeOverride(false, 0, 0 );
g_pMaterialSystem->GetRenderContext()->Viewport( 0, 0, m_nNonVRWidth, m_nNonVRHeight );
g_pMatSystemSurface->SetFullscreenViewportAndRenderTarget( 0, 0, m_nNonVRWidth, m_nNonVRHeight, NULL );
static ConVarRef cl_software_cursor( "cl_software_cursor" );
and this is what it looks like in ida:
(search for the strings sub_10341DF0("cl_software_cursor"); sub_10341030(Buffer, 0x100u, "mat_setvideomode %i %i %i\n", this[128]);
Code: [Select]
void __thiscall sub_100F7700(_DWORD *this)
{
int RenderContext; // eax
if ( dword_1058D9B4 && (*(*dword_1058D9B4 + 36))(dword_1058D9B4) )
{
(*(*dword_1058D9B4 + 104))(dword_1058D9B4);
(*(*g_pMatSystemSurface + 544))(g_pMatSystemSurface, 0, 0, 0);
RenderContext = (*(*g_pMaterialSystem + 412))(g_pMaterialSystem);
(*(*RenderContext + 152))(RenderContext, 0, 0, this[128], this[129]);
(*(*g_pMatSystemSurface + 704))(g_pMatSystemSurface, 0, 0, this[128], this[129], 0);
if ( (dword_1058F218 & 1) == 0 )
{
dword_1058F218 |= 1u;
sub_10341DF0("cl_software_cursor");
from that we can see our index for render context:
RenderContext = (*(*g_pMaterialSystem + 412))(g_pMaterialSystem);
412 bytes.. divided by 4 gives us our vtable pointer index (103)
here is a class it returns.. think i found it on UC or UnstucK
Code: [Select]
class CMaterialRenderContext
{
public:
BYTE pad0[0xc];
void** pad1;
uintptr_t RenderEntity;
__forceinline void* GetCurrentEnt()
{
if (RenderEntity == 0)
return nullptr;
return (void*)(RenderEntity - 4);
}
};
and this is how you use it in DIP
Code: [Select]
HRESULT __stdcall MyDrawIndexedPrimitive(IDirect3DDevice9* Device, D3DPRIMITIVETYPE PrimType, int BaseVertexIndex, unsigned int MinIndex, unsigned int NumVertices, unsigned int StartIndex, unsigned int PrimitiveCount)
{
if (!chams)
return OriginalDrawIndexedPrimitive(Device, PrimType, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount);
bool FillChanged = false;
static SourceEngine::CMaterialRenderContext* RenderCtx = nullptr;
if (!IsValidPointer(RenderCtx))
{
DbgLog(L"[Dx9 Dip] Trying to find Render Ctx\n");
//TODO: If the vfunc is called, it needs releaseing because its refcounted
RenderCtx = SourceEngine::s_Material->GetRenderContext();
}
if (IsValidPointer(RenderCtx))
{
SourceEngine::CValveEnt* Ent = (SourceEngine::CValveEnt*)RenderCtx->GetCurrentEnt();