clean up api related functions, and change version to 1.3
This commit is contained in:
15
utils/hook.cpp
Normal file
15
utils/hook.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
//#include "../pch.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
void* allocate_stub_memory(size_t size)
|
||||
{
|
||||
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
}
|
150
utils/hook.hpp
Normal file
150
utils/hook.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
|
||||
// stolen from plutoscript
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
void* allocate_stub_memory(size_t size);
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline ValueType get(AddressType address)
|
||||
{
|
||||
return *static_cast<ValueType*>(address);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, ValueType value)
|
||||
{
|
||||
std::memcpy((void*)address, &value, sizeof(value));
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, const ValueType* data, size_t length)
|
||||
{
|
||||
std::memcpy((void*)address, data, sizeof(ValueType) * length);
|
||||
}
|
||||
|
||||
template<typename AddressType>
|
||||
inline void nop(AddressType address, size_t length)
|
||||
{
|
||||
std::memset((void*)address, 0x90, length);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void jump(AddressType address, FuncType func)
|
||||
{
|
||||
set<uint8_t>(address, 0xE9);
|
||||
set<uintptr_t>((uintptr_t)address + 1, (uintptr_t)func - (uintptr_t)address - 5);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void call(AddressType address, FuncType func)
|
||||
{
|
||||
set<uint8_t>(address, 0xE8);
|
||||
set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
FuncType detour(AddressType target, FuncType hook, const int len)
|
||||
{
|
||||
uintptr_t tampoline = (uintptr_t)allocate_stub_memory(len + 5);
|
||||
|
||||
std::memcpy((void*)tampoline, (void*)target, len);
|
||||
|
||||
set<uint8_t>(tampoline + len, 0xE9);
|
||||
set<int>((uintptr_t)tampoline + len + 1, (intptr_t)target - (intptr_t)tampoline - 5);
|
||||
|
||||
set<uint8_t>(target, 0xE9);
|
||||
set<int>((uintptr_t)target + 1, (intptr_t)hook - (intptr_t)target - 5);
|
||||
|
||||
int pos = len - 5;
|
||||
if (pos > 0) nop((uintptr_t)target + 5, pos);
|
||||
|
||||
return reinterpret_cast<FuncType>(tampoline);
|
||||
}
|
||||
|
||||
namespace vp
|
||||
{
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, ValueType value)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memcpy((void*)address, &value, sizeof(value));
|
||||
|
||||
VirtualProtect((void*)address, sizeof(value), oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, const ValueType* data, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, sizeof(ValueType) * length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memcpy((void*)address, data, sizeof(ValueType) * length);
|
||||
|
||||
VirtualProtect((void*)address, sizeof(ValueType) * length, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename AddressType>
|
||||
inline void nop(AddressType address, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memset((void*)address, 0x90, length);
|
||||
|
||||
VirtualProtect((void*)address, length, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void jump(AddressType address, FuncType func)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(address, 0xE9);
|
||||
hook::set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
|
||||
VirtualProtect((void*)address, 5, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void call(AddressType address, FuncType func)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(address, 0xE8);
|
||||
hook::set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
|
||||
VirtualProtect((void*)address, 5, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
FuncType detour(AddressType target, FuncType hook, const int len)
|
||||
{
|
||||
uintptr_t tampoline = (uintptr_t)allocate_stub_memory(len + 5);
|
||||
|
||||
std::memcpy((void*)tampoline, (void*)target, len);
|
||||
|
||||
hook::set<uint8_t>(tampoline + len, 0xE9);
|
||||
hook::set<int>((uintptr_t)tampoline + len + 1, (intptr_t)target - (intptr_t)tampoline - 5);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)target, len, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(target, 0xE9);
|
||||
hook::set<int>((uintptr_t)target + 1, (intptr_t)hook - (intptr_t)target - 5);
|
||||
|
||||
int pos = len - 5;
|
||||
if (pos > 0) hook::nop((uintptr_t)target + 5, pos);
|
||||
|
||||
VirtualProtect((void*)target, len, oldProtect, &oldProtect);
|
||||
|
||||
return reinterpret_cast<FuncType>(tampoline);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
122
utils/memory.cpp
Normal file
122
utils/memory.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
|
||||
https://github.com/momo5502/open-iw5
|
||||
|
||||
*/
|
||||
//#include "../pch.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include "memory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace utils
|
||||
{
|
||||
memory::allocator memory::mem_allocator_;
|
||||
|
||||
memory::allocator::~allocator()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void memory::allocator::clear()
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
for (auto& data : this->pool_)
|
||||
{
|
||||
memory::free(data);
|
||||
}
|
||||
|
||||
this->pool_.clear();
|
||||
}
|
||||
|
||||
void memory::allocator::free(void* data)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
|
||||
if (j != this->pool_.end())
|
||||
{
|
||||
memory::free(data);
|
||||
this->pool_.erase(j);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::allocator::free(const void* data)
|
||||
{
|
||||
this->free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
void* memory::allocator::allocate(const size_t length)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::allocate(length);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool memory::allocator::empty() const
|
||||
{
|
||||
return this->pool_.empty();
|
||||
}
|
||||
|
||||
/*char* memory::allocator::duplicate_string(const std::string& string)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::duplicate_string(string);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}*/
|
||||
|
||||
void* memory::allocate(const size_t length)
|
||||
{
|
||||
const auto data = calloc(length, 1);
|
||||
assert(data != nullptr);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*char* memory::duplicate_string(const std::string& string)
|
||||
{
|
||||
const auto new_string = allocate_array<char>(string.size() + 1);
|
||||
std::memcpy(new_string, string.data(), string.size());
|
||||
return new_string;
|
||||
}*/
|
||||
|
||||
void memory::free(void* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
::free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::free(const void* data)
|
||||
{
|
||||
free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
bool memory::is_set(const void* mem, const char chr, const size_t length)
|
||||
{
|
||||
const auto mem_arr = static_cast<const char*>(mem);
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (mem_arr[i] != chr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
memory::allocator* memory::get_allocator()
|
||||
{
|
||||
return &memory::mem_allocator_;
|
||||
}
|
||||
}
|
76
utils/memory.hpp
Normal file
76
utils/memory.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
https://github.com/momo5502/open-iw5
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class memory final
|
||||
{
|
||||
public:
|
||||
class allocator final
|
||||
{
|
||||
public:
|
||||
~allocator();
|
||||
|
||||
void clear();
|
||||
|
||||
void free(void* data);
|
||||
|
||||
void free(const void* data);
|
||||
|
||||
void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
T* allocate()
|
||||
{
|
||||
return this->allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(this->allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
bool empty() const;
|
||||
|
||||
//char* duplicate_string(const std::string& string);
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::vector<void*> pool_;
|
||||
};
|
||||
|
||||
static void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate()
|
||||
{
|
||||
return allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
//static char* duplicate_string(const std::string& string);
|
||||
|
||||
static void free(void* data);
|
||||
static void free(const void* data);
|
||||
|
||||
static bool is_set(const void* mem, char chr, size_t length);
|
||||
|
||||
static allocator* get_allocator();
|
||||
|
||||
private:
|
||||
static allocator mem_allocator_;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user