Refactored hook calls

master
acidicoala 1 year 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)
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(VSTDLIB_DLL vstdlib_s)
@ -25,7 +25,7 @@ set(
)
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_DLLS "${DLL_INPUT}"
DEP_SOURCES "${STEAM_API_EXPORTS}"
@ -86,7 +86,7 @@ endif ()
add_library(SmokeAPI SHARED ${SMOKE_API_SOURCES} ${VERSION_RESOURCE})
configure_output_name(${ORIGINAL_DLL})
configure_output_name(${STEAMAPI_DLL})
configure_include_directories()

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

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

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

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

@ -1,5 +1,12 @@
#pragma once
#include <koalabox/koalabox.hpp>
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
#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 VIRTUAL(TYPE) __declspec(noinline) TYPE __fastcall
#define DETOUR(FUNC, ADDRESS) hook::detour_or_warn(ADDRESS, #FUNC, reinterpret_cast<FunctionAddress>(FUNC));
#define DETOUR_ORIGINAL(FUNC) DETOUR(FUNC, smoke_api::original_library)
#define GET_ORIGINAL_VIRTUAL_FUNCTION(FUNC) \
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 {
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;
}

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

@ -1,5 +1,4 @@
#include <build_config.h>
#include <smoke_api/smoke_api.hpp>
#include <koalageddon/koalageddon.hpp>
#include <koalabox/hook.hpp>
#include <koalabox/patcher.hpp>
@ -8,7 +7,7 @@
#include <Zydis/Zydis.h>
#include <Zydis/DecoderTypes.h>
using namespace smoke_api;
using namespace koalabox;
#define DEMUX_DECL(INTERFACE) \
constexpr auto INTERFACE = #INTERFACE; \
@ -19,7 +18,6 @@ DEMUX_DECL(IClientApps)
DEMUX_DECL(IClientInventory)
DEMUX_DECL(IClientUser)
DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, const char* function_name);
namespace koalageddon {
@ -34,30 +32,30 @@ namespace koalageddon {
constexpr auto INTERFACE_TARGET_COUNT = 4;
/*
* We need an interface=>function ordinal map in order to hook steam interface function
* via virtual function pointer swap. We could construct it by exploiting these code chunks:
*
* 8B01 | mov eax, dword ptr ds:[ecx]
* 68 ???????? | push steamclient.function_name
* 68 ???????? | push steamclient.interface_name
*
* Step 1: Find all addresses that begin with pattern
* 8B 01 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? FF 10
* Step 2: Extract function and interface name pointers by adding 3 and 8 respectively
* Step 3: Starting from the found address, and until the function epilogue, scan for either instructions:
*
* (1) FF50 ?? | call dword ptr ds:[eax+0x??]
* or
* (2) 8B40 ?? | mov eax, dword ptr ds:[eax+??]
* FFD0 | call eax
*
* In the case (1), the offset is encoded in the found call instruction.
* In the case (2), the offset is encoded in the instruction preceding the call.
*
* ROADBLOCK: There is actually a case (3) which calls a local variable (ebp-??),
* which itself is constructed over multiple instruction calls, making it non-deterministic.
* Until this roadblock is resolved, automatic detection of ordinals remains non-viable.
*/
* We need an interface=>function ordinal map in order to hook steam interface function
* via virtual function pointer swap. We could construct it by exploiting these code chunks:
*
* 8B01 | mov eax, dword ptr ds:[ecx]
* 68 ???????? | push steamclient.function_name
* 68 ???????? | push steamclient.interface_name
*
* Step 1: Find all addresses that begin with pattern
* 8B 01 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? FF 10
* Step 2: Extract function and interface name pointers by adding 3 and 8 respectively
* Step 3: Starting from the found address, and until the function epilogue, scan for either instructions:
*
* (1) FF50 ?? | call dword ptr ds:[eax+0x??]
* or
* (2) 8B40 ?? | mov eax, dword ptr ds:[eax+??]
* FFD0 | call eax
*
* In the case (1), the offset is encoded in the found call instruction.
* In the case (2), the offset is encoded in the instruction preceding the call.
*
* ROADBLOCK: There is actually a case (3) which calls a local variable (ebp-??),
* which itself is constructed over multiple instruction calls, making it non-deterministic.
* Until this roadblock is resolved, automatic detection of ordinals remains non-viable.
*/
[[maybe_unused]] Map<String, uint32_t> construct_interface_function_ordinal_map() {
auto* const steamclient_handle = win_util::get_module_handle_or_throw(STEAMCLIENT_DLL);
const auto steamclient_module_info = win_util::get_module_info_or_throw(steamclient_handle);
@ -170,7 +168,10 @@ namespace koalageddon {
const auto start_address = reinterpret_cast<FunctionAddress>(module_info.lpBaseOfDll);
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(
module_info,
"interface demux",
@ -212,13 +213,13 @@ namespace koalageddon {
// Finally, hook the demux functions of interest
if (IClientAppManager == interface_name) {
DETOUR(IClientAppManager_Demux, function_demux_address)
DETOUR_ADDRESS(IClientAppManager_Demux, function_demux_address)
} else if (IClientApps == interface_name) {
DETOUR(IClientApps_Demux, function_demux_address)
DETOUR_ADDRESS(IClientApps_Demux, function_demux_address)
} else if (IClientInventory == interface_name) {
DETOUR(IClientInventory_Demux, function_demux_address)
DETOUR_ADDRESS(IClientInventory_Demux, function_demux_address)
} 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
@ -252,7 +253,7 @@ namespace koalageddon {
);
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( \
globals::address_map, \
(void*) interface_address, \
#FUNC, \
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);
} catch (const Exception& ex) {
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); \
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); \
}

@ -1,17 +1,17 @@
#include <smoke_api/smoke_api.hpp>
#include <steam_functions/steam_functions.hpp>
#include <core/macros.hpp>
#include <koalageddon/koalageddon.hpp>
#include <steam_functions/steam_functions.hpp>
#include <koalabox/hook.hpp>
using namespace smoke_api;
using namespace koalageddon;
using namespace koalabox;
typedef uint32_t HCoroutine;
DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, struct CoroutineData* data);
namespace koalageddon {
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)) {
GET_ORIGINAL_FUNCTION(VStdLib_Callback_Interceptor)
GET_ORIGINAL_FUNCTION_VSTDLIB(VStdLib_Callback_Interceptor)
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;
}
@ -62,18 +63,13 @@ VIRTUAL(void) VStdLib_Callback_Interceptor(PARAMS(const char** p_name)) {
const auto name = String(data->get_callback_name());
// logger->trace("{} -> instance: {}, name: '{}'", __func__, fmt::ptr(THIS), name);
if (name == "SharedLicensesLockStatus") {
static std::once_flag flag;
std::call_once(flag, [&]() {
DETOUR(SharedLicensesLockStatus, data->get_callback_data()->get_callback_address())
hooked_functions++;
});
} else if (name == "SharedLibraryStopPlaying") {
static std::once_flag flag;
std::call_once(flag, [&]() {
DETOUR(SharedLibraryStopPlaying, data->get_callback_data()->get_callback_address())
hooked_functions++;
});
if (name == "SharedLicensesLockStatus" && !lock_status_hooked) {
DETOUR_ADDRESS(SharedLicensesLockStatus, data->get_callback_data()->get_callback_address())
lock_status_hooked = true;
} else if (name == "SharedLibraryStopPlaying" && !stop_playing_hooked) {
DETOUR_ADDRESS(SharedLibraryStopPlaying, data->get_callback_data()->get_callback_address())
stop_playing_hooked = true;
}
}
}
@ -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.
*/
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);
@ -92,7 +88,7 @@ DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, CoroutineData* d
std::call_once(flag, [&]() {
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;

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

@ -1,37 +1,8 @@
#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 {
using namespace koalabox;
extern HMODULE self_module;
extern HMODULE original_library;
extern bool is_hook_mode;
void init(HMODULE module_handle);
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_client.hpp>
#include <steam_impl/steam_inventory.hpp>
#include <steam_impl/steam_user.hpp>
using namespace smoke_api;
using namespace koalabox;
// ISteamApps
DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsSubscribedApp(ISteamApps* self, AppId_t 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);
});
@ -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) {
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);
});
@ -26,7 +26,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BIsDlcInstalled(ISteamApps* self, AppId_t a
DLL_EXPORT(int) SteamAPI_ISteamApps_GetDLCCount(ISteamApps* self) {
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);
});
@ -41,7 +41,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamApps_BGetDLCDataByIndex(
int 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(
self, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize
@ -57,7 +57,7 @@ DLL_EXPORT(EUserHasLicenseForAppResult) SteamAPI_ISteamUser_UserHasLicenseForApp
AppId_t 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);
});
@ -72,7 +72,7 @@ DLL_EXPORT(void*) SteamAPI_ISteamClient_GetISteamGenericInterface(
const char* 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);
});
@ -85,7 +85,7 @@ DLL_EXPORT(EResult) SteamAPI_ISteamInventory_GetResultStatus(
SteamInventoryResult_t 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);
});
@ -100,12 +100,12 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItems(
return steam_inventory::GetResultItems(
__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);
},
[&](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);
}
@ -122,7 +122,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetResultItemProperty(
) {
return steam_inventory::GetResultItemProperty(
__func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() {
GET_ORIGINAL_FUNCTION(SteamAPI_ISteamInventory_GetResultItemProperty)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_ISteamInventory_GetResultItemProperty)
return SteamAPI_ISteamInventory_GetResultItemProperty_o(
self, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut
@ -137,7 +137,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_CheckResultSteamID(
CSteamID 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);
});
@ -148,7 +148,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetAllItems(
SteamInventoryResult_t* 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);
});
@ -161,7 +161,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemsByID(
uint32_t 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);
});
@ -174,7 +174,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_SerializeResult(
uint32_t* 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);
});
@ -186,7 +186,7 @@ DLL_EXPORT(bool) SteamAPI_ISteamInventory_GetItemDefinitionIDs(
uint32_t* 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);
});

@ -1,11 +1,12 @@
#include <smoke_api/smoke_api.hpp>
#include <core/macros.hpp>
#include <koalabox/hook.hpp>
#include <steam_impl/steam_client.hpp>
using namespace smoke_api;
using namespace koalabox;
DLL_EXPORT(void*) SteamInternal_FindOrCreateUserInterface(HSteamUser hSteamUser, const char* version) {
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInternal_FindOrCreateUserInterface)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInternal_FindOrCreateUserInterface)
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) {
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInternal_CreateInterface)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInternal_CreateInterface)
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)) {
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}");
std::smatch match;
@ -44,7 +44,7 @@ DLL_EXPORT(void*) SteamClient() {
static auto version = get_versioned_interface(STEAM_CLIENT, "006");
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamClient)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamClient)
return SteamClient_o();
});
@ -54,7 +54,7 @@ DLL_EXPORT(void*) SteamApps() {
static auto version = get_versioned_interface(STEAM_APPS, "002");
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamApps)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamApps)
return SteamApps_o();
});
@ -64,7 +64,7 @@ DLL_EXPORT(void*) SteamUser() {
static auto version = get_versioned_interface(STEAM_USER, "012");
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamUser)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamUser)
return SteamUser_o();
});
@ -74,7 +74,7 @@ DLL_EXPORT(void*) SteamInventory() {
static auto version = get_versioned_interface(STEAM_INVENTORY, "001");
return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_FUNCTION(SteamInventory)
GET_ORIGINAL_FUNCTION_STEAMAPI(SteamInventory)
return SteamInventory_o();
});

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

@ -121,7 +121,8 @@ namespace steam_functions {
#define HOOK(MAP, FUNC) \
hook::swap_virtual_func( \
interface, \
globals::address_map, \
interface, \
#FUNC, \
get_ordinal(MAP, #FUNC, version_number), \
(FunctionAddress) (FUNC) \
@ -202,7 +203,7 @@ namespace steam_functions {
}
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;
try {
GetHSteamPipe_address = (void*) win_util::get_proc_address_or_throw(

@ -108,7 +108,8 @@ namespace steam_apps {
bool IsDlcUnlocked(
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
) {
try {

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

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

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

Loading…
Cancel
Save