geode/loader/dobby/source/Interceptor.cpp
2022-07-30 19:24:03 +03:00

71 lines
2.2 KiB
C++

#include "Interceptor.h"
#include "dobby_internal.h"
Interceptor *Interceptor::priv_interceptor_ = nullptr;
Interceptor *Interceptor::SharedInstance() {
if (Interceptor::priv_interceptor_ == nullptr) {
Interceptor::priv_interceptor_ = new Interceptor();
INIT_LIST_HEAD(&Interceptor::priv_interceptor_->hook_entry_list_);
}
return Interceptor::priv_interceptor_;
}
HookEntryNode *Interceptor::find_hook_entry_node(void *address) {
HookEntryNode *entry_node = nullptr;
#if defined(_MSC_VER)
#if 0 // only valid if offsetof(HookEntryNode, list_node) == 0
for(entry_node = (HookEntryNode *)hook_entry_list_.next; &entry_node->list_node != &hook_entry_list_; entry_node = (HookEntryNode *)entry_node->list_node.next);
#endif
struct list_head *list_node = nullptr;
for(list_node = hook_entry_list_.next; list_node != &hook_entry_list_; list_node = list_node->next) {
entry_node = (HookEntryNode *)((char *)list_node - offsetof(HookEntryNode, list_node));
#else
list_for_each_entry(entry_node, &hook_entry_list_, list_node) {
#endif
HookEntry *entry = entry_node->entry;
if (entry->instruction_address == address) {
return entry_node;
}
}
return nullptr;
}
HookEntry *Interceptor::FindHookEntry(void *address) {
HookEntryNode *entry_node = nullptr;
entry_node = find_hook_entry_node(address);
if (entry_node) {
return entry_node->entry;
}
return nullptr;
}
void Interceptor::AddHookEntry(HookEntry *entry) {
HookEntryNode *entry_node = new HookEntryNode;
entry_node->entry = entry;
list_add(&entry_node->list_node, &hook_entry_list_);
}
void Interceptor::RemoveHookEntry(void *address) {
if (HookEntryNode *entry_node = find_hook_entry_node(address)) {
list_del(&entry_node->list_node);
}
}
int Interceptor::GetHookEntryCount() {
int count = 0;
HookEntryNode *entry_node = nullptr;
#if defined(_MSC_VER)
struct list_head *list_node = nullptr;
for(list_node = hook_entry_list_.next; list_node != &hook_entry_list_; list_node = list_node->next) {
entry_node = (HookEntryNode *)((char *)list_node - offsetof(HookEntryNode, list_node));
#else
list_for_each_entry(entry_node, &hook_entry_list_, list_node) {
#endif
count += 1;
}
return count;
}