This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

84 lines
2.4 KiB
C++

#pragma once
#include <cstring>
#include "../logger.h"
typedef void* (*InstantiateInterfaceFn)();
struct InterfaceReg {
InstantiateInterfaceFn m_CreateFn;
const char* m_pName;
InterfaceReg* m_pNext;
};
inline void**& getvtable(void* inst, size_t offset = 0) {
return *reinterpret_cast<void***>((size_t)inst + offset);
}
inline const void** getvtable(const void* inst, size_t offset = 0) {
return *reinterpret_cast<const void***>((size_t)inst + offset);
}
template <typename Fn>
inline Fn getvfunc(const void* inst, size_t index, size_t offset = 0) {
return reinterpret_cast<Fn>(getvtable(inst, offset)[index]);
}
template <typename interface>
interface* GetInterface(const char* filename, const char* version,
bool exact = false) {
void* library = dlopen(filename, RTLD_NOLOAD | RTLD_NOW);
if (!library) {
// Log << " -- " << filename << " dlopen failed." << std::endl;
return nullptr;
}
void* interfaces_sym = dlsym(library, "s_pInterfaceRegs");
if (!interfaces_sym) {
// Log << " -- " << filename << " dlsym s_pInterfaceRegs failed." <<
// std::endl;
dlclose(library);
return nullptr;
}
dlclose(library);
InterfaceReg* interfaces =
*reinterpret_cast<InterfaceReg**>(interfaces_sym);
InterfaceReg* cur_interface;
for (cur_interface = interfaces; cur_interface;
cur_interface = cur_interface->m_pNext) {
if (exact) {
if (strcmp(cur_interface->m_pName, version) == 0)
return reinterpret_cast<interface*>(
cur_interface->m_CreateFn());
} else {
if (strstr(cur_interface->m_pName, version) &&
strlen(cur_interface->m_pName) - 3 == strlen(version))
return reinterpret_cast<interface*>(
cur_interface->m_CreateFn());
}
}
// Log << " -- " << filename << " Cannot find interface." << std::endl;
return nullptr;
}
inline uintptr_t GetAbsoluteAddress(uintptr_t instruction_ptr, int offset,
int size) {
return instruction_ptr +
*reinterpret_cast<uint32_t*>(instruction_ptr + offset) + size;
};
template <typename T>
T GetSymbolAddress(const char* filename, const char* symbol) {
void* handle = dlopen(filename, RTLD_NOW);
T result = reinterpret_cast<T>(dlsym(handle, symbol));
dlclose(handle);
return result;
};