Merge remote-tracking branch 'upstream/main' into dvar_sessionmode

This commit is contained in:
BrentVL-1952840 2023-03-20 19:25:00 +01:00
commit b8a8125750
9 changed files with 196 additions and 10 deletions

2
deps/curl vendored

@ -1 +1 @@
Subproject commit c3f3c2557c64d4947f8c6337a0590cd28304d8fd
Subproject commit b16d1fa8ee567b52c09a0f89940b07d8491b881d

View File

@ -4,14 +4,16 @@
#include "game/game.hpp"
#include "steam/steam.hpp"
#include <utils/hook.hpp>
#include <utils/io.hpp>
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include <utils/thread.hpp>
#include "integrity.hpp"
#include <stack>
#define ProcessDebugPort 7
#define ProcessDebugObjectHandle 30
#define ProcessDebugFlags 31
@ -19,8 +21,84 @@
namespace arxan
{
namespace detail
{
void* callstack_proxy_addr{nullptr};
static thread_local const void* address_to_call{};
void set_address_to_call(const void* address)
{
address_to_call = address;
}
}
namespace
{
thread_local std::stack<uint64_t> address_stack{};
const void* get_address_to_call()
{
return detail::address_to_call;
}
void store_address(const uint64_t address)
{
address_stack.push(address);
}
uint64_t get_stored_address()
{
const auto res = address_stack.top();
address_stack.pop();
return res;
}
void callstack_return_stub(utils::hook::assembler& a)
{
a.push(rax);
a.pushad64();
a.call_aligned(get_stored_address);
a.mov(qword_ptr(rsp, 0x80), rax);
a.popad64();
a.add(rsp, 8);
a.jmp(qword_ptr(rsp, -8));
}
uint64_t get_callstack_return_stub()
{
const auto placeholder = game::select(0x140001056, 0x140101167);
utils::hook::nop(placeholder, 1);
utils::hook::jump(placeholder + 1, utils::hook::assemble(callstack_return_stub));
return placeholder;
}
void callstack_stub(utils::hook::assembler& a)
{
a.push(rax);
a.pushad64();
a.call_aligned(get_address_to_call);
a.mov(qword_ptr(rsp, 0x80), rax);
a.mov(rcx, qword_ptr(rsp, 0x88));
a.call_aligned(store_address);
a.mov(rax, get_callstack_return_stub());
a.mov(qword_ptr(rsp, 0x88), rax);
a.popad64();
a.add(rsp, 8);
a.jmp(qword_ptr(rsp, -8));
}
constexpr auto pseudo_steam_id = 0x1337;
const auto pseudo_steam_handle = reinterpret_cast<HANDLE>(reinterpret_cast<uint64_t>(INVALID_HANDLE_VALUE) -
pseudo_steam_id);
@ -788,6 +866,8 @@ namespace arxan
{
search_and_patch_integrity_checks();
//restore_debug_functions();
detail::callstack_proxy_addr = utils::hook::assemble(callstack_stub);
}
component_priority priority() const override

View File

@ -14,9 +14,10 @@ namespace client_patches
{
utils::hook::detour preload_map_hook;
void stop_zombies_intro_if_needed()
void stop_intro_if_needed()
{
if (game::Com_SessionMode_GetMode() != game::MODE_ZOMBIES)
if (game::Com_SessionMode_GetMode() != game::MODE_ZOMBIES &&
game::Com_SessionMode_GetMode() != game::MODE_CAMPAIGN)
{
return;
}
@ -39,7 +40,7 @@ namespace client_patches
void preload_map_stub(int localClientNum, const char* mapname, const char* gametype)
{
game::Com_GametypeSettings_SetGametype(gametype, false, false);
stop_zombies_intro_if_needed();
stop_intro_if_needed();
preload_map_hook.invoke(localClientNum, mapname, gametype);
}

View File

@ -11,6 +11,8 @@
#include "game/demonware/servers/umbrella_server.hpp"
#include "game/demonware/server_registry.hpp"
#include "localized_strings.hpp"
#define TCP_BLOCKING true
#define UDP_BLOCKING false
@ -497,6 +499,8 @@ namespace demonware
utils::hook::set<uint64_t>(0x141F03130_g, 0xC300000001B8); // Kill LPC_DeleteStale
utils::hook::set<uint8_t>(0x141E0AA1B_g, 0xEB); // Release un-handled reportReward spamming loop
localized_strings::override("MENU_CONNECTING_DW", "Emulating Online Service");
}
void pre_destroy() override

View File

@ -0,0 +1,52 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "localized_strings.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include <utils/concurrency.hpp>
#include "game/game.hpp"
namespace localized_strings
{
namespace
{
utils::hook::detour seh_string_ed_get_string_hook;
using localized_map = std::unordered_map<std::string, std::string>;
utils::concurrency::container<localized_map> localized_overrides;
const char* seh_string_ed_get_string(const char* reference)
{
return localized_overrides.access<const char*>([&](const localized_map& map)
{
const auto entry = map.find(reference);
if (entry != map.end())
{
return utils::string::va("%s", entry->second.data());
}
return seh_string_ed_get_string_hook.invoke<const char*>(reference);
});
}
}
void override(const std::string& key, const std::string& value)
{
localized_overrides.access([&](localized_map& map)
{
map[key] = value;
});
}
class component final : public client_component
{
public:
void post_unpack() override
{
// Change some localized strings
seh_string_ed_get_string_hook.create(0x1422796E0_g, &seh_string_ed_get_string);
}
};
}
REGISTER_COMPONENT(localized_strings::component)

View File

@ -0,0 +1,6 @@
#pragma once
namespace localized_strings
{
void override(const std::string& key, const std::string& value);
}

View File

@ -29,6 +29,9 @@ namespace patches
{
// don't make script errors fatal error
utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub);
// Change 4 character name limit to 3 characters
utils::hook::set<uint8_t>(game::select(0x14224DBB4, 0x1405312A8), 3);
}
};
}

View File

@ -3,6 +3,12 @@
#include "structs.hpp"
#include <utils/nt.hpp>
namespace arxan::detail
{
void set_address_to_call(const void* address);
extern void* callstack_proxy_addr;
}
namespace game
{
size_t get_base();
@ -42,15 +48,15 @@ namespace game
}
template <typename T>
class symbol
class base_symbol
{
public:
symbol(const size_t address)
base_symbol(const size_t address)
: address_(address)
{
}
symbol(const size_t address, const size_t server_address)
base_symbol(const size_t address, const size_t server_address)
: address_(address)
, server_address_(server_address)
{
@ -76,6 +82,26 @@ namespace game
size_t server_address_{};
};
template <typename T>
struct symbol : base_symbol<T>
{
using base_symbol<T>::base_symbol;
};
template <typename T, typename... Args>
struct symbol<T(Args...)> : base_symbol<T(Args...)>
{
using func_type = T(Args...);
using base_symbol<func_type>::base_symbol;
T call_safe(Args... args)
{
arxan::detail::set_address_to_call(this->get());
return static_cast<func_type*>(arxan::detail::callstack_proxy_addr)(args...);
}
};
std::filesystem::path get_appdata_path();
}

View File

@ -190,12 +190,26 @@ namespace utils::hook
this->push(rsi);
this->push(rdi);
this->sub(rsp, 0x40);
this->push(r8);
this->push(r9);
this->push(r10);
this->push(r11);
this->push(r12);
this->push(r13);
this->push(r14);
this->push(r15);
}
void assembler::popad64()
{
this->add(rsp, 0x40);
this->pop(r15);
this->pop(r14);
this->pop(r13);
this->pop(r12);
this->pop(r11);
this->pop(r10);
this->pop(r9);
this->pop(r8);
this->pop(rdi);
this->pop(rsi);