init
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
namespace I {
|
||||
using InstantiateInterfaceFn = void* (*)();
|
||||
class CInterfaceReg
|
||||
{
|
||||
public:
|
||||
InstantiateInterfaceFn m_create_fn;
|
||||
const char* m_name;
|
||||
CInterfaceReg* m_next;
|
||||
};
|
||||
|
||||
inline const CInterfaceReg* Find(const char* module_name)
|
||||
{
|
||||
const HMODULE module_base = GetModuleHandleA(module_name);
|
||||
if (module_base == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const auto symbol = reinterpret_cast<std::uintptr_t>(GetProcAddress(module_base, "CreateInterface"));
|
||||
const std::uintptr_t list = symbol + *reinterpret_cast<std::int32_t*>(symbol + 3) + 7;
|
||||
return *reinterpret_cast<CInterfaceReg**>(list);
|
||||
}
|
||||
template <typename T = void*>
|
||||
T* Get(const char* module_name, const char* interface_partial_version)
|
||||
{
|
||||
for (const CInterfaceReg* current = Find(module_name); current; current = current->m_next)
|
||||
{
|
||||
if (std::string_view(current->m_name).find(interface_partial_version) != std::string_view::npos)
|
||||
{
|
||||
return reinterpret_cast<T*>(current->m_create_fn());
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "gaa.h"
|
||||
|
||||
uintptr_t M::getAbsoluteAddress(uintptr_t addr, const int nPreOffset, const int nPostOffset) {
|
||||
addr += nPreOffset;
|
||||
int32_t nRva = *reinterpret_cast<int32_t*>(addr);
|
||||
addr += nPostOffset + sizeof(uint32_t) + nRva;
|
||||
return addr;
|
||||
}
|
||||
6
TempleWare-CS2/source/templeware/utils/memory/gaa/gaa.h
Normal file
6
TempleWare-CS2/source/templeware/utils/memory/gaa/gaa.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace M {
|
||||
uintptr_t getAbsoluteAddress(uintptr_t addr, const int nPreOffset, const int nPostOffset = 0);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#define CS_CONCATENATE_DETAIL(x, y) x##y
|
||||
#define CS_CONCATENATE(x, y) CS_CONCATENATE_DETAIL(x, y)
|
||||
|
||||
#define MEM_PAD(SIZE) \
|
||||
private: \
|
||||
char CS_CONCATENATE(pad_, __COUNTER__)[SIZE]; \
|
||||
public:
|
||||
@@ -0,0 +1,132 @@
|
||||
#include "patternscan.h"
|
||||
|
||||
#include "../../module/module.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <span>
|
||||
#include <sstream>
|
||||
|
||||
#include <Psapi.h>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
std::vector<std::pair<uint8_t, bool>> PatternToBytes(const std::string& pattern) {
|
||||
std::vector<std::pair<uint8_t, bool>> patternBytes;
|
||||
const char* start = pattern.c_str();
|
||||
const char* end = start + pattern.size();
|
||||
|
||||
for (const char* current = start; current < end; ++current) {
|
||||
if (*current == ' ') continue;
|
||||
if (*current == '?') {
|
||||
patternBytes.emplace_back(0, false);
|
||||
if (*(current + 1) == '?') ++current;
|
||||
}
|
||||
else {
|
||||
patternBytes.emplace_back(strtoul(current, nullptr, 16), true);
|
||||
if (*(current + 1) != ' ') ++current;
|
||||
}
|
||||
}
|
||||
|
||||
return patternBytes;
|
||||
}
|
||||
|
||||
uintptr_t M::patternScan(const std::string& module, const std::string& pattern) {
|
||||
uintptr_t baseAddress = modules.getModule(module);
|
||||
HMODULE hModule = reinterpret_cast<HMODULE>(baseAddress);
|
||||
|
||||
if (!hModule) return 0;
|
||||
|
||||
MODULEINFO moduleInfo;
|
||||
GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(MODULEINFO));
|
||||
|
||||
size_t moduleSize = moduleInfo.SizeOfImage;
|
||||
|
||||
std::vector<std::pair<uint8_t, bool>> patternBytes = PatternToBytes(pattern);
|
||||
size_t patternLength = patternBytes.size();
|
||||
|
||||
for (size_t i = 0; i < moduleSize - patternLength; ++i) {
|
||||
bool found = true;
|
||||
for (size_t j = 0; j < patternLength; ++j) {
|
||||
if (patternBytes[j].second && patternBytes[j].first != *reinterpret_cast<uint8_t*>(baseAddress + i + j)) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return baseAddress + i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::uint8_t* M::FindPattern(const char* module_name, const std::string& byte_sequence)
|
||||
{
|
||||
// retrieve the handle to the specified module
|
||||
const HMODULE module = GetModuleHandleA(module_name);
|
||||
if (module == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// retrieve the DOS header of the module
|
||||
const auto dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
|
||||
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// retrieve the NT headers of the module
|
||||
const auto nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<std::uint8_t*>(module) + dos_header->e_lfanew);
|
||||
if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
|
||||
return nullptr;
|
||||
|
||||
// get the size and base address of the code section
|
||||
DWORD m_size = nt_headers->OptionalHeader.SizeOfCode;
|
||||
std::uint8_t* m_base = reinterpret_cast<std::uint8_t*>(module) + nt_headers->OptionalHeader.BaseOfCode;
|
||||
|
||||
using SeqByte_t = std::pair< std::uint8_t, bool >;
|
||||
|
||||
std::string str{ };
|
||||
std::vector< std::pair< std::uint8_t, bool > > byte_sequence_vec{ };
|
||||
std::stringstream stream(byte_sequence);
|
||||
// parse the byte sequence string into a vector of byte sequence elements
|
||||
while (stream >> str)
|
||||
{
|
||||
// wildcard byte
|
||||
if (str[0u] == '?')
|
||||
{
|
||||
byte_sequence_vec.emplace_back(0u, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
// invalid hex digit, skip this byte
|
||||
if (!std::isxdigit(str[0u]) || !std::isxdigit(str[1u]))
|
||||
continue;
|
||||
|
||||
byte_sequence_vec.emplace_back(static_cast<std::uint8_t>(std::strtoul(str.data(), nullptr, 16)), false);
|
||||
}
|
||||
|
||||
// end pointer of the code section
|
||||
const auto end = reinterpret_cast<std::uint8_t*>(m_base + m_size);
|
||||
|
||||
// search for the byte sequence within the code section
|
||||
const auto ret = std::search(reinterpret_cast<std::uint8_t*>(m_base), end, byte_sequence_vec.begin(), byte_sequence_vec.end(),
|
||||
[](const std::uint8_t byte, const std::pair< std::uint8_t, bool >& seq_byte)
|
||||
{
|
||||
return std::get< bool >(seq_byte) || byte == std::get< std::uint8_t >(seq_byte);
|
||||
});
|
||||
|
||||
// byte sequence found, return the pointer
|
||||
if (ret)
|
||||
return ret;
|
||||
#ifdef _DEBUG
|
||||
|
||||
// failed to find byte sequence, log error and return
|
||||
std::cout<< "failed to find pattern:" << byte_sequence.c_str() << " | inside: " << module_name << std::endl;
|
||||
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace M {
|
||||
template <typename T = std::uint8_t>
|
||||
T* abs(T* relative_address, int pre_offset = 0x0, int post_offset = 0x0)
|
||||
{
|
||||
relative_address += pre_offset;
|
||||
relative_address += sizeof(std::int32_t) + *reinterpret_cast<std::int32_t*>(relative_address);
|
||||
relative_address += post_offset;
|
||||
return relative_address;
|
||||
}
|
||||
std::uint8_t* FindPattern(const char* module_name, const std::string& byte_sequence);
|
||||
|
||||
uintptr_t patternScan(const std::string& module, const std::string& pattern);
|
||||
}
|
||||
12
TempleWare-CS2/source/templeware/utils/memory/vfunc/vfunc.h
Normal file
12
TempleWare-CS2/source/templeware/utils/memory/vfunc/vfunc.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace M {
|
||||
template <typename T, std::size_t nIndex, class CBaseClass, typename... Args_t>
|
||||
static inline T vfunc(CBaseClass* thisptr, Args_t... argList) {
|
||||
using VirtualFn_t = T(__thiscall*)(const void*, decltype(argList)...);
|
||||
return (*reinterpret_cast<VirtualFn_t* const*>(reinterpret_cast<std::uintptr_t>(thisptr)))[nIndex](thisptr, argList...);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user