Add unloading support + some broken antiaim (#39)

This commit is contained in:
F1ssi0N 2018-04-11 13:36:38 +01:00 committed by Marc
parent 8f6602ed3f
commit 86139daefe
16 changed files with 289 additions and 57 deletions

View File

@ -25,14 +25,34 @@
#include "utils/profiler.hh" #include "utils/profiler.hh"
static sdk::Convar<bool> doghook_profiling_enabled{"doghook_profiling_enabled", false, nullptr}; static sdk::Convar<bool> doghook_profiling_enabled{"doghook_profiling_enabled", false, nullptr};
static sdk::Convar<bool> doghook_unload_now{"doghook_unload_now", false, nullptr};
// Singleton for doing init / deinit of doghook // Singleton for doing init / deinit of doghook
// and dealing with hooks from gamesystem // and dealing with hooks from gamesystem
extern class Doghook doghook;
class Doghook : public GameSystem { class Doghook : public GameSystem {
public:
bool inited = false; bool inited = false;
public: #if doghook_platform_windows()
HMODULE doghook_module_handle;
#endif
static void await_shutdown() {
while (!doghook_unload_now) std::this_thread::yield();
#if doghook_platform_windows()
// TODO: the CRT should be able to take care of all our hooks as they are all declared
// as unique_ptrs...
// All other memory should be cleaned up in destructors that happen at init_time or deinit_time!!
// TODO: make sure that all memory is getting cleaned properly!
FreeLibrary(doghook.doghook_module_handle);
#endif
}
bool init() override { bool init() override {
// Guard against having init() called by the game and our constructor // Guard against having init() called by the game and our constructor
static bool init_happened = false; static bool init_happened = false;
@ -122,7 +142,6 @@ public:
// make sure that the profiler is inited first // make sure that the profiler is inited first
profiler::init(); profiler::init();
doghook_profiling_enabled = profiler::profiling_enabled();
// make sure that the netvars are initialised // make sure that the netvars are initialised
// becuase their dynamic initialiser could be after the // becuase their dynamic initialiser could be after the
@ -142,6 +161,14 @@ public:
// at this point we are now inited and ready to go! // at this point we are now inited and ready to go!
inited = true; inited = true;
std::thread{&await_shutdown}.detach();
// If we are already in game then do the level inits
if (IFace<sdk::Engine>()->in_game()) {
level_init_pre_entity();
level_init_post_entity();
}
} }
void shutdown() override {} void shutdown() override {}
@ -174,9 +201,11 @@ public:
// in theory we should be able to render here // in theory we should be able to render here
// and be perfectly ok // and be perfectly ok
// HOWEVER: it might be better to do this at frame_end() // HOWEVER: it might be better to do this at frame_end()
void update([[maybe_unused]] float frametime) override { void update(float frametime) override {
if (inited != true) return; if (inited != true) return;
profiler::set_profiling_enabled(doghook_profiling_enabled); profiler::set_profiling_enabled(doghook_profiling_enabled);
misc::update(frametime);
} }
Doghook() { Doghook() {
@ -187,10 +216,12 @@ public:
Doghook doghook; Doghook doghook;
#if doghook_platform_windows() #if doghook_platform_windows()
u32 __stdcall doghook_process_attach([[maybe_unused]] void *hmodule) { u32 __stdcall doghook_process_attach(void *hmodule) {
// TODO: pass module over to the gamesystem // TODO: pass module over to the gamesystem
doghook.process_attach(); doghook.process_attach();
doghook.doghook_module_handle = (HMODULE)hmodule;
return 0; return 0;
} }
#elif doghook_platform_linux() #elif doghook_platform_linux()

View File

@ -2,22 +2,33 @@
#include "sdk/sdk.hh" #include "sdk/sdk.hh"
#include "modules/backtrack.hh"
#include "sdk/hooks.hh" #include "sdk/hooks.hh"
#include "sdk/log.hh" #include "sdk/log.hh"
#include "sdk/player.hh" #include "sdk/player.hh"
#include "modules/aimbot.hh" #include "modules/aimbot.hh"
#include "modules/anti_aim.hh"
#include "modules/backtrack.hh"
#include "modules/lagexploit.hh" #include "modules/lagexploit.hh"
#include "modules/misc.hh"
#include "utils/math.hh" #include "utils/math.hh"
#include "utils/profiler.hh" #include "utils/profiler.hh"
#if doghook_platform_windows()
#include <intrin.h>
#endif
using namespace sdk; using namespace sdk;
namespace create_move { namespace create_move {
bool *send_packet_ptr = nullptr;
bool *send_packet() {
return send_packet_ptr;
}
// TODO: should probably move elsewhere // TODO: should probably move elsewhere
static inline auto local_player_prediction(Player *local, UserCmd *cmd) { static inline auto local_player_prediction(Player *local, UserCmd *cmd) {
char move_data_buffer[512]; char move_data_buffer[512];
@ -59,7 +70,7 @@ static inline auto local_player_prediction(Player *local, UserCmd *cmd) {
//local->tick_base() += 1; //local->tick_base() += 1;
} }
hooks::HookFunction<ClientMode, 0> *create_move_hook = nullptr; std::unique_ptr<hooks::HookFunction<ClientMode, 0>> create_move_hook;
#if doghook_platform_windows() #if doghook_platform_windows()
bool __fastcall hooked_create_move(void *instance, void *edx, float sample_framerate, UserCmd *user_cmd) bool __fastcall hooked_create_move(void *instance, void *edx, float sample_framerate, UserCmd *user_cmd)
@ -69,6 +80,18 @@ bool hooked_create_move(void *instance, float sample_framerate, UserCmd *user_cm
{ {
profiler_profile_function(); profiler_profile_function();
#if doghook_platform_windows()
uptr ebp_address;
__asm mov ebp_address, ebp;
send_packet_ptr = reinterpret_cast<bool *>(***(uptr ***)ebp_address - 1);
#else
// kotm's method
uintptr_t **fp;
__asm__("mov %%ebp, %0"
: "=r"(fp));
send_packet_ptr = reinterpret_cast<bool *>(**fp - 8);
#endif
auto local_player = Player::local(); auto local_player = Player::local();
assert(local_player); assert(local_player);
@ -97,12 +120,15 @@ bool hooked_create_move(void *instance, float sample_framerate, UserCmd *user_cm
aimbot::create_move(user_cmd); aimbot::create_move(user_cmd);
backtrack::create_move(user_cmd); backtrack::create_move(user_cmd);
lagexploit::create_move(user_cmd); lagexploit::create_move(user_cmd);
anti_aim::create_move(user_cmd);
misc::create_move(user_cmd);
} }
{ {
profiler_profile_scope("finish"); profiler_profile_scope("finish");
backtrack::create_move_finish(user_cmd); backtrack::create_move_finish(user_cmd);
} }
return false; return false;
} }
@ -110,13 +136,13 @@ void level_init() {
logging::msg("=> Hooking up!"); logging::msg("=> Hooking up!");
assert(create_move_hook == nullptr); assert(create_move_hook == nullptr);
create_move_hook = new hooks::HookFunction<ClientMode, 0>(IFace<ClientMode>().get(), 21, 22, 22, reinterpret_cast<void *>(&hooked_create_move)); create_move_hook = std::make_unique<hooks::HookFunction<ClientMode, 0>>(IFace<ClientMode>().get(), 21, 22, 22, reinterpret_cast<void *>(&hooked_create_move));
} }
void level_shutdown() { void level_shutdown() {
logging::msg("<= Deleting hooks"); logging::msg("<= Deleting hooks");
delete create_move_hook; create_move_hook.reset();
create_move_hook = nullptr; create_move_hook = nullptr;
} }

View File

@ -3,4 +3,6 @@
namespace create_move { namespace create_move {
void level_init(); void level_init();
void level_shutdown(); void level_shutdown();
bool *send_packet();
} // namespace create_move } // namespace create_move

View File

@ -11,7 +11,7 @@
using namespace sdk; using namespace sdk;
namespace paint_hook { namespace paint_hook {
hooks::HookFunction<EngineVgui, 0> *engine_vgui_hook; std::unique_ptr<hooks::HookFunction<EngineVgui, 0>> engine_vgui_hook;
using StartDrawing = void(__thiscall *)(void *); using StartDrawing = void(__thiscall *)(void *);
using FinishDrawing = void(__thiscall *)(void *); using FinishDrawing = void(__thiscall *)(void *);
@ -36,11 +36,11 @@ void hooked_paint(EngineVgui *instance, u32 paint_method)
void init_all() { void init_all() {
// hook up // hook up
engine_vgui_hook = new hooks::HookFunction<EngineVgui, 0>(IFace<EngineVgui>().get(), 13, 14, 14, reinterpret_cast<void *>(&hooked_paint)); engine_vgui_hook = std::make_unique<hooks::HookFunction<EngineVgui, 0>>(IFace<EngineVgui>().get(), 13, 14, 14, reinterpret_cast<void *>(&hooked_paint));
} }
void shutdown_all() { void shutdown_all() {
delete engine_vgui_hook; engine_vgui_hook.reset();
} }
} // namespace paint_hook } // namespace paint_hook

View File

@ -12,7 +12,7 @@ class bf_write;
namespace send_datagram { namespace send_datagram {
hooks::HookFunction<NetChannel, 0> *send_datagram_hook; std::unique_ptr<hooks::HookFunction<NetChannel, 0>> send_datagram_hook;
#if doghook_platform_windows() #if doghook_platform_windows()
u32 __fastcall hooked_send_datagram(NetChannel *channel, void *, bf_write *datagram) u32 __fastcall hooked_send_datagram(NetChannel *channel, void *, bf_write *datagram)
@ -36,11 +36,11 @@ u32 hooked_send_datagram(NetChannel *channel, bf_write *datagram)
void level_init() { void level_init() {
assert(send_datagram_hook == nullptr); assert(send_datagram_hook == nullptr);
send_datagram_hook = new hooks::HookFunction<NetChannel, 0>(IFace<Engine>()->net_channel_info(), 46, 47, 47, reinterpret_cast<void *>(&hooked_send_datagram)); send_datagram_hook = std::make_unique<hooks::HookFunction<NetChannel, 0>>(IFace<Engine>()->net_channel_info(), 46, 47, 47, reinterpret_cast<void *>(&hooked_send_datagram));
} }
void level_shutdown() { void level_shutdown() {
delete send_datagram_hook; send_datagram_hook.reset();
send_datagram_hook = nullptr; send_datagram_hook = nullptr;
} }

View File

@ -344,8 +344,11 @@ static auto try_autoshoot(sdk::UserCmd *cmd) {
} }
if (autoshoot_allowed) cmd->buttons |= 1; if (autoshoot_allowed) cmd->buttons |= 1;
return autoshoot_allowed;
} }
static Convar<bool> doghook_aimbot_always_aim = Convar<bool>{"doghook_aimbot_always_aim", false, nullptr};
static Convar<bool> doghook_aimbot_silent = Convar<bool>{"doghook_aimbot_silent", true, nullptr}; static Convar<bool> doghook_aimbot_silent = Convar<bool>{"doghook_aimbot_silent", true, nullptr};
static Convar<bool> doghook_aimbot_autoshoot = Convar<bool>{"doghook_aimbot_autoshoot", true, nullptr}; static Convar<bool> doghook_aimbot_autoshoot = Convar<bool>{"doghook_aimbot_autoshoot", true, nullptr};
static Convar<bool> doghook_aimbot_aim_if_not_attack = Convar<bool>{"doghook_aimbot_aim_if_not_attack", true, nullptr}; static Convar<bool> doghook_aimbot_aim_if_not_attack = Convar<bool>{"doghook_aimbot_aim_if_not_attack", true, nullptr};
@ -372,18 +375,19 @@ void create_move(sdk::UserCmd *cmd) {
auto new_angles = delta.to_angle(); auto new_angles = delta.to_angle();
new_angles = clamp_angle(new_angles); new_angles = clamp_angle(new_angles);
auto new_movement = fix_movement_for_new_angles({cmd->forwardmove, cmd->sidemove, 0}, cmd->viewangles, new_angles);
// TODO: shouldnt this be on the outside instead // TODO: shouldnt this be on the outside instead
if (local_weapon->can_shoot(local_player->tick_base())) { if (local_weapon->can_shoot(local_player->tick_base())) {
cmd->viewangles = new_angles; auto shot = (doghook_aimbot_autoshoot && try_autoshoot(cmd)) || (cmd->buttons & 1);
if (doghook_aimbot_autoshoot == true) try_autoshoot(cmd); if (shot || doghook_aimbot_always_aim) {
auto new_movement = fix_movement_for_new_angles({cmd->forwardmove, cmd->sidemove, 0}, cmd->viewangles, new_angles);
cmd->viewangles = new_angles;
cmd->forwardmove = new_movement.x; cmd->forwardmove = new_movement.x;
cmd->sidemove = new_movement.y; cmd->sidemove = new_movement.y;
cmd->tick_count -= target.cmd_delta; cmd->tick_count -= target.cmd_delta;
}
} }
if (doghook_aimbot_silent == false) IFace<Engine>()->set_view_angles(new_angles); if (doghook_aimbot_silent == false) IFace<Engine>()->set_view_angles(new_angles);

88
src/modules/anti_aim.cc Normal file
View File

@ -0,0 +1,88 @@
#include <precompiled.hh>
#include "anti_aim.hh"
#include <hooks/createmove.hh>
#include <sdk/convar.hh>
#include <sdk/sdk.hh>
using namespace sdk;
namespace anti_aim {
Convar<bool> doghook_antiaim_enabled{"doghook_antiaim_enabled", true, nullptr};
Convar<float> doghook_antiaim_real_angle{"doghook_antiaim_real_angle", 90, -1000, 1000, nullptr};
Convar<float> doghook_antiaim_fake_angle{"doghook_antiaim_fake_angle", -90, -1000, 1000, nullptr};
Convar<float> doghook_antiaim_pitch{"doghook_antiaim_pitch_angle", 0, -1000, 1000, nullptr};
Convar<bool> doghook_antiaim_force_sendpacket_false{"doghook_antiaim_force_sendpacket_false", false, nullptr};
Convar<bool> doghook_antiaim_add_to_angles{"doghook_antiaim_add_to_angles", true, nullptr};
Convar<bool> doghook_antiaim_set_pitch{"doghook_antiaim_set_pitch", true, nullptr};
auto send_packet_flip = false;
inline static auto clamp_angle(const math::Vector &angles) {
math::Vector out;
out.x = angles.x;
out.y = angles.y;
out.z = 0;
while (out.x > 89.0f) out.x -= 180.0f;
while (out.x < -89.0f) out.x += 180.0f;
while (out.y > 180.0f) out.y -= 360.0f;
while (out.y < -180.0f) out.y += 360.0f;
out.y = std::clamp(out.y, -180.0f, 180.0f);
out.x = std::clamp(out.x, -90.0f, 90.0f);
return out;
}
inline static auto fix_movement_for_new_angles(const math::Vector &movement, const math::Vector &old_angles, const math::Vector &new_angles) {
math::Matrix3x4 rotate_matrix;
auto delta_angles = new_angles - old_angles;
delta_angles = clamp_angle(delta_angles);
rotate_matrix.from_angle(delta_angles);
return rotate_matrix.rotate_vector(movement);
}
void create_move(sdk::UserCmd *cmd) {
auto send_packet = create_move::send_packet();
if (!(cmd->buttons & IN_ATTACK) && doghook_antiaim_enabled) {
auto old_angles = cmd->viewangles;
if (send_packet_flip) {
if (doghook_antiaim_add_to_angles)
cmd->viewangles.y += doghook_antiaim_real_angle;
else
cmd->viewangles.y = doghook_antiaim_real_angle;
} else {
if (doghook_antiaim_add_to_angles)
cmd->viewangles.y += doghook_antiaim_fake_angle;
else
cmd->viewangles.y = doghook_antiaim_fake_angle;
}
if (doghook_antiaim_set_pitch)
cmd->viewangles.x = doghook_antiaim_pitch;
//cmd->viewangles.x = -90.0f;
//clamp_angle(cmd->viewangles);
auto new_movement = fix_movement_for_new_angles({cmd->forwardmove, cmd->sidemove, 0}, old_angles, cmd->viewangles);
cmd->forwardmove = new_movement.x;
cmd->sidemove = new_movement.y;
*send_packet = send_packet_flip;
send_packet_flip = !send_packet_flip;
if (doghook_antiaim_force_sendpacket_false) *send_packet = false;
}
}
} // namespace anti_aim

9
src/modules/anti_aim.hh Normal file
View File

@ -0,0 +1,9 @@
#pragma once
namespace sdk {
class UserCmd;
}
namespace anti_aim {
void create_move(sdk::UserCmd *cmd);
}

View File

@ -4,6 +4,8 @@
#include <sdk/convar.hh> #include <sdk/convar.hh>
#include <sdk/interface.hh> #include <sdk/interface.hh>
#include <sdk/netvar.hh>
#include <sdk/player.hh>
#include <sdk/sdk.hh> #include <sdk/sdk.hh>
using namespace sdk; using namespace sdk;
@ -53,6 +55,8 @@ enum cvar_flags {
// Note: IVEngineClient::ClientCmd_Unrestricted can run any client command. // Note: IVEngineClient::ClientCmd_Unrestricted can run any client command.
}; };
Netvar local_angles{"DT_BasePlayer", "pl", "deadflag"};
void init_all() { void init_all() {
for (auto c : sdk::ConvarWrapper::get_range()) { for (auto c : sdk::ConvarWrapper::get_range()) {
auto flags = c.flags(); auto flags = c.flags();
@ -67,5 +71,20 @@ void init_all() {
c.set_flags(flags); c.set_flags(flags);
} }
local_angles.offset_delta(4);
} }
Convar<bool> doghook_misc_show_aa{"doghook_misc_show_aa", true, nullptr};
math::Vector last_viewangles;
void create_move(sdk::UserCmd *cmd) {
last_viewangles = cmd->viewangles;
}
void update(float frametime) {
if (!IFace<Engine>()->in_game()) return;
}
} // namespace misc } // namespace misc

View File

@ -1,5 +1,11 @@
#pragma once #pragma once
namespace sdk {
class UserCmd;
}
namespace misc { namespace misc {
void init_all(); void init_all();
} void create_move(sdk::UserCmd *cmd);
void update(float frametime);
} // namespace misc

View File

@ -329,6 +329,10 @@ ConvarBase::~ConvarBase() {
auto modifiable = const_cast<ConvarBase *>(c); auto modifiable = const_cast<ConvarBase *>(c);
if (c->next == this) modifiable->next = this->next; if (c->next == this) modifiable->next = this->next;
} }
// Cleanup tf_convar
// This unregisters itself
delete this->tf_convar;
} }
void ConvarBase::init_all() { void ConvarBase::init_all() {

View File

@ -9,27 +9,66 @@ GameSystem::GameSystem() {
head = this; head = this;
} }
// TODO: remove
template <typename T>
struct UtlVector {
T * mem;
int alloc_count;
int grow_size;
int size;
T * dbg_elements;
};
GameSystem::~GameSystem() { GameSystem::~GameSystem() {
// TODO: remove the gamesystem! // Check whether client was already unloaded
if (signature::resolve_library("client") == nullptr) return;
#if doghook_platform_windows()
// We are going to have to get a little creative here...
// Since no one except the destructors call Remove() it gets inlined into them
// We cant call those for obvious reasons...
// Recreate it !
// Windows:
// CUtlVector::FindAndRemove -> 55 8B EC 53 56 57 8B F9 33 D2 8B 77 0C
// s_GameSystemsPerFrame -> B9 ? ? ? ? E8 ? ? ? ? 5E 8B E5 5D C3
// s_GameSystems -> A1 ? ? ? ? 8B 0C B8 8B 01
using FindAndRemoveFn = void(__thiscall *)(void *, IGameSystem **);
static auto find_remove = signature::find_pattern<FindAndRemoveFn>("client", "55 8B EC 53 56 57 8B F9 33 D2 8B 77 0C", 0);
static auto s_GameSystems = *signature::find_pattern<UtlVector<IGameSystem *> **>("client", "A1 ? ? ? ? 8B 0C B8 8B 01", 1);
static auto s_GameSystemsPerFrame = *signature::find_pattern<UtlVector<IGameSystem *> **>("client", "A1 ? ? ? ? 8B 35 ? ? ? ? 8B CE 8B 04 B8", 1);
auto to_find = (IGameSystem *)this;
IGameSystem **mem = s_GameSystems->mem;
find_remove(s_GameSystems, &to_find);
find_remove(s_GameSystemsPerFrame, &to_find);
#else
#endif
} }
void GameSystem::add_all() { void GameSystem::add_all() {
using AddFn = void (*)(IGameSystem *); using AddFn = void (*)(IGameSystem *);
AddFn add_fn; static AddFn add_fn = []() {
if constexpr (doghook_platform::windows()) {
if constexpr (doghook_platform::windows()) { return reinterpret_cast<AddFn>(
add_fn = reinterpret_cast<AddFn>( signature::resolve_callgate(
signature::resolve_callgate( signature::find_pattern("client", "E8 ? ? ? ? 83 C4 04 8B 76 04 85 F6 75 D0")));
signature::find_pattern("client", "E8 ? ? ? ? 83 C4 04 8B 76 04 85 F6 75 D0"))); } else if constexpr (doghook_platform::linux()) {
} else if constexpr (doghook_platform::linux()) { return reinterpret_cast<AddFn>(
add_fn = reinterpret_cast<AddFn>( signature::resolve_callgate(
signature::resolve_callgate( signature::find_pattern("client", "E8 ? ? ? ? 8B 5B 04 85 DB 75 C1")));
signature::find_pattern("client", "E8 ? ? ? ? 8B 5B 04 85 DB 75 C1"))); } else if constexpr (doghook_platform::osx()) {
} else if constexpr (doghook_platform::osx()) { return reinterpret_cast<AddFn>(
add_fn = reinterpret_cast<AddFn>( signature::resolve_callgate(
signature::resolve_callgate( signature::find_pattern("client", "E8 ? ? ? ? 8B 7F 04 85 FF 75 A1")));
signature::find_pattern("client", "E8 ? ? ? ? 8B 7F 04 85 FF 75 A1"))); }
} }();
assert(add_fn); assert(add_fn);

View File

@ -115,10 +115,10 @@ public:
template <typename T, u32 offset> template <typename T, u32 offset>
class HookFunction { class HookFunction {
static std::vector<HookInstance<T, offset> *> hooks; static std::vector<std::shared_ptr<HookInstance<T, offset>>> hooks;
auto create_hook_instance(T *instance) { auto create_hook_instance(T *instance) {
auto h = new HookInstance<T, offset>(instance); auto h = std::make_shared<HookInstance<T, offset>>(instance);
hooks.push_back(h); hooks.push_back(h);
return h; return h;
} }
@ -130,7 +130,7 @@ class HookFunction {
public: public:
HookFunction(T *instance, u32 index_windows, u32 index_linux, u32 index_osx, void *f) { HookFunction(T *instance, u32 index_windows, u32 index_linux, u32 index_osx, void *f) {
assert(instance); assert(instance);
HookInstance<T, offset> *val = nullptr; std::shared_ptr<HookInstance<T, offset>> val;
for (auto &v : hooks) { for (auto &v : hooks) {
if (v->get_instance() == instance) { if (v->get_instance() == instance) {
@ -186,6 +186,6 @@ public:
}; };
template <typename T, u32 offset> template <typename T, u32 offset>
std::vector<HookInstance<T, offset> *> HookFunction<T, offset>::hooks; std::vector<std::shared_ptr<HookInstance<T, offset>>> HookFunction<T, offset>::hooks;
} // namespace hooks } // namespace hooks

View File

@ -8,10 +8,10 @@ using namespace sdk;
static Netvar *head; static Netvar *head;
void Netvar::Tree::populate_recursive(RecvTable *t, netvar_tree *nodes) { void Netvar::Tree::populate_recursive(RecvTable *t, TreeNode *nodes) {
for (auto i = 0; i < t->prop_count; i++) { for (auto i = 0; i < t->prop_count; i++) {
auto * prop = t->prop(i); auto * prop = t->prop(i);
const auto new_node = new node(); const auto new_node = std::make_shared<Node>();
new_node->p = prop; new_node->p = prop;
if (prop->recv_type == 6) populate_recursive(prop->as_datatable(), &new_node->children); if (prop->recv_type == 6) populate_recursive(prop->as_datatable(), &new_node->children);
@ -28,7 +28,7 @@ void Netvar::Tree::init() {
auto cc = IFace<Client>()->get_all_classes(); auto cc = IFace<Client>()->get_all_classes();
while (cc != nullptr) { while (cc != nullptr) {
const auto new_node = new node(); const auto new_node = std::make_shared<Node>();
new_node->p = nullptr; new_node->p = nullptr;
populate_recursive(cc->recv_table, &new_node->children); populate_recursive(cc->recv_table, &new_node->children);

View File

@ -10,17 +10,17 @@ class Netvar {
class Tree { class Tree {
struct node; struct Node;
using netvar_tree = std::vector<std::pair<const char *, node *>>; using TreeNode = std::vector<std::pair<const char *, std::shared_ptr<Node>>>;
struct node { struct Node {
netvar_tree children; TreeNode children;
class RecvProp *p; class RecvProp *p;
}; };
netvar_tree prop_tree; TreeNode prop_tree;
void populate_recursive(class RecvTable *t, netvar_tree *nodes); void populate_recursive(class RecvTable *t, TreeNode *nodes);
public: public:
Tree(); Tree();
@ -53,6 +53,8 @@ public:
return *reinterpret_cast<T *>(static_cast<char *>(instance) + offset); return *reinterpret_cast<T *>(static_cast<char *>(instance) + offset);
} }
void offset_delta(u32 d) { offset += d; }
static void init_all(); static void init_all();
}; };
} // namespace sdk } // namespace sdk

View File

@ -109,7 +109,9 @@ void *signature::resolve_library(const char *name) {
auto handle = GetModuleHandleA(buffer); auto handle = GetModuleHandleA(buffer);
assert(handle); // TODO: this is commented out to mimic linux behaviour
// TODO: do we really want this??
//assert(handle);
return handle; return handle;
@ -136,8 +138,8 @@ void *signature::resolve_library(const char *name) {
search_directory(name, "./bin", found)) { search_directory(name, "./bin", found)) {
auto handle = dlopen(found, RTLD_NOLOAD); auto handle = dlopen(found, RTLD_NOLOAD);
if (handle == nullptr) { if (handle == nullptr) {
printf("force loading library %s\n", name); //printf("force loading library %s\n", name);
handle = dlopen(found, RTLD_NOW); //handle = dlopen(found, RTLD_NOW);
} }
return handle; return handle;
} }