Added address map args

master
acidicoala 1 year ago
parent eaca0bec34
commit f29fc96dcd
No known key found for this signature in database
GPG Key ID: D24C6065B49C645B

@ -1 +1 @@
Subproject commit 6fa96ea016482b263827d82f02b86552d5e4d407 Subproject commit c0d357da78fcfa29e798b99d66d07170d73d6c9c

@ -8,18 +8,14 @@
#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 GET_ORIGINAL_VIRTUAL_FUNCTION(FUNC) \ #define GET_ORIGINAL_HOOKED_FUNCTION(FUNC) \
const auto FUNC##_o = koalabox::hook::get_original_function(globals::address_map, #FUNC, FUNC); const auto FUNC##_o = koalabox::hook::get_original_hooked_function(globals::address_map, #FUNC, FUNC);
#define $GET_ORIGINAL_MODULE_FUNCTION(FUNC, MODULE_HANDLE) \ #define GET_ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
static const auto FUNC##_o = koalabox::hook::get_original_function(MODULE_HANDLE, #FUNC, FUNC); static const auto FUNC##_o = koalabox::hook::get_original_function(globals::steamapi_module, #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) \ #define $DETOUR(FUNC, MODULE_HANDLE) \
koalabox::hook::detour_or_warn(MODULE_HANDLE, #FUNC, reinterpret_cast<FunctionAddress>(FUNC)); koalabox::hook::detour_or_warn(globals::address_map, MODULE_HANDLE, #FUNC, reinterpret_cast<FunctionAddress>(FUNC));
#define DETOUR_ADDRESS(FUNC, ADDRESS) \ #define DETOUR_ADDRESS(FUNC, ADDRESS) \
koalabox::hook::detour_or_warn(globals::address_map, ADDRESS, #FUNC, reinterpret_cast<FunctionAddress>(FUNC)); koalabox::hook::detour_or_warn(globals::address_map, ADDRESS, #FUNC, reinterpret_cast<FunctionAddress>(FUNC));

@ -5,6 +5,7 @@
#include <koalabox/dll_monitor.hpp> #include <koalabox/dll_monitor.hpp>
#include <koalabox/http_client.hpp> #include <koalabox/http_client.hpp>
#include <koalabox/util.hpp> #include <koalabox/util.hpp>
#include <steam_functions/steam_functions.hpp>
namespace koalageddon { namespace koalageddon {
KoalageddonConfig config; // NOLINT(cert-err58-cpp) KoalageddonConfig config; // NOLINT(cert-err58-cpp)
@ -65,13 +66,14 @@ namespace koalageddon {
globals::vstdlib_module = module_handle; globals::vstdlib_module = module_handle;
if (config::instance.unlock_family_sharing) { if (config::instance.unlock_family_sharing) {
init_vstdlib_hooks(); DETOUR_VSTDLIB(Coroutine_Create)
} }
} 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; globals::steamclient_module = module_handle;
init_steamclient_hooks();
DETOUR_STEAMCLIENT(CreateInterface)
} }
if (globals::vstdlib_module != nullptr && globals::steamclient_module != nullptr) { if (globals::vstdlib_module != nullptr && globals::steamclient_module != nullptr) {

@ -15,8 +15,9 @@ namespace koalageddon {
uint32_t vstdlib_callback_data_offset = 0; uint32_t vstdlib_callback_data_offset = 0;
uint32_t vstdlib_callback_name_offset = 4; uint32_t vstdlib_callback_name_offset = 4;
uint32_t client_engine_steam_client_internal_ordinal = 12;
uint32_t steam_client_internal_interface_selector_ordinal = 18;
String steamclient_interface_interceptor_pattern = "55 8B EC 8B ?? ?? ?? ?? ?? 81 EC ?? ?? ?? ?? 53 FF 15"; String steamclient_interface_interceptor_pattern = "55 8B EC 8B ?? ?? ?? ?? ?? 81 EC ?? ?? ?? ?? 53 FF 15";
String steamclient_interface_demux_pattern = "55 8B EC 83 EC ?? ?? ?? ?? 8B ?? ?? B8 ?? ?? ?? ?? 8B D9";
uint32_t IClientAppManager_IsAppDlcInstalled_ordinal = 8; uint32_t IClientAppManager_IsAppDlcInstalled_ordinal = 8;
uint32_t IClientApps_GetDLCCount_ordinal = 8; uint32_t IClientApps_GetDLCCount_ordinal = 8;
@ -40,8 +41,9 @@ namespace koalageddon {
vstdlib_callback_data_offset, vstdlib_callback_data_offset,
vstdlib_callback_name_offset, vstdlib_callback_name_offset,
client_engine_steam_client_internal_ordinal,
steam_client_internal_interface_selector_ordinal,
steamclient_interface_interceptor_pattern, steamclient_interface_interceptor_pattern,
steamclient_interface_demux_pattern,
IClientAppManager_IsAppDlcInstalled_ordinal, IClientAppManager_IsAppDlcInstalled_ordinal,
IClientApps_GetDLCCount_ordinal, IClientApps_GetDLCCount_ordinal,
@ -62,6 +64,6 @@ namespace koalageddon {
void init(); void init();
void init_steamclient_hooks(); void init_steamclient_hooks(const void* interface_selector_address);
void init_vstdlib_hooks(); void init_steamclient_hooks2();
} }

@ -9,14 +9,14 @@
using namespace koalabox; using namespace koalabox;
#define DEMUX_DECL(INTERFACE) \ #define SELECTOR_DECL(INTERFACE) \
constexpr auto INTERFACE = #INTERFACE; \ constexpr auto INTERFACE = #INTERFACE; \
DLL_EXPORT(void) INTERFACE##_Demux(const void*, const void*, const void*, const void*); \ DLL_EXPORT(void) INTERFACE##_Selector(const void*, const void*, const void*, const void*); \
DEMUX_DECL(IClientAppManager) SELECTOR_DECL(IClientAppManager)
DEMUX_DECL(IClientApps) SELECTOR_DECL(IClientApps)
DEMUX_DECL(IClientInventory) SELECTOR_DECL(IClientInventory)
DEMUX_DECL(IClientUser) SELECTOR_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);
@ -134,8 +134,8 @@ namespace koalageddon {
return (FunctionAddress) op.imm.value.u; return (FunctionAddress) op.imm.value.u;
} }
const char* find_interface_name(FunctionAddress demux_address) { const char* find_interface_name(FunctionAddress selector_address) {
auto* instruction_pointer = (uint8_t*) demux_address; auto* instruction_pointer = (uint8_t*) selector_address;
ZydisDecodedInstruction instruction{}; ZydisDecodedInstruction instruction{};
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, instruction_pointer, 1024, &instruction))) { while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, instruction_pointer, 1024, &instruction))) {
if (instruction.mnemonic == ZYDIS_MNEMONIC_PUSH) { if (instruction.mnemonic == ZYDIS_MNEMONIC_PUSH) {
@ -159,7 +159,7 @@ namespace koalageddon {
return nullptr; return nullptr;
} }
void init_steamclient_hooks() { void init_steamclient_hooks(const void* interface_selector_address) {
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32); ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
const HMODULE module_handle = win_util::get_module_handle_or_throw(STEAMCLIENT_DLL); const HMODULE module_handle = win_util::get_module_handle_or_throw(STEAMCLIENT_DLL);
@ -168,58 +168,48 @@ 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);
// TODO: There may actually be a way to find this address from "first principles" // Then iterate over each function selector call
// 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",
config.steamclient_interface_demux_pattern
);
// Then iterate over each function demux call auto* instruction_pointer = (uint8_t*) interface_selector_address;
auto* instruction_pointer = (uint8_t*) interface_demux_address;
ZydisDecodedInstruction previous_instruction{}; ZydisDecodedInstruction previous_instruction{};
ZydisDecodedInstruction instruction{}; ZydisDecodedInstruction instruction{};
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, instruction_pointer, 10, &instruction))) { while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, instruction_pointer, 10, &instruction))) {
if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP && previous_instruction.mnemonic == ZYDIS_MNEMONIC_CALL) { if (instruction.mnemonic == ZYDIS_MNEMONIC_JMP && previous_instruction.mnemonic == ZYDIS_MNEMONIC_CALL) {
// For every such call, extract a function demux address // For every such call, extract a function selector address
const auto call_demux_address = (FunctionAddress) ( const auto call_selector_address = (FunctionAddress) (
instruction_pointer - previous_instruction.length instruction_pointer - previous_instruction.length
); );
const auto function_demux_address = get_absolute_address( const auto function_selector_address = get_absolute_address(
previous_instruction, call_demux_address previous_instruction, call_selector_address
); );
if (function_demux_address == 0) { if (function_selector_address == 0) {
logger->warn("Failed to extract absolute address of call at {}", (void*) call_demux_address); logger->warn("Failed to extract absolute address of call at {}", (void*) call_selector_address);
} else { } else {
// Then use this address to extract the interface name // Then use this address to extract the interface name
const char* interface_name_address = find_interface_name(function_demux_address); const char* interface_name_address = find_interface_name(function_selector_address);
if (interface_name_address == nullptr) { if (interface_name_address == nullptr) {
logger->warn( logger->warn(
"Failed to extract interface name address of function demux at {}", "Failed to extract interface name address of function demux at {}",
(void*) function_demux_address (void*) function_selector_address
); );
} else { } else {
const String interface_name((char*) interface_name_address); const String interface_name((char*) interface_name_address);
logger->debug("Detected interface: '{}'", interface_name); logger->debug("Detected interface: '{}'", interface_name);
// Finally, hook the demux functions of interest // Finally, hook the selector functions of interest
if (IClientAppManager == interface_name) { if (IClientAppManager == interface_name) {
DETOUR_ADDRESS(IClientAppManager_Demux, function_demux_address) DETOUR_ADDRESS(IClientAppManager_Selector, function_selector_address)
} else if (IClientApps == interface_name) { } else if (IClientApps == interface_name) {
DETOUR_ADDRESS(IClientApps_Demux, function_demux_address) DETOUR_ADDRESS(IClientApps_Selector, function_selector_address)
} else if (IClientInventory == interface_name) { } else if (IClientInventory == interface_name) {
DETOUR_ADDRESS(IClientInventory_Demux, function_demux_address) DETOUR_ADDRESS(IClientInventory_Selector, function_selector_address)
} else if (IClientUser == interface_name) { } else if (IClientUser == interface_name) {
DETOUR_ADDRESS(IClientUser_Demux, function_demux_address) DETOUR_ADDRESS(IClientUser_Selector, function_selector_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
@ -256,13 +246,12 @@ namespace koalageddon {
DETOUR_ADDRESS(SteamClient_Interface_Interceptor, interface_interceptor_address) DETOUR_ADDRESS(SteamClient_Interface_Interceptor, interface_interceptor_address)
} }
} }
} }
/** /**
* This function intercepts interface name and function names, which we need to determine which functions to hook. * This function intercepts interface name and function names, which we need to determine which functions to hook.
* Unfortunately we can't reliably get interface pointer in this function, hence we need to hook corresponding * Unfortunately we can't reliably get interface pointer in this function, hence we need to hook corresponding
* parent demux functions which will contain the interface pointer as the first parameter. * parent selector functions which will contain the interface pointer as the first parameter.
*/ */
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) {
try { try {
@ -323,7 +312,7 @@ DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, c
}); });
} }
GET_ORIGINAL_VIRTUAL_FUNCTION(SteamClient_Interface_Interceptor) GET_ORIGINAL_HOOKED_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());
@ -332,11 +321,11 @@ DLL_EXPORT(void) SteamClient_Interface_Interceptor(const char* interface_name, c
/** /**
* This macro will generate a definition of a demux function, * This macro will generate a definition of a selector function,
* which will cache the interface pointer in the local map. * which will cache the interface pointer in the local map.
*/ */
#define DEMUX_IMPL(INTERFACE) \ #define SELECTOR_IMPL(INTERFACE) \
DLL_EXPORT(void) INTERFACE##_Demux( \ DLL_EXPORT(void) INTERFACE##_Selector( \
const void* arg1, \ const void* arg1, \
const void* arg2, \ const void* arg2, \
const void* arg3, \ const void* arg3, \
@ -346,11 +335,11 @@ 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_VIRTUAL_FUNCTION(INTERFACE##_Demux) \ GET_ORIGINAL_HOOKED_FUNCTION(INTERFACE##_Selector) \
INTERFACE##_Demux_o(arg1, arg2, arg3, arg4); \ INTERFACE##_Selector_o(arg1, arg2, arg3, arg4); \
} }
DEMUX_IMPL(IClientAppManager) SELECTOR_IMPL(IClientAppManager)
DEMUX_IMPL(IClientApps) SELECTOR_IMPL(IClientApps)
DEMUX_IMPL(IClientInventory) SELECTOR_IMPL(IClientInventory)
DEMUX_IMPL(IClientUser) SELECTOR_IMPL(IClientUser)

@ -6,15 +6,6 @@
using namespace koalageddon; using namespace koalageddon;
using namespace koalabox; 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_VSTDLIB(Coroutine_Create)
}
}
VIRTUAL(bool) SharedLicensesLockStatus(PARAMS(void* arg)) { // NOLINT(misc-unused-parameters) VIRTUAL(bool) SharedLicensesLockStatus(PARAMS(void* arg)) { // NOLINT(misc-unused-parameters)
logger->debug("{} -> instance: {}, arg: {}", __func__, fmt::ptr(THIS), fmt::ptr(arg)); logger->debug("{} -> instance: {}, arg: {}", __func__, fmt::ptr(THIS), fmt::ptr(arg));
return true; return true;
@ -46,7 +37,7 @@ 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(VStdLib_Callback_Interceptor) GET_ORIGINAL_HOOKED_FUNCTION(VStdLib_Callback_Interceptor)
VStdLib_Callback_Interceptor_o(ARGS(p_name)); VStdLib_Callback_Interceptor_o(ARGS(p_name));
@ -79,7 +70,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_VSTDLIB(Coroutine_Create) GET_ORIGINAL_HOOKED_FUNCTION(Coroutine_Create)
const auto result = Coroutine_Create_o(callback_address, data); const auto result = Coroutine_Create_o(callback_address, data);

@ -17,7 +17,7 @@ VIRTUAL(bool) ISteamApps_BIsDlcInstalled(PARAMS(AppId_t appID)) { // NOLINT(misc
} }
VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) { VIRTUAL(int) ISteamApps_GetDLCCount(PARAMS()) {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamApps_GetDLCCount) GET_ORIGINAL_HOOKED_FUNCTION(ISteamApps_GetDLCCount)
return steam_apps::GetDLCCount(__func__, 0, [&]() { return steam_apps::GetDLCCount(__func__, 0, [&]() {
@ -35,7 +35,7 @@ VIRTUAL(bool) ISteamApps_BGetDLCDataByIndex(
) )
) { ) {
return steam_apps::GetDLCDataByIndex(__func__, 0, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize, [&]() { return steam_apps::GetDLCDataByIndex(__func__, 0, iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamApps_BGetDLCDataByIndex) GET_ORIGINAL_HOOKED_FUNCTION(ISteamApps_BGetDLCDataByIndex)
return ISteamApps_BGetDLCDataByIndex_o( return ISteamApps_BGetDLCDataByIndex_o(
ARGS(iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize) ARGS(iDLC, pAppID, pbAvailable, pchName, cchNameBufferSize)

@ -11,7 +11,7 @@ VIRTUAL(void*) ISteamClient_GetISteamApps(
) )
) { ) {
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamClient_GetISteamApps) GET_ORIGINAL_HOOKED_FUNCTION(ISteamClient_GetISteamApps)
return ISteamClient_GetISteamApps_o(ARGS(hSteamUser, hSteamPipe, version)); return ISteamClient_GetISteamApps_o(ARGS(hSteamUser, hSteamPipe, version));
}); });
@ -25,7 +25,7 @@ VIRTUAL(void*) ISteamClient_GetISteamUser(
) )
) { ) {
return steam_client::GetGenericInterface(__func__, version, [&]() { return steam_client::GetGenericInterface(__func__, version, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamClient_GetISteamUser) GET_ORIGINAL_HOOKED_FUNCTION(ISteamClient_GetISteamUser)
return ISteamClient_GetISteamUser_o(ARGS(hSteamUser, hSteamPipe, version)); return ISteamClient_GetISteamUser_o(ARGS(hSteamUser, hSteamPipe, version));
}); });
@ -39,7 +39,7 @@ VIRTUAL(void*) ISteamClient_GetISteamGenericInterface(
) )
) { ) {
return steam_client::GetGenericInterface(__func__, pchVersion, [&]() { return steam_client::GetGenericInterface(__func__, pchVersion, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamClient_GetISteamGenericInterface) GET_ORIGINAL_HOOKED_FUNCTION(ISteamClient_GetISteamGenericInterface)
return ISteamClient_GetISteamGenericInterface_o(ARGS(hSteamUser, hSteamPipe, pchVersion)); return ISteamClient_GetISteamGenericInterface_o(ARGS(hSteamUser, hSteamPipe, pchVersion));
}); });
@ -53,7 +53,7 @@ VIRTUAL(void*) ISteamClient_GetISteamInventory(
) )
) { ) {
return steam_client::GetGenericInterface(__func__, pchVersion, [&]() { return steam_client::GetGenericInterface(__func__, pchVersion, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamClient_GetISteamInventory) GET_ORIGINAL_HOOKED_FUNCTION(ISteamClient_GetISteamInventory)
return ISteamClient_GetISteamInventory_o(ARGS(hSteamUser, hSteamPipe, pchVersion)); return ISteamClient_GetISteamInventory_o(ARGS(hSteamUser, hSteamPipe, pchVersion));
}); });

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(EResult) ISteamInventory_GetResultStatus(PARAMS(SteamInventoryResult_t resultHandle)) { VIRTUAL(EResult) ISteamInventory_GetResultStatus(PARAMS(SteamInventoryResult_t resultHandle)) {
return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() { return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetResultStatus) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetResultStatus)
return ISteamInventory_GetResultStatus_o(ARGS(resultHandle)); return ISteamInventory_GetResultStatus_o(ARGS(resultHandle));
}); });
@ -22,12 +22,12 @@ VIRTUAL(bool) ISteamInventory_GetResultItems(
return steam_inventory::GetResultItems( return steam_inventory::GetResultItems(
__func__, resultHandle, pOutItemsArray, punOutItemsArraySize, __func__, resultHandle, pOutItemsArray, punOutItemsArraySize,
[&]() { [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetResultItems) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetResultItems)
return ISteamInventory_GetResultItems_o(ARGS(resultHandle, pOutItemsArray, punOutItemsArraySize)); return ISteamInventory_GetResultItems_o(ARGS(resultHandle, pOutItemsArray, punOutItemsArraySize));
}, },
[&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) { [&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetItemDefinitionIDs) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetItemDefinitionIDs)
return ISteamInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, punItemDefIDsArraySize)); return ISteamInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, punItemDefIDsArraySize));
} }
@ -45,7 +45,7 @@ VIRTUAL(bool) ISteamInventory_GetResultItemProperty(
) { ) {
return steam_inventory::GetResultItemProperty( return steam_inventory::GetResultItemProperty(
__func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() { __func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetResultItemProperty) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetResultItemProperty)
return ISteamInventory_GetResultItemProperty_o( return ISteamInventory_GetResultItemProperty_o(
ARGS(resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut) ARGS(resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut)
@ -61,7 +61,7 @@ VIRTUAL(bool) ISteamInventory_CheckResultSteamID(
) )
) { ) {
return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() { return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_CheckResultSteamID) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_CheckResultSteamID)
return ISteamInventory_CheckResultSteamID_o(ARGS(resultHandle, steamIDExpected)); return ISteamInventory_CheckResultSteamID_o(ARGS(resultHandle, steamIDExpected));
}); });
@ -69,7 +69,7 @@ VIRTUAL(bool) ISteamInventory_CheckResultSteamID(
VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) { VIRTUAL(bool) ISteamInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) {
return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() { return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetAllItems) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetAllItems)
return ISteamInventory_GetAllItems_o(ARGS(pResultHandle)); return ISteamInventory_GetAllItems_o(ARGS(pResultHandle));
}); });
@ -83,7 +83,7 @@ VIRTUAL(bool) ISteamInventory_GetItemsByID(
) )
) { ) {
return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() { return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetItemsByID) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetItemsByID)
return ISteamInventory_GetItemsByID_o(ARGS(pResultHandle, pInstanceIDs, unCountInstanceIDs)); return ISteamInventory_GetItemsByID_o(ARGS(pResultHandle, pInstanceIDs, unCountInstanceIDs));
}); });
@ -97,7 +97,7 @@ VIRTUAL(bool) ISteamInventory_SerializeResult(
) )
) { ) {
return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() { return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_SerializeResult) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_SerializeResult)
return ISteamInventory_SerializeResult_o(ARGS(resultHandle, pOutBuffer, punOutBufferSize)); return ISteamInventory_SerializeResult_o(ARGS(resultHandle, pOutBuffer, punOutBufferSize));
}); });
@ -110,7 +110,7 @@ VIRTUAL(bool) ISteamInventory_GetItemDefinitionIDs(
) )
) { ) {
return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, punItemDefIDsArraySize, [&]() { return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, punItemDefIDsArraySize, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamInventory_GetItemDefinitionIDs) GET_ORIGINAL_HOOKED_FUNCTION(ISteamInventory_GetItemDefinitionIDs)
return ISteamInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, punItemDefIDsArraySize)); return ISteamInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, punItemDefIDsArraySize));
}); });

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t appID)) { VIRTUAL(EUserHasLicenseForAppResult) ISteamUser_UserHasLicenseForApp(PARAMS(CSteamID steamID, AppId_t appID)) {
return steam_user::UserHasLicenseForApp(__func__, appID, [&]() { return steam_user::UserHasLicenseForApp(__func__, appID, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(ISteamUser_UserHasLicenseForApp) GET_ORIGINAL_HOOKED_FUNCTION(ISteamUser_UserHasLicenseForApp)
return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, appID)); return ISteamUser_UserHasLicenseForApp_o(ARGS(steamID, appID));
}); });

@ -1,9 +1,8 @@
#include <steam_functions/steam_functions.hpp> #include <steam_functions/steam_functions.hpp>
#include <build_config.h> #include <build_config.h>
#include <koalabox/hook.hpp> #include <koalabox/hook.hpp>
#include <koalageddon/koalageddon.hpp>
#include <koalabox/win_util.hpp> #include <koalabox/win_util.hpp>
#include <polyhook2/Misc.hpp> #include <polyhook2/Misc.hpp>
namespace steam_functions { namespace steam_functions {
@ -195,6 +194,19 @@ namespace steam_functions {
if (version_number >= 2) { if (version_number >= 2) {
HOOK_STEAM_INVENTORY(ISteamInventory_GetResultItemProperty) HOOK_STEAM_INVENTORY(ISteamInventory_GetResultItemProperty)
} }
} else if (version_string.starts_with(CLIENT_ENGINE)) {
// Koalageddon mode
const auto* steam_client_internal = ((const void****) interface)[
koalageddon::config.client_engine_steam_client_internal_ordinal
];
const auto* interface_selector_address = (*steam_client_internal)[
koalageddon::config.steam_client_internal_interface_selector_ordinal
];
logger->debug("Found interface selector at: {}", interface_selector_address);
koalageddon::init_steamclient_hooks(interface_selector_address);
} else { } else {
return; return;
} }

@ -42,7 +42,6 @@ class ISteamApps;
class ISteamUser; class ISteamUser;
class ISteamInventory; class ISteamInventory;
// TODO: Refactor into multiple headers // TODO: Refactor into multiple headers
// ISteamClient // ISteamClient
@ -128,6 +127,9 @@ VIRTUAL(bool) IClientInventory_GetItemsByID(PARAMS(SteamInventoryResult_t*, cons
VIRTUAL(bool) IClientInventory_SerializeResult(PARAMS(SteamInventoryResult_t, void*, uint32_t, uint32_t *)); VIRTUAL(bool) IClientInventory_SerializeResult(PARAMS(SteamInventoryResult_t, void*, uint32_t, uint32_t *));
VIRTUAL(bool) IClientInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint32_t, uint32_t *)); VIRTUAL(bool) IClientInventory_GetItemDefinitionIDs(PARAMS(SteamItemDef_t*, uint32_t, uint32_t *));
typedef uint32_t HCoroutine;
DLL_EXPORT(HCoroutine) Coroutine_Create(void* callback_address, struct CoroutineData* data);
namespace steam_functions { namespace steam_functions {
using namespace koalabox; using namespace koalabox;
@ -135,6 +137,7 @@ namespace steam_functions {
const String STEAM_CLIENT = "SteamClient"; // NOLINT(cert-err58-cpp) const String STEAM_CLIENT = "SteamClient"; // NOLINT(cert-err58-cpp)
const String STEAM_USER = "SteamUser"; // NOLINT(cert-err58-cpp) const String STEAM_USER = "SteamUser"; // NOLINT(cert-err58-cpp)
const String STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V"; // NOLINT(cert-err58-cpp) const String STEAM_INVENTORY = "STEAMINVENTORY_INTERFACE_V"; // NOLINT(cert-err58-cpp)
const String CLIENT_ENGINE = "CLIENTENGINE_INTERFACE_VERSION"; // NOLINT(cert-err58-cpp)
void hook_virtuals(void* interface, const String& version_string); void hook_virtuals(void* interface, const String& version_string);
uint32_t get_app_id_or_throw(); uint32_t get_app_id_or_throw();

@ -1,11 +1,8 @@
#include <smoke_api/smoke_api.hpp>
#include <steam_impl/steam_client.hpp> #include <steam_impl/steam_client.hpp>
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_STEAMCLIENT(CreateInterface) GET_ORIGINAL_HOOKED_FUNCTION(CreateInterface)
return CreateInterface_o(interface_string, out_result); return CreateInterface_o(interface_string, out_result);
}); });

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(bool) IClientAppManager_IsAppDlcInstalled(PARAMS(AppId_t app_id, AppId_t dlc_id)) { VIRTUAL(bool) IClientAppManager_IsAppDlcInstalled(PARAMS(AppId_t app_id, AppId_t dlc_id)) {
return steam_apps::IsDlcUnlocked(__func__, app_id, dlc_id, [&]() { return steam_apps::IsDlcUnlocked(__func__, app_id, dlc_id, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientAppManager_IsAppDlcInstalled) GET_ORIGINAL_HOOKED_FUNCTION(IClientAppManager_IsAppDlcInstalled)
return IClientAppManager_IsAppDlcInstalled_o(ARGS(app_id, dlc_id)); return IClientAppManager_IsAppDlcInstalled_o(ARGS(app_id, dlc_id));
}); });

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) { VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) {
return steam_apps::GetDLCCount(__func__, appId, [&]() { return steam_apps::GetDLCCount(__func__, appId, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientApps_GetDLCCount) GET_ORIGINAL_HOOKED_FUNCTION(IClientApps_GetDLCCount)
return IClientApps_GetDLCCount_o(ARGS(appId)); return IClientApps_GetDLCCount_o(ARGS(appId));
}); });
@ -22,7 +22,7 @@ VIRTUAL(bool) IClientApps_BGetDLCDataByIndex(
) )
) { ) {
return steam_apps::GetDLCDataByIndex(__func__, appID, iDLC, pDlcID, pbAvailable, pchName, cchNameBufferSize, [&]() { return steam_apps::GetDLCDataByIndex(__func__, appID, iDLC, pDlcID, pbAvailable, pchName, cchNameBufferSize, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientApps_BGetDLCDataByIndex) GET_ORIGINAL_HOOKED_FUNCTION(IClientApps_BGetDLCDataByIndex)
return IClientApps_BGetDLCDataByIndex_o( return IClientApps_BGetDLCDataByIndex_o(
ARGS(appID, iDLC, pDlcID, pbAvailable, pchName, cchNameBufferSize) ARGS(appID, iDLC, pDlcID, pbAvailable, pchName, cchNameBufferSize)

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(EResult) IClientInventory_GetResultStatus(PARAMS(SteamInventoryResult_t resultHandle)) { VIRTUAL(EResult) IClientInventory_GetResultStatus(PARAMS(SteamInventoryResult_t resultHandle)) {
return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() { return steam_inventory::GetResultStatus(__func__, resultHandle, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetResultStatus) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetResultStatus)
return IClientInventory_GetResultStatus_o(ARGS(resultHandle)); return IClientInventory_GetResultStatus_o(ARGS(resultHandle));
}); });
@ -22,7 +22,7 @@ VIRTUAL(bool) IClientInventory_GetResultItems(
return steam_inventory::GetResultItems( return steam_inventory::GetResultItems(
__func__, resultHandle, pOutItemsArray, punOutItemsArraySize, __func__, resultHandle, pOutItemsArray, punOutItemsArraySize,
[&]() { [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetResultItems) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetResultItems)
*punOutItemsArraySize = item_count; *punOutItemsArraySize = item_count;
return IClientInventory_GetResultItems_o( return IClientInventory_GetResultItems_o(
@ -30,7 +30,7 @@ VIRTUAL(bool) IClientInventory_GetResultItems(
); );
}, },
[&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) { [&](SteamItemDef_t* pItemDefIDs, uint32_t* punItemDefIDsArraySize) {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetItemDefinitionIDs) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetItemDefinitionIDs)
return IClientInventory_GetItemDefinitionIDs_o( return IClientInventory_GetItemDefinitionIDs_o(
ARGS(pItemDefIDs, *punItemDefIDsArraySize, punItemDefIDsArraySize) ARGS(pItemDefIDs, *punItemDefIDsArraySize, punItemDefIDsArraySize)
@ -51,7 +51,7 @@ VIRTUAL(bool) IClientInventory_GetResultItemProperty(
) { ) {
return steam_inventory::GetResultItemProperty( return steam_inventory::GetResultItemProperty(
__func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() { __func__, resultHandle, unItemIndex, pchPropertyName, pchValueBuffer, punValueBufferSizeOut, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetResultItemProperty) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetResultItemProperty)
*punValueBufferSizeOut = item_count; *punValueBufferSizeOut = item_count;
return IClientInventory_GetResultItemProperty_o( return IClientInventory_GetResultItemProperty_o(
@ -68,7 +68,7 @@ VIRTUAL(bool) IClientInventory_CheckResultSteamID(
) )
) { ) {
return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() { return steam_inventory::CheckResultSteamID(__func__, resultHandle, steamIDExpected, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_CheckResultSteamID) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_CheckResultSteamID)
return IClientInventory_CheckResultSteamID_o(ARGS(resultHandle, steamIDExpected)); return IClientInventory_CheckResultSteamID_o(ARGS(resultHandle, steamIDExpected));
}); });
@ -76,7 +76,7 @@ VIRTUAL(bool) IClientInventory_CheckResultSteamID(
VIRTUAL(bool) IClientInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) { VIRTUAL(bool) IClientInventory_GetAllItems(PARAMS(SteamInventoryResult_t* pResultHandle)) {
return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() { return steam_inventory::GetAllItems(__func__, pResultHandle, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetAllItems) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetAllItems)
return IClientInventory_GetAllItems_o(ARGS(pResultHandle)); return IClientInventory_GetAllItems_o(ARGS(pResultHandle));
}); });
@ -90,7 +90,7 @@ VIRTUAL(bool) IClientInventory_GetItemsByID(
) )
) { ) {
return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() { return steam_inventory::GetItemsByID(__func__, pResultHandle, pInstanceIDs, unCountInstanceIDs, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetItemsByID) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetItemsByID)
return IClientInventory_GetItemsByID_o(ARGS(pResultHandle, pInstanceIDs, unCountInstanceIDs)); return IClientInventory_GetItemsByID_o(ARGS(pResultHandle, pInstanceIDs, unCountInstanceIDs));
}); });
@ -105,7 +105,7 @@ VIRTUAL(bool) IClientInventory_SerializeResult(
) )
) { ) {
return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() { return steam_inventory::SerializeResult(__func__, resultHandle, pOutBuffer, punOutBufferSize, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_SerializeResult) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_SerializeResult)
*punOutBufferSize = buffer_size; *punOutBufferSize = buffer_size;
return IClientInventory_SerializeResult_o(ARGS(resultHandle, pOutBuffer, buffer_size, punOutBufferSize)); return IClientInventory_SerializeResult_o(ARGS(resultHandle, pOutBuffer, buffer_size, punOutBufferSize));
@ -120,7 +120,7 @@ VIRTUAL(bool) IClientInventory_GetItemDefinitionIDs(
) )
) { ) {
return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, p_array_size, [&]() { return steam_inventory::GetItemDefinitionIDs(__func__, pItemDefIDs, p_array_size, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientInventory_GetItemDefinitionIDs) GET_ORIGINAL_HOOKED_FUNCTION(IClientInventory_GetItemDefinitionIDs)
*p_array_size = item_count; *p_array_size = item_count;
return IClientInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, item_count, p_array_size)); return IClientInventory_GetItemDefinitionIDs_o(ARGS(pItemDefIDs, item_count, p_array_size));

@ -5,7 +5,7 @@ using namespace smoke_api;
VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t app_id)) { VIRTUAL(bool) IClientUser_BIsSubscribedApp(PARAMS(AppId_t app_id)) {
return steam_apps::IsDlcUnlocked(__func__, 0, app_id, [&]() { return steam_apps::IsDlcUnlocked(__func__, 0, app_id, [&]() {
GET_ORIGINAL_VIRTUAL_FUNCTION(IClientUser_BIsSubscribedApp) GET_ORIGINAL_HOOKED_FUNCTION(IClientUser_BIsSubscribedApp)
return IClientUser_BIsSubscribedApp_o(ARGS(app_id)); return IClientUser_BIsSubscribedApp_o(ARGS(app_id));
}); });

Loading…
Cancel
Save