shjit
This commit is contained in:
131
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/cmodule.cpp
Normal file
131
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/cmodule.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
#include "../pointer/pointer.hpp"
|
||||
#include "cmodule.hpp"
|
||||
#include "../fnv1a.hpp"
|
||||
#include <wtypes.h>
|
||||
#include <Psapi.h>
|
||||
CModule::CModule(const char* name) {
|
||||
m_Name = name;
|
||||
m_Hash = fnv1a::Hash(name);
|
||||
m_Handle = nullptr;
|
||||
|
||||
m_Begin = m_Size = 0;
|
||||
}
|
||||
|
||||
CModule::~CModule() {
|
||||
if (!m_Handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
dlclose(m_Handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CModule::Retrieve() {
|
||||
if (m_Handle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
InitializeHandle();
|
||||
InitializeBounds();
|
||||
|
||||
return m_Handle != nullptr;
|
||||
}
|
||||
|
||||
uintptr_t CModule::GetInterface(const char* version) {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
CPointer pCreateInterface = GetProcAddress("CreateInterface");
|
||||
if (!pCreateInterface.IsValid()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Used internally to register classes.
|
||||
struct InterfaceReg {
|
||||
std::add_pointer_t<uintptr_t()> m_CreateFn;
|
||||
const char* m_pName;
|
||||
InterfaceReg* m_pNext; // For the global list.
|
||||
};
|
||||
|
||||
InterfaceReg* s_pInterfaceRegs =
|
||||
#ifdef _WIN32
|
||||
pCreateInterface.Absolute(3, 0).Dereference(1).Get<InterfaceReg*>()
|
||||
#elif __linux__
|
||||
pCreateInterface.Absolute(1, 0).Absolute(19, 0).Dereference(1).Get<InterfaceReg*>()
|
||||
#endif
|
||||
;
|
||||
|
||||
uint32_t versionHash = fnv1a::Hash(version);
|
||||
for (; s_pInterfaceRegs; s_pInterfaceRegs = s_pInterfaceRegs->m_pNext) {
|
||||
if (fnv1a::Hash(s_pInterfaceRegs->m_pName) == versionHash) {
|
||||
rv = s_pInterfaceRegs->m_CreateFn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
uintptr_t CModule::GetProcAddress(const char* procName) {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
rv = reinterpret_cast<uintptr_t>(::GetProcAddress(static_cast<HMODULE>(m_Handle), procName));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
uintptr_t CModule::FindPattern(const std::span<const int>& pattern) const {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
uint8_t* bytes = reinterpret_cast<uint8_t*>(m_Begin);
|
||||
|
||||
// Faster than pattern[] in debug builds because of _STL_VERIFY.
|
||||
const int* patternData = pattern.data();
|
||||
const size_t patternSize = pattern.size();
|
||||
|
||||
for (size_t i = 0; i < m_Size - patternSize; ++i) {
|
||||
bool found = true;
|
||||
for (size_t j = 0; j < patternSize; ++j) {
|
||||
if (bytes[i + j] != patternData[j] && patternData[j] != -1) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
rv = reinterpret_cast<uintptr_t>(&bytes[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void CModule::InitializeHandle() {
|
||||
#ifdef _WIN32
|
||||
m_Handle = GetModuleHandle(GetName());
|
||||
#else
|
||||
m_Handle = dlopen(GetName(), RTLD_LAZY | RTLD_NOLOAD);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CModule::InitializeBounds() {
|
||||
if (!m_Handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
MODULEINFO mi;
|
||||
BOOL status = GetModuleInformation(GetCurrentProcess(), static_cast<HMODULE>(m_Handle), &mi, sizeof(mi));
|
||||
if (status != 0) {
|
||||
SetBounds(reinterpret_cast<uintptr_t>(m_Handle), mi.SizeOfImage);
|
||||
}
|
||||
}
|
||||
|
||||
void CModule::SetBounds(uintptr_t begin, uintptr_t size) {
|
||||
m_Begin = begin;
|
||||
m_Size = size;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string>
|
||||
class CModule {
|
||||
public:
|
||||
CModule(const char* name);
|
||||
~CModule();
|
||||
|
||||
auto GetHash() const { return m_Hash; }
|
||||
auto GetHandle() const { return m_Handle; }
|
||||
auto GetName() const { return m_Name.c_str(); }
|
||||
|
||||
// Returns false if module not loaded.
|
||||
bool Retrieve();
|
||||
|
||||
uintptr_t GetInterface(const char* version);
|
||||
uintptr_t GetProcAddress(const char* procName);
|
||||
uintptr_t FindPattern(const std::span<const int>& pattern) const;
|
||||
|
||||
private:
|
||||
void InitializeHandle();
|
||||
void InitializeBounds();
|
||||
|
||||
void SetBounds(uintptr_t begin, uintptr_t size);
|
||||
|
||||
// Module name.
|
||||
std::string m_Name;
|
||||
|
||||
// Module name fnv1a hash.
|
||||
uint32_t m_Hash;
|
||||
|
||||
// Module handle.
|
||||
void* m_Handle;
|
||||
|
||||
// Used for pattern scanning.
|
||||
uintptr_t m_Begin, m_Size;
|
||||
};
|
||||
58
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/memadd.cpp
Normal file
58
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/memadd.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
#include "../memory/memadd.h"
|
||||
#include "../csig/sigscan.hpp"
|
||||
#include "../fnv1a.hpp"
|
||||
void CMemory::Initialize() {
|
||||
|
||||
for (CSigScan* it : m_ScheduledScans) {
|
||||
it->FindSignature();
|
||||
it->FreeData();
|
||||
}
|
||||
|
||||
std::vector<CSigScan*>().swap(m_ScheduledScans);
|
||||
}
|
||||
|
||||
ModulePtr_t& CMemory::GetModuleInternal(const char* libName) {
|
||||
auto hash = fnv1a::Hash(libName);
|
||||
|
||||
auto it = m_CachedModules.find(hash);
|
||||
if (it != m_CachedModules.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
auto module = std::make_unique<CModule>(libName);
|
||||
if (module->Retrieve()) {
|
||||
return m_CachedModules.emplace(hash, std::move(module)).first->second;
|
||||
}
|
||||
|
||||
|
||||
static ModulePtr_t null{};
|
||||
return null;
|
||||
}
|
||||
|
||||
CPointer CMemory::GetInterfaceInternal(const char* libName, const char* version) {
|
||||
CPointer rv = 0;
|
||||
|
||||
auto& library = CMemory::GetModuleInternal(libName);
|
||||
if (!library) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = library->GetInterface(version);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
CPointer CMemory::GetProcAddressInternal(const char* libName, const char* procName) {
|
||||
CPointer rv = 0;
|
||||
|
||||
auto& library = CMemory::GetModuleInternal(libName);
|
||||
if (!library) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = library->GetProcAddress(procName);
|
||||
|
||||
return rv;
|
||||
}
|
||||
37
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/memadd.h
Normal file
37
examples/Axion-CS2-RAGE-CHEAT/cstrike/core/memory/memadd.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "../memory/cmodule.hpp"
|
||||
#include "../pointer/pointer.hpp"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class CSigScan;
|
||||
|
||||
using ModulePtr_t = std::unique_ptr<CModule>;
|
||||
|
||||
class CMemory {
|
||||
public:
|
||||
static CMemory& Get() {
|
||||
static CMemory inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
static auto& GetModule(const char* libName) { return Get().GetModuleInternal(libName); }
|
||||
static auto GetInterface(const char* libName, const char* version) { return Get().GetInterfaceInternal(libName, version); }
|
||||
static auto GetProcAddress(const char* libName, const char* procName) { return Get().GetProcAddressInternal(libName, procName); }
|
||||
|
||||
// Used internally.
|
||||
static auto ScheduleScan(CSigScan* sigScan) { Get().m_ScheduledScans.emplace_back(sigScan); }
|
||||
|
||||
void Initialize();
|
||||
|
||||
private:
|
||||
ModulePtr_t& GetModuleInternal(const char* libName);
|
||||
|
||||
CPointer GetInterfaceInternal(const char* libName, const char* version);
|
||||
CPointer GetProcAddressInternal(const char* libName, const char* procName);
|
||||
|
||||
std::unordered_map<uint32_t, ModulePtr_t> m_CachedModules;
|
||||
std::vector<CSigScan*> m_ScheduledScans;
|
||||
};
|
||||
Reference in New Issue
Block a user