mirror of
https://github.com/acidicoala/SmokeAPI.git
synced 2026-01-26 22:42:51 -05:00
Reworked tools
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <core/globals.hpp>
|
||||
#include <koalabox/core.hpp>
|
||||
#include <koalabox/hook.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
/**
|
||||
* By default, virtual functions are declared with __thiscall
|
||||
@@ -30,35 +30,39 @@
|
||||
* The macros below implement the above-mentioned considerations.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
#define PARAMS(...) void* RCX, __VA_ARGS__
|
||||
#define PARAMS(...) void *RCX, __VA_ARGS__
|
||||
#define ARGS(...) RCX, __VA_ARGS__
|
||||
#define THIS RCX
|
||||
#else
|
||||
#define PARAMS(...) const void* ECX, const void* EDX, __VA_ARGS__
|
||||
#define PARAMS(...) const void *ECX, const void *EDX, __VA_ARGS__
|
||||
#define ARGS(...) ECX, EDX, __VA_ARGS__
|
||||
#define THIS ECX
|
||||
#endif
|
||||
|
||||
// Names beginning with $ designate macros that are not meant to be used directly by the sources consuming this file
|
||||
// Names beginning with $ designate macros that are not meant to be used directly by the sources
|
||||
// consuming this file
|
||||
|
||||
// IMPORTANT: DLL_EXPORT is hardcoded in exports_generator.cpp,
|
||||
// so any name changes here must be reflected there as well.
|
||||
#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
|
||||
|
||||
// TODO: Replace with direct call
|
||||
#define GET_ORIGINAL_HOOKED_FUNCTION(FUNC) \
|
||||
#define GET_ORIGINAL_HOOKED_FUNCTION(FUNC) \
|
||||
static const auto FUNC##_o = koalabox::hook::get_original_hooked_function(#FUNC, FUNC);
|
||||
|
||||
#define ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
|
||||
#define ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
|
||||
koalabox::hook::get_original_function(globals::steamapi_module, #FUNC, FUNC)
|
||||
|
||||
// TODO: Rename to DEFINE_ORIGINAL_FUNCTION_STEAMAPI
|
||||
#define GET_ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
|
||||
#define GET_ORIGINAL_FUNCTION_STEAMAPI(FUNC) \
|
||||
static const auto FUNC##_o = ORIGINAL_FUNCTION_STEAMAPI(FUNC);
|
||||
|
||||
#define DETOUR_ADDRESS(FUNC, ADDRESS) \
|
||||
#define DETOUR_ADDRESS(FUNC, ADDRESS) \
|
||||
koalabox::hook::detour_or_warn(ADDRESS, #FUNC, reinterpret_cast<uintptr_t>(FUNC));
|
||||
|
||||
#define $DETOUR(FUNC, NAME, MODULE_HANDLE) \
|
||||
#define $DETOUR(FUNC, NAME, MODULE_HANDLE) \
|
||||
koalabox::hook::detour_or_warn(MODULE_HANDLE, NAME, reinterpret_cast<uintptr_t>(FUNC));
|
||||
|
||||
#define DETOUR_STEAMCLIENT(FUNC) $DETOUR(FUNC, #FUNC, globals::steamclient_module)
|
||||
@@ -116,16 +120,15 @@ struct App {
|
||||
using AppDlcNameMap = Map<AppIdKey, App>;
|
||||
|
||||
class DLC {
|
||||
private:
|
||||
private:
|
||||
// These 2 names must match the property names from Steam API
|
||||
String appid;
|
||||
String name;
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit DLC() = default;
|
||||
|
||||
explicit DLC(String appid, String name) : appid{std::move(appid)}, name{std::move(name)} {
|
||||
}
|
||||
explicit DLC(String appid, String name) : appid{std::move(appid)}, name{std::move(name)} {}
|
||||
|
||||
[[nodiscard]] String get_id_str() const {
|
||||
return appid;
|
||||
@@ -141,7 +144,7 @@ public:
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(DLC, appid, name)
|
||||
|
||||
static Vector<DLC> get_dlcs_from_apps(const AppDlcNameMap &apps, AppId_t app_id);
|
||||
static Vector<DLC> get_dlcs_from_apps(const AppDlcNameMap& apps, AppId_t app_id);
|
||||
|
||||
static DlcNameMap get_dlc_map_from_vector(const Vector<DLC> &vector);
|
||||
static DlcNameMap get_dlc_map_from_vector(const Vector<DLC>& vector);
|
||||
};
|
||||
@@ -1,5 +1,18 @@
|
||||
#include <smoke_api/config.hpp>
|
||||
|
||||
|
||||
// DLL_EXPORT(void) SteamAPI_Shutdown1() {
|
||||
// LOG_INFO("{} -> Game requested shutdown", __func__);
|
||||
//
|
||||
// ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_Shutdown)();
|
||||
// }
|
||||
|
||||
/*DLL_EXPORT(void) SteamAPI_Shutdown2() {
|
||||
LOG_INFO("{} -> Game requested shutdown", __func__);
|
||||
|
||||
ORIGINAL_FUNCTION_STEAMAPI(SteamAPI_Shutdown)();
|
||||
}*/
|
||||
|
||||
// TODO: Detour in hook mode
|
||||
DLL_EXPORT(bool) SteamAPI_RestartAppIfNecessary(
|
||||
[[maybe_unused]] const uint32_t unOwnAppID
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <koalabox/hook.hpp>
|
||||
#include <koalabox/loader.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
#include <koalabox/str.hpp>
|
||||
#include <koalabox/util.hpp>
|
||||
#include <koalabox/win_util.hpp>
|
||||
|
||||
@@ -40,8 +41,9 @@
|
||||
namespace {
|
||||
void override_app_id() {
|
||||
const auto override_app_id = smoke_api::config::instance.override_app_id;
|
||||
if (override_app_id == 0)
|
||||
if (override_app_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
spdlog::default_logger_raw();
|
||||
LOG_DEBUG("Overriding app id to {}", override_app_id);
|
||||
@@ -74,7 +76,7 @@ namespace {
|
||||
|
||||
bool is_valve_steam(const String& exe_name) noexcept {
|
||||
try {
|
||||
if (exe_name < not_equals > "steam.exe") {
|
||||
if (not koalabox::str::eq(exe_name, "steam.exe")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ namespace {
|
||||
const auto manifest = koalabox::win_util::get_module_manifest(steam_handle);
|
||||
|
||||
// Steam.exe manifest is expected to contain this string
|
||||
return manifest < contains > "valvesoftware.steam.steam";
|
||||
return manifest.contains("valvesoftware.steam.steam");
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("{} -> {}", __func__, e.what());
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
VIRTUAL(bool) IClientAppManager_IsAppDlcInstalled(PARAMS(AppId_t app_id, AppId_t dlc_id)) {
|
||||
try {
|
||||
return steam_apps::IsDlcUnlocked(
|
||||
__func__, app_id, dlc_id, [&]() {
|
||||
__func__, app_id, dlc_id, [&] {
|
||||
GET_ORIGINAL_HOOKED_FUNCTION(IClientAppManager_IsAppDlcInstalled)
|
||||
|
||||
return IClientAppManager_IsAppDlcInstalled_o(ARGS(app_id, dlc_id));
|
||||
}
|
||||
);
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ VIRTUAL(int) IClientApps_GetDLCCount(PARAMS(AppId_t appId)) {
|
||||
}
|
||||
);
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ VIRTUAL(bool) IClientApps_BGetDLCDataByIndex(
|
||||
ARGS(appID, iDLC, pDlcID, pbAvailable, pchName, cchNameBufferSize)
|
||||
);
|
||||
},
|
||||
[&](AppId_t dlc_id) {
|
||||
[&](const AppId_t dlc_id) {
|
||||
const auto* app_manager_interface = store::steamclient::interface_name_to_address_map["IClientAppManager"];
|
||||
if (app_manager_interface) {
|
||||
IClientAppManager_IsAppDlcInstalled(app_manager_interface, EDX, appID, dlc_id);
|
||||
@@ -48,7 +48,7 @@ VIRTUAL(bool) IClientApps_BGetDLCDataByIndex(
|
||||
}
|
||||
);
|
||||
} catch (const Exception& e) {
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what())
|
||||
LOG_ERROR("{} -> Error: {}", __func__, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace store::steamclient {
|
||||
}
|
||||
|
||||
void detour_interface_selector(const String& interface_name, uintptr_t function_selector_address) {
|
||||
LOG_DEBUG("Detected interface: '{}'", interface_name)
|
||||
LOG_DEBUG("Detected interface: '{}'", interface_name);
|
||||
|
||||
DETOUR_SELECTOR(IClientAppManager)
|
||||
DETOUR_SELECTOR(IClientApps)
|
||||
@@ -198,10 +198,10 @@ namespace store::steamclient {
|
||||
const std::list<ZydisDecodedInstruction>& instruction_list
|
||||
)>& callback
|
||||
) {
|
||||
LOG_TRACE("{} -> start_address: {}", __func__, (void*) start_address)
|
||||
LOG_TRACE("{} -> start_address: {}", __func__, (void*) start_address);
|
||||
|
||||
if (visited_addresses.contains(start_address)) {
|
||||
LOG_TRACE("Breaking recursion due to visited address")
|
||||
LOG_TRACE("Breaking recursion due to visited address");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace store::steamclient {
|
||||
LOG_TRACE(
|
||||
"{} -> visiting {} │ {}",
|
||||
__func__, (void*) current_address, *get_instruction_string(instruction, current_address)
|
||||
)
|
||||
);
|
||||
|
||||
const auto operand = instruction.operands[0];
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace store::steamclient {
|
||||
visit_code(visited_addresses, jump_taken_destination, context, callback);
|
||||
visit_code(visited_addresses, jump_not_taken_destination, context, callback);
|
||||
|
||||
LOG_TRACE("{} -> Breaking recursion due to a conditional branch", __func__)
|
||||
LOG_TRACE("{} -> Breaking recursion due to a conditional branch", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -266,12 +266,12 @@ namespace store::steamclient {
|
||||
table_entry++;
|
||||
}
|
||||
|
||||
LOG_TRACE("{} -> Breaking recursion due to a jump table", __func__)
|
||||
LOG_TRACE("{} -> Breaking recursion due to a jump table", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (instruction.mnemonic == ZYDIS_MNEMONIC_RET) {
|
||||
LOG_TRACE("{} -> Breaking recursion due to return instruction", __func__)
|
||||
LOG_TRACE("{} -> Breaking recursion due to return instruction", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ namespace store::steamclient {
|
||||
if (offset && is_derived_from_base_reg) {
|
||||
const auto ordinal = *offset / sizeof(uintptr_t);
|
||||
|
||||
LOG_DEBUG("Found function ordinal {}::{}@{}", target_interface, function_name, ordinal)
|
||||
LOG_DEBUG("Found function ordinal {}::{}@{}", target_interface, function_name, ordinal);
|
||||
|
||||
function_name_to_ordinal_map[function_name] = ordinal;
|
||||
return true;
|
||||
@@ -410,7 +410,7 @@ namespace store::steamclient {
|
||||
const auto&
|
||||
) {
|
||||
if (instruction.mnemonic == ZYDIS_MNEMONIC_CALL && operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) {
|
||||
LOG_TRACE("Found call instruction at {}", (void*) current_address)
|
||||
LOG_TRACE("Found call instruction at {}", (void*) current_address);
|
||||
|
||||
const auto function_selector_address = get_absolute_address(instruction, current_address);
|
||||
|
||||
@@ -436,15 +436,15 @@ namespace store::steamclient {
|
||||
store::config.steam_client_internal_interface_selector_ordinal
|
||||
];
|
||||
|
||||
LOG_DEBUG("Found interface selector at: {}", (void*) interface_selector_address)
|
||||
LOG_DEBUG("Found interface selector at: {}", (void*) interface_selector_address);
|
||||
|
||||
if (ZYAN_FAILED(ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32))) {
|
||||
LOG_ERROR("Failed to initialize zydis decoder")
|
||||
if (ZYAN_FAILED(ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_STACK_WIDTH_32))) {
|
||||
LOG_ERROR("Failed to initialize zydis decoder");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ZYAN_FAILED(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL))) {
|
||||
LOG_ERROR("Failed to initialize zydis formatter")
|
||||
LOG_ERROR("Failed to initialize zydis formatter");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#include <store_mode/store.hpp>
|
||||
#include <store_mode/vstdlib/vstdlib.hpp>
|
||||
#include <store_mode/store_cache.hpp>
|
||||
#include <store_mode/store_api.hpp>
|
||||
#include <smoke_api/config.hpp>
|
||||
#include "koalabox/str.hpp"
|
||||
|
||||
#include <build_config.h>
|
||||
#include <koalabox/dll_monitor.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
#include <koalabox/ipc.hpp>
|
||||
#include <common/steamclient_exports.hpp>
|
||||
#include <koalabox/dll_monitor.hpp>
|
||||
#include <koalabox/ipc.hpp>
|
||||
#include <koalabox/logger.hpp>
|
||||
#include <smoke_api/config.hpp>
|
||||
#include <store_mode/store.hpp>
|
||||
#include <store_mode/store_api.hpp>
|
||||
#include <store_mode/store_cache.hpp>
|
||||
#include <store_mode/vstdlib/vstdlib.hpp>
|
||||
|
||||
namespace store {
|
||||
|
||||
@@ -18,7 +20,7 @@ namespace store {
|
||||
*/
|
||||
void init_store_config() {
|
||||
const auto print_source = [](const String& source) {
|
||||
LOG_INFO("Loaded Store config from the {}", source)
|
||||
LOG_INFO("Loaded Store config from the {}", source);
|
||||
};
|
||||
|
||||
// First try to read a local config override
|
||||
@@ -30,7 +32,7 @@ namespace store {
|
||||
print_source("local config override");
|
||||
return;
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get local store_mode config: {}", ex.what())
|
||||
LOG_ERROR("Failed to get local store_mode config: {}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +42,7 @@ namespace store {
|
||||
|
||||
print_source("disk cache");
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get cached store_mode config: {}", ex.what())
|
||||
LOG_ERROR("Failed to get cached store_mode config: {}", ex.what());
|
||||
|
||||
print_source("default config bundled in the binary");
|
||||
|
||||
@@ -62,7 +64,7 @@ namespace store {
|
||||
store_cache::save_store_config(github_config);
|
||||
|
||||
if (github_config == config) {
|
||||
LOG_DEBUG("Fetched Store config is equal to existing config")
|
||||
LOG_DEBUG("Fetched Store config is equal to existing config");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +81,7 @@ namespace store {
|
||||
MB_SETFOREGROUND | MB_ICONINFORMATION | MB_OK
|
||||
);
|
||||
} catch (const Exception& ex) {
|
||||
LOG_ERROR("Failed to get remote store_mode config: {}", ex.what())
|
||||
LOG_ERROR("Failed to get remote store_mode config: {}", ex.what());
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -90,7 +92,7 @@ namespace store {
|
||||
koalabox::dll_monitor::init_listener(
|
||||
{VSTDLIB_DLL, STEAMCLIENT_DLL}, [](const HMODULE& module_handle, const String& name) {
|
||||
try {
|
||||
if (name < equals > VSTDLIB_DLL) {
|
||||
if (koalabox::str::eq(name, VSTDLIB_DLL)) {
|
||||
// VStdLib DLL handles Family Sharing functions
|
||||
|
||||
globals::vstdlib_module = module_handle;
|
||||
@@ -98,7 +100,7 @@ namespace store {
|
||||
if (smoke_api::config::instance.unlock_family_sharing) {
|
||||
DETOUR_VSTDLIB(Coroutine_Create)
|
||||
}
|
||||
} else if (name < equals > STEAMCLIENT_DLL) {
|
||||
} else if (koalabox::str::eq(name, STEAMCLIENT_DLL)) {
|
||||
// SteamClient DLL handles unlocking functions
|
||||
|
||||
globals::steamclient_module = module_handle;
|
||||
@@ -113,7 +115,7 @@ namespace store {
|
||||
LOG_ERROR(
|
||||
"Error listening to DLL load events. Module: '{}', Message: {}",
|
||||
name, ex.what()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user