mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Fix unresolved external symbol errors for loader.dll
Moved CModule statics to a separate translation unit, preventing the linker to link unused stuff into the loader module, thus allowing us to drop the linkage of unused libraries.
This commit is contained in:
parent
a82b4c950c
commit
c1a0276951
@ -20,14 +20,7 @@ target_link_libraries( ${PROJECT_NAME} PRIVATE
|
||||
"vpc"
|
||||
"tier0"
|
||||
|
||||
# TODO: these have to be removed, currently
|
||||
# linked as it would otherwise throw linker
|
||||
# errors due to undefined external symbols.
|
||||
"libdetours"
|
||||
"liblzham"
|
||||
"libprotobuf"
|
||||
"libspdlog"
|
||||
"SigCache_Pb"
|
||||
)
|
||||
|
||||
end_sources()
|
||||
|
@ -37,6 +37,7 @@ add_sources( SOURCE_GROUP "Runtime"
|
||||
"jobthread.cpp"
|
||||
"memaddr.cpp"
|
||||
"module.cpp"
|
||||
"module_statics.cpp"
|
||||
"platform.cpp"
|
||||
"sigcache.cpp"
|
||||
"threadtools.cpp"
|
||||
|
@ -432,137 +432,6 @@ CMemory CModule::GetVirtualMethodTable(const char* szTableName, const size_t nRe
|
||||
return CMemory();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get address of imported function in target module
|
||||
// Input : *szModuleName -
|
||||
// *szSymbolName -
|
||||
// bGetSymbolReference -
|
||||
// Output : CMemory
|
||||
//-----------------------------------------------------------------------------
|
||||
CMemory CModule::GetImportedSymbol(QWORD pModuleBase, const char* szModuleName,
|
||||
const char* szSymbolName, const bool bGetSymbolReference)
|
||||
{
|
||||
IMAGE_DOS_HEADER* pDOSHeader = GetDOSHeader(pModuleBase);
|
||||
IMAGE_NT_HEADERS64* pNTHeaders = GetNTHeaders(pModuleBase);
|
||||
|
||||
if (!pDOSHeader || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
if (!pNTHeaders || pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of IMAGE_IMPORT_DESCRIPTOR for this
|
||||
// module by adding the IMAGE_DIRECTORY_ENTRY_IMPORT
|
||||
// relative virtual address onto our module base address.
|
||||
IMAGE_IMPORT_DESCRIPTOR* pImageImportDescriptors = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>
|
||||
(pModuleBase + pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
|
||||
if (!pImageImportDescriptors)
|
||||
return nullptr;
|
||||
|
||||
for (IMAGE_IMPORT_DESCRIPTOR* pIID = pImageImportDescriptors; pIID->Name != 0; pIID++)
|
||||
{
|
||||
// Get virtual relative Address of the imported module name.
|
||||
// Then add module base Address to get the actual location.
|
||||
const char* szImportedModuleName = reinterpret_cast<char*>(reinterpret_cast<DWORD*>(pModuleBase + pIID->Name));
|
||||
|
||||
if (stricmp(szImportedModuleName, szModuleName) == NULL)
|
||||
{
|
||||
IMAGE_THUNK_DATA* pOgFirstThunk = reinterpret_cast<IMAGE_THUNK_DATA*>(pModuleBase + pIID->OriginalFirstThunk);
|
||||
|
||||
// To get actual function address.
|
||||
IMAGE_THUNK_DATA* pFirstThunk = reinterpret_cast<IMAGE_THUNK_DATA*>(pModuleBase + pIID->FirstThunk);
|
||||
for (; pOgFirstThunk->u1.AddressOfData; ++pOgFirstThunk, ++pFirstThunk)
|
||||
{
|
||||
// Get image import by name.
|
||||
const IMAGE_IMPORT_BY_NAME* pImageImportByName = reinterpret_cast<IMAGE_IMPORT_BY_NAME*>(
|
||||
pModuleBase + pOgFirstThunk->u1.AddressOfData);
|
||||
|
||||
if (strcmp(pImageImportByName->Name, szSymbolName) == NULL)
|
||||
{
|
||||
// Grab function address from firstThunk.
|
||||
QWORD* pFunctionAddress = &pFirstThunk->u1.Function;
|
||||
|
||||
// Reference or address?
|
||||
return bGetSymbolReference ? CMemory(pFunctionAddress) : CMemory(*pFunctionAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get address of exported symbol in this module
|
||||
// Input : *pModuleBase -
|
||||
// szSymbolName -
|
||||
// Output : CMemory
|
||||
//-----------------------------------------------------------------------------
|
||||
CMemory CModule::GetExportedSymbol(QWORD pModuleBase, const char* szSymbolName)
|
||||
{
|
||||
IMAGE_DOS_HEADER* pDOSHeader = GetDOSHeader(pModuleBase);
|
||||
IMAGE_NT_HEADERS64* pNTHeaders = GetNTHeaders(pModuleBase);
|
||||
|
||||
if (!pDOSHeader || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
if (!pNTHeaders || pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of IMAGE_EXPORT_DIRECTORY for this
|
||||
// module by adding the IMAGE_DIRECTORY_ENTRY_EXPORT
|
||||
// relative virtual address onto our module base address.
|
||||
const IMAGE_EXPORT_DIRECTORY* pImageExportDirectory =
|
||||
reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(pModuleBase
|
||||
+ pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
if (!pImageExportDirectory)
|
||||
return nullptr;
|
||||
|
||||
if (!pImageExportDirectory->NumberOfFunctions)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of the functions.
|
||||
const DWORD* pAddressOfFunctions = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfFunctions);
|
||||
|
||||
if (!pAddressOfFunctions)
|
||||
return nullptr;
|
||||
|
||||
// Get the names of the functions.
|
||||
const DWORD* pAddressOfName = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfNames);
|
||||
|
||||
if (!pAddressOfName)
|
||||
return nullptr;
|
||||
|
||||
// Get the ordinals of the functions.
|
||||
DWORD* pAddressOfOrdinals = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
if (!pAddressOfOrdinals)
|
||||
return nullptr;
|
||||
|
||||
for (DWORD i = 0; i < pImageExportDirectory->NumberOfFunctions; i++)
|
||||
{
|
||||
// Get virtual relative Address of the function name,
|
||||
// then add module base Address to get the actual location.
|
||||
const char* ExportFunctionName =
|
||||
reinterpret_cast<char*>(reinterpret_cast<DWORD*>(
|
||||
pModuleBase + pAddressOfName[i]));
|
||||
|
||||
if (strcmp(ExportFunctionName, szSymbolName) == NULL)
|
||||
{
|
||||
// Get the function ordinal, then grab the relative
|
||||
// virtual address of our wanted function. Then add
|
||||
// module base address so we get the actual location.
|
||||
return pModuleBase
|
||||
+ pAddressOfFunctions[reinterpret_cast<WORD*>(pAddressOfOrdinals)[i]];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: unlink module from peb
|
||||
// Disclaimer: This does not bypass GetMappedFileName. That function calls
|
||||
|
141
r5dev/tier0/module_statics.cpp
Normal file
141
r5dev/tier0/module_statics.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
//===========================================================================//
|
||||
//
|
||||
// Purpose: Implementation of static methods in the CModule class.
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Static methods are implemented here to avoid linker errors, as the CModule
|
||||
// class relies on a protobuf based caching implementation. This allows us to
|
||||
// not link unnecessary libraries to modules using these methods.
|
||||
//===========================================================================//
|
||||
#include "tier0/module.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get address of imported function in target module
|
||||
// Input : *szModuleName -
|
||||
// *szSymbolName -
|
||||
// bGetSymbolReference -
|
||||
// Output : CMemory
|
||||
//-----------------------------------------------------------------------------
|
||||
CMemory CModule::GetImportedSymbol(QWORD pModuleBase, const char* szModuleName,
|
||||
const char* szSymbolName, const bool bGetSymbolReference)
|
||||
{
|
||||
IMAGE_DOS_HEADER* pDOSHeader = GetDOSHeader(pModuleBase);
|
||||
IMAGE_NT_HEADERS64* pNTHeaders = GetNTHeaders(pModuleBase);
|
||||
|
||||
if (!pDOSHeader || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
if (!pNTHeaders || pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of IMAGE_IMPORT_DESCRIPTOR for this
|
||||
// module by adding the IMAGE_DIRECTORY_ENTRY_IMPORT
|
||||
// relative virtual address onto our module base address.
|
||||
IMAGE_IMPORT_DESCRIPTOR* pImageImportDescriptors = reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>
|
||||
(pModuleBase + pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
|
||||
if (!pImageImportDescriptors)
|
||||
return nullptr;
|
||||
|
||||
for (IMAGE_IMPORT_DESCRIPTOR* pIID = pImageImportDescriptors; pIID->Name != 0; pIID++)
|
||||
{
|
||||
// Get virtual relative Address of the imported module name.
|
||||
// Then add module base Address to get the actual location.
|
||||
const char* szImportedModuleName = reinterpret_cast<char*>(reinterpret_cast<DWORD*>(pModuleBase + pIID->Name));
|
||||
|
||||
if (stricmp(szImportedModuleName, szModuleName) == NULL)
|
||||
{
|
||||
IMAGE_THUNK_DATA* pOgFirstThunk = reinterpret_cast<IMAGE_THUNK_DATA*>(pModuleBase + pIID->OriginalFirstThunk);
|
||||
|
||||
// To get actual function address.
|
||||
IMAGE_THUNK_DATA* pFirstThunk = reinterpret_cast<IMAGE_THUNK_DATA*>(pModuleBase + pIID->FirstThunk);
|
||||
for (; pOgFirstThunk->u1.AddressOfData; ++pOgFirstThunk, ++pFirstThunk)
|
||||
{
|
||||
// Get image import by name.
|
||||
const IMAGE_IMPORT_BY_NAME* pImageImportByName = reinterpret_cast<IMAGE_IMPORT_BY_NAME*>(
|
||||
pModuleBase + pOgFirstThunk->u1.AddressOfData);
|
||||
|
||||
if (strcmp(pImageImportByName->Name, szSymbolName) == NULL)
|
||||
{
|
||||
// Grab function address from firstThunk.
|
||||
QWORD* pFunctionAddress = &pFirstThunk->u1.Function;
|
||||
|
||||
// Reference or address?
|
||||
return bGetSymbolReference ? CMemory(pFunctionAddress) : CMemory(*pFunctionAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get address of exported symbol in this module
|
||||
// Input : *pModuleBase -
|
||||
// szSymbolName -
|
||||
// Output : CMemory
|
||||
//-----------------------------------------------------------------------------
|
||||
CMemory CModule::GetExportedSymbol(QWORD pModuleBase, const char* szSymbolName)
|
||||
{
|
||||
IMAGE_DOS_HEADER* pDOSHeader = GetDOSHeader(pModuleBase);
|
||||
IMAGE_NT_HEADERS64* pNTHeaders = GetNTHeaders(pModuleBase);
|
||||
|
||||
if (!pDOSHeader || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
if (!pNTHeaders || pNTHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of IMAGE_EXPORT_DIRECTORY for this
|
||||
// module by adding the IMAGE_DIRECTORY_ENTRY_EXPORT
|
||||
// relative virtual address onto our module base address.
|
||||
const IMAGE_EXPORT_DIRECTORY* pImageExportDirectory =
|
||||
reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(pModuleBase
|
||||
+ pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
|
||||
if (!pImageExportDirectory)
|
||||
return nullptr;
|
||||
|
||||
if (!pImageExportDirectory->NumberOfFunctions)
|
||||
return nullptr;
|
||||
|
||||
// Get the location of the functions.
|
||||
const DWORD* pAddressOfFunctions = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfFunctions);
|
||||
|
||||
if (!pAddressOfFunctions)
|
||||
return nullptr;
|
||||
|
||||
// Get the names of the functions.
|
||||
const DWORD* pAddressOfName = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfNames);
|
||||
|
||||
if (!pAddressOfName)
|
||||
return nullptr;
|
||||
|
||||
// Get the ordinals of the functions.
|
||||
DWORD* pAddressOfOrdinals = reinterpret_cast<DWORD*>(pModuleBase
|
||||
+ pImageExportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
if (!pAddressOfOrdinals)
|
||||
return nullptr;
|
||||
|
||||
for (DWORD i = 0; i < pImageExportDirectory->NumberOfFunctions; i++)
|
||||
{
|
||||
// Get virtual relative Address of the function name,
|
||||
// then add module base Address to get the actual location.
|
||||
const char* ExportFunctionName =
|
||||
reinterpret_cast<char*>(reinterpret_cast<DWORD*>(
|
||||
pModuleBase + pAddressOfName[i]));
|
||||
|
||||
if (strcmp(ExportFunctionName, szSymbolName) == NULL)
|
||||
{
|
||||
// Get the function ordinal, then grab the relative
|
||||
// virtual address of our wanted function. Then add
|
||||
// module base address so we get the actual location.
|
||||
return pModuleBase
|
||||
+ pAddressOfFunctions[reinterpret_cast<WORD*>(pAddressOfOrdinals)[i]];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user