diff --git a/r5dev/public/utility/vtable.cpp b/r5dev/public/utility/vtable.cpp
new file mode 100644
index 00000000..e110dcc7
--- /dev/null
+++ b/r5dev/public/utility/vtable.cpp
@@ -0,0 +1,89 @@
+//===========================================================================//
+//
+// Purpose: Implementation of the CVTableHelper class, used to assist in
+//          function rebuilding and reverse engineering.
+//          DO NOT USE FOR SHIPPING CODE!!!!!!!!!!
+//
+//===========================================================================//
+#include "core/stdafx.h"
+#include "public/utility/vtable.h"
+#include "public/utility/memaddr.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: create class instance from passed module and virtual table name
+// Input  : CModule* -
+//          const std::string& -
+//          uint32_t
+//-----------------------------------------------------------------------------
+CVTableHelper::CVTableHelper(CModule* module, const std::string& tableName, uint32_t refIndex) : m_svVirtualTableName(tableName)
+{
+	m_pVirtualTable = module->GetVirtualMethodTable(tableName, refIndex);
+	m_nVirtualFunctionCount = GetVTableLength();
+	GetAllVTableFunctions();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: create class instance from passed pointer
+// Input  : uintptr_t -
+//          const std::string& -
+//-----------------------------------------------------------------------------
+CVTableHelper::CVTableHelper(uintptr_t virtualTable, const std::string& tableName) : m_pVirtualTable(virtualTable), m_svVirtualTableName(tableName)
+{
+	m_nVirtualFunctionCount = GetVTableLength();
+	GetAllVTableFunctions();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: create class instance from passed pointer
+// Input  : void* -
+//          const std::string& -
+//-----------------------------------------------------------------------------
+CVTableHelper::CVTableHelper(void* virtualTable, const std::string& tableName) : m_pVirtualTable(uintptr_t(virtualTable)), m_svVirtualTableName(tableName)
+{
+	m_nVirtualFunctionCount = GetVTableLength();
+	GetAllVTableFunctions();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: gets function count of m_pVirtualTable
+// Output : ptrdiff_t
+//-----------------------------------------------------------------------------
+ptrdiff_t CVTableHelper::GetVTableLength()
+{
+	uintptr_t* pStartOfVTable = reinterpret_cast<uintptr_t*>(m_pVirtualTable);
+	MEMORY_BASIC_INFORMATION memInfo = { NULL };
+	ptrdiff_t vtSize = -1;
+
+	do {
+		vtSize++;
+		VirtualQuery(reinterpret_cast<void*>(pStartOfVTable[vtSize]), &memInfo, sizeof(memInfo));
+	} while (memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_EXECUTE_READWRITE);
+
+	return vtSize;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: populate m_vVirtualFunctions with all virtual function pointers
+//-----------------------------------------------------------------------------
+void CVTableHelper::GetAllVTableFunctions()
+{
+	for (ptrdiff_t i = 0; i < m_nVirtualFunctionCount; i++)
+	{
+		m_vVirtualFunctions.push_back(*reinterpret_cast<uintptr_t*>(m_pVirtualTable + (8 * i)));
+	}
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: call function from m_vVirtualFunctions with passed index
+// Input  : int -
+//          void* -
+//          arg_list -
+// Output : Assigned template return type
+//-----------------------------------------------------------------------------
+template <typename ReturnType, typename ...Args>
+ReturnType CVTableHelper::Call(int index, void* thisPtr, Args... args)
+{
+	return reinterpret_cast<ReturnType(__fastcall*)(void*, Args...)>(m_vVirtualFunctions.at(index))(thisPtr, args...);
+}
\ No newline at end of file
diff --git a/r5dev/public/utility/vtable.h b/r5dev/public/utility/vtable.h
new file mode 100644
index 00000000..247255fd
--- /dev/null
+++ b/r5dev/public/utility/vtable.h
@@ -0,0 +1,53 @@
+#pragma once
+
+class CVTableHelper
+{
+public:
+
+	CVTableHelper(void) = default;
+	CVTableHelper(CModule* module, const std::string& tableName = "", uint32_t refIndex = 0);
+	CVTableHelper(uintptr_t virtualTable, const std::string& tableName = "");
+	CVTableHelper(void* virtualTable, const std::string& tableName = "");
+
+	inline operator uintptr_t(void) const
+	{
+		return m_pVirtualTable;
+	}
+
+	inline operator void* (void) const
+	{
+		return reinterpret_cast<void*>(m_pVirtualTable);
+	}
+
+	inline operator bool(void) const
+	{
+		return m_pVirtualTable != NULL && !m_vVirtualFunctions.empty();
+	}
+
+	uintptr_t GetVirtualFunctionTable()
+	{
+		return m_pVirtualTable;
+	}
+
+	ptrdiff_t GetVirtualFunctionCount()
+	{
+		return m_nVirtualFunctionCount;
+	}
+
+	const std::string& GetVTableName()
+	{
+		return m_svVirtualTableName;
+	}
+
+	template <typename ReturnType, typename ...Args>
+	ReturnType Call(int index, void* thisPtr, Args... args);
+
+private:
+	void GetAllVTableFunctions();
+	ptrdiff_t GetVTableLength();
+
+	uintptr_t m_pVirtualTable;
+	string m_svVirtualTableName;
+	ptrdiff_t m_nVirtualFunctionCount;
+	vector<uintptr_t> m_vVirtualFunctions;
+};
\ No newline at end of file
diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj
index 1ebcecaf..59c7c3d9 100644
--- a/r5dev/vproj/clientsdk.vcxproj
+++ b/r5dev/vproj/clientsdk.vcxproj
@@ -107,6 +107,7 @@
     <ClCompile Include="..\public\utility\module.cpp" />
     <ClCompile Include="..\public\utility\sigcache.cpp" />
     <ClCompile Include="..\public\utility\utility.cpp" />
+    <ClCompile Include="..\public\utility\vtable.cpp" />
     <ClCompile Include="..\rtech\rtech_utils.cpp" />
     <ClCompile Include="..\rtech\rtech_game.cpp" />
     <ClCompile Include="..\rtech\rui\rui.cpp" />
@@ -315,6 +316,7 @@
     <ClInclude Include="..\public\utility\sigcache.h" />
     <ClInclude Include="..\public\utility\utility.h" />
     <ClInclude Include="..\public\utility\vdf_parser.h" />
+    <ClInclude Include="..\public\utility\vtable.h" />
     <ClInclude Include="..\public\worldsize.h" />
     <ClInclude Include="..\rtech\rtech_utils.h" />
     <ClInclude Include="..\rtech\rtech_game.h" />
diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters
index 2e0f11c1..2505cc74 100644
--- a/r5dev/vproj/clientsdk.vcxproj.filters
+++ b/r5dev/vproj/clientsdk.vcxproj.filters
@@ -645,6 +645,9 @@
     <ClCompile Include="..\engine\matsys_interface.cpp">
       <Filter>sdk\engine</Filter>
     </ClCompile>
+    <ClCompile Include="..\public\utility\vtable.cpp">
+      <Filter>sdk\public\utility</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\client\cdll_engine_int.h">
@@ -1871,6 +1874,9 @@
     <ClInclude Include="..\engine\matsys_interface.h">
       <Filter>sdk\engine</Filter>
     </ClInclude>
+    <ClInclude Include="..\public\utility\vtable.h">
+      <Filter>sdk\public\utility</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="..\shared\resource\lockedserver.png">
diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj
index 2b940ac2..d9469e8d 100644
--- a/r5dev/vproj/dedicated.vcxproj
+++ b/r5dev/vproj/dedicated.vcxproj
@@ -248,6 +248,7 @@
     <ClInclude Include="..\public\utility\sigcache.h" />
     <ClInclude Include="..\public\utility\utility.h" />
     <ClInclude Include="..\public\utility\vdf_parser.h" />
+    <ClInclude Include="..\public\utility\vtable.h" />
     <ClInclude Include="..\public\worldsize.h" />
     <ClInclude Include="..\rtech\rtech_utils.h" />
     <ClInclude Include="..\rtech\rtech_game.h" />
@@ -566,6 +567,7 @@
     <ClCompile Include="..\public\utility\module.cpp" />
     <ClCompile Include="..\public\utility\sigcache.cpp" />
     <ClCompile Include="..\public\utility\utility.cpp" />
+    <ClCompile Include="..\public\utility\vtable.cpp" />
     <ClCompile Include="..\rtech\rtech_utils.cpp" />
     <ClCompile Include="..\rtech\rtech_game.cpp" />
     <ClCompile Include="..\rtech\stryder\stryder.cpp" />
diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters
index d1026dc6..41de95c6 100644
--- a/r5dev/vproj/dedicated.vcxproj.filters
+++ b/r5dev/vproj/dedicated.vcxproj.filters
@@ -1281,6 +1281,9 @@
     <ClInclude Include="..\public\utility\sigcache.h">
       <Filter>sdk\public\utility</Filter>
     </ClInclude>
+    <ClInclude Include="..\public\utility\vtable.h">
+      <Filter>sdk\public\utility</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\common\opcodes.cpp">
@@ -1616,6 +1619,9 @@
     <ClCompile Include="..\public\utility\sigcache.cpp">
       <Filter>sdk\public\utility</Filter>
     </ClCompile>
+    <ClCompile Include="..\public\utility\vtable.cpp">
+      <Filter>sdk\public\utility</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\Dedicated.def" />
diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj
index 901c44d1..ea6527ac 100644
--- a/r5dev/vproj/gamesdk.vcxproj
+++ b/r5dev/vproj/gamesdk.vcxproj
@@ -116,6 +116,7 @@
     <ClCompile Include="..\public\utility\module.cpp" />
     <ClCompile Include="..\public\utility\sigcache.cpp" />
     <ClCompile Include="..\public\utility\utility.cpp" />
+    <ClCompile Include="..\public\utility\vtable.cpp" />
     <ClCompile Include="..\rtech\rtech_utils.cpp" />
     <ClCompile Include="..\rtech\rtech_game.cpp" />
     <ClCompile Include="..\rtech\rui\rui.cpp" />
@@ -345,6 +346,7 @@
     <ClInclude Include="..\public\utility\module.h" />
     <ClInclude Include="..\public\utility\sigcache.h" />
     <ClInclude Include="..\public\utility\utility.h" />
+    <ClInclude Include="..\public\utility\vtable.h" />
     <ClInclude Include="..\public\worldsize.h" />
     <ClInclude Include="..\rtech\rtech_utils.h" />
     <ClInclude Include="..\rtech\rtech_game.h" />
diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters
index 28608123..a70d2663 100644
--- a/r5dev/vproj/gamesdk.vcxproj.filters
+++ b/r5dev/vproj/gamesdk.vcxproj.filters
@@ -687,6 +687,9 @@
     <ClCompile Include="..\engine\matsys_interface.cpp">
       <Filter>sdk\engine</Filter>
     </ClCompile>
+    <ClCompile Include="..\public\utility\vtable.cpp">
+      <Filter>sdk\public\utility</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\client\cdll_engine_int.h">
@@ -1973,6 +1976,9 @@
     <ClInclude Include="..\engine\matsys_interface.h">
       <Filter>sdk\engine</Filter>
     </ClInclude>
+    <ClInclude Include="..\public\utility\vtable.h">
+      <Filter>sdk\public\utility</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Image Include="..\shared\resource\lockedserver.png">