Reworked algorithm for finding App ID

This commit is contained in:
acidicoala
2025-09-22 21:20:13 +05:00
parent 7ab9895b58
commit 8decbafb53
11 changed files with 124 additions and 63 deletions

View File

@@ -104,15 +104,8 @@ namespace {
}
}
},
{
STEAM_UTILS,
interface_data_t{
.fallback_version = "SteamUtils009",
.entry_map = {
ENTRY(ISteamUtils, GetAppID),
}
}
},
// Hooking SteamUtils for GetAppID should be avoided, since it leads to crashes in TW:WH3.
// No idea why...
};
}
@@ -257,4 +250,46 @@ namespace steam_interfaces {
LOG_ERROR("{} -> Unhandled exception: {}", __func__, e.what());
}
}
void* find_function(
const void* instance_ptr,
const std::string& interface_name,
const std::string& function_name
) {
if(!get_interface_name_to_version_map().contains(interface_name)) {
LOG_ERROR("Unsupported interface name: '{}'", interface_name);
return nullptr;
}
const auto& interface_version = get_interface_name_to_version_map().at(interface_name);
static const auto lookup = read_interface_lookup();
if(!lookup.contains(interface_version)) {
LOG_ERROR("Interface '{}' not found in lookup map", interface_version);
return nullptr;
}
const auto interface_lookup = lookup.at(interface_version);
if(!interface_lookup.contains(function_name)) {
LOG_ERROR("Function '{}' not found in the map of '{}'", function_name, interface_version);
return nullptr;
}
const auto ordinal = interface_lookup.at(function_name);
const auto virtual_class = static_cast<const kb::hook::virtual_class_t*>(instance_ptr);
return virtual_class->vtable[ordinal];
}
const std::map<std::string, std::string>& get_interface_name_to_version_map() {
// Choose minimal supported versions for maximum compatibility
// Is it better to get the interface version found in steam_api library?
static const std::map<std::string, std::string> map = {
{"ISteamClient", "SteamClient007"},
{"ISteamUtils", "SteamUtils002"},
};
return map;
}
}

View File

@@ -1,7 +1,13 @@
#pragma once
#include <map>
#include <string>
#define SMK_FIND_INTERFACE_FUNC(INTERFACE_PTR, INTERFACE_NAME, FUNCTION_NAME) \
reinterpret_cast<decltype(&INTERFACE_NAME##_##FUNCTION_NAME)>( \
steam_interfaces::find_function(INTERFACE_PTR, #INTERFACE_NAME, #FUNCTION_NAME) \
)
namespace steam_interfaces {
void hook_virtuals(const void* interface_ptr, const std::string& version_string);
@@ -15,4 +21,12 @@ namespace steam_interfaces {
void* steamclient_handle,
const std::string& steam_client_interface_version
) noexcept;
void* find_function(
const void* instance_ptr,
const std::string& interface_name,
const std::string& function_name
);
const std::map<std::string, std::string>& get_interface_name_to_version_map();
}

View File

@@ -17,7 +17,7 @@ VIRTUAL(bool) ISteamInventory_GetResultItems(
SteamItemDetails_t* pOutItemsArray,
uint32_t* punOutItemsArraySize
)
) noexcept {
) noexcept {
return smoke_api::steam_inventory::GetResultItems(
__func__,
resultHandle,

View File

@@ -1,9 +0,0 @@
#include <koalabox/logger.hpp>
#include "smoke_api/smoke_api.hpp"
#include "smoke_api/interfaces/steam_user.hpp"
#include "steam_api/virtuals/steam_api_virtuals.hpp"
VIRTUAL(AppId_t) ISteamUtils_GetAppID(PARAMS()) noexcept {
SWAPPED_CALL(THIS, ISteamUtils_GetAppID, ARGS());
}

View File

@@ -13,6 +13,7 @@ VIRTUAL(void*) ISteamClient_GetISteamApps(PARAMS(HSteamUser, HSteamPipe, const c
VIRTUAL(void*) ISteamClient_GetISteamUser(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept;
VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept;
VIRTUAL(void*) ISteamClient_GetISteamInventory(PARAMS(HSteamUser, HSteamPipe, const char*)) noexcept;
VIRTUAL(void*) ISteamClient_GetISteamUtils(PARAMS(HSteamPipe, const char*)) noexcept; // Unhooked
// ISteamHTTP
VIRTUAL(bool) ISteamHTTP_GetHTTPResponseBodyData(PARAMS(HTTPRequestHandle, const uint8_t*, uint32_t)) noexcept;
@@ -43,7 +44,7 @@ VIRTUAL(bool) ISteamInventory_CheckResultSteamID(PARAMS(SteamInventoryResult_t,
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t)) noexcept;
// ISteamUtils
VIRTUAL(AppId_t) ISteamUtils_GetAppID(PARAMS()) noexcept;
VIRTUAL(AppId_t) ISteamUtils_GetAppID(PARAMS()) noexcept; // Unhooked
// ISteamGameServer
VIRTUAL(EUserHasLicenseForAppResult) ISteamGameServer_UserHasLicenseForApp(PARAMS(CSteamID, AppId_t)) noexcept;