mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
utils: print out DLL metadata (#596)
## Link to GitHub Issue or related Pull Request, if one exists #592 ## Description of change * when custom DLLs are detected (`d3d9.dll`) print out some basic data from the PE header * for our own NVIDIA DLL stubs, add manifest files to identify ourselves * as a bonus, when DLL hooks are loaded from `-k`, print DLL info there as well This is mainly to detect when DXVK is in use.
This commit is contained in:
@@ -266,6 +266,7 @@ set_source_files_properties(cfg/manifest.rc PROPERTIES LANGUAGE RC)
|
|||||||
set_source_files_properties(cfg/icon.rc PROPERTIES LANGUAGE RC)
|
set_source_files_properties(cfg/icon.rc PROPERTIES LANGUAGE RC)
|
||||||
set_source_files_properties(cfg/Win32D.rc PROPERTIES LANGUAGE RC)
|
set_source_files_properties(cfg/Win32D.rc PROPERTIES LANGUAGE RC)
|
||||||
set_source_files_properties(build/manifest64.rc PROPERTIES LANGUAGE RC)
|
set_source_files_properties(build/manifest64.rc PROPERTIES LANGUAGE RC)
|
||||||
|
set_source_files_properties(stubs/manifest.rc PROPERTIES LANGUAGE RC)
|
||||||
|
|
||||||
# sources
|
# sources
|
||||||
#########
|
#########
|
||||||
@@ -813,7 +814,8 @@ endif()
|
|||||||
|
|
||||||
# nvcuda.dll
|
# nvcuda.dll
|
||||||
set(SOURCE_FILES stubs/nvcuda.cpp)
|
set(SOURCE_FILES stubs/nvcuda.cpp)
|
||||||
add_library(spicetools_stubs_nvcuda SHARED ${SOURCE_FILES} stubs/nvcuda.def)
|
set(RESOURCE_FILES stubs/manifest.rc)
|
||||||
|
add_library(spicetools_stubs_nvcuda SHARED ${SOURCE_FILES} ${RESOURCE_FILES} stubs/nvcuda.def)
|
||||||
set_target_properties(spicetools_stubs_nvcuda PROPERTIES PREFIX "")
|
set_target_properties(spicetools_stubs_nvcuda PROPERTIES PREFIX "")
|
||||||
set_target_properties(spicetools_stubs_nvcuda PROPERTIES OUTPUT_NAME "nvcuda")
|
set_target_properties(spicetools_stubs_nvcuda PROPERTIES OUTPUT_NAME "nvcuda")
|
||||||
|
|
||||||
@@ -823,7 +825,8 @@ endif()
|
|||||||
|
|
||||||
# nvcuvid.dll
|
# nvcuvid.dll
|
||||||
set(SOURCE_FILES stubs/nvcuvid.cpp)
|
set(SOURCE_FILES stubs/nvcuvid.cpp)
|
||||||
add_library(spicetools_stubs_nvcuvid SHARED ${SOURCE_FILES} stubs/nvcuvid.def)
|
set(RESOURCE_FILES stubs/manifest.rc)
|
||||||
|
add_library(spicetools_stubs_nvcuvid SHARED ${SOURCE_FILES} ${RESOURCE_FILES} stubs/nvcuvid.def)
|
||||||
set_target_properties(spicetools_stubs_nvcuvid PROPERTIES PREFIX "")
|
set_target_properties(spicetools_stubs_nvcuvid PROPERTIES PREFIX "")
|
||||||
set_target_properties(spicetools_stubs_nvcuvid PROPERTIES OUTPUT_NAME "nvcuvid")
|
set_target_properties(spicetools_stubs_nvcuvid PROPERTIES OUTPUT_NAME "nvcuvid")
|
||||||
|
|
||||||
@@ -833,7 +836,8 @@ endif()
|
|||||||
|
|
||||||
# nvEncodeAPI64.dll
|
# nvEncodeAPI64.dll
|
||||||
set(SOURCE_FILES stubs/nvEncodeAPI64.cpp)
|
set(SOURCE_FILES stubs/nvEncodeAPI64.cpp)
|
||||||
add_library(spicetools_stubs_nvEncodeAPI64 SHARED ${SOURCE_FILES} stubs/nvEncodeAPI64.def)
|
set(RESOURCE_FILES stubs/manifest.rc)
|
||||||
|
add_library(spicetools_stubs_nvEncodeAPI64 SHARED ${SOURCE_FILES} ${RESOURCE_FILES} stubs/nvEncodeAPI64.def)
|
||||||
set_target_properties(spicetools_stubs_nvEncodeAPI64 PROPERTIES PREFIX "")
|
set_target_properties(spicetools_stubs_nvEncodeAPI64 PROPERTIES PREFIX "")
|
||||||
set_target_properties(spicetools_stubs_nvEncodeAPI64 PROPERTIES OUTPUT_NAME "nvEncodeAPI64")
|
set_target_properties(spicetools_stubs_nvEncodeAPI64 PROPERTIES OUTPUT_NAME "nvEncodeAPI64")
|
||||||
|
|
||||||
@@ -843,7 +847,8 @@ endif()
|
|||||||
|
|
||||||
# cpusbxpkm.dll (32 bit)
|
# cpusbxpkm.dll (32 bit)
|
||||||
set(SOURCE_FILES stubs/cpusbxpkm.cpp)
|
set(SOURCE_FILES stubs/cpusbxpkm.cpp)
|
||||||
add_library(spicetools_stubs_cpusbxpkm SHARED ${SOURCE_FILES} stubs/cpusbxpkm.def)
|
set(RESOURCE_FILES stubs/manifest.rc)
|
||||||
|
add_library(spicetools_stubs_cpusbxpkm SHARED ${SOURCE_FILES} ${RESOURCE_FILES} stubs/cpusbxpkm.def)
|
||||||
set_target_properties(spicetools_stubs_cpusbxpkm PROPERTIES PREFIX "")
|
set_target_properties(spicetools_stubs_cpusbxpkm PROPERTIES PREFIX "")
|
||||||
set_target_properties(spicetools_stubs_cpusbxpkm PROPERTIES OUTPUT_NAME "cpusbxpkm")
|
set_target_properties(spicetools_stubs_cpusbxpkm PROPERTIES OUTPUT_NAME "cpusbxpkm")
|
||||||
|
|
||||||
|
|||||||
@@ -2307,6 +2307,7 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
// load hooks
|
// load hooks
|
||||||
for (auto &hook : game_hooks) {
|
for (auto &hook : game_hooks) {
|
||||||
log_info("launcher", "loading hook DLL {}", hook);
|
log_info("launcher", "loading hook DLL {}", hook);
|
||||||
|
libutils::print_dll_info(hook);
|
||||||
HMODULE module;
|
HMODULE module;
|
||||||
if (!(module = libutils::try_library(hook))) {
|
if (!(module = libutils::try_library(hook))) {
|
||||||
log_warning("launcher", "failed to load hook {}: {}", hook, get_last_error_string());
|
log_warning("launcher", "failed to load hook {}: {}", hook, get_last_error_string());
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION 1,0,0,0
|
||||||
|
PRODUCTVERSION 1,0,0,0
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904E4"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "SpiceTools"
|
||||||
|
VALUE "FileDescription", "SpiceTools DLL Stub"
|
||||||
|
VALUE "FileVersion", "1.0.0.0"
|
||||||
|
VALUE "ProductName", "SpiceTools DLL Stub"
|
||||||
|
VALUE "ProductVersion", "1.0.0.0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1252
|
||||||
|
END
|
||||||
|
END
|
||||||
@@ -9,6 +9,16 @@
|
|||||||
#include "peb.h"
|
#include "peb.h"
|
||||||
#include "util/fileutils.h"
|
#include "util/fileutils.h"
|
||||||
#include "util/dependencies.h"
|
#include "util/dependencies.h"
|
||||||
|
#include "util/unique_plain_ptr.h"
|
||||||
|
|
||||||
|
#define DEBUG_VERBOSE 0
|
||||||
|
|
||||||
|
#if DEBUG_VERBOSE
|
||||||
|
#define log_debug(module, format_str, ...) logger::push( \
|
||||||
|
LOG_FORMAT("M", module, format_str, ## __VA_ARGS__), logger::Style::GREY)
|
||||||
|
#else
|
||||||
|
#define log_debug(module, format_str, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
std::filesystem::path libutils::module_file_name(HMODULE module) {
|
std::filesystem::path libutils::module_file_name(HMODULE module) {
|
||||||
std::wstring buf;
|
std::wstring buf;
|
||||||
@@ -361,11 +371,106 @@ void libutils::check_duplicate_dlls() {
|
|||||||
void libutils::warn_if_dll_exists(const std::string &file_name) {
|
void libutils::warn_if_dll_exists(const std::string &file_name) {
|
||||||
if (fileutils::file_exists(MODULE_PATH / file_name)) {
|
if (fileutils::file_exists(MODULE_PATH / file_name)) {
|
||||||
log_info("libutils", "found user-supplied {} in modules directory", file_name);
|
log_info("libutils", "found user-supplied {} in modules directory", file_name);
|
||||||
|
libutils::print_dll_info(MODULE_PATH / file_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto &spice_bin_path = libutils::module_file_name(nullptr).parent_path();
|
const auto &spice_bin_path = libutils::module_file_name(nullptr).parent_path();
|
||||||
if (fileutils::file_exists(spice_bin_path / file_name)) {
|
if (fileutils::file_exists(spice_bin_path / file_name)) {
|
||||||
log_info("libutils", "found user-supplied {} next to spice executable path", file_name);
|
log_info("libutils", "found user-supplied {} next to spice executable path", file_name);
|
||||||
|
libutils::print_dll_info(spice_bin_path / file_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void libutils::print_dll_info(std::filesystem::path filename) {
|
||||||
|
DWORD handle;
|
||||||
|
const auto size = GetFileVersionInfoSizeA(filename.string().c_str(), &handle);
|
||||||
|
if (size == 0) {
|
||||||
|
log_debug(
|
||||||
|
"libutils",
|
||||||
|
"GetFileVersionInfoSizeA failed for {}: {}",
|
||||||
|
filename.filename().string(),
|
||||||
|
get_last_error_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = util::make_unique_plain<VOID>(size);
|
||||||
|
if (!GetFileVersionInfoA(filename.string().c_str(), handle, size, data.get())) {
|
||||||
|
log_debug(
|
||||||
|
"libutils",
|
||||||
|
"GetFileVersionInfoA failed for {}: {}",
|
||||||
|
filename.filename().string(),
|
||||||
|
get_last_error_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LANGANDCODEPAGE {
|
||||||
|
WORD wLanguage;
|
||||||
|
WORD wCodePage;
|
||||||
|
} *lpTranslate = nullptr;
|
||||||
|
|
||||||
|
UINT cbTranslate = 0;
|
||||||
|
if (!VerQueryValueA(data.get(), "\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate, &cbTranslate)) {
|
||||||
|
log_debug(
|
||||||
|
"libutils",
|
||||||
|
"VerQueryValueA failed for {}: {}",
|
||||||
|
filename.filename().string(),
|
||||||
|
get_last_error_string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cbTranslate == 0 || lpTranslate == nullptr) {
|
||||||
|
log_debug(
|
||||||
|
"libutils",
|
||||||
|
"VerQueryValueA returned invalid results for {}",
|
||||||
|
filename.filename().string());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pick language - prefer English
|
||||||
|
WORD lang = 0, codepage = 0;
|
||||||
|
for (UINT i = 0; i < cbTranslate / sizeof(*lpTranslate); i++) {
|
||||||
|
if (lpTranslate[i].wLanguage == 0x0409) { // en-us
|
||||||
|
lang = lpTranslate[i].wLanguage;
|
||||||
|
codepage = lpTranslate[i].wCodePage;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lang == 0) {
|
||||||
|
lang = lpTranslate[0].wLanguage;
|
||||||
|
codepage = lpTranslate[0].wCodePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFileInfo helper
|
||||||
|
auto query_string = [&](const char* key) -> std::string {
|
||||||
|
std::string subBlock = fmt::format(
|
||||||
|
"\\StringFileInfo\\{:04x}{:04x}\\{}",
|
||||||
|
lang, codepage, key
|
||||||
|
);
|
||||||
|
|
||||||
|
char* value = nullptr;
|
||||||
|
UINT size_out = 0;
|
||||||
|
|
||||||
|
if (VerQueryValueA(data.get(), subBlock.c_str(), (LPVOID*)&value, &size_out) && value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
log_debug(
|
||||||
|
"libutils",
|
||||||
|
"VerQueryValueA({}) failed for {}: {}",
|
||||||
|
subBlock,
|
||||||
|
filename.filename().string(),
|
||||||
|
get_last_error_string());
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto company_name = query_string("CompanyName");
|
||||||
|
const auto product_name = query_string("ProductName");
|
||||||
|
const auto version_str = query_string("FileVersion");
|
||||||
|
|
||||||
|
log_info(
|
||||||
|
"libutils",
|
||||||
|
"DLL info for {}: CompanyName = {}, ProductName = {}, Version = {}",
|
||||||
|
filename.filename().string(),
|
||||||
|
company_name.empty() ? "?" : company_name,
|
||||||
|
product_name.empty() ? "?" : product_name,
|
||||||
|
version_str.empty() ? "?" : version_str);
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,4 +77,6 @@ namespace libutils {
|
|||||||
intptr_t rva2offset(const std::filesystem::path &path, intptr_t rva);
|
intptr_t rva2offset(const std::filesystem::path &path, intptr_t rva);
|
||||||
intptr_t offset2rva(IMAGE_NT_HEADERS *nt_headers, intptr_t offset);
|
intptr_t offset2rva(IMAGE_NT_HEADERS *nt_headers, intptr_t offset);
|
||||||
intptr_t offset2rva(const std::filesystem::path &path, intptr_t offset);
|
intptr_t offset2rva(const std::filesystem::path &path, intptr_t offset);
|
||||||
|
|
||||||
|
void print_dll_info(std::filesystem::path filename);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user