Dota2Patcher
 
Загрузка...
Поиск...
Не найдено
CreateInterface.h
См. документацию.
1#pragma once
2#include <unordered_set>
3#include <functional>
4#include "../Dota2Patcher.h"
5#include "../Utils/Memory.h"
6
7class Interface {
8public:
9 uintptr_t base() const {
10 const auto base_ptr = Memory::read_memory<uintptr_t>(this);
11 return Memory::absolute_address<uintptr_t>(base_ptr.value()).value_or(0);
12 }
13
14 optional<string> name() const {
15 const auto name_ptr = Memory::read_memory<uintptr_t>(this + 0x8);
16 return !name_ptr ? nullopt : Memory::read_string(name_ptr.value());
17 }
18
19 optional<Interface*> next() const {
20 return Memory::read_memory<Interface*>(this + 0x10);
21 }
22};
23
24class CreateInterface : public Interface {
25public:
28 std::unordered_map<string, std::function<void(uintptr_t)>> interface_handlers;
30 };
31
32 static optional<Interface*> get_first_interface(const string& module_name) {
33 const auto CreateInterfaceFn = Memory::pattern_scan(module_name, Patches::Patterns::create_interface);
34 if (!CreateInterfaceFn) {
35 LOG::CRITICAL("Can't find [{}] CreateInterface pattern!", module_name);
36 return nullopt;
37 }
38
39 LOG::INFO("{} CreateInterface -> [{}]", module_name, TO_VOID(CreateInterfaceFn.value()));
40
41 const auto first_interface_base = Memory::absolute_address<uintptr_t>(CreateInterfaceFn.value());
42 if (!first_interface_base)
43 return nullopt;
44
45 return Memory::read_memory<Interface*>(first_interface_base.value());
46 }
47
48 static void load_interfaces(const ModuleInterfaces& module, bool iterate_all = false) {
49 const auto interface_ptr = get_first_interface(module.module_name);
50 if (!interface_ptr)
51 return;
52
53 Interface* iface = interface_ptr.value();
54 std::unordered_set<std::string> seen_interfaces;
55
56 while (iface) {
57 const auto name = iface->name();
58 if (!name || seen_interfaces.contains(name.value())) {
59 iface = iface->next().value_or(nullptr);
60 continue;
61 }
62
63 const auto base = iface->base();
64 if (!base || base == 0) {
65 iface = iface->next().value_or(nullptr);
66 continue;
67 }
68
69 seen_interfaces.insert(name.value());
70 int vfuncs = Memory::count_vms(base);
71
72 if (iterate_all)
73 LOG::INFO("[{}] -> [{}]", name.value(), TO_VOID(base));
74
75 else if (module.interface_handlers.find(name.value()) != module.interface_handlers.end()) {
76 LOG::INFO("Interface [{}] -> [{}]", name.value(), TO_VOID(base));
77 if (vfuncs != module.known_vfuncs)
78 LOG::ERR("VMT has changed! [{}] -> [{}]", module.known_vfuncs, vfuncs);
79 module.interface_handlers.at(name.value())(base);
80 }
81
82 iface = iface->next().value_or(nullptr);
83 }
84 }
85};
Definition CreateInterface.h:24
static optional< Interface * > get_first_interface(const string &module_name)
Definition CreateInterface.h:32
static void load_interfaces(const ModuleInterfaces &module, bool iterate_all=false)
Definition CreateInterface.h:48
Definition CreateInterface.h:7
uintptr_t base() const
Definition CreateInterface.h:9
optional< Interface * > next() const
Definition CreateInterface.h:19
optional< string > name() const
Definition CreateInterface.h:14
static optional< T > read_memory(const N &address)
Definition Memory.h:78
static optional< string > read_string(const T &address, const size_t max_length=64)
Definition Memory.h:125
static optional< uintptr_t > pattern_scan(const string &target_module, const string &target_pattern)
Definition Memory.cpp:25
static int count_vms(const T &vmt)
Definition Memory.h:150
Definition CreateInterface.h:26
string module_name
Definition CreateInterface.h:27
std::unordered_map< string, std::function< void(uintptr_t)> > interface_handlers
Definition CreateInterface.h:28
int known_vfuncs
Definition CreateInterface.h:29
static const string create_interface
Definition Dota2Patcher.h:20