From c5f8a3770249b4f361a5c861f7d23071f5fa2559 Mon Sep 17 00:00:00 2001 From: acidicoala <67734819+acidicoala@users.noreply.github.com> Date: Sun, 21 Sep 2025 21:48:24 +0500 Subject: [PATCH] Fixed late hooking --- CMakeLists.txt | 2 +- KoalaBox | 2 +- README.md | 9 +++++---- src/smoke_api/smoke_api.cpp | 32 ++++++++++++++++-------------- src/steam_api/steam_interfaces.cpp | 2 +- sync.json | 2 +- 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c26029..5953b4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.24) -project(SmokeAPI VERSION 3.1.3) +project(SmokeAPI VERSION 3.1.5) include(KoalaBox/cmake/KoalaBox.cmake) if(CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/KoalaBox b/KoalaBox index 44be3bf..183184c 160000 --- a/KoalaBox +++ b/KoalaBox @@ -1 +1 @@ -Subproject commit 44be3bf94f8d5e54a429e29f7faeaf90d0dd62df +Subproject commit 183184cf5bbf18dd92d5e92d2ccf445d795f445b diff --git a/README.md b/README.md index b303d20..1263d5b 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ If that didn't work, refer to the _Troubleshooting_ section below. ### 🪝 Hook mode - Download the [latest SmokeAPI release zip]. -- From this downloaded zip extract `SmokeAPI32.dll` or `SmokeAPI64.dll`, depending on a game's bitness. +- From this downloaded zip extract `smoke_api32.dll` or `smoke_api64.dll`, depending on a game's bitness. - Rename the unzipped DLL to `version.dll`. - Place this `version.dll` next to the game's `.exe` file. @@ -99,8 +99,8 @@ For example, assuming that the game loads `winmm.dll`: - Place `winmm.dll` next to the game's `.exe` file. - Install SmokeAPI - Download the [latest SmokeAPI release zip]. - - From this downloaded zip extract `SmokeAPI32.dll` or `SmokeAPI64.dll`, depending on a game's bitness. - - Place `SmokeAPI32.dll` or `SmokeAPI64.dll` next to the game's `.exe` file. + - From this downloaded zip extract `smoke_api32.dll` or `smoke_api64.dll`, depending on a game's bitness. + - Place `smoke_api32.dll` or `smoke_api64.dll` next to the game's `.exe` file. #### 🪝 Hook mode with Special K @@ -111,7 +111,7 @@ In such cases, it might be worth trying [Special K], which can inject SmokeAPI a - Find a `steam_api.dll` or `steam_api64.dll` file in game directory, and rename it to `steam_api_o.dll` or `steam_api64_o.dll`. - Download the [latest SmokeAPI release zip]. -- From this downloaded zip extract `SmokeAPI32.dll` or `SmokeAPI64.dll`, depending on a game's bitness. +- From this downloaded zip extract `smoke_api32.dll` or `smoke_api64.dll`, depending on a game's bitness. - Rename this extracted DLL to `steam_api.dll` or `steam_api64.dll`, depending on a game's bitness. - Place this renamed unlocker DLL next to the `steam_api_o.dll` or `steam_api64_o.dll` file. @@ -309,6 +309,7 @@ This project makes use of the following open source projects: - [pantor/inja](https://github.com/pantor/inja) - [bshoshany/thread-pool](https://github.com/bshoshany/thread-pool) - [batterycenter/embed](https://github.com/batterycenter/embed) +- [serge1/ELFIO](https://github.com/serge1/ELFIO) ## 📄 License diff --git a/src/smoke_api/smoke_api.cpp b/src/smoke_api/smoke_api.cpp index ca72666..e467335 100644 --- a/src/smoke_api/smoke_api.cpp +++ b/src/smoke_api/smoke_api.cpp @@ -42,6 +42,7 @@ namespace { namespace kb = koalabox; void* original_steamapi_handle = nullptr; + bool is_hook_mode; std::set find_steamclient_versions(void* steamapi_handle) { if(!steamapi_handle) { @@ -80,13 +81,19 @@ namespace { #endif } + // ReSharper disable once CppDFAConstantFunctionResult bool on_steamclient_loaded(void* steamclient_handle) { - static const auto CreateInterface$ = KB_MOD_GET_FUNC(steamclient_handle, CreateInterface); + KB_HOOK_DETOUR_MODULE(CreateInterface, steamclient_handle); - auto* steamapi_handle = original_steamapi_handle - ? original_steamapi_handle - : kb::lib::get_library_handle(STEAM_API_MODULE); - if(steamapi_handle) { + if(!is_hook_mode) { + return true; + } + + // Check for late hooking + + static const auto CreateInterface$ = KB_LIB_GET_FUNC(steamclient_handle, CreateInterface); + + if(auto* steamapi_handle = kb::lib::get_library_handle(STEAM_API_MODULE)) { // SteamAPI might have been initialized. // Hence, we need to query SteamClient interfaces and hook them if needed. const auto steamclient_versions = find_steamclient_versions(steamapi_handle); @@ -101,15 +108,11 @@ namespace { } } - KB_HOOK_DETOUR_MODULE(CreateInterface, steamclient_handle); - return true; } void init_lib_monitor() { - kb::lib_monitor::init_listener( - {{STEAMCLIENT_DLL, on_steamclient_loaded}} - ); + kb::lib_monitor::init_listener({{STEAMCLIENT_DLL, on_steamclient_loaded}}); } } @@ -133,7 +136,7 @@ namespace smoke_api { const auto exe_name = kb::path::to_str(exe_path.filename()); LOG_DEBUG("Process name: '{}' [{}-bit]", exe_name, kb::util::BITNESS); - LOG_DEBUG("Self handle: {}", module_handle); + LOG_DEBUG("Self name: '{}'", kb::path::to_str(kb::lib::get_fs_path(module_handle).filename())); // We need to hook functions in either mode kb::hook::init(true); @@ -141,17 +144,16 @@ namespace smoke_api { if(kb::hook::is_hook_mode(module_handle, STEAM_API_MODULE)) { LOG_INFO("Detected hook mode"); + is_hook_mode = true; init_lib_monitor(); } else { LOG_INFO("Detected proxy mode"); + is_hook_mode = true; init_lib_monitor(); const auto self_path = kb::paths::get_self_dir(); - original_steamapi_handle = kb::lib::load_original_library( - self_path, - STEAM_API_MODULE - ); + original_steamapi_handle = kb::lib::load_original_library(self_path, STEAM_API_MODULE); } LOG_INFO("Initialization complete"); diff --git a/src/steam_api/steam_interfaces.cpp b/src/steam_api/steam_interfaces.cpp index cc467be..806b3ce 100644 --- a/src/steam_api/steam_interfaces.cpp +++ b/src/steam_api/steam_interfaces.cpp @@ -218,7 +218,7 @@ namespace steam_interfaces { // Map virtual hook map to a set of keys const auto prefixes = std::views::keys(virtual_hook_map) | std::ranges::to(); - const auto CreateInterface$ = KB_MOD_GET_FUNC(steamclient_handle, CreateInterface); + const auto CreateInterface$ = KB_LIB_GET_FUNC(steamclient_handle, CreateInterface); DECLARE_ARGS(); THIS = CreateInterface$(steam_client_interface_version.c_str(), nullptr); diff --git a/sync.json b/sync.json index a472eaf..716a345 100644 --- a/sync.json +++ b/sync.json @@ -8,7 +8,7 @@ "sdk_dll_names": "`steam_api.dll` or `steam_api64.dll`", "sdk_dll_orig_names": "`steam_api_o.dll` or `steam_api64_o.dll`", "show_3rd_party_point": true, - "unlocker_dll_names": "`SmokeAPI32.dll` or `SmokeAPI64.dll`", + "unlocker_dll_names": "`smoke_api32.dll` or `smoke_api64.dll`", "config_filename": "SmokeAPI.config.json", "github_repo_url": "https://github.com/acidicoala/SmokeAPI", "forum_topic_url": "https://cs.rin.ru/forum/viewtopic.php?p=2597932#p2597932",