Refactored hook calls

master
acidicoala 2 years ago
parent 011f3fac5d
commit eaca0bec34
No known key found for this signature in database
GPG Key ID: D24C6065B49C645B

@ -6,7 +6,7 @@ include(KoalaBox/cmake/KoalaBox.cmake)
add_subdirectory(KoalaBox EXCLUDE_FROM_ALL) add_subdirectory(KoalaBox EXCLUDE_FROM_ALL)
set_32_and_64(ORIGINAL_DLL steam_api) set_32_and_64(STEAMAPI_DLL steam_api)
set_32_and_64(STEAMCLIENT_DLL steamclient) set_32_and_64(STEAMCLIENT_DLL steamclient)
set_32_and_64(VSTDLIB_DLL vstdlib_s) set_32_and_64(VSTDLIB_DLL vstdlib_s)
@ -25,7 +25,7 @@ set(
) )
configure_linker_exports( configure_linker_exports(
FORWARDED_DLL "${ORIGINAL_DLL}_o" FORWARDED_DLL "${STEAMAPI_DLL}_o"
INPUT_SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/steam_api_exports" INPUT_SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/steam_api_exports"
INPUT_DLLS "${DLL_INPUT}" INPUT_DLLS "${DLL_INPUT}"
DEP_SOURCES "${STEAM_API_EXPORTS}" DEP_SOURCES "${STEAM_API_EXPORTS}"
@ -86,7 +86,7 @@ endif ()
add_library(SmokeAPI SHARED ${SMOKE_API_SOURCES} ${VERSION_RESOURCE}) add_library(SmokeAPI SHARED ${SMOKE_API_SOURCES} ${VERSION_RESOURCE})
configure_output_name(${ORIGINAL_DLL}) configure_output_name(${STEAMAPI_DLL})
configure_include_directories() configure_include_directories()

@ -1 +1 @@
Subproject commit 53731ddc6b82281df820884f2d2424ee3a62df54 Subproject commit 6fa96ea016482b263827d82f02b86552d5e4d407

@ -1,5 +1,5 @@
#pragma once #pragma once
#define ORIGINAL_DLL "${ORIGINAL_DLL}" #define STEAMAPI_DLL "${STEAMAPI_DLL}"
#define STEAMCLIENT_DLL "${STEAMCLIENT_DLL}" #define STEAMCLIENT_DLL "${STEAMCLIENT_DLL}"
#define VSTDLIB_DLL "${VSTDLIB_DLL}" #define VSTDLIB_DLL "${VSTDLIB_DLL}"

@ -5,6 +5,7 @@
namespace config { namespace config {
Config instance; // NOLINT(cert-err58-cpp) Config instance; // NOLINT(cert-err58-cpp)
// TODO: Reloading via export
void init() { void init() {
instance = config_parser::parse<Config>(paths::get_config_path()); instance = config_parser::parse<Config>(paths::get_config_path());
} }

@ -1,4 +1,9 @@
#include <core/globals.hpp>
namespace globals { namespace globals {
HMODULE self_module = nullptr; HMODULE smokeapi_handle = nullptr;
// TODO: Original module (rename to proxy module?) HMODULE steamapi_module = nullptr;
HMODULE vstdlib_module = nullptr;
HMODULE steamclient_module = nullptr;
Map<String, FunctionAddress> address_map;
} }

@ -1,5 +1,12 @@
#pragma once #pragma once
#include <koalabox/koalabox.hpp>
namespace globals { namespace globals {
extern HMODULE self_module; using namespace koalabox;
extern HMODULE smokeapi_handle;
extern HMODULE steamclient_module;
extern HMODULE steamapi_module;
extern HMODULE vstdlib_module;
extern Map<String, FunctionAddress> address_map;
} }

@ -1,7 +1,28 @@
#pragma once #pragma once
#include <core/globals.hpp>
#include <koalabox/hook.hpp>
// Names beginning with $ designate macros that are not meant to be used directly by the sources consuming this file
#define DLL_EXPORT(TYPE) extern "C" [[maybe_unused]] __declspec( dllexport ) TYPE __cdecl #define DLL_EXPORT(TYPE) extern "C" [[maybe_unused]] __declspec( dllexport ) TYPE __cdecl
#define VIRTUAL(TYPE) __declspec(noinline) TYPE __fastcall #define VIRTUAL(TYPE) __declspec(noinline) TYPE __fastcall
#define DETOUR(FUNC, ADDRESS) hook::detour_or_warn(ADDRESS, #FUNC, reinterpret_cast<FunctionAddress>(FUNC)); #define GET_ORIGINAL_VIRTUAL_FUNCTION(FUNC) \
#define DETOUR_ORIGINAL(FUNC) DETOUR(FUNC, smoke_api::original_library) const auto FUNC##_o = koalabox::hook::get_original_function(globals::address_map, #FUNC, FUNC);
#define $GET_ORIGINAL_MODULE_FUNCTION(FUNC, MODULE_HANDLE) \
static const auto FUNC##_o = koalabox::hook::get_original_function(MODULE_HANDLE, #FUNC, FUNC);
#define GET_ORIGINAL_FUNCTION_STEAMCLIENT(FUNC) $GET_ORIGINAL_MODULE_FUNCTION(FUNC, globals::steamclient_module)
#define GET_ORIGINAL_FUNCTION_STEAMAPI(FUNC) $GET_ORIGINAL_MODULE_FUNCTION(FUNC, globals::steamapi_module)
#define GET_ORIGINAL_FUNCTION_VSTDLIB(FUNC) $GET_ORIGINAL_MODULE_FUNCTION(FUNC, globals::vstdlib_module)
#define $DETOUR(FUNC, MODULE_HANDLE) \
koalabox::hook::detour_or_warn(MODULE_HANDLE, #FUNC, reinterpret_cast<FunctionAddress>(FUNC));
#define DETOUR_ADDRESS(FUNC, ADDRESS) \
koalabox::hook::detour_or_warn(globals::address_map, ADDRESS, #FUNC, reinterpret_cast<FunctionAddress>(FUNC));
#define DETOUR_STEAMCLIENT(FUNC) $DETOUR(FUNC, globals::steamclient_module)
#define DETOUR_VSTDLIB(FUNC) $DETOUR(FUNC, globals::vstdlib_module)

@ -4,7 +4,7 @@
namespace paths { namespace paths {
Path get_self_path() { Path get_self_path() {
static const auto path = loader::get_module_dir(globals::self_module); static const auto path = loader::get_module_dir(globals::smokeapi_handle);
return path; return path;
} }

@ -2,9 +2,9 @@
#include <build_config.h> #include <build_config.h>
#include <core/cache.hpp> #include <core/cache.hpp>
#include <core/config.hpp> #include <core/config.hpp>
#include <smoke_api/smoke_api.hpp>
#include <koalabox/dll_monitor.hpp> #include <koalabox/dll_monitor.hpp>
#include <koalabox/http_client.hpp> #include <koalabox/http_client.hpp>
#include <koalabox/util.hpp>
namespace koalageddon { namespace koalageddon {
KoalageddonConfig config; // NOLINT(cert-err58-cpp) KoalageddonConfig config; // NOLINT(cert-err58-cpp)
@ -57,24 +57,24 @@ namespace koalageddon {
logger->info("Loaded Koalageddon config from the {}", kg_config_source); logger->info("Loaded Koalageddon config from the {}", kg_config_source);
}).detach(); }).detach();
dll_monitor::init({VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& library, const String& name) { dll_monitor::init({VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& module_handle, const String& name) {
try { try {
smoke_api::original_library = library;
static auto init_count = 0;
if (util::strings_are_equal(name, VSTDLIB_DLL)) { if (util::strings_are_equal(name, VSTDLIB_DLL)) {
// VStdLib DLL handles Family Sharing functions // VStdLib DLL handles Family Sharing functions
globals::vstdlib_module = module_handle;
if (config::instance.unlock_family_sharing) { if (config::instance.unlock_family_sharing) {
init_vstdlib_hooks(); init_vstdlib_hooks();
} }
init_count++;
} else if (util::strings_are_equal(name, STEAMCLIENT_DLL)) { } else if (util::strings_are_equal(name, STEAMCLIENT_DLL)) {
// SteamClient DLL handles unlocking functions // SteamClient DLL handles unlocking functions
globals::steamclient_module = module_handle;
init_steamclient_hooks(); init_steamclient_hooks();
init_count++;
} }
if (init_count == 2) { if (globals::vstdlib_module != nullptr && globals::steamclient_module != nullptr) {
dll_monitor::shutdown(); dll_monitor::shutdown();
} }
} catch (const Exception& ex) { } catch (const Exception& ex) {

@ -1,5 +1,4 @@
#include <build_config.h> #include <build_config.h>
#include <smoke_api/smoke_api.hpp>
#include <koalageddon/koalageddon.hpp> #include <koalageddon/koalageddon.hpp>
#include <koalabox/hook.hpp> #include <koalabox/hook.hpp>
#include <koalabox/patcher.hpp> #include <koalabox/patcher.hpp>
@ -8,7 +7,7 @@
#include <Zydis/Zydis.h> #include <Zydis/Zydis.h>
#include <Zydis/DecoderTypes.h> #include <Zydis/DecoderTypes.h>
using namespace smoke_api; using namespace koalabox;
#define DEMUX_DECL(INTERFACE) \ #define DEMUX_DECL(INTERFACE) \
constexpr auto INTERFACE = #INTERFACE; \ constexpr auto INTERFACE = #INTERFACE; \
@ -19,7 +18,6 @@ DEMUX_DECL(IClientApps)
DEMUX_DECL(IClientInventory) DEMUX_DECL(IClientInventory)
DEMUX_DECL(IClientUser) DEMUX_DECL(IClientUser)
DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, const char* function_name); DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, const char* function_name);
namespace koalageddon { namespace koalageddon {
@ -170,7 +168,10 @@ namespace koalageddon {
const auto start_address = reinterpret_cast<FunctionAddress>(module_info.lpBaseOfDll); const auto start_address = reinterpret_cast<FunctionAddress>(module_info.lpBaseOfDll);
auto* terminal_address = (uint8_t*) (start_address + module_info.SizeOfImage); auto* terminal_address = (uint8_t*) (start_address + module_info.SizeOfImage);
// First, find the interface demux // TODO: There may actually be a way to find this address from "first principles"
// SteamClient.Steam_CreateSteamPipe begins with a call to fun_alpha()
// fun_alpha() calls fun_beta()
// ordinal 18
const auto* interface_demux_address = patcher::find_pattern_address( const auto* interface_demux_address = patcher::find_pattern_address(
module_info, module_info,
"interface demux", "interface demux",
@ -212,13 +213,13 @@ namespace koalageddon {
// Finally, hook the demux functions of interest // Finally, hook the demux functions of interest
if (IClientAppManager == interface_name) { if (IClientAppManager == interface_name) {
DETOUR(IClientAppManager_Demux, function_demux_address) DETOUR_ADDRESS(IClientAppManager_Demux, function_demux_address)
} else if (IClientApps == interface_name) { } else if (IClientApps == interface_name) {
DETOUR(IClientApps_Demux, function_demux_address) DETOUR_ADDRESS(IClientApps_Demux, function_demux_address)
} else if (IClientInventory == interface_name) { } else if (IClientInventory == interface_name) {
DETOUR(IClientInventory_Demux, function_demux_address) DETOUR_ADDRESS(IClientInventory_Demux, function_demux_address)
} else if (IClientUser == interface_name) { } else if (IClientUser == interface_name) {
DETOUR(IClientUser_Demux, function_demux_address) DETOUR_ADDRESS(IClientUser_Demux, function_demux_address)
} }
// Update the terminal address to limit the search scope only to relevant portion of the code // Update the terminal address to limit the search scope only to relevant portion of the code
@ -252,7 +253,7 @@ namespace koalageddon {
); );
if (interface_interceptor_address) { if (interface_interceptor_address) {
DETOUR(SteamClient_Interface_Interceptor, interface_interceptor_address) DETOUR_ADDRESS(SteamClient_Interface_Interceptor, interface_interceptor_address)
} }
} }
@ -290,6 +291,7 @@ DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, c
}; };
#define HOOK_INTERFACE(FUNC) hook::swap_virtual_func_or_throw( \ #define HOOK_INTERFACE(FUNC) hook::swap_virtual_func_or_throw( \
globals::address_map, \
(void*) interface_address, \ (void*) interface_address, \
#FUNC, \ #FUNC, \
koalageddon::config.FUNC##_ordinal, \ koalageddon::config.FUNC##_ordinal, \
@ -321,7 +323,7 @@ DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, c
}); });
} }
GET_ORIGINAL_FUNCTION(SteamClient_Interface_Interceptor) GET_ORIGINAL_VIRTUAL_FUNCTION(SteamClient_Interface_Interceptor)
SteamClient_Interface_Interceptor_o(interface_name, function_name); SteamClient_Interface_Interceptor_o(interface_name, function_name);
} catch (const Exception& ex) { } catch (const Exception& ex) {
logger->error("{} -> Error: {}", __func__, ex.what()); logger->error("{} -> Error: {}", __func__, ex.what());
@ -344,7 +346,7 @@ DLL_EXPORT(void) INTERFACE##_Demux( \
const std::lock_guard<std::mutex> guard(koalageddon::map_mutex); \ const std::lock_guard<std::mutex> guard(koalageddon::map_mutex); \
koalageddon::interface_name_pointer_map[INTERFACE] = arg1; \ koalageddon::interface_name_pointer_map[INTERFACE] = arg1; \
} \ } \
GET_ORIGINAL_FUNCTION(INTERFACE##_Demux) \ GET_ORIGINAL_VIRTUAL_FUNCTION(INTERFACE##_Demux) \
INTERFACE##_Demux_o(arg1, arg2, arg3, arg4); \ INTERFACE##_Demux_o(arg1, arg2, arg3, arg4); \
} }

@ -1,17 +1,17 @@
#include <smoke_api/smoke_api.hpp> #include <core/macros.hpp>
#include <steam_functions/steam_functions.hpp>
#include <koalageddon/koalageddon.hpp> #include <koalageddon/koalageddon.hpp>
#include <steam_functions/steam_functions.hpp>
#include <koalabox/hook.hpp> #include <koalabox/hook.hpp>
using namespace smoke_api; using namespace koalageddon;
using namespace koalabox;
typedef uint32_t HCoroutine; typedef uint32_t HCoroutine;
DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, struct CoroutineData* data); DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, struct CoroutineData* data);
namespace koalageddon { namespace koalageddon {
void init_vstdlib_hooks() { void init_vstdlib_hooks() {
DETOUR_ORIGINAL(Coroutine_Create) DETOUR_VSTDLIB(Coroutine_Create)
} }
} }
@ -46,13 +46,14 @@ struct CoroutineData {
}; };
VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** p_name)) { VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** p_name)) {
GET_ORIGINAL_FUNCTION(VStdLib_Callback_Interceptor) GET_ORIGINAL_FUNCTION_VSTDLIB(VStdLib_Callback_Interceptor)
VStdLib_Callback_Interceptor_o(ARGS(p_name)); VStdLib_Callback_Interceptor_o(ARGS(p_name));
static auto hooked_functions = 0; static auto lock_status_hooked = false;
static auto stop_playing_hooked = false;
if (hooked_functions == 2) { if (lock_status_hooked && stop_playing_hooked) {
return; return;
} }
@ -62,18 +63,13 @@ VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** p_name)) {
const auto name = String(data->get_callback_name()); const auto name = String(data->get_callback_name());
// logger->trace("{} -> instance: {}, name: '{}'", __func__, fmt::ptr(THIS), name); // logger->trace("{} -> instance: {}, name: '{}'", __func__, fmt::ptr(THIS), name);
if (name == "SharedLicensesLockStatus") {
static std::once_flag flag; if (name == "SharedLicensesLockStatus" && !lock_status_hooked) {
std::call_once(flag, [&]() { DETOUR_ADDRESS(SharedLicensesLockStatus, data->get_callback_data()->get_callback_address())
DETOUR(SharedLicensesLockStatus, data->get_callback_data()->get_callback_address()) lock_status_hooked = true;
hooked_functions++; } else if (name == "SharedLibraryStopPlaying" && !stop_playing_hooked) {
}); DETOUR_ADDRESS(SharedLibraryStopPlaying, data->get_callback_data()->get_callback_address())
} else if (name == "SharedLibraryStopPlaying") { stop_playing_hooked = true;
static std::once_flag flag;
std::call_once(flag, [&]() {
DETOUR(SharedLibraryStopPlaying, data->get_callback_data()->get_callback_address())
hooked_functions++;
});
} }
} }
} }
@ -83,7 +79,7 @@ VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** p_name)) {
* hence we must hook an interface method that sets the callback name. * hence we must hook an interface method that sets the callback name.
*/ */
DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, CoroutineData* data) { DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, CoroutineData* data) {
GET_ORIGINAL_FUNCTION(Coroutine_Create) GET_ORIGINAL_FUNCTION_VSTDLIB(Coroutine_Create)
const auto result = Coroutine_Create_o(callback_address, data); const auto result = Coroutine_Create_o(callback_address, data);
@ -92,7 +88,7 @@ DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, CoroutineData* d
std::call_once(flag, [&]() { std::call_once(flag, [&]() {
logger->debug("Coroutine_Create -> callback: {}, data: {}", callback_address, fmt::ptr(data)); logger->debug("Coroutine_Create -> callback: {}, data: {}", callback_address, fmt::ptr(data));
DETOUR(VStdLib_Callback_Interceptor, data->get_callback_data()->get_callback_intercept_address()) DETOUR_ADDRESS(VStdLib_Callback_Interceptor, data->get_callback_data()->get_callback_intercept_address())
}); });
return result; return result;

@ -11,30 +11,29 @@
#include <koalabox/loader.hpp> #include <koalabox/loader.hpp>
#include <koalabox/win_util.hpp> #include <koalabox/win_util.hpp>
// TODO: Define COMPILE_KOALAGEDDON in CMake
#ifndef _WIN64 #ifndef _WIN64
#include <koalageddon/koalageddon.hpp> #include <koalageddon/koalageddon.hpp>
#endif #endif
namespace smoke_api { namespace smoke_api {
HMODULE original_library = nullptr; using namespace koalabox;
HMODULE self_module = nullptr;
bool is_hook_mode = false;
void init_proxy_mode() { void init_proxy_mode() {
logger->info("🔀 Detected proxy mode"); logger->info("🔀 Detected proxy mode");
original_library = loader::load_original_library(paths::get_self_path(), ORIGINAL_DLL); globals::steamapi_module = loader::load_original_library(paths::get_self_path(), STEAMAPI_DLL);
} }
void init_hook_mode() { void init_hook_mode() {
logger->info("🪝 Detected hook mode"); logger->info("🪝 Detected hook mode");
dll_monitor::init(STEAMCLIENT_DLL, [](const HMODULE& library) { dll_monitor::init(STEAMCLIENT_DLL, [](const HMODULE& library) {
original_library = library; globals::steamclient_module = library;
DETOUR_ORIGINAL(CreateInterface) DETOUR_STEAMCLIENT(CreateInterface)
dll_monitor::shutdown();
}); });
// Hooking steam_api has shown itself to be less desirable than steamclient // Hooking steam_api has shown itself to be less desirable than steamclient
@ -79,7 +78,7 @@ namespace smoke_api {
try { try {
DisableThreadLibraryCalls(module_handle); DisableThreadLibraryCalls(module_handle);
globals::self_module = module_handle; globals::smokeapi_handle = module_handle;
koalabox::project_name = PROJECT_NAME; koalabox::project_name = PROJECT_NAME;
@ -97,9 +96,7 @@ namespace smoke_api {
logger->debug(R"(Process name: "{}" [{}-bit])", exe_name, exe_bitness); logger->debug(R"(Process name: "{}" [{}-bit])", exe_name, exe_bitness);
is_hook_mode = hook::is_hook_mode(self_module, ORIGINAL_DLL); if (hook::is_hook_mode(globals::smokeapi_handle, STEAMAPI_DLL)) {
if (is_hook_mode) {
hook::init(true); hook::init(true);
#ifdef _WIN64 #ifdef _WIN64
@ -125,10 +122,8 @@ namespace smoke_api {
void shutdown() { void shutdown() {
try { try {
if (is_hook_mode) { if (globals::steamapi_module != nullptr) {
dll_monitor::shutdown(); win_util::free_library(globals::steamapi_module);
} else {
win_util::free_library(original_library);
} }
logger->info("💀 Shutdown complete"); logger->info("💀 Shutdown complete");

@ -1,37 +1,8 @@
#pragma once #pragma once
#include <koalabox/koalabox.hpp>
#include <koalabox/hook.hpp> // For macros
#include <nlohmann/json.hpp>
#define GET_ORIGINAL_FUNCTION(FUNC) \
static const auto FUNC##_o = hook::get_original_function( \
smoke_api::is_hook_mode, \
smoke_api::original_library, \
#FUNC, \
FUNC \
);
#define GET_ORIGINAL_VIRTUAL_FUNCTION(FUNC) \
const auto FUNC##_o = hook::get_original_function( \
true, \
smoke_api::original_library, \
#FUNC, \
FUNC \
);
namespace smoke_api { namespace smoke_api {
using namespace koalabox;
extern HMODULE self_module;
extern HMODULE original_library;
extern bool is_hook_mode;
void init(HMODULE module_handle); void init(HMODULE module_handle);
void shutdown(); void shutdown();
} }

@ -1,16 +1,16 @@
#include <smoke_api/smoke_api.hpp> #include <core/macros.hpp>
#include <steam_impl/steam_apps.hpp> #include <steam_impl/steam_apps.hpp>
#include <steam_impl/steam_client.hpp> #include <steam_impl/steam_client.hpp>
#include <steam_impl/steam_inventory.hpp> #include <steam_impl/steam_inventory.hpp>
#include <steam_impl/steam_user.hpp> #include <steam_impl/steam_user.hpp>
using namespace smoke_api; using namespace koalabox;
// ISteamApps // ISteamApps
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps* self, AppId_t appID) { DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps* self, AppId_t appID) {
return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() { return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamApps_BIsSubscribedApp) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsSubscribedApp)
return SteamAPI_ISteamApps_BIsSubscribedApp_o(self, appID); return SteamAPI_ISteamApps_BIsSubscribedApp_o(self, appID);
}); });
@ -18,7 +18,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps* self, AppId_t
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps* self, AppId_t appID) { DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps* self, AppId_t appID) {
return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() { return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamApps_BIsDlcInstalled) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BIsDlcInstalled)
return SteamAPI_ISteamApps_BIsDlcInstalled_o(self, appID); return SteamAPI_ISteamApps_BIsDlcInstalled_o(self, appID);
}); });
@ -26,7 +26,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps* self, AppId_t a
DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps* self) { DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps* self) {
return steam_apps::GetDLCCount(__func__, 0, [&]() { return steam_apps::GetDLCCount(__func__, 0, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamApps_GetDLCCount) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_GetDLCCount)
return SteamAPI_ISteamApps_GetDLCCount_o(self); return SteamAPI_ISteamApps_GetDLCCount_o(self);
}); });
@ -41,7 +41,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(
int cchNameBufferSize int cchNameBufferSize
) { ) {
return steam_apps::GetDLCDataByIndex(__func__, 0, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize, [&]() { return steam_apps::GetDLCDataByIndex(__func__, 0, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamApps_BGetDLCDataByIndex) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamApps_BGetDLCDataByIndex)
return SteamAPI_ISteamApps_BGetDLCDataByIndex_o( return SteamAPI_ISteamApps_BGetDLCDataByIndex_o(
self, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize self, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize
@ -57,7 +57,7 @@ DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp
AppId_t appID AppId_t appID
) { ) {
return steam_user::UserHasLicenseForApp(__func__, appID, [&]() { return steam_user::UserHasLicenseForApp(__func__, appID, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamUser_UserHasLicenseForApp) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamUser_UserHasLicenseForApp)
return SteamAPI_ISteamUser_UserHasLicenseForApp_o(self, steamID, appID); return SteamAPI_ISteamUser_UserHasLicenseForApp_o(self, steamID, appID);
}); });
@ -72,7 +72,7 @@ DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
const char* pchVersion const char* pchVersion
) { ) {
return steam_client::GetGenericInterface(__func__, pchVersion, [&]() { return steam_client::GetGenericInterface(__func__, pchVersion, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamClient_GetISteamGenericInterface) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamClient_GetISteamGenericInterface)
return SteamAPI_ISteamClient_GetISteamGenericInterface_o(self, hSteamUser, hSteamPipe, pchVersion); return SteamAPI_ISteamClient_GetISteamGenericInterface_o(self, hSteamUser, hSteamPipe, pchVersion);
}); });
@ -85,7 +85,7 @@ DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
SteamInventoryResult_t resultHandle SteamInventoryResult_t resultHandle
) { ) {
return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() { return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetResultStatus) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetResultStatus)
return SteamAPI_ISteamInventory_GetResultStatus_o(self, resultHandle); return SteamAPI_ISteamInventory_GetResultStatus_o(self, resultHandle);
}); });
@ -100,12 +100,12 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
return steam_inventory::GetResultItems( return steam_inventory::GetResultItems(
__func__, resultHandle, pOutItemsArray, punOutItemsArraySize, __func__, resultHandle, pOutItemsArray, punOutItemsArraySize,
[&]() { [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetResultItems) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetResultItems)
return SteamAPI_ISteamInventory_GetResultItems_o(self, resultHandle, pOutItemsArray, punOutItemsArraySize); return SteamAPI_ISteamInventory_GetResultItems_o(self, resultHandle, pOutItemsArray, punOutItemsArraySize);
}, },
[&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) { [&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetItemDefinitionIDs) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetItemDefinitionIDs)
return SteamAPI_ISteamInventory_GetItemDefinitionIDs_o(self, pItemDefIDs, punItemDefIDsArraySize); return SteamAPI_ISteamInventory_GetItemDefinitionIDs_o(self, pItemDefIDs, punItemDefIDsArraySize);
} }
@ -122,7 +122,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
) { ) {
return steam_inventory::GetResultItemProperty( return steam_inventory::GetResultItemProperty(
__func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() { __func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetResultItemProperty) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetResultItemProperty)
return SteamAPI_ISteamInventory_GetResultItemProperty_o( return SteamAPI_ISteamInventory_GetResultItemProperty_o(
self, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut self, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut
@ -137,7 +137,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
CSteamID steamIDExpected CSteamID steamIDExpected
) { ) {
return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() { return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_CheckResultSteamID) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_CheckResultSteamID)
return SteamAPI_ISteamInventory_CheckResultSteamID_o(self, resultHandle, steamIDExpected); return SteamAPI_ISteamInventory_CheckResultSteamID_o(self, resultHandle, steamIDExpected);
}); });
@ -148,7 +148,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
SteamInventoryResult_t* pResultHandle SteamInventoryResult_t* pResultHandle
) { ) {
return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() { return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetAllItems) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetAllItems)
return SteamAPI_ISteamInventory_GetAllItems_o(self, pResultHandle); return SteamAPI_ISteamInventory_GetAllItems_o(self, pResultHandle);
}); });
@ -161,7 +161,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
uint32_t unCountInstanceIDs uint32_t unCountInstanceIDs
) { ) {
return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() { return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetItemsByID) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetItemsByID)
return SteamAPI_ISteamInventory_GetItemsByID_o(self, pResultHandle, pInstanceIDs, unCountInstanceIDs); return SteamAPI_ISteamInventory_GetItemsByID_o(self, pResultHandle, pInstanceIDs, unCountInstanceIDs);
}); });
@ -174,7 +174,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
uint32_t* punOutBufferSize uint32_t* punOutBufferSize
) { ) {
return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() { return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_SerializeResult) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_SerializeResult)
return SteamAPI_ISteamInventory_SerializeResult_o(self, resultHandle, pOutBuffer, punOutBufferSize); return SteamAPI_ISteamInventory_SerializeResult_o(self, resultHandle, pOutBuffer, punOutBufferSize);
}); });
@ -186,7 +186,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(
uint32_t* punItemDefIDsArraySize uint32_t* punItemDefIDsArraySize
) { ) {
return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, punItemDefIDsArraySize, [&]() { return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, punItemDefIDsArraySize, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetItemDefinitionIDs) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetItemDefinitionIDs)
return SteamAPI_ISteamInventory_GetItemDefinitionIDs_o(self, pItemDefIDs, punItemDefIDsArraySize); return SteamAPI_ISteamInventory_GetItemDefinitionIDs_o(self, pItemDefIDs, punItemDefIDsArraySize);
}); });

@ -1,11 +1,12 @@
#include <smoke_api/smoke_api.hpp> #include <core/macros.hpp>
#include <koalabox/hook.hpp>
#include <steam_impl/steam_client.hpp> #include <steam_impl/steam_client.hpp>
using namespace smoke_api; using namespace koalabox;
DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser hSteamUser, const char* version) { DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser hSteamUser, const char* version) {
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInternal_FindOrCreateUserInterface) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInternal_FindOrCreateUserInterface)
return SteamInternal_FindOrCreateUserInterface_o(hSteamUser, version); return SteamInternal_FindOrCreateUserInterface_o(hSteamUser, version);
}); });
@ -13,7 +14,7 @@ DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser hSteamUser,
DLL_EXPORT(void*) SteamInternal_CreateInterface(const char* version) { DLL_EXPORT(void*) SteamInternal_CreateInterface(const char* version) {
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInternal_CreateInterface) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInternal_CreateInterface)
return SteamInternal_CreateInterface_o(version); return SteamInternal_CreateInterface_o(version);
}); });

@ -17,7 +17,7 @@ String get_versioned_interface(const String& version_prefix, const String& fallb
if (not version_map.contains(version_prefix)) { if (not version_map.contains(version_prefix)) {
try { try {
const String rdata = win_util::get_pe_section_data_or_throw(original_library, ".rdata"); const String rdata = win_util::get_pe_section_data_or_throw(globals::steamapi_module, ".rdata");
const std::regex regex(version_prefix + "\\d{3}"); const std::regex regex(version_prefix + "\\d{3}");
std::smatch match; std::smatch match;
@ -44,7 +44,7 @@ DLL_EXPORT(void*) SteamClient() {
static auto version = get_versioned_interface(STEAM_CLIENT, "006"); static auto version = get_versioned_interface(STEAM_CLIENT, "006");
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamClient) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamClient)
return SteamClient_o(); return SteamClient_o();
}); });
@ -54,7 +54,7 @@ DLL_EXPORT(void*) SteamApps() {
static auto version = get_versioned_interface(STEAM_APPS, "002"); static auto version = get_versioned_interface(STEAM_APPS, "002");
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamApps) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamApps)
return SteamApps_o(); return SteamApps_o();
}); });
@ -64,7 +64,7 @@ DLL_EXPORT(void*) SteamUser() {
static auto version = get_versioned_interface(STEAM_USER, "012"); static auto version = get_versioned_interface(STEAM_USER, "012");
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamUser) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamUser)
return SteamUser_o(); return SteamUser_o();
}); });
@ -74,7 +74,7 @@ DLL_EXPORT(void*) SteamInventory() {
static auto version = get_versioned_interface(STEAM_INVENTORY, "001"); static auto version = get_versioned_interface(STEAM_INVENTORY, "001");
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInventory) GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInventory)
return SteamInventory_o(); return SteamInventory_o();
}); });

@ -1,11 +1,8 @@
#include <smoke_api/smoke_api.hpp>
#include <steam_impl/steam_apps.hpp> #include <steam_impl/steam_apps.hpp>
using namespace smoke_api;
VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t appID)) { // NOLINT(misc-unused-parameters) VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t appID)) { // NOLINT(misc-unused-parameters)
return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() { return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() {
GET_ORIGINAL_FUNCTION(ISteamApps_BIsSubscribedApp) GET_ORIGINAL_FUNCTION_STEAMAPI(ISteamApps_BIsSubscribedApp)
return ISteamApps_BIsSubscribedApp_o(ARGS(appID)); return ISteamApps_BIsSubscribedApp_o(ARGS(appID));
}); });
@ -13,7 +10,7 @@ VIRTUAL(bool) ISteamApps_BIsSubscribedApp(PARAMS(AppId_t appID)) { // NOLINT(mis
VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t appID)) { // NOLINT(misc-unused-parameters) VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t appID)) { // NOLINT(misc-unused-parameters)
return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() { return steam_apps::IsDlcUnlocked(__func__, 0, appID, [&]() {
GET_ORIGINAL_FUNCTION(ISteamApps_BIsDlcInstalled) GET_ORIGINAL_FUNCTION_STEAMAPI(ISteamApps_BIsDlcInstalled)
return ISteamApps_BIsDlcInstalled_o(ARGS(appID)); return ISteamApps_BIsDlcInstalled_o(ARGS(appID));
}); });

@ -121,6 +121,7 @@ namespace steam_functions {
#define HOOK(MAP, FUNC) \ #define HOOK(MAP, FUNC) \
hook::swap_virtual_func( \ hook::swap_virtual_func( \
globals::address_map, \
interface, \ interface, \
#FUNC, \ #FUNC, \
get_ordinal(MAP, #FUNC, version_number), \ get_ordinal(MAP, #FUNC, version_number), \
@ -202,7 +203,7 @@ namespace steam_functions {
} }
HSteamPipe get_steam_pipe_or_throw() { HSteamPipe get_steam_pipe_or_throw() {
const auto& steam_api_module = win_util::get_module_handle_or_throw(ORIGINAL_DLL); const auto& steam_api_module = win_util::get_module_handle_or_throw(STEAMAPI_DLL);
void* GetHSteamPipe_address; void* GetHSteamPipe_address;
try { try {
GetHSteamPipe_address = (void*) win_util::get_proc_address_or_throw( GetHSteamPipe_address = (void*) win_util::get_proc_address_or_throw(

@ -108,7 +108,8 @@ namespace steam_apps {
bool IsDlcUnlocked( bool IsDlcUnlocked(
const String& function_name, const String& function_name,
AppId_t app_id, AppId_t dlc_id, AppId_t app_id,
AppId_t dlc_id,
const std::function<bool()>& original_function const std::function<bool()>& original_function
) { ) {
try { try {

@ -1,8 +1,8 @@
#include <smoke_api/smoke_api.hpp> #include <koalabox/koalabox.hpp>
#include <steam_functions/steam_functions.hpp> #include <steam_functions/steam_functions.hpp>
namespace steam_client { namespace steam_client {
using namespace smoke_api; using namespace koalabox;
void* GetGenericInterface( void* GetGenericInterface(
const String& function_name, const String& function_name,

@ -1,9 +1,8 @@
#include <smoke_api/smoke_api.hpp> #include <koalabox/koalabox.hpp>
#include <steam_functions/steam_functions.hpp> #include <steam_functions/steam_functions.hpp>
using namespace smoke_api;
namespace steam_user { namespace steam_user {
using namespace koalabox;
EUserHasLicenseForAppResult UserHasLicenseForApp( EUserHasLicenseForAppResult UserHasLicenseForApp(
const String& function_name, const String& function_name,

@ -5,7 +5,7 @@ using namespace smoke_api;
DLL_EXPORT(void*) CreateInterface(const char* interface_string, int* out_result) { DLL_EXPORT(void*) CreateInterface(const char* interface_string, int* out_result) {
return steam_client::GetGenericInterface(__func__, interface_string, [&]() { return steam_client::GetGenericInterface(__func__, interface_string, [&]() {
GET_ORIGINAL_FUNCTION(CreateInterface) GET_ORIGINAL_FUNCTION_STEAMCLIENT(CreateInterface)
return CreateInterface_o(interface_string, out_result); return CreateInterface_o(interface_string, out_result);
}); });

Loading…
Cancel
Save