This commit is contained in:
Oscar
2025-07-25 21:45:33 +03:00
parent 1edd51c46f
commit 50f4002acc
396 changed files with 243692 additions and 86 deletions

View File

@@ -0,0 +1,406 @@
// used: [win] winapi
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "config.h"
// used: getworkingpath
#include "../core.h"
// used: l_print
#include "../utilities/log.h"
// used: integertostring
#include "../utilities/crt.h"
// used: heapalloc, heapfree
#include "../utilities/memory.h"
// used: formatter implementation
#if defined(CS_CONFIGURATION_BINARY)
#include "../../extensions/binary.h"
#elif defined(CS_CONFIGURATION_JSON)
#include "../../extensions/json.h"
#elif defined(CS_CONFIGURATION_TOML)
#include "../../extensions/toml.h"
#endif
// default configurations working path
static wchar_t wszConfigurationsPath[MAX_PATH];
#pragma region config_user_data_type
std::size_t C::UserDataType_t::GetSerializationSize() const
{
std::size_t nTotalDataSize = 0U;
for (const UserDataMember_t& member : vecMembers)
nTotalDataSize += sizeof(FNV1A_t[2]) + member.nDataSize;
return nTotalDataSize;
}
#pragma endregion
#pragma region config_variable_object
void C::VariableObject_t::SetStorage(const void* pValue)
{
// check is available to store value in the local storage
if (this->nStorageSize <= sizeof(this->storage.uLocal))
{
CRT::MemorySet(&this->storage.uLocal, 0U, sizeof(this->storage.uLocal));
CRT::MemoryCopy(&this->storage.uLocal, pValue, this->nStorageSize);
}
// otherwise use heap memory to store it
else
{
CS_ASSERT(this->storage.pHeap != nullptr); // tried to access non allocated storage
CRT::MemorySet(this->storage.pHeap, 0U, this->nStorageSize);
CRT::MemoryCopy(this->storage.pHeap, pValue, this->nStorageSize);
}
}
std::size_t C::VariableObject_t::GetSerializationSize() const
{
std::size_t nSerializationSize = this->nStorageSize;
// denote a custom serialization size when it different from the storage size
switch (this->uTypeHash)
{
// lookup for array data type
case FNV1A::HashConst("bool[]"):
case FNV1A::HashConst("int[]"):
case FNV1A::HashConst("unsigned int[]"):
case FNV1A::HashConst("float[]"):
case FNV1A::HashConst("char[][]"):
// arrays also serialize their size
nSerializationSize += sizeof(std::size_t);
break;
// lookup for user-defined data type
default:
{
for (const UserDataType_t& userType : vecUserTypes)
{
if (userType.uTypeHash == this->uTypeHash)
{
nSerializationSize = sizeof(std::size_t) + userType.GetSerializationSize();
break;
}
}
break;
}
}
return nSerializationSize;
}
#pragma endregion
bool C::Setup(const wchar_t* wszDefaultFileName)
{
if (!CORE::GetWorkingPath(wszConfigurationsPath))
return false;
CRT::StringCat(wszConfigurationsPath, CS_XOR(L"settings\\"));
// create directory if it doesn't exist
if (!::CreateDirectoryW(wszConfigurationsPath, nullptr))
{
if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
L_PRINT(LOG_ERROR) << CS_XOR("failed to create configurations directory, because one or more intermediate directories don't exist");
return false;
}
}
// @note: define custom data types we want to serialize
AddUserType(FNV1A::HashConst("KeyBind_t"),
{
UserDataMember_t{ FNV1A::HashConst("uKey"), FNV1A::HashConst("unsigned int"), &KeyBind_t::uKey },
UserDataMember_t{ FNV1A::HashConst("nMode"), FNV1A::HashConst("int"), &KeyBind_t::nMode }
});
AddUserType(FNV1A::HashConst("ColorPickerVar_t"),
{
UserDataMember_t{ FNV1A::HashConst("bRainbow"), FNV1A::HashConst("bool"), &ColorPickerVar_t::bRainbow },
UserDataMember_t{ FNV1A::HashConst("flRainbowSpeed"), FNV1A::HashConst("float"), &ColorPickerVar_t::flRainbowSpeed },
UserDataMember_t{ FNV1A::HashConst("colPrimary"), FNV1A::HashConst("Color_t"), &ColorPickerVar_t::colValue },
});
AddUserType(FNV1A::HashConst("TextOverlayVar_t"),
{
UserDataMember_t{ FNV1A::HashConst("bEnable"), FNV1A::HashConst("bool"), &TextOverlayVar_t::bEnable },
UserDataMember_t{ FNV1A::HashConst("flThickness"), FNV1A::HashConst("float"), &TextOverlayVar_t::flThickness },
UserDataMember_t{ FNV1A::HashConst("colPrimary"), FNV1A::HashConst("Color_t"), &TextOverlayVar_t::colPrimary },
UserDataMember_t{ FNV1A::HashConst("colOutline"), FNV1A::HashConst("Color_t"), &TextOverlayVar_t::colOutline }
});
AddUserType(FNV1A::HashConst("FrameOverlayVar_t"),
{
UserDataMember_t{ FNV1A::HashConst("bEnable"), FNV1A::HashConst("bool"), &FrameOverlayVar_t::bEnable },
UserDataMember_t{ FNV1A::HashConst("flThickness"), FNV1A::HashConst("float"), &FrameOverlayVar_t::flThickness },
UserDataMember_t{ FNV1A::HashConst("flRounding"), FNV1A::HashConst("float"), &FrameOverlayVar_t::flRounding },
UserDataMember_t{ FNV1A::HashConst("colPrimary"), FNV1A::HashConst("Color_t"), &FrameOverlayVar_t::colPrimary },
UserDataMember_t{ FNV1A::HashConst("colOutline"), FNV1A::HashConst("Color_t"), &FrameOverlayVar_t::colOutline }
});
AddUserType(FNV1A::HashConst("BarOverlayVar_t"),
{
UserDataMember_t{ FNV1A::HashConst("bEnable"), FNV1A::HashConst("bool"), &BarOverlayVar_t::bEnable },
UserDataMember_t{ FNV1A::HashConst("bGradient"), FNV1A::HashConst("bool"), &BarOverlayVar_t::bGradient },
UserDataMember_t{ FNV1A::HashConst("bUseFactorColor"), FNV1A::HashConst("bool"), &BarOverlayVar_t::bUseFactorColor },
UserDataMember_t{ FNV1A::HashConst("flThickness"), FNV1A::HashConst("float"), &BarOverlayVar_t::flThickness },
UserDataMember_t{ FNV1A::HashConst("colPrimary"), FNV1A::HashConst("Color_t"), &BarOverlayVar_t::colPrimary },
UserDataMember_t{ FNV1A::HashConst("colSecondary"), FNV1A::HashConst("Color_t"), &BarOverlayVar_t::colSecondary },
UserDataMember_t{ FNV1A::HashConst("colBackground"), FNV1A::HashConst("Color_t"), &BarOverlayVar_t::colBackground },
UserDataMember_t{ FNV1A::HashConst("colOutline"), FNV1A::HashConst("Color_t"), &BarOverlayVar_t::colOutline }
});
// create default configuration
if (!CreateFile(wszDefaultFileName))
return false;
// store existing configurations list
Refresh();
return true;
}
#pragma region config_main
void C::Refresh()
{
// clear and free previous stored file names
vecFileNames.clear();
// make configuration files path filter
wchar_t wszPathFilter[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszPathFilter, wszConfigurationsPath), CS_XOR(L"*" CS_CONFIGURATION_FILE_EXTENSION));
// iterate through all files with our filter
WIN32_FIND_DATAW findData;
if (const HANDLE hFindFile = ::FindFirstFileW(wszPathFilter, &findData); hFindFile != INVALID_HANDLE_VALUE)
{
do
{
vecFileNames.push_back(new wchar_t[CRT::StringLength(findData.cFileName) + 1U]);
CRT::StringCopy(vecFileNames.back(), findData.cFileName);
L_PRINT(LOG_INFO) << CS_XOR("found configuration file: \"") << findData.cFileName << CS_XOR("\"");
} while (::FindNextFileW(hFindFile, &findData));
::FindClose(hFindFile);
}
}
void C::AddUserType(const FNV1A_t uTypeHash, const std::initializer_list<UserDataMember_t> vecUserMembers)
{
if (vecUserMembers.size() == 0U)
return;
UserDataType_t userDataType;
userDataType.uTypeHash = uTypeHash;
for (const auto& userDataMember : vecUserMembers)
userDataType.vecMembers.push_back(userDataMember);
vecUserTypes.emplace_back(CRT::Move(userDataType));
}
bool C::SaveFileVariable(const std::size_t nFileIndex, const VariableObject_t& variable)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
#if defined(CS_CONFIGURATION_BINARY)
if (BIN::SaveVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_JSON)
if (JSON::SaveVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_TOML)
if (TOML::SaveVariable(wszFilePath, variable))
#endif
{
return true;
}
return false;
}
bool C::LoadFileVariable(const std::size_t nFileIndex, VariableObject_t& variable)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
#if defined(CS_CONFIGURATION_BINARY)
if (BIN::LoadVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_JSON)
if (JSON::LoadVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_TOML)
if (TOML::LoadVariable(wszFilePath, variable))
#endif
{
return true;
}
return false;
}
bool C::RemoveFileVariable(const std::size_t nFileIndex, const VariableObject_t& variable)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
#if defined(CS_CONFIGURATION_BINARY)
if (BIN::RemoveVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_JSON)
if (JSON::RemoveVariable(wszFilePath, variable))
#elif defined(CS_CONFIGURATION_TOML)
if (TOML::RemoveVariable(wszFilePath, variable))
#endif
{
return true;
}
return false;
}
bool C::CreateFile(const wchar_t* wszFileName)
{
const wchar_t* wszFileExtension = CRT::StringCharR(wszFileName, L'.');
// get length of the given filename and strip out extension if there any
const std::size_t nFileNameLength = (wszFileExtension != nullptr ? wszFileExtension - wszFileName : CRT::StringLength(wszFileName));
wchar_t* wszFullFileName = new wchar_t[nFileNameLength + CRT::StringLength(CS_CONFIGURATION_FILE_EXTENSION) + 1U];
// copy filename without extension
wchar_t* wszFullFileNameEnd = CRT::StringCopyN(wszFullFileName, wszFileName, nFileNameLength);
*wszFullFileNameEnd = L'\0';
// append correct extension to the filename
CRT::StringCat(wszFullFileNameEnd, CS_XOR(CS_CONFIGURATION_FILE_EXTENSION));
// add filename to the list
vecFileNames.push_back(wszFullFileName);
// create and save it by the index
if (SaveFile(vecFileNames.size() - 1U))
{
L_PRINT(LOG_INFO) << CS_XOR("created configuration file: \"") << wszFullFileName << CS_XOR("\"");
return true;
}
L_PRINT(LOG_WARNING) << CS_XOR("failed to create configuration file: \"") << wszFullFileName << CS_XOR("\"");
return false;
}
bool C::SaveFile(const std::size_t nFileIndex)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
#if defined(CS_CONFIGURATION_BINARY)
if (BIN::SaveFile(wszFilePath))
#elif defined(CS_CONFIGURATION_JSON)
if (JSON::SaveFile(wszFilePath))
#elif defined(CS_CONFIGURATION_TOML)
if (TOML::SaveFile(wszFilePath))
#endif
{
L_PRINT(LOG_INFO) << CS_XOR("saved configuration file: \"") << wszFileName << CS_XOR("\"");
return true;
}
L_PRINT(LOG_WARNING) << CS_XOR("failed to save configuration file: \"") << wszFileName << CS_XOR("\"");
return false;
}
bool C::LoadFile(const std::size_t nFileIndex)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
#if defined(CS_CONFIGURATION_BINARY)
if (BIN::LoadFile(wszFilePath))
#elif defined(CS_CONFIGURATION_JSON)
if (JSON::LoadFile(wszFilePath))
#elif defined(CS_CONFIGURATION_TOML)
if (TOML::LoadFile(wszFilePath))
#endif
{
L_PRINT(LOG_INFO) << CS_XOR("loaded configuration file: \"") << wszFileName << CS_XOR("\"");
return true;
}
L_PRINT(LOG_WARNING) << CS_XOR("failed to load configuration file: \"") << wszFileName << CS_XOR("\"");
return false;
}
void C::RemoveFile(const std::size_t nFileIndex)
{
const wchar_t* wszFileName = vecFileNames[nFileIndex];
// unable to delete default config
if (CRT::StringCompare(wszFileName, CS_XOR(CS_CONFIGURATION_DEFAULT_FILE_NAME CS_CONFIGURATION_FILE_EXTENSION)) == 0)
{
L_PRINT(LOG_WARNING) << CS_XOR("unable to remove default configuration file: \"") << wszFileName << CS_XOR("\"");
return;
}
wchar_t wszFilePath[MAX_PATH];
CRT::StringCat(CRT::StringCopy(wszFilePath, wszConfigurationsPath), wszFileName);
if (::DeleteFileW(wszFilePath))
{
// erase and free filename from the list
vecFileNames.erase(vecFileNames.cbegin() + nFileIndex);
L_PRINT(LOG_INFO) << CS_XOR("removed configuration file: \"") << wszFileName << CS_XOR("\"");
}
}
#pragma endregion
#pragma region config_get
std::size_t C::GetVariableIndex(const FNV1A_t uNameHash)
{
for (std::size_t i = 0U; i < vecVariables.size(); i++)
{
if (vecVariables[i].uNameHash == uNameHash)
return i;
}
return C_INVALID_VARIABLE;
}
#pragma endregion
#pragma region config_user_types
void ColorPickerVar_t::UpdateRainbow()
{
// @todo: improve + optimize this code
// progress rainbow color
if (this->bRainbow)
{
const float flTime = static_cast<float>(ImGui::GetTime());
// create a rainbow color with copied alpha
float arrRainbowColors[] = {
sin(flTime * this->flRainbowSpeed) * 0.5f + 0.5f,
sin(flTime * this->flRainbowSpeed * MATH::_PI / 3) * 0.5f + 0.5f,
sin(flTime * this->flRainbowSpeed * MATH::_PI / 3) * 0.5f + 0.5f,
this->colValue.Base<COLOR_A>()
};
// set the rainbow color
this->colValue = Color_t::FromBase4(arrRainbowColors);
}
}

View File

@@ -0,0 +1,462 @@
#pragma once
// used: [stl] vector
#include <vector>
// used: [stl] type_info
#include <typeinfo>
// used: [win] undname_no_arguments
#include <dbghelp.h>
#include "../common.h"
#include "../sdk/datatypes/color.h"
// used: l_print
#include "../utilities/log.h"
// used: heapalloc, heapfree
#include "../utilities/memory.h"
// used: fnv1a hashing
#include "../utilities/fnv1a.h"
#pragma region config_definitions
#define C_ADD_VARIABLE(TYPE, NAME, DEFAULT) const std::size_t NAME = C::AddVariable<TYPE>(FNV1A::HashConst(#NAME), FNV1A::HashConst(#TYPE), DEFAULT);
#define C_ADD_VARIABLE_ARRAY(TYPE, SIZE, NAME, DEFAULT) const std::size_t NAME = C::AddVariableArray<TYPE[SIZE]>(FNV1A::HashConst(#NAME), FNV1A::HashConst(#TYPE "[]"), DEFAULT);
#define C_ADD_VARIABLE_ARRAY_ARRAY(TYPE, SIZE, SUBSIZE, NAME, DEFAULT) const std::size_t NAME = C::AddVariableArray<TYPE[SIZE][SUBSIZE]>(FNV1A::HashConst(#NAME), FNV1A::HashConst(#TYPE "[][]"), DEFAULT);
#define C_INVALID_VARIABLE static_cast<std::size_t>(-1)
#define C_GET(TYPE, NAME) C::Get<TYPE>(NAME)
#define C_SET(TYPE, NAME, VALUE) C::Set<TYPE>(C::GetVariableIndex(FNV1A::HashConst(#NAME)), VALUE)
#define C_GET_ARRAY(TYPE, SIZE, NAME, INDEX) C::Get<TYPE[SIZE]>(NAME)[INDEX]
#pragma endregion
#pragma region config_user_types
enum class EKeyBindMode : int
{
HOLD = 0,
TOGGLE
};
struct KeyBind_t
{
constexpr KeyBind_t(const char* szName, const unsigned int uKey = 0U, const EKeyBindMode nMode = EKeyBindMode::HOLD) :
szName(szName), uKey(uKey), nMode(nMode) { }
bool bEnable = false;
const char* szName = nullptr;
unsigned int uKey = 0U;
EKeyBindMode nMode = EKeyBindMode::HOLD;
};
struct ColorPickerVar_t
{
// default constructor
constexpr ColorPickerVar_t(const Color_t& colValue = Color_t(255, 255, 255), const bool bRainbow = false, const float flRainbowSpeed = 0.5f) :
colValue(colValue), bRainbow(bRainbow), flRainbowSpeed(flRainbowSpeed) { }
// @note: other contructors will only construct Color_t object and set rainbow to false and speed to 0.5f
// 8-bit color constructor (in: [0 .. 255])
constexpr ColorPickerVar_t(const std::uint8_t r, const std::uint8_t g, const std::uint8_t b, const std::uint8_t a = 255) :
colValue(r, g, b, a), bRainbow(false), flRainbowSpeed(0.5f) { }
// 8-bit color constructor (in: [0 .. 255])
constexpr ColorPickerVar_t(const int r, const int g, const int b, const int a = 255) :
colValue(r, g, b, a), bRainbow(false), flRainbowSpeed(0.5f) { }
// 8-bit array color constructor (in: [0.0 .. 1.0])
explicit constexpr ColorPickerVar_t(const std::uint8_t arrColor[4]) :
colValue(arrColor), bRainbow(false), flRainbowSpeed(0.5f) { }
// 32-bit packed color constructor (in: 0x00000000 - 0xFFFFFFFF)
explicit constexpr ColorPickerVar_t(const ImU32 uPackedColor) :
colValue(uPackedColor), bRainbow(false), flRainbowSpeed(0.5f) { }
// 32-bit color constructor (in: [0.0 .. 1.0])
constexpr ColorPickerVar_t(const float r, const float g, const float b, const float a = 1.0f) :
colValue(r, g, b, a), bRainbow(false), flRainbowSpeed(0.5f) { }
void UpdateRainbow();
Color_t colValue = Color_t(255, 255, 255, 255);
bool bRainbow = false;
float flRainbowSpeed = 0.5f;
};
/// hold config variables for text component overlay
struct TextOverlayVar_t
{
constexpr TextOverlayVar_t(const bool bEnable, const bool bIcon, const float flThickness = 1.f, const Color_t& colPrimary = Color_t(255, 255, 255), const Color_t& colOutline = Color_t(0, 0, 0)) :
bEnable(bEnable), bIcon(bIcon), flThickness(flThickness), colPrimary(colPrimary), colOutline(colOutline) { }
bool bEnable = false;
bool bIcon = false;
float flThickness = 1.f;
Color_t colPrimary = Color_t(255, 255, 255);
Color_t colOutline = Color_t(0, 0, 0);
};
/// hold config variables for frame/box component overlay
struct FrameOverlayVar_t
{
constexpr FrameOverlayVar_t(const bool bEnable, const float flThickness = 1.f, const float flRounding = 0.f, const Color_t& colPrimary = Color_t(255, 255, 255), const Color_t& colOutline = Color_t(0, 0, 0)) :
bEnable(bEnable), flThickness(flThickness), flRounding(flRounding), colPrimary(colPrimary), colOutline(colOutline) { }
bool bEnable = false;
float flThickness = 1.f;
float flRounding = 0.f;
Color_t colPrimary = Color_t(255, 255, 255);
Color_t colOutline = Color_t(0, 0, 0);
};
/// hold config variables for bar component overlay
struct BarOverlayVar_t
{
constexpr BarOverlayVar_t(const bool bEnable, const bool bGradient = false, const bool bUseFactorColor = false, const float flThickness = 1.f, const Color_t& colPrimary = Color_t(255, 255, 255), const Color_t& colSecondary = Color_t(255, 255, 255), const Color_t& colBackground = Color_t(), const Color_t& colOutline = Color_t(), const bool background = true, const bool outline = true) :
bEnable(bEnable), bGradient(bGradient), bUseFactorColor(bUseFactorColor), flThickness(flThickness), colPrimary(colPrimary), colSecondary(colSecondary), colBackground(colBackground), colOutline(colOutline), bBackground(background), bOutline(outline) { }
bool bEnable = false;
bool bGradient = false;
bool bShowValue = false;
bool bOutline = false;
bool bGlowShadow = false;
bool bBackground = false;
bool bUseFactorColor = false;
float flThickness = 1.f;
Color_t colPrimary = Color_t(255, 255, 255);
Color_t colSecondary = Color_t(255, 255, 255);
Color_t colShadow = Color_t(56, 255, 125);
Color_t colBackground = Color_t{15, 15, 15, 55};
Color_t colOutline = Color_t{ 0, 0, 0, 55 };
};
#pragma endregion
/*
* CONFIGURATION
* - cheat variables serialization/de-serialization manager
*/
namespace C
{
// member of user-defined custom serialization structure
struct UserDataMember_t
{
// @todo: not sure is it possible and how todo this with projections, so currently done with pointer-to-member thing, probably could be optimized
template <typename T, typename C>
constexpr UserDataMember_t(const FNV1A_t uNameHash, const FNV1A_t uTypeHash, const T C::*pMember) :
uNameHash(uNameHash), uTypeHash(uTypeHash), nDataSize(sizeof(std::remove_pointer_t<T>)), uBaseOffset(reinterpret_cast<std::size_t>(std::addressof(static_cast<C*>(nullptr)->*pMember))) { } // @test: 'CS_OFFSETOF' must expand to the same result but for some reason it doesn't
// hash of custom variable name
FNV1A_t uNameHash = 0U;
// hash of custom variable type
FNV1A_t uTypeHash = 0U;
// data size of custom variable type
std::size_t nDataSize = 0U;
// offset to the custom variable from the base of class
std::size_t uBaseOffset = 0U;
};
// user-defined custom serialization structure
struct UserDataType_t
{
[[nodiscard]] std::size_t GetSerializationSize() const;
FNV1A_t uTypeHash = 0U;
std::vector<UserDataMember_t> vecMembers = {};
};
// variable info and value storage holder
struct VariableObject_t
{
// @test: it's required value to be either trivially copyable or allocated/copied by new/placement-new operators, otherwise it may cause UB
template <typename T> requires (!std::is_void_v<T> && std::is_trivially_copyable_v<T>)
VariableObject_t(const FNV1A_t uNameHash, const FNV1A_t uTypeHash, const T& valueDefault) :
uNameHash(uNameHash), uTypeHash(uTypeHash), nStorageSize(sizeof(T))
{
#ifndef CS_NO_RTTI
// store RTTI address if available
this->pTypeInfo = &typeid(std::remove_cvref_t<T>);
#endif
// @todo: do not call setstorage, instead construct it by placement-new operator
// allocate storage on the heap if it doesnt't fit on the local one
if constexpr (sizeof(T) > sizeof(this->storage.uLocal))
this->storage.pHeap = MEM::HeapAlloc(this->nStorageSize);
SetStorage(&valueDefault);
}
VariableObject_t(VariableObject_t&& other) noexcept :
uNameHash(other.uNameHash), uTypeHash(other.uTypeHash), nStorageSize(other.nStorageSize)
{
#ifndef CS_NO_RTTI
this->pTypeInfo = other.pTypeInfo;
#endif
if (this->nStorageSize <= sizeof(this->storage.uLocal))
CRT::MemoryCopy(&this->storage.uLocal, &other.storage.uLocal, sizeof(this->storage.uLocal));
else
{
this->storage.pHeap = other.storage.pHeap;
// prevent it from being freed when the moved object is destroyed
other.storage.pHeap = nullptr;
}
}
VariableObject_t(const VariableObject_t& other) :
uNameHash(other.uNameHash), uTypeHash(other.uTypeHash), nStorageSize(other.nStorageSize)
{
#ifndef CS_NO_RTTI
this->pTypeInfo = other.pTypeInfo;
#endif
if (this->nStorageSize <= sizeof(this->storage.uLocal))
CRT::MemoryCopy(&this->storage.uLocal, &other.storage.uLocal, sizeof(this->storage.uLocal));
else if (other.storage.pHeap != nullptr)
{
this->storage.pHeap = MEM::HeapAlloc(this->nStorageSize);
CRT::MemoryCopy(this->storage.pHeap, other.storage.pHeap, this->nStorageSize);
}
}
~VariableObject_t()
{
// check if heap memory is in use and allocated
if (this->nStorageSize > sizeof(this->storage.uLocal) && this->storage.pHeap != nullptr)
MEM::HeapFree(this->storage.pHeap);
}
VariableObject_t& operator=(VariableObject_t&& other) noexcept
{
// check if heap memory is in use and allocated
if (this->nStorageSize > sizeof(this->storage.uLocal) && this->storage.pHeap != nullptr)
MEM::HeapFree(this->storage.pHeap);
this->uNameHash = other.uNameHash;
this->uTypeHash = other.uTypeHash;
this->nStorageSize = other.nStorageSize;
#ifndef CS_NO_RTTI
this->pTypeInfo = other.pTypeInfo;
#endif
if (this->nStorageSize <= sizeof(this->storage.uLocal))
CRT::MemoryCopy(&this->storage.uLocal, &other.storage.uLocal, sizeof(this->storage.uLocal));
else
{
this->storage.pHeap = other.storage.pHeap;
// prevent it from being freed when the moved object is destroyed
other.storage.pHeap = nullptr;
}
return *this;
}
VariableObject_t& operator=(const VariableObject_t& other)
{
// check if heap memory is in use and allocated
if (this->nStorageSize > sizeof(this->storage.uLocal) && this->storage.pHeap != nullptr)
MEM::HeapFree(this->storage.pHeap);
this->uNameHash = other.uNameHash;
this->uTypeHash = other.uTypeHash;
this->nStorageSize = other.nStorageSize;
#ifndef CS_NO_RTTI
this->pTypeInfo = other.pTypeInfo;
#endif
if (this->nStorageSize <= sizeof(this->storage.uLocal))
CRT::MemoryCopy(&this->storage.uLocal, &other.storage.uLocal, sizeof(this->storage.uLocal));
else if (other.storage.pHeap != nullptr)
{
this->storage.pHeap = MEM::HeapAlloc(this->nStorageSize);
CRT::MemoryCopy(this->storage.pHeap, other.storage.pHeap, this->nStorageSize);
}
return *this;
}
/// @tparam bTypeSafe if true, activates additional comparison of source and requested type information, requires RTTI
/// @returns: pointer to the value storage, null if @a'bTypeSafe' is active and the access type does not match the variable type
template <typename T, bool bTypeSafe = true> requires (std::is_object_v<T>)
[[nodiscard]] const T* GetStorage() const
{
/*
#ifndef CS_NO_RTTI
// sanity check of stored value type and asked value type
if constexpr (bTypeSafe)
{
if (const std::type_info& currentTypeInfo = typeid(std::remove_cvref_t<T>); this->pTypeInfo != nullptr && CRT::StringCompare(this->pTypeInfo->raw_name(), currentTypeInfo.raw_name()) != 0)
{
if (char szPresentTypeName[64] = {}, szAccessTypeName[64] = {};
MEM::fnUnDecorateSymbolName(this->pTypeInfo->raw_name() + 1U, szPresentTypeName, CS_ARRAYSIZE(szPresentTypeName), UNDNAME_NO_ARGUMENTS) != 0UL &&
MEM::fnUnDecorateSymbolName(currentTypeInfo.raw_name() + 1U, szAccessTypeName, CS_ARRAYSIZE(szAccessTypeName), UNDNAME_NO_ARGUMENTS) != 0UL)
{
L_PRINT(LOG_ERROR) << CS_XOR("accessing variable of type: \"") << szPresentTypeName << CS_XOR("\" with wrong type: \"") << szAccessTypeName << CS_XOR("\"");
}
CS_ASSERT(false); // storage value and asked data type mismatch
return nullptr;
}
}
#endif*/
// check is value stored in the local storage
if (this->nStorageSize <= sizeof(this->storage.uLocal))
return reinterpret_cast<const std::remove_cvref_t<T>*>(&this->storage.uLocal);
// otherwise it is allocated in the heap memory
CS_ASSERT(this->storage.pHeap != nullptr); // tried to access non allocated storage
return static_cast<const std::remove_cvref_t<T>*>(this->storage.pHeap);
}
template <typename T, bool bTypeSafe = true> requires (std::is_object_v<T>)
[[nodiscard]] T* GetStorage()
{
return const_cast<T*>(static_cast<const VariableObject_t*>(this)->GetStorage<T, bTypeSafe>());
}
// replace variable contained value
void SetStorage(const void* pValue);
/// @returns: the size of the data to be serialized/de-serialized into/from the configuration file
[[nodiscard]] std::size_t GetSerializationSize() const;
// hash of variable name
FNV1A_t uNameHash = 0x0;
// hash of value type
FNV1A_t uTypeHash = 0x0;
#ifndef CS_NO_RTTI
// address of RTTI type data for value type
const std::type_info* pTypeInfo = nullptr;
#endif
// value storage size in bytes
std::size_t nStorageSize = 0U;
// value storage
union
{
void* pHeap;
std::uint8_t uLocal[sizeof(std::uintptr_t)]; // @test: expand local storage size to fit max possible size of trivial type so we can minimize heap allocations count
} storage = { nullptr };
};
// create directories and default configuration file
bool Setup(const wchar_t* wszDefaultFileName);
/* @section: main */
// loop through directory content and store all user configurations filenames
void Refresh();
/// register user-defined data structure type and it's member variables
/// @param[in] vecUserMembers member variables of structure that needs to be serialized/de-serialized
void AddUserType(const FNV1A_t uTypeHash, std::initializer_list<UserDataMember_t> vecUserMembers);
/// write/re-write single variable to existing configuration file
/// @returns: true if variable has been found or created and successfully written, false otherwise
bool SaveFileVariable(const std::size_t nFileIndex, const VariableObject_t& variable);
/// read single variable from existing configuration file
/// @remarks: when the version of cheat is greater than version of the configuration file and @a'variable' wasn't found, this function saves it and updates the version to the current one, note that it doesn't affect to return value
/// @returns: true if variable has been found and successfully read, false otherwise
bool LoadFileVariable(const std::size_t nFileIndex, VariableObject_t& variable);
/// erase single variable from existing configuration file
/// @returns: true if variable did not exist or was successfully removed, false otherwise
bool RemoveFileVariable(const std::size_t nFileIndex, const VariableObject_t& variable);
/// create a new configuration file and save it
/// @param[in] wszFileName file name of configuration file to save and write in
/// @returns: true if file has been successfully created and all variables were written to it, false otherwise
bool CreateFile(const wchar_t* wszFileName);
/// serialize variables into the configuration file
/// @param[in] nFileIndex index of the exist configuration file name
/// @returns: true if all variables were successfully written to the file, false otherwise
bool SaveFile(const std::size_t nFileIndex);
/// de-serialize variables from the configuration file
/// @param[in] nFileIndex index of the exist configuration file name
/// @returns: true if all variables were successfully loaded from the file, false otherwise
bool LoadFile(const std::size_t nFileIndex);
/// remove configuration file
/// @param[in] nFileIndex index of the exist configuration file name
void RemoveFile(const std::size_t nFileIndex);
/* @section: values */
// all user configuration filenames
inline std::vector<wchar_t*> vecFileNames = {};
// custom user-defined serialization data types
inline std::vector<UserDataType_t> vecUserTypes = {};
// configuration variables storage
inline std::vector<VariableObject_t> vecVariables = {};
/* @section: get */
/// @returns: index of variable with given name hash if it exist, 'C_INVALID_VARIABLE' otherwise
[[nodiscard]] std::size_t GetVariableIndex(const FNV1A_t uNameHash);
/// @tparam T type of variable we're going to get, must be exactly the same as when registered
/// @returns: variable value at given index
template <typename T>
[[nodiscard]] T& Get(const std::size_t nIndex)
{
return *vecVariables[nIndex].GetStorage<T>();
}
// @todo: get rid of templates, so it doesn't compile duplicates and we're able to merge things to .cpp
/// add new configuration variable
/// @returns: index of added variable
template <typename T> requires (!std::is_array_v<T>)
std::size_t AddVariable(const FNV1A_t uNameHash, const FNV1A_t uTypeHash, const T& valueDefault)
{
vecVariables.emplace_back(uNameHash, uTypeHash, valueDefault);
return vecVariables.size() - 1U;
}
template <typename T>
bool Set(const std::size_t nIndex, const T& value)
{
if (nIndex < vecVariables.size())
{
vecVariables[nIndex].SetStorage(&value);
return true;
}
return false;
}
/// add new configuration array variable initialized by single value
/// @returns: index of added array variable
template <typename T> requires (std::is_array_v<T>)
std::size_t AddVariableArray(const FNV1A_t uNameHash, const FNV1A_t uTypeHash, const std::remove_pointer_t<std::decay_t<T>> valueDefault)
{
using BaseType_t = std::remove_pointer_t<std::decay_t<T>>;
T arrValueDefault;
for (std::size_t i = 0U; i < sizeof(T) / sizeof(BaseType_t); i++)
arrValueDefault[i] = valueDefault;
vecVariables.emplace_back(uNameHash, uTypeHash, arrValueDefault);
return vecVariables.size() - 1U;
}
/// add new configuration array variable with multiple values initialized
/// @returns: index of added array variable
template <typename T> requires (std::is_array_v<T>)
std::size_t AddVariableArray(const FNV1A_t uNameHash, const FNV1A_t uTypeHash, std::initializer_list<std::remove_pointer_t<std::decay_t<T>>> vecValuesDefault)
{
using BaseType_t = std::remove_pointer_t<std::decay_t<T>>;
T arrValueDefault;
CRT::MemorySet(arrValueDefault, 0U, sizeof(T));
CRT::MemoryCopy(arrValueDefault, vecValuesDefault.begin(), vecValuesDefault.size() * sizeof(BaseType_t));
vecVariables.emplace_back(uNameHash, uTypeHash, arrValueDefault);
return vecVariables.size() - 1U;
}
inline void RemoveVariable(const std::size_t nIndex)
{
vecVariables.erase(vecVariables.begin() + nIndex);
}
}

View File

@@ -0,0 +1,193 @@
// used: [stl] vector
#include <vector>
// used: [stl] find_if
#include <algorithm>
#include "convars.h"
// used: convar interface
#include "interfaces.h"
#include "../sdk/interfaces/ienginecvar.h"
// used: l_print
#include "../utilities/log.h"
// used: getworkingpath
#include "../core.h"
inline static void WriteConVarType(HANDLE hFile, const uint32_t nType)
{
switch ((EConVarType)nType)
{
case EConVarType_Bool:
::WriteFile(hFile, CS_XOR("[bool] "), CRT::StringLength(CS_XOR("[bool] ")), nullptr, nullptr);
break;
case EConVarType_Int16:
::WriteFile(hFile, CS_XOR("[int16] "), CRT::StringLength(CS_XOR("[int16] ")), nullptr, nullptr);
break;
case EConVarType_UInt16:
::WriteFile(hFile, CS_XOR("[uint16] "), CRT::StringLength(CS_XOR("[uint16] ")), nullptr, nullptr);
break;
case EConVarType_Int32:
::WriteFile(hFile, CS_XOR("[int32] "), CRT::StringLength(CS_XOR("[int32] ")), nullptr, nullptr);
break;
case EConVarType_UInt32:
::WriteFile(hFile, CS_XOR("[uint32] "), CRT::StringLength(CS_XOR("[uint32] ")), nullptr, nullptr);
break;
case EConVarType_Int64:
::WriteFile(hFile, CS_XOR("[int64] "), CRT::StringLength(CS_XOR("[int64] ")), nullptr, nullptr);
break;
case EConVarType_UInt64:
::WriteFile(hFile, CS_XOR("[uint64] "), CRT::StringLength(CS_XOR("[uint64] ")), nullptr, nullptr);
break;
case EConVarType_Float32:
::WriteFile(hFile, CS_XOR("[float32] "), CRT::StringLength(CS_XOR("[float32] ")), nullptr, nullptr);
break;
case EConVarType_Float64:
::WriteFile(hFile, CS_XOR("[float64] "), CRT::StringLength(CS_XOR("[float64] ")), nullptr, nullptr);
break;
case EConVarType_String:
::WriteFile(hFile, CS_XOR("[string] "), CRT::StringLength(CS_XOR("[string] ")), nullptr, nullptr);
break;
case EConVarType_Color:
::WriteFile(hFile, CS_XOR("[color] "), CRT::StringLength(CS_XOR("[color] ")), nullptr, nullptr);
break;
case EConVarType_Vector2:
::WriteFile(hFile, CS_XOR("[vector2] "), CRT::StringLength(CS_XOR("[vector2] ")), nullptr, nullptr);
break;
case EConVarType_Vector3:
::WriteFile(hFile, CS_XOR("[vector3] "), CRT::StringLength(CS_XOR("[vector3] ")), nullptr, nullptr);
break;
case EConVarType_Vector4:
::WriteFile(hFile, CS_XOR("[vector4] "), CRT::StringLength(CS_XOR("[vector4] ")), nullptr, nullptr);
break;
case EConVarType_Qangle:
::WriteFile(hFile, CS_XOR("[qangle] "), CRT::StringLength(CS_XOR("[qangle] ")), nullptr, nullptr);
break;
default:
::WriteFile(hFile, CS_XOR("[unknown-type] "), CRT::StringLength(CS_XOR("[unknown-type] ")), nullptr, nullptr);
break;
}
}
inline static void WriteConVarFlags(HANDLE hFile, const uint32_t nFlags)
{
if (nFlags & FCVAR_CLIENTDLL)
::WriteFile(hFile, CS_XOR("[client.dll] "), CRT::StringLength(CS_XOR("[client.dll] ")), nullptr, nullptr);
else if (nFlags & FCVAR_GAMEDLL)
::WriteFile(hFile, CS_XOR("[games's dll] "), CRT::StringLength(CS_XOR("[games's dll] ")), nullptr, nullptr);
if (nFlags & FCVAR_PROTECTED)
::WriteFile(hFile, CS_XOR("[protected] "), CRT::StringLength(CS_XOR("[protected] ")), nullptr, nullptr);
if (nFlags & FCVAR_CHEAT)
::WriteFile(hFile, CS_XOR("[cheat] "), CRT::StringLength(CS_XOR("[cheat] ")), nullptr, nullptr);
if (nFlags & FCVAR_HIDDEN)
::WriteFile(hFile, CS_XOR("[hidden] "), CRT::StringLength(CS_XOR("[hidden] ")), nullptr, nullptr);
if (nFlags & FCVAR_DEVELOPMENTONLY)
::WriteFile(hFile, CS_XOR("[devonly] "), CRT::StringLength(CS_XOR("[devonly] ")), nullptr, nullptr);
::WriteFile(hFile, CS_XOR("\n"), CRT::StringLength(CS_XOR("\n")), nullptr, nullptr);
}
bool CONVAR::Dump(const wchar_t* wszFileName)
{
wchar_t wszDumpFilePath[MAX_PATH];
if (!CORE::GetWorkingPath(wszDumpFilePath))
return false;
CRT::StringCat(wszDumpFilePath, wszFileName);
HANDLE hOutFile = ::CreateFileW(wszDumpFilePath, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hOutFile == INVALID_HANDLE_VALUE)
return false;
// @todo: maybe remove this redundant? and put it inside CRT::String_t c'tor
const std::time_t time = std::time(nullptr);
std::tm timePoint;
localtime_s(&timePoint, &time);
CRT::String_t<64> szTimeBuffer(CS_XOR("[%d-%m-%Y %T] asphyxia | convars dump\n\n"), &timePoint);
// write current date, time and info
::WriteFile(hOutFile, szTimeBuffer.Data(), szTimeBuffer.Length(), nullptr, nullptr);
for (int i = I::Cvar->listConvars.Head(); i != I::Cvar->listConvars.InvalidIndex(); i = I::Cvar->listConvars.Next(i))
{
CConVar* pConVar = I::Cvar->listConvars.Element(i);
if (pConVar != nullptr)
{
// dump to file
WriteConVarType(hOutFile, pConVar->nType);
CRT::String_t<526> szBuffer(CS_XOR("%s : \"%s\" "), pConVar->szName, pConVar->szDescription[0] == '\0' ? CS_XOR("no description") : pConVar->szDescription);
::WriteFile(hOutFile, szBuffer.Data(), szBuffer.Length(), nullptr, nullptr);
// write flags
WriteConVarFlags(hOutFile, pConVar->nFlags);
}
}
::CloseHandle(hOutFile);
return true;
}
bool CONVAR::Setup()
{
bool bSuccess = true;
m_pitch = I::Cvar->Find(FNV1A::HashConst("m_pitch"));
bSuccess &= m_pitch != nullptr;
m_yaw = I::Cvar->Find(FNV1A::HashConst("m_yaw"));
bSuccess &= m_yaw != nullptr;
sensitivity = I::Cvar->Find(FNV1A::HashConst("sensitivity"));
bSuccess &= sensitivity != nullptr;
game_type = I::Cvar->Find(FNV1A::HashConst("game_type"));
bSuccess &= game_type != nullptr;
game_mode = I::Cvar->Find(FNV1A::HashConst("game_mode"));
bSuccess &= game_mode != nullptr;
mp_teammates_are_enemies = I::Cvar->Find(FNV1A::HashConst("mp_teammates_are_enemies"));
bSuccess &= mp_teammates_are_enemies != nullptr;
sv_autobunnyhopping = I::Cvar->Find(FNV1A::HashConst("sv_autobunnyhopping"));
bSuccess &= sv_autobunnyhopping != nullptr;
cam_idealdist = I::Cvar->Find(FNV1A::HashConst("cam_idealdist")); // flaot
bSuccess &= cam_idealdist != nullptr;
cam_collision = I::Cvar->Find(FNV1A::HashConst("cam_collision")); // flaot
bSuccess &= cam_collision != nullptr;
cam_snapto = I::Cvar->Find(FNV1A::HashConst("cam_snapto")); // flaot
bSuccess &= cam_snapto != nullptr;
c_thirdpersonshoulder = I::Cvar->Find(FNV1A::HashConst("c_thirdpersonshoulder")); // flaot
bSuccess &= c_thirdpersonshoulder != nullptr;
c_thirdpersonshoulderaimdist = I::Cvar->Find(FNV1A::HashConst("c_thirdpersonshoulderaimdist")); // flaot
bSuccess &= c_thirdpersonshoulderaimdist != nullptr;
c_thirdpersonshoulderdist = I::Cvar->Find(FNV1A::HashConst("c_thirdpersonshoulderdist")); // flaot
bSuccess &= c_thirdpersonshoulderdist != nullptr;
c_thirdpersonshoulderheight = I::Cvar->Find(FNV1A::HashConst("c_thirdpersonshoulderheight")); // flaot
bSuccess &= c_thirdpersonshoulderheight != nullptr;
c_thirdpersonshoulderoffset = I::Cvar->Find(FNV1A::HashConst("c_thirdpersonshoulderoffset")); // flaot
bSuccess &= c_thirdpersonshoulderoffset != nullptr;
cl_interpolate = I::Cvar->Find(FNV1A::HashConst("cl_interpolate")); // flaot
bSuccess &= cl_interpolate != nullptr;
cl_interp_ratio = I::Cvar->Find(FNV1A::HashConst("cl_interp_ratio")); // flaot
bSuccess &= cl_interp_ratio != nullptr;
return bSuccess;
}

View File

@@ -0,0 +1,42 @@
#pragma once
class CConVar;
namespace CONVAR
{
// dump convars to file
bool Dump(const wchar_t* wszFileName);
// setup convars
bool Setup();
inline CConVar* m_pitch = nullptr;
inline CConVar* m_yaw = nullptr;
inline CConVar* sensitivity = nullptr;
inline CConVar* game_type = nullptr;
inline CConVar* game_mode = nullptr;
inline CConVar* mp_teammates_are_enemies = nullptr;
inline CConVar* sv_autobunnyhopping = nullptr;
inline CConVar* cam_idealdist = nullptr;
inline CConVar* cam_collision = nullptr;
inline CConVar* cam_snapto = nullptr;
inline CConVar* c_thirdpersonshoulder = nullptr;
inline CConVar* c_thirdpersonshoulderaimdist = nullptr;
inline CConVar* c_thirdpersonshoulderdist = nullptr;
inline CConVar* c_thirdpersonshoulderheight = nullptr;
inline CConVar* c_thirdpersonshoulderoffset = nullptr;
inline CConVar* cl_interpolate = nullptr;
inline CConVar* cl_interp_ratio = nullptr;
}

View File

@@ -0,0 +1,57 @@
#include "sigscan.hpp"
#include "../../utilities/log.h"
#include "../memory/memadd.h"
CSigScan::CSigScan(const char* name, const char* libraryName, const std::initializer_list<SigData_t>& data) {
#ifdef SDK_ENABLE_LOGGING
m_Name = name;
#else
m_Name = "";
#endif
m_LibraryName = libraryName;
m_Data.reserve(data.size());
m_Data.insert(m_Data.end(), data.begin(), data.end());
CSigScanManager::Get().ScheduleScan(this);
}
void CSigScan::FindSignature() {
auto& library = CMemory::GetModule(m_LibraryName);
if (!library) {
L_PRINT(LOG_WARNING) << CS_XOR("\"signature\" Couldn't find {} because {} was not loaded.");
}
for (size_t i = 0; i < m_Data.size(); ++i) {
// Faster than m_Data[] in debug builds because of _STL_VERIFY.
const auto& data = m_Data.data()[i];
m_Value = library->FindPattern(data.m_Signature);
if (m_Value.IsValid()) {
if (data.m_Procedure) {
data.m_Procedure(m_Value);
}
L_PRINT(LOG_INFO) << CS_XOR("\"signature\" Couldn't find " << m_Name << " because{} " << m_Value.Get<void*>() << "was not loaded " << i << " | index.");
}
}
L_PRINT(LOG_ERROR) << CS_XOR("\"signature\" Couldn't find ");
}
void CSigScanManager::ScheduleScan(CSigScan* sigScan) { m_ScheduledScans.emplace_back(sigScan); }
void CSigScanManager::ProcessScans() {
for (size_t i = 0; i < m_ScheduledScans.size(); ++i) {
// Faster than m_ScheduledScans[] in debug builds because of _STL_VERIFY.
const auto& scheduledScan = m_ScheduledScans.data()[i];
scheduledScan->FindSignature();
scheduledScan->FreeData();
}
// No need to keep the scans in memory if we're done with them.
std::vector<CSigScan*>().swap(m_ScheduledScans);
}

View File

@@ -0,0 +1,52 @@
#pragma once
#include "../pointer/pointer.hpp"
#include <span>
#include <functional>
class CSigScan {
public:
using ProcedureFn = std::function<void(CPointer&)>;
struct SigData_t {
std::span<const int> m_Signature;
ProcedureFn m_Procedure;
};
CSigScan(const char* name, const char* libraryName, const std::initializer_list<SigData_t>& data);
void FindSignature();
auto FreeData() { std::vector<SigData_t>().swap(m_Data); }
auto GetPtr() const { return m_Value; }
template <typename T>
auto GetPtrAs() const {
return m_Value.Get<T>();
}
CSigScan(const CSigScan&) = delete;
CSigScan& operator=(const CSigScan&) = delete;
private:
const char* m_Name;
const char* m_LibraryName;
std::vector<SigData_t> m_Data;
CPointer m_Value;
};
class CSigScanManager {
public:
static CSigScanManager& Get() {
static CSigScanManager inst;
return inst;
}
void ScheduleScan(CSigScan* sigScan);
void ProcessScans();
private:
std::vector<CSigScan*> m_ScheduledScans;
};

View File

@@ -0,0 +1,5 @@
#pragma once
namespace fnv1a {
constexpr uint32_t Hash(const char* str) noexcept { return (*str ? (Hash(str + 1) ^ *str) * 0x01000193 : 0x811c9dc5); }
} // namespace fnv1a

View File

@@ -0,0 +1,693 @@
#include "hooks.h"
// used: variables
#include "variables.h"
// used: game's sdk
#include "../sdk/interfaces/iswapchaindx11.h"
#include "../sdk/interfaces/iviewrender.h"
#include "../sdk/interfaces/cgameentitysystem.h"
#include "../sdk/interfaces/ccsgoinput.h"
#include "../sdk/interfaces/iinputsystem.h"
#include "../sdk/interfaces/iengineclient.h"
#include "../sdk/interfaces/inetworkclientservice.h"
#include "../sdk/interfaces/iglobalvars.h"
#include "../sdk/interfaces/imaterialsystem.h"
#include "../core/memory/cmodule.hpp"
#include "../features/visuals/overlay.h"
#include "../features/visuals/overlay.h"
#include "../features/legit/legit.h"
#include "../features/lagcomp/lagcomp.h"
#include "../features/skins/ccsinventorymanager.hpp"
#include "../cstrike/features/skins/skin_changer.hpp"
#include "../cstrike/features/antiaim/antiaim.hpp"
// used: viewsetup
#include "../sdk/datatypes/viewsetup.h"
// used: entity
#include "../sdk/entity.h"
// used: get virtual function, find pattern, ...
#include "../utilities/memory.h"
// used: inputsystem
#include "../utilities/inputsystem.h"
// used: draw
#include "../utilities/draw.h"
// used: features callbacks
#include "../features.h"
// used: game's interfaces
#include "interfaces.h"
#include "sdk.h"
// used: menu
#include "menu.h"
#define STB_OMIT_TESTS
#include "stb.hh"
#include "../sdk/interfaces/events.h"
#include "../cstrike/features/legit/legit.h"
#include "spoofcall/invoker.h"
#include "convars.h"
#include "../sdk/interfaces/ienginecvar.h"
#include "../cstrike/features/rage/rage.h"
#include "spoofcall/virtualization/VirtualizerSDK64.h"
#include <dxgi.h>
#include <d3d11.h>
#define SDK_SIG(sig) stb::simple_conversion::build<stb::fixed_string{sig}>::value
IDXGIDevice* pDXGIDevice = NULL;
IDXGIAdapter* pDXGIAdapter = NULL;
IDXGIFactory* pIDXGIFactory = NULL;
#define MEMORY_VARIABLE(var) var, "H::" #var
namespace sigs {
CSigScan GetHitboxSet("C_BaseEntity::GetHitboxSet", "client.dll",
{
{SDK_SIG("E8 ? ? ? ? 48 85 C0 0F 85 ? ? ? ? 44 8D 48 07"), [](CPointer& ptr) { ptr.Absolute(1, 0); }},
{SDK_SIG("41 8B D6 E8 ? ? ? ? 4C 8B F8"), [](CPointer& ptr) { ptr.Absolute(4, 0); }},
});
CSigScan GetBoneName("CModel::GetBoneName", "client.dll",
{
{SDK_SIG("48 8B CE E8 ? ? ? ? 48 8B 0F"), [](CPointer& ptr) { ptr.Offset(0x4); }},
});
CSigScan HitboxToWorldTransforms("C_BaseEntity::HitboxToWorldTransforms", "client.dll",
{
{SDK_SIG("E8 ? ? ? ? 4C 8B A3"), [](CPointer& ptr) { ptr.Absolute(1, 0); }},
});
CSigScan ComputeHitboxSurroundingBox("C_BaseEntity::ComputeHitboxSurroundingBox", "client.dll",
{
{SDK_SIG("E9 ? ? ? ? F6 43 5B FD"), [](CPointer& ptr) { ptr.Absolute(1, 0); }},
});
}
#define CS2_SDK_SIGs(sig) \
stb::simple_conversion::build<stb::fixed_string{sig}>::value
#define COMPUTE_HITBOX_SURROUNDING_BOX CS2_SDK_SIGs("E9 ? ? ? ? F6 43 5B FD")
bool H::Setup()
{
VIRTUALIZER_MUTATE_ONLY_START;
if (MH_Initialize() != MH_OK)
{
L_PRINT(LOG_ERROR) << CS_XOR("failed to initialize minhook");
return false;
}
L_PRINT(LOG_INFO) << CS_XOR("Initializing ShadowVMT & SilentInlineHoooking");
SilenthkPresent.Setup(I::SwapChain->pDXGISwapChain);
SilenthkPresent.HookIndex((int)VTABLE::D3D::PRESENT, Present);
SilenthkPresent.HookIndex((int)VTABLE::D3D::RESIZEBUFFERS, ResizeBuffers);
I::Device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice));
pDXGIDevice->GetAdapter(&pDXGIAdapter);
pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory));
Silentdxgi.Setup(pIDXGIFactory);
Silentdxgi.HookIndex((int)VTABLE::DXGI::CREATESWAPCHAIN, CreateSwapChain);
if (pDXGIDevice) {
pDXGIDevice->Release();
pDXGIDevice = nullptr;
}
if (pDXGIAdapter) {
pDXGIAdapter->Release();
pDXGIAdapter = nullptr;
}
if (pIDXGIFactory) {
pIDXGIFactory->Release();
pIDXGIFactory = nullptr;
}
// fnGetClientSystem = reinterpret_cast<CGCClientSystem*>(MEM::ResolveRelativeAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("E8 ? ? ? ? 48 8B 4F 10 8B 1D ? ? ? ?")), 0x1, 0x0));
// L_PRINT(LOG_INFO) << CS_XOR("captured fnGetClientSystem \"") << CS_XOR("\" interface at address: ") << L::AddFlags(LOG_MODE_INT_SHOWBASE | LOG_MODE_INT_FORMAT_HEX) << reinterpret_cast<std::uintptr_t>(fnGetClientSystem);
MEM::FindPatterns(CLIENT_DLL, CS_XOR("E8 ? ? ? ? 48 8B 4F 10 8B 1D ? ? ? ?")).ToAbsolute(1, 0).Get(MEMORY_VARIABLE(fnGetClientSystem));
MEM::FindPatterns(CLIENT_DLL, CS_XOR("48 83 EC 28 B9 ? ? ? ? E8 ? ? ? ? 48 85 C0 74 3A 48 8D 0D ? ? ? ? C7 40 ? ? ? ? ?")).Get(MEMORY_VARIABLE(fnCreateSharedObjectSubclassEconItem));
MEM::FindPatterns(CLIENT_DLL, CS_XOR("E9 ? ? ? ? CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC 49 8B C0 48")).ToAbsolute(1, 0).Get(MEMORY_VARIABLE(fnSetDynamicAttributeValueUint));
MEM::FindPatterns(CLIENT_DLL, CS_XOR("E8 ? ? ? ? 48 63 BB ? ? ? ? 48 8D 68 28 83 FF FF")).ToAbsolute(1, 0).Get(MEMORY_VARIABLE(fnGetInventoryManager));
MEM::FindPatterns(CLIENT_DLL, CS_XOR("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 48 8D 99 60")).Get(MEMORY_VARIABLE(SetMeshGroupMask));
MEM::FindPatterns(CLIENT_DLL, CS_XOR("48 89 5C 24 10 48 89 6C 24 18 56 57 41 57 48 83 EC 20 83 79 10 00 49 8B F1 41 8B E8 4C 8B FA 48 8B D9 74 72 44 8B 49 14 48 8B 39 41 FF C9 45 8B D9 45 23 D8 41")).Get(MEMORY_VARIABLE(fnFindMaterialIndex));
SilentEntitySystem.Setup(I::GameResourceService->pGameEntitySystem);
SilentEntitySystem.HookIndex(14, OnAddEntity);
SilentEntitySystem.HookIndex(15, OnRemoveEntity);
SilentInput.Setup(I::Input);
SilentInput.HookIndex((int)VTABLE::CLIENT::MOUSEINPUTENABLED, MouseInputEnabled);
SilentInput.HookIndex((int)VTABLE::CLIENT::CREATEMOVE, CreateMove);
spoof_call<void>(_fake_addr, &EntCache::CacheCurrentEntities);
// @ida: class CViewRender->OnRenderStart call GetMatricesForView
CS_ASSERT(hkGetMatrixForView.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("40 53 48 81 EC ? ? ? ? 49 8B C1")), reinterpret_cast<void*>(&GetMatrixForView)));
CS_ASSERT(hkSetViewModelFOV.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("40 53 48 83 EC 30 33 C9 E8 ? ? ? ? 48 8B D8 48 85 C0 0F 84 ? ? ? ? 48 8B 00 48 8B CB FF 90 ? ? ? ? 84 C0 0F 84 ? ? ? ? 48 8B CB")), reinterpret_cast<float*>(&SetViewModelFOV)));
CS_ASSERT(hkFOVObject.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("40 53 48 81 EC 80 00 00 00 48 8B D9 E8 ?? ?? ?? ?? 48 85")), reinterpret_cast<float*>(&GetRenderFov)));
CS_ASSERT(hkInputParser.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 8B C4 4C 89 48 20 55 56 41 56 48 8D 68 B1 48 81 EC D0 00 00 00")), reinterpret_cast<void*>(&InputParser)));
// client.dll; 40 55 53 41 55 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 02
CS_ASSERT(hkGameEvents.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("40 55 53 41 55 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 02")), reinterpret_cast<void*>(&HandleGameEvents)));
// I could just do VTABLE too idx: 15
//CS_ASSERT(hkPredictionSimulation.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 8B C4 4C 89 40 18 48 89 48 08 55 53 56 57 48")), reinterpret_cast<void*>(&PredictionSimulation)));
// @ida: ClientModeShared -> #STR: "mapname", "transition", "game_newmap"
CS_ASSERT(hkLevelInit.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 ? 56 48 83 EC ? 48 8B 0D ? ? ? ? 48 8B F2")), reinterpret_cast<void*>(&LevelInit)));
// @ida: ClientModeShared -> #STR: "map_shutdown"
CS_ASSERT(hkLevelShutdown.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 83 EC ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 45 33 C9 45 33 C0 48 8B 01 FF 50 ? 48 85 C0 74 ? 48 8B 0D ? ? ? ? 48 8B D0 4C 8B 01 48 83 C4 ? 49 FF 60 ? 48 83 C4 ? C3 CC CC CC 48 83 EC ? 4C 8B D9")), reinterpret_cast<void*>(&LevelShutdown)));
CS_ASSERT(hkDrawObject.Create(MEM::FindPattern(SCENESYSTEM_DLL, CS_XOR("48 8B C4 48 89 50 ? 55 41 56")), reinterpret_cast<void*>(&DrawObject)));
//CS_ASSERT(hkCameraInput.Create(MEM::GetVFunc(I::Input, VTABLE::CLIENT::CAMERA), reinterpret_cast<void*>(&CameraInput)));
//CS_ASSERT(hkSendInputMessage.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 81 EC ? ? ? ? 49 8B D9")), reinterpret_cast<void*>(&SendNetInputMessage)));
CS_ASSERT(hkFrameStageNotify.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 10 56 48 83 EC 30 8B 05")), reinterpret_cast<void*>(&FrameStageNotify)));
CS_ASSERT(hkSetModel.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 10 48 89 7C 24 20 55 48 8B EC 48 83 EC 50")), reinterpret_cast<void*>(&SetModel)));
CS_ASSERT(hkEquipItemInLoadout.Create(MEM::GetVFunc(CCSInventoryManager::GetInstance(), 54u), reinterpret_cast<void*>(&EquipItemInLoadout)));
CS_ASSERT(hkOverrideView.Create(MEM::GetVFunc(I::Input, 9u), reinterpret_cast<void*>(&OverrideView)));
CS_ASSERT(hkAllowCameraChange.Create(MEM::GetVFunc(I::Input, 7u), reinterpret_cast<void*>(&AllowCameraAngleChange)));
//CS_ASSERT(hkPreFireEvent.Create(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 5C 24 ? 56 57 41 54 48 83 EC 30 48 8B F2")), reinterpret_cast<void*>(&FireEventClientSide)));
F::RAGE::rage->BuildSeed();
F::LAGCOMP::lagcomp->Initialize();
//F::LAGCOMP::lagcomp->Initialize();
VIRTUALIZER_MUTATE_ONLY_END;
return true;
}
void H::Destroy()
{
skin_changer::Shutdown();
MH_DisableHook(MH_ALL_HOOKS);
MH_RemoveHook(MH_ALL_HOOKS);
MH_Uninitialize();
SilenthkPresent.UnhookAll();
Silentdxgi.UnhookAll();
SilentInput.UnhookAll();
SilentEntitySystem.UnhookAll();
}
// client.dll; 40 55 53 41 55 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 02
// xref: "winpanel-basic-round-result-visible"
using namespace F::RAGE;
void* CS_FASTCALL H::InputParser(CCSInputMessage* Input, CCSGOInputHistoryEntryPB* InputHistoryEntry, char a3, void* a4, void* a5, void* a6)
{
auto original = hkInputParser.GetOriginal();
auto result = original(Input, InputHistoryEntry, a3, a4, a5, a6);
if (!SDK::Cmd)
return result;
if (I::Engine->IsConnected() || I::Engine->IsInGame() && SDK::LocalPawn && SDK::LocalPawn->GetHealth() > 0 ) {
if (rage->sub_tick_data.command == F::RAGE::impl::command_msg::silent) {
// modify predicted sub tick viewangles to our rage bestpoint forcing silent w predicted cmds
Input->m_view_angles = rage->sub_tick_data.best_point_vec;
Input->m_view_angles.clamp();
InputHistoryEntry->m_pViewCmd->m_angValue = rage->sub_tick_data.best_point;
InputHistoryEntry->m_pViewCmd->m_angValue.Clamp();
rage->sub_tick_data.response = impl::response_msg::validated_view_angles;
}
else
rage->sub_tick_data.response = impl::response_msg::empty;
if (F::RAGE::rage->rage_data.rapid_fire) {
if (rage->sub_tick_data.command == impl::command_msg::rapid_fire) {
// override angles just to prevent
Input->m_view_angles = rage->sub_tick_data.best_point_vec;
Input->m_view_angles.clamp();
InputHistoryEntry->m_pViewCmd->m_angValue = rage->sub_tick_data.best_point;
InputHistoryEntry->m_pViewCmd->m_angValue.Clamp();
// override tickcount
InputHistoryEntry->m_nPlayerTickCount = 0;
Input->m_player_tick_count = 0;
// perform shooting
SDK::Cmd->m_nButtons.m_nValue |= IN_ATTACK;
}
else
SDK::Cmd->m_nButtons.m_nValue &= ~IN_ATTACK;
}
if (rage->sub_tick_data.command == impl::command_msg::teleport) {
// overflow viewangles
// send new msg to sv
// maybe change our shoot pos? idk
}
}
return result;
}
//40 53 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 C7 83 D0
void CS_FASTCALL H::CameraInput(void* Input, int a1) {
//auto horiginal = hkCameraInput.GetOriginal();
//if (!I::Engine->IsConnected() || !I::Engine->IsInGame() || !SDK::LocalPawn || !cheat->alive)
// return horiginal(Input, a1);
//auto backup = *(Vector_t*)((uintptr_t)Input + 0x5390);
//// store old camera angles
//// call original
//horiginal(Input, a1);
//*(Vector_t*)((uintptr_t)Input + 0x5390) = backup;
}
float CS_FASTCALL H::GetRenderFov(uintptr_t rcx)
{
const auto oFOV = hkFOVObject.GetOriginal();
if (!I::Engine->IsConnected() || !I::Engine->IsInGame())
{
oFOV(rcx);
}
else if (!SDK::LocalController || !SDK::LocalController->IsPawnAlive()) // Checking if your spectating and alive
{
oFOV(rcx);
}
else
{
auto localPlayerController = SDK::LocalController;
auto localPlayerPawn = I::GameResourceService->pGameEntitySystem->Get<C_CSPlayerPawn>(localPlayerController->GetPawnHandle());
if (C_GET(bool, Vars.bFOV) && !localPlayerPawn->IsScoped())
{
return C_GET(float, Vars.fFOVAmount);
}
else
{
oFOV(rcx);
}
}
}
float CS_FASTCALL H::SetViewModelFOV()
{
const auto oSetViewModelFOV = hkSetViewModelFOV.GetOriginal();
if (C_GET(float, Vars.flSetViewModelFOV) == 0.f)
return oSetViewModelFOV();
return C_GET(float, Vars.flSetViewModelFOV);
}
// client.dll; 40 55 53 41 55 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 02
// xref: "winpanel-basic-round-result-visible"
void CS_FASTCALL H::HandleGameEvents(void* rcx, IGameEvent* const ev)
{
const auto original = hkGameEvents.GetOriginal();
if (!I::Engine->IsConnected() || !I::Engine->IsInGame() || !SDK::LocalPawn || !cheat->alive)
return original(rcx, ev);
switch (const char* event_name{ ev->GetName() }; FNV1A::Hash(event_name)) {
case FNV1A::HashConst(CS_XOR("player_death")): {
auto controller = SDK::LocalController;
if (!controller)
break;
const auto event_controller = ev->get_player_controller("attacker");
if (!event_controller)
return;
skin_changer::OnPreFireEvent(ev);
F::LEGIT::legit->Events(ev, F::LEGIT::events::player_death);
} break;
case FNV1A::HashConst(CS_XOR("round_start")): {
auto controller = SDK::LocalController;
if (!controller)
break;
// fix skins not showing up on round start event
Vars.full_update = true;
// reset some shit related to legitbot
F::LEGIT::legit->Events(ev, F::LEGIT::events::round_start);
} break;
default:
break;
}
original(rcx, ev);
}
bool init = false;
HRESULT __stdcall H::Present(IDXGISwapChain* pSwapChain, UINT uSyncInterval, UINT uFlags)
{
auto hResult = SilenthkPresent.GetOg<decltype(&Present)>((int)VTABLE::D3D::PRESENT);
if (!init && I::RenderTargetView == nullptr)
{
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&I::Device)))
{
I::Device->GetImmediateContext(&I::DeviceContext);
DXGI_SWAP_CHAIN_DESC sd;
pSwapChain->GetDesc(&sd);
IPT::hWindow = sd.OutputWindow;
ID3D11Texture2D* pBackBuffer;
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
I::Device->CreateRenderTargetView(pBackBuffer, NULL, &I::RenderTargetView);
pBackBuffer->Release();
D::InitImGui();
init = true;
}
else
return hResult(pSwapChain, uSyncInterval, uFlags);
}
D::Render();
return hResult(pSwapChain, uSyncInterval, uFlags);
}
#include"../dependencies/imgui/imgui_impl_dx11.h"
#include"../dependencies/imgui/imgui_impl_win32.h"
HRESULT CS_FASTCALL H::ResizeBuffers(IDXGISwapChain* pSwapChain, std::uint32_t nBufferCount, std::uint32_t nWidth, std::uint32_t nHeight, DXGI_FORMAT newFormat, std::uint32_t nFlags)
{
ImGui_ImplDX11_InvalidateDeviceObjects();
auto hResult = SilenthkPresent.GetOg<decltype(&ResizeBuffers)>((int)VTABLE::D3D::RESIZEBUFFERS);
if (SUCCEEDED(hResult))
I::CreateRenderTarget(pSwapChain);
return hResult(pSwapChain, nBufferCount, nWidth, nHeight, newFormat, nFlags);
}
HRESULT __stdcall H::CreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain)
{
auto hResult = Silentdxgi.GetOg<decltype(&CreateSwapChain)>((int)VTABLE::DXGI::CREATESWAPCHAIN);
I::DestroyRenderTarget();
L_PRINT(LOG_INFO) << CS_XOR("render target view has been destroyed");
return hResult(pFactory, pDevice, pDesc, ppSwapChain);
}
long H::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (D::OnWndProc(hWnd, uMsg, wParam, lParam))
return 1L;
return ::CallWindowProcW(IPT::pOldWndProc, hWnd, uMsg, wParam, lParam);
}
void* CS_FASTCALL H::OnAddEntity(void* rcx, CEntityInstance* pInstance, CBaseHandle hHandle) {
spoof_call<void>(_fake_addr, EntCache::OnAddEntity, pInstance, hHandle);
return SilentEntitySystem.GetOg<decltype(&OnAddEntity)>(14)(rcx, pInstance, hHandle);
}
void* CS_FASTCALL H::OnRemoveEntity(void* rcx, CEntityInstance* pInstance, CBaseHandle hHandle) {
spoof_call<void>(_fake_addr, EntCache::OnRemoveEntity, pInstance, hHandle);
return SilentEntitySystem.GetOg<decltype(&OnRemoveEntity)>(15)(rcx, pInstance, hHandle);
}
ViewMatrix_t* CS_FASTCALL H::GetMatrixForView(CRenderGameSystem* pRenderGameSystem, IViewRender* pViewRender, ViewMatrix_t* pOutWorldToView, ViewMatrix_t* pOutViewToProjection, ViewMatrix_t* pOutWorldToProjection, ViewMatrix_t* pOutWorldToPixels)
{ // Call the original function
const auto oGetMatrixForView = hkGetMatrixForView.GetOriginal();
ViewMatrix_t* matResult = oGetMatrixForView(pRenderGameSystem, pViewRender, pOutWorldToView, pOutViewToProjection, pOutWorldToProjection, pOutWorldToPixels); // get view matrix
SDK::ViewMatrix = *pOutWorldToProjection;
// get camera position
// @note: ida @GetMatrixForView(global_pointer, pRenderGameSystem + 16, ...)
SDK::CameraPosition = pViewRender->vecOrigin;
// keep bounding box updated
if (I::Engine->IsConnected() && I::Engine->IsInGame())
spoof_call<void>(_fake_addr, &F::VISUALS::OVERLAY::CalculateBoundingBoxes);
return matResult;
}
// SendNetInputMessage - 48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 81 EC ? ? ? ? 49 8B D9
int64_t CS_FASTCALL H::SendNetInputMessage(CNetInputMessage* a1, int64_t a2, int64_t a3, int64_t a4, int64_t a5, int64_t a6)
{
const auto bres = hkSendInputMessage.GetOriginal();
return bres(a1, a2, a3, a4, a5, a6);
}
#include "..\cstrike\sdk\datatypes\usercmd.h"
#include "../features/misc.h"
#include "../features/misc/movement.h"
void H::AllowCameraAngleChange(CCSGOInput* pCSGOInput, int a2)
{
const auto Original = hkAllowCameraChange.GetOriginal();
if (!I::Engine->IsInGame() || !I::Engine->IsConnected() || pCSGOInput == nullptr)
return Original(pCSGOInput, a2);
CUserCmd* pCmd = pCSGOInput->GetUserCmd();
if (pCmd == nullptr)
return Original(pCSGOInput, a2);
QAngle_t angOriginalAngle = pCmd->m_csgoUserCmd.m_pBaseCmd->m_pViewangles->m_angValue;
pCmd->m_csgoUserCmd.m_pBaseCmd->m_pViewangles->m_angValue = F::ANTIAIM::angStoredViewBackup;
Original(pCSGOInput, a2);
pCmd->m_csgoUserCmd.m_pBaseCmd->m_pViewangles->m_angValue = angOriginalAngle;
}
bool CS_FASTCALL H::CreateMove(CCSGOInput* pInput, int nSlot, bool nUnk, std::byte nUnk2)
{
const bool bResult = SilentInput.GetOg<decltype(&CreateMove)>((int)VTABLE::CLIENT::CREATEMOVE)(pInput, nSlot, nUnk, nUnk2);
if (!I::Engine->IsConnected() || !I::Engine->IsInGame())
return bResult;
CUserCmd* pCmd = SDK::Cmd = pInput->GetUserCmd();
if (pCmd == nullptr)
return bResult;
F::ANTIAIM::angStoredViewBackup = pCmd->m_csgoUserCmd.m_pBaseCmd->m_pViewangles->m_angValue;
SDK::LocalController = CCSPlayerController::GetLocalPlayerController();
if (SDK::LocalController == nullptr)
return bResult;
SDK::LocalPawn = I::GameResourceService->pGameEntitySystem->Get<C_CSPlayerPawn>(SDK::LocalController->GetPawnHandle());
if (SDK::LocalPawn == nullptr)
return bResult;
F::ANTIAIM::RunAA(pCmd);
cheat->alive = SDK::LocalPawn->GetHealth() > 0 && SDK::LocalPawn->GetLifeState() != ELifeState::LIFE_DEAD;
cheat->onground = (SDK::LocalPawn->GetFlags() & FL_ONGROUND);
cheat->canShot = SDK::LocalPawn->CanShoot(I::GlobalVars->nTickCount);
if (cheat->alive) {
auto network = I::NetworkClientService->GetNetworkClient();
if (network && Vars.full_update) {
network->Update();
Vars.full_update = false;
}
// process legit bot
if (C_GET(bool, Vars.legit_enable)) {
F::LEGIT::legit->SetupAdaptiveWeapon(SDK::LocalPawn);
F::LEGIT::legit->Run(pCmd);
}
F::LAGCOMP::lagcomp->Start(pCmd);
// we should run engine pred here for movement features etc
// in order to predict ( velocity, flags, origin )
// setup menu adaptive weapon with rage data
if (C_GET(bool, Vars.rage_enable)) {
F::RAGE::rage->SetupAdaptiveWeapon(SDK::LocalPawn);
F::RAGE::rage->Run(SDK::LocalPawn, pInput, pCmd);
}
F::MISC::MOVEMENT::ProcessMovement(pCmd, SDK::LocalController, SDK::LocalPawn);
}
return bResult;
}
#include "../features/misc/movement.h"
void CS_FASTCALL H::PredictionSimulation(CCSGOInput* pInput, int nSlot, CUserCmd* pCmd)
{
static auto bResult = SilentInput.GetOg<decltype(&PredictionSimulation)>((int)VTABLE::CLIENT::PREDICTION);
if (!I::Engine->IsConnected() || !I::Engine->IsInGame())
return bResult(pInput, nSlot, pCmd);
CUserCmd* commandnr = pInput->GetUserCmd();
if (commandnr == nullptr)
return bResult(pInput, nSlot, pCmd);
auto predicted_local_controller = CCSPlayerController::GetLocalPlayerController();
if (predicted_local_controller == nullptr)
return bResult(pInput, nSlot, pCmd);
auto pred = I::GameResourceService->pGameEntitySystem->Get<C_CSPlayerPawn>(predicted_local_controller->m_hPredictedPawn());
if (pred == nullptr)
return bResult(pInput, nSlot, pCmd);
// run auto stop w predicted cmd
// F::RAGE::rage->AutomaticStop(pred, pred->ActiveWeapon(), pCmd);
// fix our command number members for predicted values (move correction etc)
return bResult(pInput, nSlot, pCmd);
}
double CS_FASTCALL H::WeaponAcurracySpreadClientSide(void* a1) {
static auto fnWeaponAcurracySpreadClientSide = hkWeapoSpreadClientSide.GetOriginal();
if (C_GET(bool, Vars.remove_weapon_accuracy_spread))
return 0.0;
return fnWeaponAcurracySpreadClientSide(a1);
}
double CS_FASTCALL H::WeaponAcurracySpreadServerSide(void* a1) {
static auto fnWeaponAcurracySpreadServerSide = hkWeapoSpreadServerSide.GetOriginal();
if (C_GET(bool, Vars.remove_weapon_accuracy_spread))
return 0.0;
return fnWeaponAcurracySpreadServerSide(a1);
}
bool CS_FASTCALL H::FireEventClientSide(void* rcx, IGameEvent* event, bool bServerOnly)
{
const auto oPreFire = hkPreFireEvent.GetOriginal();
return oPreFire(rcx, event, bServerOnly);
}
bool CS_FASTCALL H::MouseInputEnabled(void* pThisptr)
{
return MENU::bMainWindowOpened ? false : SilentInput.GetOg<decltype(&MouseInputEnabled)>((int)VTABLE::CLIENT::MOUSEINPUTENABLED)(pThisptr);
}
void CS_FASTCALL H::SetModel(void* rcx, const char* model) {
const auto oSetModel = hkSetModel.GetOriginal();
skin_changer::OnSetModel((C_BaseModelEntity*)rcx, model);
return oSetModel(rcx, model);
}
bool CS_FASTCALL H::EquipItemInLoadout(void* rcx, int iTeam, int iSlot,
uint64_t iItemID) {
const auto oEquipItemInLoadout = hkEquipItemInLoadout.GetOriginal();
skin_changer::OnEquipItemInLoadout(iTeam, iSlot, iItemID);
return oEquipItemInLoadout(rcx, iTeam, iSlot, iItemID);
}
void CS_FASTCALL H::FrameStageNotify(void* rcx, int nFrameStage)
{
const auto oFrameStageNotify = hkFrameStageNotify.GetOriginal();
if (I::Engine->IsConnected() && I::Engine->IsInGame())
skin_changer::OnFrameStageNotify(nFrameStage);
return oFrameStageNotify(rcx, nFrameStage);
}
__int64* CS_FASTCALL H::LevelInit(void* pClientModeShared, const char* szNewMap)
{
const auto oLevelInit = hkLevelInit.GetOriginal();
// if global variables are not captured during I::Setup or we join a new game, recapture it
if (I::GlobalVars == nullptr)
I::GlobalVars = *reinterpret_cast<IGlobalVars**>(MEM::ResolveRelativeAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 0D ? ? ? ? 48 89 41")), 0x3, 0x7));
return oLevelInit(pClientModeShared, szNewMap);
}
//0x8D4C00000D1C8310
// client.dll 7FFB83FD0000
__int64 CS_FASTCALL H::LevelShutdown(void* pClientModeShared)
{
const auto oLevelShutdown = hkLevelShutdown.GetOriginal();
// reset global variables since it got discarded by the game
I::GlobalVars = nullptr;
return oLevelShutdown(pClientModeShared);
}
void CS_FASTCALL H::OverrideView(void* pClientModeCSNormal, CViewSetup* pSetup)
{
const auto oOverrideView = hkOverrideView.GetOriginal();
if (!I::Engine->IsConnected() || !I::Engine->IsInGame())
return hkOverrideView.GetOriginal()(pClientModeCSNormal, pSetup);
if (!SDK::LocalController->IsPawnAlive() || !SDK::LocalController)
return hkOverrideView.GetOriginal()(pClientModeCSNormal, pSetup);
static auto progress = 0.f;
if (C_GET(bool, Vars.bThirdperson))
{
auto bezier = [](const float t)
{
return t * t * (3.0f - 2.0f * t);
};
progress = MATH::clamp(progress + I::GlobalVars->flFrameTime * 6.f, 40.f / C_GET(float, Vars.flThirdperson), 1.f);
CONVAR::cam_idealdist->value.fl = C_GET(float, Vars.flThirdperson) * (C_GET(bool, Vars.bThirdpersonNoInterp) ? 1.f : bezier(progress));
CONVAR::cam_collision->value.i1 = true;
CONVAR::cam_snapto->value.i1 = true;
CONVAR::c_thirdpersonshoulder->value.i1 = true;
CONVAR::c_thirdpersonshoulderaimdist->value.fl = 0.f;
CONVAR::c_thirdpersonshoulderdist->value.fl = 0.f;
CONVAR::c_thirdpersonshoulderheight->value.fl = 0.f;
CONVAR::c_thirdpersonshoulderoffset->value.fl = 0.f;
I::Input->bInThirdPerson = true;
}
else
{
progress = C_GET(bool, Vars.bThirdperson) ? 1.f : 0.f;
I::Input->bInThirdPerson = false;
}
oOverrideView(pClientModeCSNormal, pSetup);
}
//8D4C7FFB91198310
void CS_FASTCALL H::DrawObject(void* pAnimatableSceneObjectDesc, void* pDx11, material_data_t* arrMeshDraw, int nDataCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2)
{
const auto oDrawObject = hkDrawObject.GetOriginal();
if (!I::Engine->IsConnected() || !I::Engine->IsInGame())
return oDrawObject(pAnimatableSceneObjectDesc, pDx11, arrMeshDraw, nDataCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (SDK::LocalController == nullptr || SDK::LocalPawn == nullptr)
return oDrawObject(pAnimatableSceneObjectDesc, pDx11, arrMeshDraw, nDataCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!F::OnDrawObject(pAnimatableSceneObjectDesc, pDx11, arrMeshDraw, nDataCount, pSceneView, pSceneLayer, pUnk, pUnk2))
oDrawObject(pAnimatableSceneObjectDesc, pDx11, arrMeshDraw, nDataCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}

View File

@@ -0,0 +1,150 @@
#pragma once
// used: [d3d] api
#include <d3d11.h>
#include <dxgi1_2.h>
// used: chookobject
#include "../utilities/detourhook.h"
#include "..\sdk\entity_handle.h"
// used: viewmatrix_t
#include "../sdk/datatypes/matrix.h"
#include "../core/sdk.h"
#include "../sdk/entity.h"
#include "../core/silentvmt/ShadowVMT.h"
#include "../core/silentvmt/InlineHook.h"
namespace VTABLE
{
namespace D3D
{
enum
{
PRESENT = 8U,
RESIZEBUFFERS = 13U,
RESIZEBUFFERS_CSTYLE = 39U,
};
}
namespace DXGI
{
enum
{
CREATESWAPCHAIN = 10U,
};
}
namespace CLIENT
{
enum
{
CREATEMOVE = 5U,
CAMERA = 7U,
PREDICTION = 15U,
MOUSEINPUTENABLED = 14U,
FRAMESTAGENOTIFY = 33U,
};
}
namespace INVENTORY
{
enum {
EQUIPITEMLOADOUT = 54U,
};
}
}
class CNetInputMessage;
class CRenderGameSystem;
class IViewRender;
class CCSGOInput;
class CViewSetup;
class IGameEvent;
class C_BaseModelEntity;
class material_data_t;
class CGCClientSystem;
class CGCClientSharedObjectTypeCache;
class CCSGOInputHistoryEntryPB;
class CCSInputMessage;
namespace sigs {
extern CSigScan GetHitboxSet;
extern CSigScan HitboxToWorldTransforms;
extern CSigScan ComputeHitboxSurroundingBox;
extern CSigScan GetBoneName;
} // namespace signatures
namespace H
{
bool Setup();
void Destroy();
/* @section: handlers */
// d3d11 & wndproc
HRESULT WINAPI Present(IDXGISwapChain* pSwapChain, UINT uSyncInterval, UINT uFlags);
HRESULT CS_FASTCALL ResizeBuffers(IDXGISwapChain* pSwapChain, std::uint32_t nBufferCount, std::uint32_t nWidth, std::uint32_t nHeight, DXGI_FORMAT newFormat, std::uint32_t nFlags);
HRESULT WINAPI CreateSwapChain(IDXGIFactory* pFactory, IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain);
long CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// game's functions
ViewMatrix_t* CS_FASTCALL GetMatrixForView(CRenderGameSystem* pRenderGameSystem, IViewRender* pViewRender, ViewMatrix_t* pOutWorldToView, ViewMatrix_t* pOutViewToProjection, ViewMatrix_t* pOutWorldToProjection, ViewMatrix_t* pOutWorldToPixels);
bool CS_FASTCALL CreateMove(CCSGOInput* pInput, int nSlot, bool nUnk, std::byte nUnk2);
void CS_FASTCALL PredictionSimulation(CCSGOInput* pInput, int nSlot, CUserCmd* cmd);
void CS_FASTCALL AllowCameraAngleChange(CCSGOInput* pCSGOInput, int a2);
double CS_FASTCALL WeaponAcurracySpreadServerSide(void* a1);
bool CS_FASTCALL FireEventClientSide(void* rcx, IGameEvent* event, bool bServerOnly);
double CS_FASTCALL WeaponAcurracySpreadClientSide(void* a1);
bool CS_FASTCALL EquipItemInLoadout(void* rcx, int iTeam, int iSlot, uint64_t iItemID);
bool CS_FASTCALL MouseInputEnabled(void* pThisptr);
void* CS_FASTCALL OnAddEntity(void* rcx, CEntityInstance* pInstance, CBaseHandle hHandle);
void* CS_FASTCALL OnRemoveEntity(void* rcx, CEntityInstance* pInstance, CBaseHandle hHandle);
void CS_FASTCALL FrameStageNotify(void* rcx, int nFrameStage);
__int64* CS_FASTCALL LevelInit(void* pClientModeShared, const char* szNewMap);
__int64 CS_FASTCALL LevelShutdown(void* pClientModeShared);
void CS_FASTCALL OverrideView(void* pClientModeCSNormal, CViewSetup* pSetup);
void CS_FASTCALL DrawObject(void* pAnimatableSceneObjectDesc, void* pDx11, material_data_t* arrMeshDraw, int nDataCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2);
void CS_FASTCALL HandleGameEvents(void* rcx, IGameEvent* const event);
void CS_FASTCALL SetModel(void* rcx, const char* model_name);
int64_t CS_FASTCALL SendNetInputMessage(CNetInputMessage* a1, int64_t a2, int64_t a3, int64_t a4, int64_t a5, int64_t a6);
void CS_FASTCALL CameraInput(void* Input, int a1);
float CS_FASTCALL SetViewModelFOV();
float CS_FASTCALL GetRenderFov(uintptr_t rcx);
void* CS_FASTCALL InputParser(CCSInputMessage* a1, CCSGOInputHistoryEntryPB* a2, char a3, void* a4, void* a5, void* a6);
inline ShadowVMT SilenthkPresent{ };
inline ShadowVMT Silentdxgi{ };
inline ShadowVMT SilentInput{ };
inline ShadowVMT SilentEntitySystem{ };
inline ShadowVMT SilentInvetoryManager{ };
inline CCSInventoryManager* (*fnGetInventoryManager)();
inline CGCClientSystem* (*fnGetClientSystem)();
inline void* (CS_FASTCALL* fnSetDynamicAttributeValueUint)(void*, void*,
void*);
inline CEconItem* (*fnCreateSharedObjectSubclassEconItem)();
inline void(CS_FASTCALL* SetMeshGroupMask)(void*, uint64_t);
inline int(CS_FASTCALL* fnFindMaterialIndex)(void*, void*, int, bool);
inline CBaseHookObject<decltype(&GetMatrixForView)> hkGetMatrixForView = {};
inline CBaseHookObject<decltype(&SetViewModelFOV)> hkSetViewModelFOV = {};
inline CBaseHookObject<decltype(&GetRenderFov)> hkFOVObject = {};
inline CBaseHookObject<decltype(&HandleGameEvents)> hkGameEvents = {};
inline CBaseHookObject<decltype(&LevelInit)> hkLevelInit = {};
inline CBaseHookObject<decltype(&DrawObject)> hkDrawObject = {};
inline CBaseHookObject<decltype(&LevelShutdown)> hkLevelShutdown = {};
inline CBaseHookObject<decltype(&WeaponAcurracySpreadClientSide)> hkWeapoSpreadClientSide = {};
inline CBaseHookObject<decltype(&WeaponAcurracySpreadServerSide)> hkWeapoSpreadServerSide = {};
inline CBaseHookObject<decltype(&FireEventClientSide)> hkPreFireEvent = {};
inline CBaseHookObject<decltype(&FrameStageNotify)> hkFrameStageNotify = {};
inline CBaseHookObject<decltype(&SetModel)> hkSetModel = {};
inline CBaseHookObject<decltype(&EquipItemInLoadout)> hkEquipItemInLoadout = {};
inline CBaseHookObject<decltype(&PredictionSimulation)> hkPredictionSimulation = {};
inline CBaseHookObject<decltype(&SendNetInputMessage)> hkSendInputMessage = {};
inline CBaseHookObject<decltype(&AllowCameraAngleChange)> hkAllowCameraChange = {};
inline CBaseHookObject<decltype(&CameraInput)> hkCameraInput = {};
inline CBaseHookObject<decltype(&OverrideView)> hkOverrideView = {};
inline CBaseHookObject<decltype(&InputParser)> hkInputParser = {};
}

View File

@@ -0,0 +1,243 @@
// used: [d3d] api
#include <d3d11.h>
#include "interfaces.h"
// used: findpattern, callvirtual, getvfunc...
#include "../utilities/memory.h"
// used: l_print
#include "../utilities/log.h"
// used: iswapchaindx11
#include "../sdk/interfaces/iswapchaindx11.h"
#include "hooks.h"
#include "../sdk/datatypes/resourceutils.h"
#include "../cstrike/sdk/interfaces/events.h"
#include "../sdk/interfaces/imaterialsystem.h"
#pragma region interfaces_get
using InstantiateInterfaceFn_t = void* (*)();
class CInterfaceRegister
{
public:
InstantiateInterfaceFn_t fnCreate;
const char* szName;
CInterfaceRegister* pNext;
};
static const CInterfaceRegister* GetRegisterList(const wchar_t* wszModuleName)
{
void* hModule = MEM::GetModuleBaseHandle(wszModuleName);
if (hModule == nullptr)
return nullptr;
std::uint8_t* pCreateInterface = reinterpret_cast<std::uint8_t*>(MEM::GetExportAddress(hModule, CS_XOR("CreateInterface")));
if (pCreateInterface == nullptr)
{
L_PRINT(LOG_ERROR) << CS_XOR("failed to get \"CreateInterface\" address");
return nullptr;
}
return *reinterpret_cast<CInterfaceRegister**>(MEM::ResolveRelativeAddress(pCreateInterface, 0x3, 0x7));
}
template <typename T = void*>
T* Capture(const CInterfaceRegister* pModuleRegister, const char* szInterfaceName)
{
for (const CInterfaceRegister* pRegister = pModuleRegister; pRegister != nullptr; pRegister = pRegister->pNext)
{
if (const std::size_t nInterfaceNameLength = CRT::StringLength(szInterfaceName);
// found needed interface
CRT::StringCompareN(szInterfaceName, pRegister->szName, nInterfaceNameLength) == 0 &&
// and we've given full name with hardcoded digits
(CRT::StringLength(pRegister->szName) == nInterfaceNameLength ||
// or it contains digits after name
CRT::StringToInteger<int>(pRegister->szName + nInterfaceNameLength, nullptr, 10) > 0))
{
// capture our interface
void* pInterface = pRegister->fnCreate();
#ifdef _DEBUG
// log interface address
L_PRINT(LOG_INFO) << CS_XOR("captured \"") << pRegister->szName << CS_XOR("\" interface at address: ") << L::AddFlags(LOG_MODE_INT_SHOWBASE | LOG_MODE_INT_FORMAT_HEX) << reinterpret_cast<std::uintptr_t>(pInterface);
#else
L_PRINT(LOG_INFO) << CS_XOR("captured \"") << pRegister->szName << CS_XOR("\" interface");
#endif
return static_cast<T*>(pInterface);
}
}
L_PRINT(LOG_ERROR) << CS_XOR("failed to find interface \"") << szInterfaceName << CS_XOR("\"");
return nullptr;
}
#pragma endregion
bool I::Setup()
{
bool bSuccess = true;
#pragma region interface_game_exported
const auto pTier0Handle = MEM::GetModuleBaseHandle(TIER0_DLL);
if (pTier0Handle == nullptr)
return false;
MemAlloc = *reinterpret_cast<IMemAlloc**>(MEM::GetExportAddress(pTier0Handle, CS_XOR("g_pMemAlloc")));
bSuccess &= (MemAlloc != nullptr);
const auto pSchemaSystemRegisterList = GetRegisterList(SCHEMASYSTEM_DLL);
if (pSchemaSystemRegisterList == nullptr)
return false;
SchemaSystem = Capture<ISchemaSystem>(pSchemaSystemRegisterList, SCHEMA_SYSTEM);
bSuccess &= (SchemaSystem != nullptr);
const auto pInputSystemRegisterList = GetRegisterList(INPUTSYSTEM_DLL);
if (pInputSystemRegisterList == nullptr)
return false;
InputSystem = Capture<IInputSystem>(pInputSystemRegisterList, INPUT_SYSTEM_VERSION);
bSuccess &= (InputSystem != nullptr);
const auto pEngineRegisterList = GetRegisterList(ENGINE2_DLL);
if (pEngineRegisterList == nullptr)
return false;
GameResourceService = Capture<IGameResourceService>(pEngineRegisterList, GAME_RESOURCE_SERVICE_CLIENT);
bSuccess &= (GameResourceService != nullptr);
Engine = Capture<IEngineClient>(pEngineRegisterList, SOURCE2_ENGINE_TO_CLIENT);
bSuccess &= (Engine != nullptr);
NetworkClientService = Capture<INetworkClientService>(pEngineRegisterList, NETWORK_CLIENT_SERVICE);
bSuccess &= (NetworkClientService != nullptr);
const auto pTier0RegisterList = GetRegisterList(TIER0_DLL);
if (pTier0RegisterList == nullptr)
return false;
Cvar = Capture<IEngineCVar>(pTier0RegisterList, ENGINE_CVAR);
bSuccess &= (Cvar != nullptr);
const auto pClientRegister = GetRegisterList(CLIENT_DLL);
if (pClientRegister == nullptr)
return false;
Client = Capture<ISource2Client>(pClientRegister, SOURCE2_CLIENT);
bSuccess &= (Client != nullptr);
const auto pLocalizeRegisterList = GetRegisterList(LOCALIZE_DLL);
if (pLocalizeRegisterList == nullptr)
return false;
Localize = Capture<CLocalize>(pLocalizeRegisterList, LOCALIZE);
bSuccess &= (Localize != nullptr);
/* material sys */
const auto pMaterialSystem2Register = GetRegisterList(MATERIAL_SYSTEM2_DLL);
if (pMaterialSystem2Register == nullptr)
return false;
MaterialSystem2 = Capture<material_system_t>(pMaterialSystem2Register, MATERIAL_SYSTEM2);
bSuccess &= (MaterialSystem2 != nullptr);
const auto pResourceSystemRegisterList = GetRegisterList(RESOURCESYSTEM_DLL);
if (pResourceSystemRegisterList == nullptr)
return false;
ResourceSystem = Capture<IResourceSystem>(pResourceSystemRegisterList, RESOURCE_SYSTEM);
bSuccess &= (ResourceSystem != nullptr);
if (ResourceSystem != nullptr)
{
ResourceHandleUtils = reinterpret_cast<CResourceHandleUtils*>(ResourceSystem->QueryInterface(RESOURCE_HANDLE_UTILS));
bSuccess &= (ResourceHandleUtils != nullptr);
}
/* //render game sys
const auto pRenderSysRegister = GetRegisterList(RENDERSYSTEM_DLL);
if (pRenderSysRegister == nullptr)
return false;
RenderGameSystem = Capture<CRenderGameSystem>(pRenderSysRegister, RENDERSYS_SYSTEM);
bSuccess &= (RenderGameSystem != nullptr);*/
#pragma endregion
Trace = *reinterpret_cast<i_trace**>(MEM::GetAbsoluteAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("4C 8B 3D ? ? ? ? 24 C9 0C 49 66 0F 7F 45 ?")), 0x3));
bSuccess &= (Trace != nullptr);
L_PRINT(LOG_INFO) << CS_XOR("captured Trace \"") << CS_XOR("\" interface at address: ") << L::AddFlags(LOG_MODE_INT_SHOWBASE | LOG_MODE_INT_FORMAT_HEX) << reinterpret_cast<std::uintptr_t>(Trace);
GameEvent = *reinterpret_cast<IGameEventManager2**>(MEM::ResolveRelativeAddress(MEM::GetVFunc<std::uint8_t*>(Client, 14U) + 0x3E, 0x3, 0x7));
bSuccess &= (GameEvent != nullptr);
// @ida: #STR: "r_gpu_mem_stats", "-threads", "CTSListBase: Misaligned list\n", "CTSQueue: Misaligned queue\n", "Display GPU memory usage.", "-r_max_device_threads"
SwapChain = **reinterpret_cast<ISwapChainDx11***>(MEM::ResolveRelativeAddress(MEM::FindPattern(RENDERSYSTEM_DLL, CS_XOR("66 0F 7F 05 ? ? ? ? 66 0F 7F 0D ? ? ? ? 48 89 35")), 0x4, 0x8));
bSuccess &= (SwapChain != nullptr);
// grab's d3d11 interfaces for later use
if (SwapChain != nullptr)
{
if (FAILED(SwapChain->pDXGISwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&Device)))
{
L_PRINT(LOG_ERROR) << CS_XOR("failed to get device from swapchain");
CS_ASSERT(false);
return false;
}
else
// we successfully got device, so we can get immediate context
Device->GetImmediateContext(&DeviceContext);
}
bSuccess &= (Device != nullptr && DeviceContext != nullptr);
Input = *reinterpret_cast<CCSGOInput**>(MEM::ResolveRelativeAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 8B 0D ? ? ? ? E8 ? ? ? ? 8B BE ? ? ? ? 44 8B F0 85 FF 78 04 FF C7 EB 03")), 0x3, 0x7));
bSuccess &= (Input != nullptr);
// @ida: STR '%s: %f tick(%d) curtime(%f) OnSequenceCycleChanged: %s : %d=[%s]'
GlobalVars = *reinterpret_cast<IGlobalVars**>(MEM::ResolveRelativeAddress(MEM::FindPattern(CLIENT_DLL, CS_XOR("48 89 0D ? ? ? ? 48 89 41")), 0x3, 0x7));
bSuccess &= (GlobalVars != nullptr);
return bSuccess;
}
bool I::CreateRenderTarget(IDXGISwapChain* pSwapChain) {
SwapChain->pDXGISwapChain = pSwapChain;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
if (FAILED(SwapChain->pDXGISwapChain->GetDesc(&swapChainDesc))) {
L_PRINT(LOG_ERROR) << (CS_XOR("Failed to get swap chain description."));
return false;
}
if (FAILED(SwapChain->pDXGISwapChain->GetDevice(__uuidof(ID3D11Device), reinterpret_cast<PVOID*>(&Device)))) {
L_PRINT(LOG_ERROR) << (CS_XOR("Failed to get device from swap chain."));
return false;
}
Device->GetImmediateContext(&DeviceContext);
ID3D11Texture2D* back_buffer;
if (FAILED(SwapChain->pDXGISwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<PVOID*>(&back_buffer)))) {
L_PRINT(LOG_ERROR) << (CS_XOR("Failed to get buffer from swap chain."));
return false;
}
D3D11_RENDER_TARGET_VIEW_DESC desc;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
if (FAILED(Device->CreateRenderTargetView(back_buffer, &desc, &RenderTargetView))) {
back_buffer->Release();
L_PRINT(LOG_ERROR) << (CS_XOR("Failed to create render target view."));
return false;
}
back_buffer->Release();
return true;
}
void I::DestroyRenderTarget()
{
if (RenderTargetView != nullptr)
{
RenderTargetView->Release();
RenderTargetView = nullptr;
}
}

View File

@@ -0,0 +1,92 @@
#pragma once
#include "../common.h"
#include <d3d11.h>
#include "../utilities/memory.h"
#pragma region sdk_definitons
#define GAME_RESOURCE_SERVICE_CLIENT CS_XOR("GameResourceServiceClientV00")
#define SOURCE2_CLIENT CS_XOR("Source2Client00")
#define SCHEMA_SYSTEM CS_XOR("SchemaSystem_00")
#define INPUT_SYSTEM_VERSION CS_XOR("InputSystemVersion00")
#define SOURCE2_ENGINE_TO_CLIENT CS_XOR("Source2EngineToClient00")
#define ENGINE_CVAR CS_XOR("VEngineCvar00")
#define LOCALIZE CS_XOR("Localize_00")
#define NETWORK_CLIENT_SERVICE CS_XOR("NetworkClientService_001")
#define MATERIAL_SYSTEM2 CS_XOR("VMaterialSystem2_00")
#define RENDERSYS_SYSTEM CS_XOR("RenderGameSystem_00")
#define RESOURCE_SYSTEM CS_XOR("ResourceSystem013")
#define RESOURCE_HANDLE_UTILS CS_XOR("ResourceHandleUtils001")
// @source: master/game/shared/shareddefs.h
#define TICK_INTERVAL (I::GlobalVars->flIntervalPerTick)
#define TIME_TO_TICKS(TIME) (static_cast<int>(0.5f + static_cast<float>(TIME) / TICK_INTERVAL))
#define TICKS_TO_TIME(TICKS) (TICK_INTERVAL * static_cast<float>(TICKS))
#define ROUND_TO_TICKS(TIME) (TICK_INTERVAL * TIME_TO_TICKS(TIME))
#define TICK_NEVER_THINK (-1)
#pragma endregion
// game interfaces
class ISwapChainDx11;
class IMemAlloc;
class CCSGOInput;
class ISchemaSystem;
class IGlobalVars;
class IInputSystem;
class IGameResourceService;
class ISource2Client;
class IEngineClient;
class IEngineCVar;
class INetworkClientService;
class material_system_t;
class CLocalize;
class IResourceSystem;
class CResourceHandleUtils;
class i_trace;
class IGameEvent;
class IGameEventManager2;
class CGCClientSystem;
class CCSInventoryManager;
// [d3d] struct
struct ID3D11Device;
struct ID3D11DeviceContext;
struct ID3D11RenderTargetView;
class CLocalize {
public:
auto FindSafe(const char* tokenName) {
return MEM::CallVFunc<const char*, 17U>(this, tokenName);
}
};
namespace I
{
bool Setup();
/* @section: helpers */
// create and destroy render target view for handling resize
bool CreateRenderTarget(IDXGISwapChain* pSwapChain);
void DestroyRenderTarget();
inline ID3D11ShaderResourceView* Maintexture = nullptr;
inline IGameEventManager2* GameEvent = nullptr;
inline i_trace* Trace = nullptr;
inline IMemAlloc* MemAlloc = nullptr;
inline ISwapChainDx11* SwapChain = nullptr;
inline ID3D11Device* Device = nullptr;
inline ID3D11DeviceContext* DeviceContext = nullptr;
inline ID3D11RenderTargetView* RenderTargetView = nullptr;
inline CCSGOInput* Input = nullptr;
inline ISchemaSystem* SchemaSystem = nullptr;
inline IGlobalVars* GlobalVars = nullptr;
inline IInputSystem* InputSystem = nullptr;
inline IGameResourceService* GameResourceService = nullptr;
inline ISource2Client* Client = nullptr;
inline IEngineClient* Engine = nullptr;
inline IEngineCVar* Cvar = nullptr;
inline INetworkClientService* NetworkClientService = nullptr;
inline material_system_t* MaterialSystem2 = nullptr;
inline CLocalize* Localize = nullptr;
inline CResourceHandleUtils* ResourceHandleUtils = nullptr;
inline IResourceSystem* ResourceSystem = nullptr;
}

View File

@@ -0,0 +1,115 @@
#ifndef CS2_CHEAT_MEMORY_HPP
#define CS2_CHEAT_MEMORY_HPP
#include <vector>
#include <cstdint>
#include <cstddef>
#include <optional>
#include <string_view>
namespace Core::Memory
{
struct Address_t
{
constexpr Address_t() noexcept = default;
constexpr ~Address_t() noexcept = default;
explicit constexpr Address_t(std::uintptr_t uAddress) noexcept
: m_uAddress(uAddress)
{
}
explicit Address_t(const void* pAddress) noexcept
: m_uAddress(reinterpret_cast<std::uintptr_t>(pAddress))
{
}
constexpr operator std::uintptr_t() const noexcept
{
return m_uAddress;
}
constexpr operator bool() const noexcept
{
return m_uAddress;
}
operator void* () const noexcept
{
return reinterpret_cast<void*>(m_uAddress);
}
template< typename tReturn = Address_t >
[[nodiscard]] constexpr tReturn Offset(std::ptrdiff_t iOffset) const noexcept
{
return tReturn(m_uAddress + iOffset);
}
template< typename tReturn = Address_t >
[[nodiscard]] inline tReturn Get(std::uint32_t iDereferenceCount = 1) const noexcept
{
std::uintptr_t uOutAddress = m_uAddress;
while (iDereferenceCount-- && uOutAddress)
uOutAddress = *reinterpret_cast<std::uintptr_t*>(uOutAddress);
return tReturn(uOutAddress);
}
template< typename tReturn = Address_t >
[[nodiscard]] inline tReturn Jump(std::ptrdiff_t iOffset = 0x1) const noexcept
{
std::uintptr_t uOutAddress = m_uAddress + iOffset;
uOutAddress += *reinterpret_cast<std::int32_t*>(uOutAddress); // @note / xnxkzeu: those could be negative.
uOutAddress += 4;
return tReturn(uOutAddress);
}
template< typename tReturn = std::uintptr_t >
[[nodiscard]] constexpr tReturn Cast() const noexcept
{
return tReturn(m_uAddress);
}
private:
std::uintptr_t m_uAddress = { };
};
[[nodiscard]] Address_t GetModuleBaseAddress(std::string_view szModuleName) noexcept;
[[nodiscard]] Address_t GetModuleBaseAddress(std::wstring_view szModuleName) noexcept;
[[nodiscard]] Address_t GetExportAddress(Address_t uModuleBaseAddress, std::string_view szProcedureName) noexcept;
[[nodiscard]] bool GetSectionInfo(Address_t uModuleAddress, std::string_view szSectionName, Address_t* pOutSectionAddress, std::size_t* pOutSectionSize) noexcept;
[[nodiscard]] Address_t FindPattern(std::string_view szModuleName, std::string_view szPattern) noexcept;
[[nodiscard]] Address_t FindPattern(Address_t uRegionAddress, std::size_t uRegionSize, std::string_view szPattern) noexcept;
[[nodiscard]] std::vector< std::optional< std::byte > > PatternToBytes(std::string_view szPattern) noexcept;
template< typename tReturn, std::size_t uIndex, typename... tArgs >
constexpr inline tReturn CallVFunc(void* pInstance, tArgs... argList) noexcept
{
using fnVirtual_t = tReturn(__thiscall*)(void*, tArgs...) noexcept;
return (*static_cast<fnVirtual_t**>(pInstance))[uIndex](pInstance, argList...);
}
} // namespace Core::Memory
#define VFUNC( uIndex, fnVirtual, tArgs, tReturn, ... ) \
auto fnVirtual noexcept \
{ \
return Core::Memory::CallVFunc< tReturn __VA_OPT__(, ) __VA_ARGS__, uIndex > tArgs; \
}
#define OFFSET( iOffset, fnVariable, tReturn, ... ) \
[[nodiscard]] std::add_lvalue_reference_t< tReturn __VA_OPT__(, ) __VA_ARGS__ > fnVariable( ) noexcept \
{ \
return *reinterpret_cast< std::add_pointer_t< tReturn __VA_OPT__(, ) __VA_ARGS__ > >( reinterpret_cast< std::uintptr_t >( this ) + iOffset ); \
} \
[[nodiscard]] std::add_lvalue_reference_t< std::add_const_t< tReturn __VA_OPT__(, ) __VA_ARGS__ > > fnVariable( ) const noexcept \
{ \
return *reinterpret_cast< std::add_pointer_t< std::add_const_t< tReturn __VA_OPT__(, ) __VA_ARGS__ > > >( reinterpret_cast< std::uintptr_t >( this ) + iOffset ); \
}
#endif // CS2_CHEAT_MEMORY_HPP

View 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;
}

View File

@@ -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;
};

View 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;
}

View 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;
};

View File

@@ -0,0 +1,106 @@
#pragma once
// used: [stl] vector
#include <vector>
#include "../common.h"
// used: [ext] imgui, draw, animation
#include "../utilities/draw.h"
#define MENU_MAX_BACKGROUND_PARTICLES 100
class CTab
{
public:
const char* szName;
void (*pRenderFunction)();
};
namespace MENU
{
void RenderMainWindow();
void RenderWatermark();
void UpdateStyle(ImGuiStyle* pStyle = nullptr);
/* @section: particles */
struct ParticleData_t
{
ParticleData_t(const ImVec2& vecPosition, const ImVec2& vecVelocity) :
vecPosition(vecPosition), vecVelocity(vecVelocity) { }
// current particle position
ImVec2 vecPosition = {};
// current particle velocity
ImVec2 vecVelocity = {};
};
struct ParticleContext_t
{
ParticleContext_t(const int nMaxParticles = 100)
{
// allocate memory for particles
this->vecParticles.reserve(nMaxParticles);
// create particles if needed
}
~ParticleContext_t()
{
// since no memory allocated, just clear vector
this->vecParticles.clear();
}
void Render(ImDrawList* pDrawList, const ImVec2& vecScreenSize, const float flAlpha);
// create particle with random velocity/position
void AddParticle(const ImVec2& vecScreenSize);
// current size of particles
const size_t Count() const { return this->vecParticles.size(); }
private:
// draw particle (circle)
void DrawParticle(ImDrawList* pDrawList, ParticleData_t& particle, const Color_t& colPrimary);
// find & draw connection as a line between particles
void FindConnections(ImDrawList* pDrawList, ParticleData_t& particle, const Color_t& colPrimary, float flMaxDistance);
void DrawConnection(ImDrawList* pDrawList, ParticleData_t& particle, ParticleData_t& otherParticle, float flAlpha, const Color_t& colPrimary) const;
// update particle position/velocity
// reversed direction when particle is out of screen
void UpdatePosition(ParticleData_t& particle, const ImVec2& vecScreenSize) const;
void ResolveScreenCollision(ParticleData_t& particle, const ImVec2& vecScreenSize) const;
// all our particles data
std::vector<ParticleData_t> vecParticles;
};
inline bool bMainWindowOpened = false;
inline int nCurrentMainTab = 0;
inline int g_cur_tab_idx = 0;
inline char szConfigFile[256U] = {};
inline unsigned long long nSelectedConfig = ~1U;
inline ParticleContext_t menuParticle = ParticleContext_t(MENU_MAX_BACKGROUND_PARTICLES);
inline AnimationHandler_t animMenuDimBackground;
inline float flDpiScale = 1.f;
}
namespace T
{
/* @section: main */
void Render(const char* szTabBar, const CTab* arrTabs, const unsigned long long nTabsCount, int* nCurrentTab, ImGuiTabBarFlags flags = ImGuiTabBarFlags_NoCloseWithMiddleMouseButton | ImGuiTabBarFlags_NoTooltip);
/* @section: tabs */
void RageBot();
void LegitBot();
void Visuals();
void Miscellaneous();
void SkinsChanger();
/* @section: values */
// user-defined configuration filename in miscellaneous tab
inline char szConfigFile[256U] = {};
// current selected configuration in miscellaneous tab
inline unsigned long long nSelectedConfig = ~1U;
// current sub tab overlay in visuals tab
inline int nCurrentOverlaySubtab = 0;
}

View File

@@ -0,0 +1,44 @@
#include "pointer.hpp"
#include <iostream>
CPointer CPointer::GetFieldPtr(int offset) const {
if (IsValid()) {
return m_Value + offset;
}
LogInvalid();
static CPointer null{};
return &null;
}
CPointer& CPointer::Offset(int offset) {
if (IsValid()) {
m_Value += offset;
}
return *this;
}
CPointer& CPointer::Absolute(int preAbs, int postAbs) {
if (IsValid()) {
Offset(preAbs);
m_Value = m_Value + sizeof(int) + *reinterpret_cast<int*>(m_Value);
Offset(postAbs);
}
return *this;
}
CPointer& CPointer::Dereference(int count) {
if (IsValid()) {
while (count-- != 0) {
m_Value = *reinterpret_cast<uintptr_t*>(m_Value);
}
}
return *this;
}
void CPointer::LogInvalid() const { std::cout << "invalid offset\n"; }

View File

@@ -0,0 +1,49 @@
#pragma once
#include <cstdint>
#include <type_traits>
class CPointer {
public:
CPointer() { m_Value = 0; }
template <typename T>
CPointer(T value) {
m_Value = (uintptr_t)(value);
}
bool IsValid() const { return m_Value != 0; }
template <typename T>
auto Get() const {
return reinterpret_cast<T>(m_Value);
}
template <typename T>
std::add_lvalue_reference_t<T> GetField(int offset) const {
return *GetFieldPtr(offset).Get<T*>();
}
template <typename T, typename... Args>
auto Call(Args... args) const {
if constexpr (std::is_invocable_v<T, Args...>) {
if (IsValid()) {
return std::invoke(Get<T>(), std::forward<Args>(args)...);
}
} else {
static_assert(std::is_invocable_v<T, Args...>, "T must be an invocable type.");
}
LogInvalid();
return std::invoke_result_t<T, Args...>{};
}
CPointer GetFieldPtr(int offset) const;
CPointer& Offset(int offset);
CPointer& Absolute(int preAbs, int postAbs);
CPointer& Dereference(int count);
private:
void LogInvalid() const;
uintptr_t m_Value;
};

View File

@@ -0,0 +1,168 @@
#include "schema.h"
// used: [stl] vector
#include <vector>
// used: [stl] find_if
#include <algorithm>
// used: getworkingpath
#include "../core.h"
// used: ischemasystem
#include "interfaces.h"
#include "../sdk/interfaces/ischemasystem.h"
// used: l_print
#include "../utilities/log.h"
struct SchemaData_t
{
FNV1A_t uHashedFieldName = 0x0ULL;
std::uint32_t uOffset = 0x0U;
};
static std::vector<SchemaData_t> vecSchemaData;
bool SCHEMA::Setup(const wchar_t* wszFileName, const char* szModuleName)
{
wchar_t wszDumpFilePath[MAX_PATH];
if (!CORE::GetWorkingPath(wszDumpFilePath))
return false;
CRT::StringCat(wszDumpFilePath, wszFileName);
HANDLE hOutFile = ::CreateFileW(wszDumpFilePath, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hOutFile == INVALID_HANDLE_VALUE)
return false;
// @todo: maybe remove this redundant? and put it inside CRT::String_t c'tor
const std::time_t time = std::time(nullptr);
std::tm timePoint;
localtime_s(&timePoint, &time);
CRT::String_t<64> szTimeBuffer(CS_XOR("[%d-%m-%Y %T] asphyxia | schema dump\n\n"), &timePoint);
// write current date, time and info
::WriteFile(hOutFile, szTimeBuffer.Data(), szTimeBuffer.Length(), nullptr, nullptr);
CSchemaSystemTypeScope* pTypeScope = I::SchemaSystem->FindTypeScopeForModule(szModuleName);
if (pTypeScope == nullptr)
return false;
const int nTableSize = pTypeScope->hashClasses.Count();
L_PRINT(LOG_INFO) << CS_XOR("found \"") << nTableSize << CS_XOR("\" schema classes in module");
// allocate memory for elements
UtlTSHashHandle_t* pElements = new UtlTSHashHandle_t[nTableSize + 1U];
const auto nElements = pTypeScope->hashClasses.GetElements(0, nTableSize, pElements);
for (int i = 0; i < nElements; i++)
{
const UtlTSHashHandle_t hElement = pElements[i];
if (hElement == 0)
continue;
CSchemaClassBinding* pClassBinding = pTypeScope->hashClasses[hElement];
if (pClassBinding == nullptr)
continue;
SchemaClassInfoData_t* pDeclaredClassInfo;
pTypeScope->FindDeclaredClass(&pDeclaredClassInfo, pClassBinding->szBinaryName);
if (pDeclaredClassInfo == nullptr)
continue;
if (pDeclaredClassInfo->nFieldSize == 0)
continue;
CRT::String_t<MAX_PATH> szClassBuffer(CS_XOR("class %s\n"), pDeclaredClassInfo->szName);
::WriteFile(hOutFile, szClassBuffer.Data(), szClassBuffer.Length(), nullptr, nullptr);
for (auto j = 0; j < pDeclaredClassInfo->nFieldSize; j++)
{
SchemaClassFieldData_t* pFields = pDeclaredClassInfo->pFields;
CRT::String_t<MAX_PATH> szFieldClassBuffer(CS_XOR("%s->%s"), pClassBinding->szBinaryName, pFields[j].szName);
// store field info
vecSchemaData.emplace_back(FNV1A::Hash(szFieldClassBuffer.Data()), pFields[j].nSingleInheritanceOffset);
CRT::String_t<MAX_PATH> szFieldBuffer(CS_XOR(" %s %s = 0x%X\n"), pFields[j].pSchemaType->szName, pFields[j].szName, pFields[j].nSingleInheritanceOffset);
// write field info
::WriteFile(hOutFile, szFieldBuffer.Data(), szFieldBuffer.Length(), nullptr, nullptr);
}
#ifdef _DEBUG
L_PRINT(LOG_INFO) << CS_XOR("dumped \"") << pDeclaredClassInfo->szName << CS_XOR("\" (total: ") << pDeclaredClassInfo->nFieldSize << CS_XOR(" fields)");
#endif
}
// free allocated memory
delete[] pElements;
// close file
::CloseHandle(hOutFile);
return true;
}
std::uint32_t SCHEMA::GetOffset(const FNV1A_t uHashedFieldName)
{
if (const auto it = std::ranges::find_if(vecSchemaData, [uHashedFieldName](const SchemaData_t& data)
{ return data.uHashedFieldName == uHashedFieldName; });
it != vecSchemaData.end())
return it->uOffset;
L_PRINT(LOG_ERROR) << CS_XOR("failed to find offset for field with hash: ") << L::AddFlags(LOG_MODE_INT_FORMAT_HEX | LOG_MODE_INT_SHOWBASE) << uHashedFieldName;
CS_ASSERT(false); // schema field not found
return 0U;
}
// @todo: optimize this, this is really poorly do and can be done much better?
std::uint32_t SCHEMA::GetForeignOffset(const char* szModulenName, const FNV1A_t uHashedClassName, const FNV1A_t uHashedFieldName)
{
CSchemaSystemTypeScope* pTypeScope = I::SchemaSystem->FindTypeScopeForModule(szModulenName);
if (pTypeScope == nullptr)
return false;
const int nTableSize = pTypeScope->hashClasses.Count();
// allocate memory for elements
UtlTSHashHandle_t* pElements = new UtlTSHashHandle_t[nTableSize + 1U];
const auto nElements = pTypeScope->hashClasses.GetElements(0, nTableSize, pElements);
std::uint32_t uOffset = 0x0;
for (int i = 0; i < nElements; i++)
{
const UtlTSHashHandle_t hElement = pElements[i];
if (hElement == 0)
continue;
CSchemaClassBinding* pClassBinding = pTypeScope->hashClasses[hElement];
if (pClassBinding == nullptr)
continue;
SchemaClassInfoData_t* pDeclaredClassInfo;
pTypeScope->FindDeclaredClass(&pDeclaredClassInfo, pClassBinding->szBinaryName);
if (pDeclaredClassInfo == nullptr)
continue;
if (pDeclaredClassInfo->nFieldSize == 0)
continue;
for (auto j = 0; j < pDeclaredClassInfo->nFieldSize; j++)
{
SchemaClassFieldData_t* pFields = pDeclaredClassInfo->pFields;
if (pFields == nullptr)
continue;
SchemaClassFieldData_t field = pFields[j];
if (FNV1A::Hash(pClassBinding->szBinaryName) == uHashedClassName && FNV1A::Hash(field.szName) == uHashedFieldName)
uOffset = field.nSingleInheritanceOffset;
}
}
if (uOffset == 0x0)
L_PRINT(LOG_WARNING) << CS_XOR("failed to find offset for field with hash: ") << L::AddFlags(LOG_MODE_INT_FORMAT_HEX | LOG_MODE_INT_SHOWBASE) << uHashedFieldName;
return uOffset;
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "../common.h"
// used: fnv-1a hash
#include "../utilities/fnv1a.h"
#define SCHEMA_ADD_OFFSET(TYPE, NAME, OFFSET) \
[[nodiscard]] CS_INLINE std::add_lvalue_reference_t<TYPE> NAME() \
{ \
static const std::uint32_t uOffset = OFFSET; \
return *reinterpret_cast<std::add_pointer_t<TYPE>>(reinterpret_cast<std::uint8_t*>(this) + (uOffset)); \
}
#define SCHEMA_ADD_POFFSET(TYPE, NAME, OFFSET) \
[[nodiscard]] CS_INLINE std::add_pointer_t<TYPE> NAME() \
{ \
const static std::uint32_t uOffset = OFFSET; \
return reinterpret_cast<std::add_pointer_t<TYPE>>(reinterpret_cast<std::uint8_t*>(this) + (uOffset)); \
}
#define SCHEMA_ADD_FIELD_OFFSET(TYPE, NAME, FIELD, ADDITIONAL) SCHEMA_ADD_OFFSET(TYPE, NAME, SCHEMA::GetOffset(FNV1A::HashConst(FIELD)) + ADDITIONAL)
#define SCHEMA_ADD_FIELD(TYPE, NAME, FIELD) SCHEMA_ADD_FIELD_OFFSET(TYPE, NAME, FIELD, 0U)
#define SCHEMA_ADD_PFIELD_OFFSET(TYPE, NAME, FIELD, ADDITIONAL) SCHEMA_ADD_POFFSET(TYPE, NAME, SCHEMA::GetOffset(FNV1A::HashConst(FIELD)) + ADDITIONAL)
#define SCHEMA_ADD_PFIELD(TYPE, NAME, FIELD) SCHEMA_ADD_PFIELD_OFFSET(TYPE, NAME, FIELD, 0U)
// @todo: dump enums?
namespace SCHEMA
{
// store the offset of the field in the class
// dump stored data to file
bool Setup(const wchar_t* wszFileName, const char* szModuleName);
/* @section: get */
// get offset of the field in the class
// @note: only client.dll class & fields
[[nodiscard]] std::uint32_t GetOffset(const FNV1A_t uHashedFieldName);
// get foregin offset from other .dll
[[nodiscard]] std::uint32_t GetForeignOffset(const char* szModulenName, const FNV1A_t uHashedClassName, const FNV1A_t uHashedFieldName);
}

View File

@@ -0,0 +1,34 @@
#include "schemav2.hpp"
#include "../sdk/interfaces/ischemasystem.h"
#include "../utilities/fnv1a.h"
#include "../utilities/log.h"
std::optional<int32_t> CSchemaManager::GetSchemaOffsetInternal(const char* moduleName, const char* bindingName, const char* fieldName) {
CSchemaSystemTypeScope* typeScope = I::SchemaSystem->FindTypeScopeForModule(moduleName);
if (!typeScope) {
L_PRINT(LOG_ERROR) << CS_XOR("\"schemamgr\" No type scope found for " << moduleName);
return {};
}
SchemaClassInfoData_t* classInfo;
typeScope->FindDeclaredClass(&classInfo, bindingName);
if (!classInfo) {
L_PRINT(LOG_INFO) << CS_XOR("\"schemamgr\" No binding named '{}' has been found in module '{}'.");
return {};
}
uint32_t fieldHash = FNV1A::Hash(fieldName);
for (int i = 0; classInfo->pFields && i < classInfo->nFieldSize; ++i) {
auto& field = classInfo->pFields[i];
if (FNV1A::Hash(field.szName) == fieldHash) {
L_PRINT(LOG_WARNING) << CS_XOR("\"schemamgr\" offset" << bindingName << "field: " << fieldName);
return field.nSingleInheritanceOffset;
}
}
L_PRINT(LOG_ERROR) << CS_XOR("\"schemamgr\" No field named " << fieldName << "in binding: " << bindingName);
return {};
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "pointer/pointer.hpp"
#include <optional>
class CSchemaManager {
public:
static CSchemaManager& Get() {
static CSchemaManager inst;
return inst;
}
static auto GetSchemaOffset(const char* moduleName, const char* bindingName, const char* fieldName) {
return Get().GetSchemaOffsetInternal(moduleName, bindingName, fieldName);
}
private:
std::optional<int32_t> GetSchemaOffsetInternal(const char* moduleName, const char* bindingName, const char* fieldName);
};
#define SCHEMA_EXTENDED(type, name, module_name, binding_name, field_name, extra_offset) \
std::add_lvalue_reference_t<type> name() const { \
static const auto offset = CSchemaManager::GetSchemaOffset(module_name, binding_name, field_name); \
if (offset) return CPointer(this).GetField<type>(offset.value() + extra_offset); \
static type null{}; \
return null; \
}
#define SCHEMA(type, name, binding_name, field_name) SCHEMA_EXTENDED(type, name, CConstants::CLIENT_LIB, binding_name, field_name, 0)
#define PSCHEMA_EXTENDED(type, name, module_name, binding_name, field_name, extra_offset) \
std::add_pointer_t<type> name() const { \
static const auto offset = CSchemaManager::GetSchemaOffset(module_name, binding_name, field_name); \
if (offset) return CPointer(this).GetFieldPtr(offset.value() + extra_offset).Get<std::add_pointer_t<type>>(); \
return nullptr; \
}
#define PSCHEMA(type, name, binding_name, field_name) PSCHEMA_EXTENDED(type, name, CConstants::CLIENT_LIB, binding_name, field_name, 0)

View File

@@ -0,0 +1,18 @@
#include "sdk.h"
// used: getmodulebasehandle
#include "../utilities/memory.h"
bool SDK::Setup()
{
bool bSuccess = true;
const void* hTier0Lib = MEM::GetModuleBaseHandle(TIER0_DLL);
if (hTier0Lib == nullptr)
return false;
fnConColorMsg = reinterpret_cast<decltype(fnConColorMsg)>(MEM::GetExportAddress(hTier0Lib, CS_XOR("?ConColorMsg@@YAXAEBVColor@@PEBDZZ")));
bSuccess &= fnConColorMsg != nullptr;
return bSuccess;
}

View File

@@ -0,0 +1,51 @@
#pragma once
// used: viewmatrix_t
#include "../sdk/datatypes/matrix.h"
// used: color_t
#include "../sdk/datatypes/color.h"
#pragma region sdk_definitions
// @source: master/public/worldsize.h
// world coordinate bounds
#define MAX_COORD_FLOAT 16'384.f
#define MIN_COORD_FLOAT (-MAX_COORD_FLOAT)
// @source: master/public/vphysics_interface.h
// coordinates are in HL units. 1 unit == 1 inch
#define METERS_PER_INCH 0.0254f
#pragma endregion
class CCSPlayerController;
class C_CSPlayerPawn;
class CUserCmd;
namespace SDK
{
// capture game's exported functions
bool Setup();
inline ViewMatrix_t ViewMatrix = ViewMatrix_t();
inline Vector_t CameraPosition = Vector_t();
inline CCSPlayerController* LocalController = nullptr;
inline C_CSPlayerPawn* LocalPawn = nullptr;
inline CUserCmd* Cmd = nullptr;
inline void(CS_CDECL* fnConColorMsg)(const Color_t&, const char*, ...) = nullptr;
}
class Cheat
{
public:
bool onground = false;
bool alive = false;
bool canShot = false;
bool canShotRevolver = false;
unsigned int tickbase = 0;
QAngle_t viewangles = QAngle_t(0, 0, 0);
};
inline Cheat* cheat = new Cheat();

View File

@@ -0,0 +1,55 @@
#include "InlineHook.h"
#include <stdio.h>
#include <cstdint>
#include <iostream>
#include <memoryapi.h>
#include "../cstrike/core/spoofcall/lazy_importer.hpp"
bool detour(BYTE* src, BYTE* dst, const uintptr_t len)
{
if (len < 5) return false;
DWORD curProtection;
LI_FN(VirtualProtect).safe()(src, len, PAGE_EXECUTE_READWRITE, &curProtection);
memset(src, 0x90, len);
uintptr_t relativeAddress = ((uintptr_t)dst - (uintptr_t)src) - 5;
*(BYTE*)src = 0xE9;
*(uintptr_t*)((uintptr_t)src + 1) = relativeAddress;
DWORD temp;
LI_FN(VirtualProtect).safe()(src, len, curProtection, &temp);
return true;
}
BYTE* trampHook(BYTE* src, BYTE* dst, const uintptr_t len)
{
if (len < 5) return 0;
void* gateway = LI_FN(VirtualAlloc).safe()(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(gateway, src, len);
intptr_t gatewayRelativeAddr = ((intptr_t)src - (intptr_t)gateway) - 5;
*(char*)((intptr_t)gateway + len) = 0xE9;
*(intptr_t*)((intptr_t)gateway + len + 1) = gatewayRelativeAddr;
// detour(src, dst, len);
return (BYTE*) gateway;
}
void InlineHook::Hook(void* src, void* dest, const size_t len)
{
const BYTE* src_bytes = (BYTE*) src;
for(int i = 0; i < len; i++)
og_bytes.push_back(src_bytes[i]);
source = (DWORD) src;
original = (DWORD)trampHook((BYTE*) src, (BYTE*) dest, len);
if(original)
bEnabled = true;
}
void InlineHook::Unhook()
{
BYTE* bytes = (BYTE*) source;
int i = 0;
for(const BYTE& b : og_bytes)
bytes[i++] = b;
}

View File

@@ -0,0 +1,56 @@
#pragma once
#include <Windows.h>
#include <vector>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <array>
#include <functional>
#include <sstream>
#include <string>
#include <string_view>
#include <chrono>
#include <random>
#include <numeric>
#include <cstdint>
#include <memory>
#include <thread>
#include <type_traits>
#include <regex>
#include <cmath>
#include <fstream>
#include <cassert>
#include <process.h>
#include <DbgHelp.h>
#include <filesystem>
#include <libloaderapi.h>
#include <Psapi.h>
#include <corecrt_math_defines.h>
#include <numbers>
#include <iomanip>
#include <iosfwd>
#include <set>
#include <unordered_set>
#include <list>
#include <TlHelp32.h>
#include <cinttypes>
#include <cstring>
class InlineHook
{
std::vector<BYTE> og_bytes;
DWORD original = 0;
DWORD source = 0;
bool bEnabled = false;
public:
InlineHook(){}
void Hook(void* src, void* dest, const size_t len);
void Unhook();
template<typename T>
T GetOg()
{
return (T)original;
}
};

View File

@@ -0,0 +1,60 @@
#include "ShadowVMT.h"
#include <cstdint>
#include <iostream>
#include <memoryapi.h>
#include "../spoofcall/lazy_importer.hpp"
ShadowVMT::ShadowVMT()
: class_base(nullptr), vftbl_len(0), new_vftbl(nullptr), old_vftbl(nullptr)
{
}
ShadowVMT::ShadowVMT(void* base)
: class_base(base), vftbl_len(0), new_vftbl(nullptr), old_vftbl(nullptr)
{
}
ShadowVMT::~ShadowVMT()
{
UnhookAll();
}
bool ShadowVMT::Setup(void* base)
{
if(base != nullptr)
class_base = base;
if(class_base == nullptr)
return false;
old_vftbl = *(std::uintptr_t**)class_base;
vftbl_len = CalcVtableLength(old_vftbl) * sizeof(std::uintptr_t);
if(vftbl_len == 0)
return false;
new_vftbl = new std::uintptr_t[vftbl_len + 1]();
std::memcpy(&new_vftbl[1], old_vftbl, vftbl_len * sizeof(std::uintptr_t));
try {
DWORD old;
LI_FN(VirtualProtect).safe()(class_base, sizeof(uintptr_t), PAGE_READWRITE, &old);
new_vftbl[0] = old_vftbl[-1];
*(std::uintptr_t**)class_base = &new_vftbl[1];
LI_FN(VirtualProtect).safe()(class_base, sizeof(uintptr_t), old, &old);
} catch(...) {
delete[] new_vftbl;
return false;
}
return true;
}
std::size_t ShadowVMT::CalcVtableLength(std::uintptr_t* vftbl_start)
{
MEMORY_BASIC_INFORMATION memInfo = { NULL };
int m_nSize = -1;
do {
m_nSize++;
LI_FN( VirtualQuery).safe()(reinterpret_cast<LPCVOID>(vftbl_start[m_nSize]), &memInfo, sizeof(memInfo));
} while (memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_EXECUTE_READWRITE);
return m_nSize;
}

View File

@@ -0,0 +1,84 @@
#pragma once
#include <Windows.h>
#include <vector>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <array>
#include <functional>
#include <sstream>
#include <string>
#include <string_view>
#include <chrono>
#include <random>
#include <numeric>
#include <cstdint>
#include <memory>
#include <thread>
#include <type_traits>
#include <regex>
#include <cmath>
#include <fstream>
#include <cassert>
#include <process.h>
#include <DbgHelp.h>
#include <filesystem>
#include <libloaderapi.h>
#include <Psapi.h>
#include <corecrt_math_defines.h>
#include <numbers>
#include <iomanip>
#include <iosfwd>
#include <set>
#include <unordered_set>
#include <list>
#include <TlHelp32.h>
#include <cstring>
class ShadowVMT
{
public:
ShadowVMT();
ShadowVMT(void* base);
~ShadowVMT();
bool Setup(void* class_base = nullptr);
template<typename T>
void HookIndex(int index, T fun)
{
new_vftbl[index + 1] = reinterpret_cast<std::uintptr_t>(fun);
}
void UnhookIndex(int index)
{
new_vftbl[index] = old_vftbl[index];
}
void UnhookAll()
{
try {
if (old_vftbl != nullptr) {
DWORD old;
VirtualProtect(class_base, sizeof(uintptr_t), PAGE_READWRITE, &old);
*(std::uintptr_t**)class_base = old_vftbl;
old_vftbl = nullptr;
VirtualProtect(class_base, sizeof(uintptr_t), old, &old);
}
}
catch (...) {
}
}
template<typename T>
T GetOg(int index)
{
return (T)old_vftbl[index];
}
private:
inline std::size_t CalcVtableLength(std::uintptr_t* vftbl_start);
void* class_base;
std::size_t vftbl_len;
std::uintptr_t* new_vftbl;
std::uintptr_t* old_vftbl;
};

View File

@@ -0,0 +1,30 @@
PUBLIC _spoofer_stub
.code
_spoofer_stub PROC
pop r11
add rsp, 8
mov rax, [rsp + 24]
mov r10, [rax]
mov [rsp], r10
mov r10, [rax + 8]
mov [rax + 8], r11
mov [rax + 16], rbx
lea rbx, fixup
mov [rax], rbx
mov rbx, rax
jmp r10
fixup:
sub rsp, 16
mov rcx, rbx
mov rbx, [rcx + 16]
jmp QWORD PTR [rcx + 8]
_spoofer_stub ENDP
END

View File

@@ -0,0 +1,120 @@
#include <type_traits>
namespace detail
{
extern "C" void* _spoofer_stub();
template <typename Ret, typename... Args>
static inline auto shellcode_stub_helper(
const void* shell,
Args... args
) -> Ret
{
auto fn = (Ret(*)(Args...))(shell);
return fn(args...);
}
template <std::size_t Argc, typename>
struct argument_remapper
{
// At least 5 params
template<
typename Ret,
typename First,
typename Second,
typename Third,
typename Fourth,
typename... Pack
>
static auto do_call(
const void* shell,
void* shell_param,
First first,
Second second,
Third third,
Fourth fourth,
Pack... pack
) -> Ret
{
return shellcode_stub_helper<
Ret,
First,
Second,
Third,
Fourth,
void*,
void*,
Pack...
>(
shell,
first,
second,
third,
fourth,
shell_param,
nullptr,
pack...
);
}
};
template <std::size_t Argc>
struct argument_remapper<Argc, std::enable_if_t<Argc <= 4>>
{
// 4 or less params
template<
typename Ret,
typename First = void*,
typename Second = void*,
typename Third = void*,
typename Fourth = void*
>
static auto do_call(
const void* shell,
void* shell_param,
First first = First{},
Second second = Second{},
Third third = Third{},
Fourth fourth = Fourth{}
) -> Ret
{
return shellcode_stub_helper<
Ret,
First,
Second,
Third,
Fourth,
void*,
void*
>(
shell,
first,
second,
third,
fourth,
shell_param,
nullptr
);
}
};
}
template <typename Ret, typename... Args>
static inline auto spoof_call(
const void* trampoline,
Ret(*fn)(Args...),
Args... args
) -> Ret
{
struct shell_params
{
const void* trampoline;
void* function;
void* rbx;
};
shell_params p{ trampoline, reinterpret_cast<void*>(fn) };
using mapper = detail::argument_remapper<sizeof...(Args), void>;
return mapper::template do_call<Ret, Args...>((const void*)&detail::_spoofer_stub, &p, args...);
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include "Utils.h"
class RetSpoofInvoker {
private:
void* gadgetAddress{ 0 };
public:
void init(std::uintptr_t gadgetAddress) noexcept
{
this->gadgetAddress = reinterpret_cast<void*>(gadgetAddress);
}
template <typename ReturnType, typename... Args>
ReturnType invokeFastcall(std::uintptr_t functionAddress, Args&&... args) const noexcept
{
return detail::shellcode_stub_helper<ReturnType(Args...)>::spoof_call(this->gadgetAddress, reinterpret_cast<void*>(functionAddress), std::forward<Args>(args)...);
}
};
inline RetSpoofInvoker invoker;

View File

@@ -0,0 +1,723 @@
/*
* Copyright 2018-2022 Justas Masiulis
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// === FAQ === documentation is available at https://github.com/JustasMasiulis/lazy_importer
// * Code doesn't compile with errors about pointer conversion:
// - Try using `nullptr` instead of `NULL` or call `get()` instead of using the overloaded operator()
// * Lazy importer can't find the function I want:
// - Double check that the module in which it's located in is actually loaded
// - Try #define LAZY_IMPORTER_CASE_INSENSITIVE
// This will start using case insensitive comparison globally
// - Try #define LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS
// This will enable forwarded export resolution globally instead of needing explicit `forwarded()` calls
#ifndef LAZY_IMPORTER_HPP
#define LAZY_IMPORTER_HPP
#define LI_FN(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), decltype(&name)>()
#define LI_FN_DEF(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), name>()
#define LI_MODULE(name) ::li::detail::lazy_module<LAZY_IMPORTER_KHASH(name)>()
#ifndef LAZY_IMPORTER_CPP_FORWARD
#ifdef LAZY_IMPORTER_NO_CPP_FORWARD
#define LAZY_IMPORTER_CPP_FORWARD(t, v) v
#else
#include <utility>
#define LAZY_IMPORTER_CPP_FORWARD(t, v) std::forward<t>( v )
#endif
#endif
#include <intrin.h>
#ifndef LAZY_IMPORTER_NO_FORCEINLINE
#if defined(_MSC_VER)
#define LAZY_IMPORTER_FORCEINLINE __forceinline
#elif defined(__GNUC__) && __GNUC__ > 3
#define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__))
#else
#define LAZY_IMPORTER_FORCEINLINE inline
#endif
#else
#define LAZY_IMPORTER_FORCEINLINE inline
#endif
#ifdef LAZY_IMPORTER_CASE_INSENSITIVE
#define LAZY_IMPORTER_CASE_SENSITIVITY false
#else
#define LAZY_IMPORTER_CASE_SENSITIVITY true
#endif
#define LAZY_IMPORTER_STRINGIZE(x) #x
#define LAZY_IMPORTER_STRINGIZE_EXPAND(x) LAZY_IMPORTER_STRINGIZE(x)
#define LAZY_IMPORTER_KHASH(str) ::li::detail::khash(str, \
::li::detail::khash_impl( __TIME__ __DATE__ LAZY_IMPORTER_STRINGIZE_EXPAND(__LINE__) LAZY_IMPORTER_STRINGIZE_EXPAND(__COUNTER__), 2166136261 ))
namespace li { namespace detail {
namespace win {
struct LIST_ENTRY_T {
const char* Flink;
const char* Blink;
};
struct UNICODE_STRING_T {
unsigned short Length;
unsigned short MaximumLength;
wchar_t* Buffer;
};
struct PEB_LDR_DATA_T {
unsigned long Length;
unsigned long Initialized;
const char* SsHandle;
LIST_ENTRY_T InLoadOrderModuleList;
};
struct PEB_T {
unsigned char Reserved1[2];
unsigned char BeingDebugged;
unsigned char Reserved2[1];
const char* Reserved3[2];
PEB_LDR_DATA_T* Ldr;
};
struct LDR_DATA_TABLE_ENTRY_T {
LIST_ENTRY_T InLoadOrderLinks;
LIST_ENTRY_T InMemoryOrderLinks;
LIST_ENTRY_T InInitializationOrderLinks;
const char* DllBase;
const char* EntryPoint;
union {
unsigned long SizeOfImage;
const char* _dummy;
};
UNICODE_STRING_T FullDllName;
UNICODE_STRING_T BaseDllName;
LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*
load_order_next() const noexcept
{
return reinterpret_cast<const LDR_DATA_TABLE_ENTRY_T*>(
InLoadOrderLinks.Flink);
}
};
struct IMAGE_DOS_HEADER { // DOS .EXE header
unsigned short e_magic; // Magic number
unsigned short e_cblp; // Bytes on last page of file
unsigned short e_cp; // Pages in file
unsigned short e_crlc; // Relocations
unsigned short e_cparhdr; // Size of header in paragraphs
unsigned short e_minalloc; // Minimum extra paragraphs needed
unsigned short e_maxalloc; // Maximum extra paragraphs needed
unsigned short e_ss; // Initial (relative) SS value
unsigned short e_sp; // Initial SP value
unsigned short e_csum; // Checksum
unsigned short e_ip; // Initial IP value
unsigned short e_cs; // Initial (relative) CS value
unsigned short e_lfarlc; // File address of relocation table
unsigned short e_ovno; // Overlay number
unsigned short e_res[4]; // Reserved words
unsigned short e_oemid; // OEM identifier (for e_oeminfo)
unsigned short e_oeminfo; // OEM information; e_oemid specific
unsigned short e_res2[10]; // Reserved words
long e_lfanew; // File address of new exe header
};
struct IMAGE_FILE_HEADER {
unsigned short Machine;
unsigned short NumberOfSections;
unsigned long TimeDateStamp;
unsigned long PointerToSymbolTable;
unsigned long NumberOfSymbols;
unsigned short SizeOfOptionalHeader;
unsigned short Characteristics;
};
struct IMAGE_EXPORT_DIRECTORY {
unsigned long Characteristics;
unsigned long TimeDateStamp;
unsigned short MajorVersion;
unsigned short MinorVersion;
unsigned long Name;
unsigned long Base;
unsigned long NumberOfFunctions;
unsigned long NumberOfNames;
unsigned long AddressOfFunctions; // RVA from base of image
unsigned long AddressOfNames; // RVA from base of image
unsigned long AddressOfNameOrdinals; // RVA from base of image
};
struct IMAGE_DATA_DIRECTORY {
unsigned long VirtualAddress;
unsigned long Size;
};
struct IMAGE_OPTIONAL_HEADER64 {
unsigned short Magic;
unsigned char MajorLinkerVersion;
unsigned char MinorLinkerVersion;
unsigned long SizeOfCode;
unsigned long SizeOfInitializedData;
unsigned long SizeOfUninitializedData;
unsigned long AddressOfEntryPoint;
unsigned long BaseOfCode;
unsigned long long ImageBase;
unsigned long SectionAlignment;
unsigned long FileAlignment;
unsigned short MajorOperatingSystemVersion;
unsigned short MinorOperatingSystemVersion;
unsigned short MajorImageVersion;
unsigned short MinorImageVersion;
unsigned short MajorSubsystemVersion;
unsigned short MinorSubsystemVersion;
unsigned long Win32VersionValue;
unsigned long SizeOfImage;
unsigned long SizeOfHeaders;
unsigned long CheckSum;
unsigned short Subsystem;
unsigned short DllCharacteristics;
unsigned long long SizeOfStackReserve;
unsigned long long SizeOfStackCommit;
unsigned long long SizeOfHeapReserve;
unsigned long long SizeOfHeapCommit;
unsigned long LoaderFlags;
unsigned long NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
};
struct IMAGE_OPTIONAL_HEADER32 {
unsigned short Magic;
unsigned char MajorLinkerVersion;
unsigned char MinorLinkerVersion;
unsigned long SizeOfCode;
unsigned long SizeOfInitializedData;
unsigned long SizeOfUninitializedData;
unsigned long AddressOfEntryPoint;
unsigned long BaseOfCode;
unsigned long BaseOfData;
unsigned long ImageBase;
unsigned long SectionAlignment;
unsigned long FileAlignment;
unsigned short MajorOperatingSystemVersion;
unsigned short MinorOperatingSystemVersion;
unsigned short MajorImageVersion;
unsigned short MinorImageVersion;
unsigned short MajorSubsystemVersion;
unsigned short MinorSubsystemVersion;
unsigned long Win32VersionValue;
unsigned long SizeOfImage;
unsigned long SizeOfHeaders;
unsigned long CheckSum;
unsigned short Subsystem;
unsigned short DllCharacteristics;
unsigned long SizeOfStackReserve;
unsigned long SizeOfStackCommit;
unsigned long SizeOfHeapReserve;
unsigned long SizeOfHeapCommit;
unsigned long LoaderFlags;
unsigned long NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
};
struct IMAGE_NT_HEADERS {
unsigned long Signature;
IMAGE_FILE_HEADER FileHeader;
#ifdef _WIN64
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
#else
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
#endif
};
} // namespace win
struct forwarded_hashes {
unsigned module_hash;
unsigned function_hash;
};
// 64 bit integer where 32 bits are used for the hash offset
// and remaining 32 bits are used for the hash computed using it
using offset_hash_pair = unsigned long long;
LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_hash(offset_hash_pair pair) noexcept { return ( pair & 0xFFFFFFFF ); }
LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_offset(offset_hash_pair pair) noexcept { return static_cast<unsigned>( pair >> 32 ); }
template<bool CaseSensitive = LAZY_IMPORTER_CASE_SENSITIVITY>
LAZY_IMPORTER_FORCEINLINE constexpr unsigned hash_single(unsigned value, char c) noexcept
{
return (value ^ static_cast<unsigned>((!CaseSensitive && c >= 'A' && c <= 'Z') ? (c | (1 << 5)) : c)) * 16777619;
}
LAZY_IMPORTER_FORCEINLINE constexpr unsigned
khash_impl(const char* str, unsigned value) noexcept
{
return (*str ? khash_impl(str + 1, hash_single(value, *str)) : value);
}
LAZY_IMPORTER_FORCEINLINE constexpr offset_hash_pair khash(
const char* str, unsigned offset) noexcept
{
return ((offset_hash_pair{ offset } << 32) | khash_impl(str, offset));
}
template<class CharT = char>
LAZY_IMPORTER_FORCEINLINE unsigned hash(const CharT* str, unsigned offset) noexcept
{
unsigned value = offset;
for(;;) {
char c = *str++;
if(!c)
return value;
value = hash_single(value, c);
}
}
LAZY_IMPORTER_FORCEINLINE unsigned hash(
const win::UNICODE_STRING_T& str, unsigned offset) noexcept
{
auto first = str.Buffer;
const auto last = first + (str.Length / sizeof(wchar_t));
auto value = offset;
for(; first != last; ++first)
value = hash_single(value, static_cast<char>(*first));
return value;
}
LAZY_IMPORTER_FORCEINLINE forwarded_hashes hash_forwarded(
const char* str, unsigned offset) noexcept
{
forwarded_hashes res{ offset, offset };
for(; *str != '.'; ++str)
res.module_hash = hash_single<true>(res.module_hash, *str);
++str;
for(; *str; ++str)
res.function_hash = hash_single(res.function_hash, *str);
return res;
}
// some helper functions
LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept
{
#if defined(_M_X64) || defined(__amd64__)
#if defined(_MSC_VER)
return reinterpret_cast<const win::PEB_T*>(__readgsqword(0x60));
#else
const win::PEB_T* ptr;
__asm__ __volatile__ ("mov %%gs:0x60, %0" : "=r"(ptr));
return ptr;
#endif
#elif defined(_M_IX86) || defined(__i386__)
#if defined(_MSC_VER)
return reinterpret_cast<const win::PEB_T*>(__readfsdword(0x30));
#else
const win::PEB_T* ptr;
__asm__ __volatile__ ("mov %%fs:0x30, %0" : "=r"(ptr));
return ptr;
#endif
#elif defined(_M_ARM) || defined(__arm__)
return *reinterpret_cast<const win::PEB_T**>(_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0x30);
#elif defined(_M_ARM64) || defined(__aarch64__)
return *reinterpret_cast<const win::PEB_T**>(__getReg(18) + 0x60);
#elif defined(_M_IA64) || defined(__ia64__)
return *reinterpret_cast<const win::PEB_T**>(static_cast<char*>(_rdteb()) + 0x60);
#else
#error Unsupported platform. Open an issue and Ill probably add support.
#endif
}
LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()
{
return reinterpret_cast<const win::PEB_LDR_DATA_T*>(peb()->Ldr);
}
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(
const char* base) noexcept
{
return reinterpret_cast<const win::IMAGE_NT_HEADERS*>(
base + reinterpret_cast<const win::IMAGE_DOS_HEADER*>(base)->e_lfanew);
}
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir(
const char* base) noexcept
{
return reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(
base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress);
}
LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept
{
return reinterpret_cast<const win::LDR_DATA_TABLE_ENTRY_T*>(
ldr()->InLoadOrderModuleList.Flink);
}
struct exports_directory {
unsigned long _ied_size;
const char* _base;
const win::IMAGE_EXPORT_DIRECTORY* _ied;
public:
using size_type = unsigned long;
LAZY_IMPORTER_FORCEINLINE
exports_directory(const char* base) noexcept : _base(base)
{
const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0];
_ied = reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(
base + ied_data_dir.VirtualAddress);
_ied_size = ied_data_dir.Size;
}
LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept
{
return reinterpret_cast<const char*>(_ied) != _base;
}
LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept
{
return _ied->NumberOfNames;
}
LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; }
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept
{
return _ied;
}
LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept
{
return _base + reinterpret_cast<const unsigned long*>(_base + _ied->AddressOfNames)[index];
}
LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept
{
const auto* const rva_table =
reinterpret_cast<const unsigned long*>(_base + _ied->AddressOfFunctions);
const auto* const ord_table = reinterpret_cast<const unsigned short*>(
_base + _ied->AddressOfNameOrdinals);
return _base + rva_table[ord_table[index]];
}
LAZY_IMPORTER_FORCEINLINE bool is_forwarded(
const char* export_address) const noexcept
{
const auto ui_ied = reinterpret_cast<const char*>(_ied);
return (export_address > ui_ied && export_address < ui_ied + _ied_size);
}
};
struct safe_module_enumerator {
using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T;
value_type* value;
value_type* head;
LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept
: safe_module_enumerator(ldr_data_entry())
{}
LAZY_IMPORTER_FORCEINLINE
safe_module_enumerator(const detail::win::LDR_DATA_TABLE_ENTRY_T* ldr) noexcept
: value(ldr->load_order_next()), head(value)
{}
LAZY_IMPORTER_FORCEINLINE void reset() noexcept
{
value = head->load_order_next();
}
LAZY_IMPORTER_FORCEINLINE bool next() noexcept
{
value = value->load_order_next();
return value != head && value->DllBase;
}
};
struct unsafe_module_enumerator {
using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*;
value_type value;
LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept
: value(ldr_data_entry())
{}
LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); }
LAZY_IMPORTER_FORCEINLINE bool next() noexcept
{
value = value->load_order_next();
return true;
}
};
// provides the cached functions which use Derive classes methods
template<class Derived, class DefaultType = void*>
class lazy_base {
protected:
// This function is needed because every templated function
// with different args has its own static buffer
LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept
{
static void* value = nullptr;
return value;
}
public:
template<class T = DefaultType>
LAZY_IMPORTER_FORCEINLINE static T safe() noexcept
{
return Derived::template get<T, safe_module_enumerator>();
}
template<class T = DefaultType, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static T cached() noexcept
{
auto& cached = _cache();
if(!cached)
cached = Derived::template get<void*, Enum>();
return (T)(cached);
}
template<class T = DefaultType>
LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept
{
return cached<T, safe_module_enumerator>();
}
};
template<offset_hash_pair OHP>
struct lazy_module : lazy_base<lazy_module<OHP>> {
template<class T = void*, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static T get() noexcept
{
Enum e;
do {
if(hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))
return (T)(e.value->DllBase);
} while(e.next());
return {};
}
template<class T = void*, class Ldr>
LAZY_IMPORTER_FORCEINLINE static T in(Ldr ldr) noexcept
{
safe_module_enumerator e(reinterpret_cast<const detail::win::LDR_DATA_TABLE_ENTRY_T*>(ldr));
do {
if(hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))
return (T)(e.value->DllBase);
} while(e.next());
return {};
}
template<class T = void*, class Ldr>
LAZY_IMPORTER_FORCEINLINE static T in_cached(Ldr ldr) noexcept
{
auto& cached = lazy_base<lazy_module<OHP>>::_cache();
if(!cached)
cached = in(ldr);
return (T)(cached);
}
};
template<offset_hash_pair OHP, class T>
struct lazy_function : lazy_base<lazy_function<OHP, T>, T> {
using base_type = lazy_base<lazy_function<OHP, T>, T>;
template<class... Args>
LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const
{
#ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS
return get()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);
#else
return this->cached()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);
#endif
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F get() noexcept
{
// for backwards compatability.
// Before 2.0 it was only possible to resolve forwarded exports when
// this macro was enabled
#ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS
return forwarded<F, Enum>();
#else
Enum e;
do {
#ifdef LAZY_IMPORTER_HARDENED_MODULE_CHECKS
if(!e.value->DllBase || !e.value->FullDllName.Length)
continue;
#endif
const exports_directory exports(e.value->DllBase);
if(exports) {
auto export_index = exports.size();
while(export_index--)
if(hash(exports.name(export_index), get_offset(OHP)) == get_hash(OHP))
return (F)(exports.address(export_index));
}
} while(e.next());
return {};
#endif
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept
{
detail::win::UNICODE_STRING_T name;
forwarded_hashes hashes{ 0, get_hash(OHP) };
Enum e;
do {
name = e.value->BaseDllName;
name.Length -= 8; // get rid of .dll extension
if(!hashes.module_hash || hash(name, get_offset(OHP)) == hashes.module_hash) {
const exports_directory exports(e.value->DllBase);
if(exports) {
auto export_index = exports.size();
while(export_index--)
if(hash(exports.name(export_index), get_offset(OHP)) == hashes.function_hash) {
const auto addr = exports.address(export_index);
if(exports.is_forwarded(addr)) {
hashes = hash_forwarded(
reinterpret_cast<const char*>(addr),
get_offset(OHP));
e.reset();
break;
}
return (F)(addr);
}
}
}
} while(e.next());
return {};
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept
{
return forwarded<F, safe_module_enumerator>();
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept
{
auto& value = base_type::_cache();
if(!value)
value = forwarded<void*, Enum>();
return (F)(value);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept
{
return forwarded_cached<F, safe_module_enumerator>();
}
template<class F = T, bool IsSafe = false, class Module>
LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept
{
if(IsSafe && !m)
return {};
const exports_directory exports((const char*)(m));
if(IsSafe && !exports)
return {};
for(unsigned long i{};; ++i) {
if(IsSafe && i == exports.size())
break;
if(hash(exports.name(i), get_offset(OHP)) == get_hash(OHP))
return (F)(exports.address(i));
}
return {};
}
template<class F = T, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept
{
return in<F, true>(m);
}
template<class F = T, bool IsSafe = false, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept
{
auto& value = base_type::_cache();
if(!value)
value = in<void*, IsSafe>(m);
return (F)(value);
}
template<class F = T, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept
{
return in_cached<F, true>(m);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt() noexcept
{
return in<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept
{
return in_safe<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept
{
return in_cached<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept
{
return in_safe_cached<F>(ldr_data_entry()->load_order_next()->DllBase);
}
};
}} // namespace li::detail
#endif // include guard

View File

@@ -0,0 +1,456 @@
#pragma once
#ifndef DIRECT_SYSCALL_HPP
#define DIRECT_SYSCALL_HPP
#include <cstdint>
#include <string>
#include <windows.h>
#ifndef SYSCALL_NO_FORCEINLINE
#if defined(_MSC_VER)
#define SYSCALL_FORCEINLINE __forceinline
#endif
#else
#define SYSCALL_FORCEINLINE inline
#endif
#include <intrin.h>
#include <memory>
#include <vector>
#define SYSCALL_HASH_CT(str) \
[]() [[msvc::forceinline]] { \
constexpr uint32_t hash_out{::syscall::fnv1a::hash_ctime(str)}; \
\
return hash_out; \
}()
#define SYSCALL_HASH(str) ::syscall::fnv1a::hash_rtime(str)
#define INVOKE_LAZY_FN(type, export_name, ...) \
[&]() [[msvc::forceinline]] { \
constexpr uint32_t export_hash{::syscall::fnv1a::hash_ctime(#export_name)}; \
\
return syscall::invoke_lazy_import<type>(export_hash, __VA_ARGS__); \
}()
#define INVOKE_SYSCALL(type, export_name, ...) \
[&]() [[msvc::forceinline]] { \
constexpr uint32_t export_hash{::syscall::fnv1a::hash_ctime(#export_name)}; \
\
return syscall::invoke_syscall<type>(export_hash, __VA_ARGS__); \
}()
namespace syscall {
namespace nt {
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
struct UNICODE_STRING {
uint16_t Length;
uint16_t MaximumLength;
wchar_t* Buffer;
};
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, * PLDR_MODULE;
typedef struct _PEB_FREE_BLOCK {
_PEB_FREE_BLOCK* Next;
ULONG Size;
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
PVOID Reserved2[2];
PVOID DllBase;
PVOID EntryPoint;
PVOID Reserved3;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
PVOID Reserved5[3];
union {
ULONG CheckSum;
PVOID Reserved6;
};
ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StdInputHandle;
HANDLE StdOutputHandle;
HANDLE StdErrorHandle;
UNICODE_STRING CurrentDirectoryPath;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingPositionLeft;
ULONG StartingPositionTop;
ULONG Width;
ULONG Height;
ULONG CharWidth;
ULONG CharHeight;
ULONG ConsoleTextAttributes;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopName;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
RTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
uintptr_t FastPebLockRoutine;
uintptr_t FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
uintptr_t KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
uintptr_t ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
uintptr_t* ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, * PPEB;
}// namespace nt
constexpr uint32_t xor_key_1 = __TIME__[2];
constexpr uint32_t xor_key_2 = __TIME__[4];
constexpr uint32_t xor_key_offset = (xor_key_1 ^ xor_key_2);
namespace fnv1a {
constexpr uint32_t fnv_prime_value = 0x01000193;
SYSCALL_FORCEINLINE consteval uint32_t hash_ctime(const char* input, unsigned val = 0x811c9dc5 ^ ::syscall::xor_key_offset) noexcept
{
return input[0] == CS_XOR('\0') ? val : hash_ctime(input + 1, (val ^ *input) * fnv_prime_value);
}
SYSCALL_FORCEINLINE constexpr uint32_t hash_rtime(const char* input, unsigned val = 0x811c9dc5 ^ ::syscall::xor_key_offset) noexcept
{
return input[0] == CS_XOR('\0') ? val : hash_rtime(input + 1, (val ^ *input) * fnv_prime_value);
}
}// namespace fnv1a
namespace utils {
SYSCALL_FORCEINLINE std::string wide_to_string(wchar_t* buffer) noexcept
{
const auto out{ std::wstring(buffer) };
if (out.empty())
return "";
return std::string(out.begin(), out.end());
}
}// namespace utils
namespace win {
SYSCALL_FORCEINLINE nt::PEB* get_peb() noexcept
{
#if defined(_M_IX86) || defined(__i386__)
return reinterpret_cast<::syscall::nt::PEB*>(__readfsdword(0x30));
#else
return reinterpret_cast<::syscall::nt::PEB*>(__readgsqword(0x60));
#endif
}
template<typename T>
static SYSCALL_FORCEINLINE T get_module_handle_from_hash(const uint32_t& module_hash) noexcept
{
auto peb = ::syscall::win::get_peb();
if (!peb)
return NULL;
auto head = &peb->LoaderData->InLoadOrderModuleList;
for (auto it = head->Flink; it != head; it = it->Flink) {
::syscall::nt::_LDR_DATA_TABLE_ENTRY* ldr_entry = CONTAINING_RECORD(it, nt::LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if (!ldr_entry->BaseDllName.Buffer)
continue;
auto name = ::syscall::utils::wide_to_string(ldr_entry->BaseDllName.Buffer);
if (SYSCALL_HASH(name.data()) == module_hash)
return reinterpret_cast<T>(ldr_entry->DllBase);
}
return NULL;
}
template<typename T>
static SYSCALL_FORCEINLINE T get_module_export_from_table(uintptr_t module_address,
const uint32_t& export_hash) noexcept
{
auto dos_headers = reinterpret_cast<IMAGE_DOS_HEADER*>(module_address);
if (dos_headers->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
PIMAGE_EXPORT_DIRECTORY export_directory = nullptr;
auto nt_headers32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(module_address + dos_headers->e_lfanew);
auto nt_headers64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(module_address + dos_headers->e_lfanew);
PIMAGE_OPTIONAL_HEADER32 optional_header32 = &nt_headers32->OptionalHeader;
PIMAGE_OPTIONAL_HEADER64 optional_header64 = &nt_headers64->OptionalHeader;
// for 32bit modules.
if (nt_headers32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
// does not have a export table.
if (optional_header32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size <= 0U)
return NULL;
export_directory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(module_address + optional_header32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
}
// for 64bit modules.
else if (nt_headers64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
// does not have a export table.
if (optional_header64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size <= 0U)
return NULL;
export_directory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(module_address + optional_header64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
}
auto names_rva = reinterpret_cast<uint32_t*>(module_address + export_directory->AddressOfNames);
auto functions_rva = reinterpret_cast<uint32_t*>(module_address + export_directory->AddressOfFunctions);
auto name_ordinals = reinterpret_cast<unsigned short*>(module_address + export_directory->AddressOfNameOrdinals);
uint32_t number_of_names = export_directory->NumberOfNames;
for (size_t i = 0ul; i < number_of_names; i++) {
const char* export_name = reinterpret_cast<const char*>(module_address + names_rva[i]);
if (export_hash == SYSCALL_HASH(export_name))
return static_cast<T>(module_address + functions_rva[name_ordinals[i]]);
}
return NULL;
}
template<typename T>
SYSCALL_FORCEINLINE T force_find_export(const uint32_t& export_hash) noexcept
{
auto peb = ::syscall::win::get_peb();
if (!peb || !export_hash)
return NULL;
auto head = &peb->LoaderData->InLoadOrderModuleList;
for (auto it = head->Flink; it != head; it = it->Flink) {
::syscall::nt::_LDR_DATA_TABLE_ENTRY* ldr_entry = CONTAINING_RECORD(it,
nt::LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if (!ldr_entry->BaseDllName.Buffer)
continue;
auto name = ::syscall::utils::wide_to_string(ldr_entry->BaseDllName.Buffer);
auto export_address = ::syscall::win::get_module_export_from_table<uintptr_t>(
reinterpret_cast<uintptr_t>(ldr_entry->DllBase),
export_hash);
if (!export_address)
continue;
return static_cast<T>(export_address);
}
}
}// namespace win
SYSCALL_FORCEINLINE uint16_t get_return_code_from_export(uintptr_t export_address) noexcept
{
if (!export_address)
return NULL;
return *reinterpret_cast<int*>(static_cast<uintptr_t>(export_address + 12) + 1);
}
SYSCALL_FORCEINLINE int get_syscall_id_from_export(uintptr_t export_address) noexcept
{
if (!export_address)
return NULL;
#if defined(_M_IX86) || defined(__i386__)
return *reinterpret_cast<int*>(static_cast<uintptr_t>(export_address) + 1);
#else
return *reinterpret_cast<int*>(static_cast<uintptr_t>(export_address + 3) + 1);
#endif
}
struct create_function {
void* _allocated_memory = nullptr;
void* _function = nullptr;
uint32_t _export_hash;
public:
SYSCALL_FORCEINLINE ~create_function() noexcept
{
if (this->_allocated_memory) {
VirtualFree(this->_allocated_memory, 0, MEM_RELEASE);
this->_allocated_memory = nullptr;
}
}
SYSCALL_FORCEINLINE create_function(uint32_t export_hash) noexcept
: _export_hash(export_hash)
{
static auto exported_address = ::syscall::win::force_find_export<uintptr_t>(this->_export_hash);
static auto syscall_table_id = ::syscall::get_syscall_id_from_export(exported_address);
if (!exported_address || !syscall_table_id)
return;
std::vector<uint8_t> shellcode = {
#if defined(_M_IX86) || defined(__i386__)
0xB8, 0x00, 0x10, 0x00, 0x00, // mov eax, <syscall_id>
0x64, 0x8B, 0x15, 0xC0, 0x00, 0x00, 0x00,// mov edx, DWORD PTR fs:0xc0 (
0xFF, 0xD2, // call edx
0xC2, 0x04, 0x00 // ret 4
#else
0x49, 0x89, 0xCA, // mov r10, rcx
0xB8, 0x3F, 0x10, 0x00, 0x00, // mov eax, <syscall_id>
0x0F, 0x05, // syscall
0xC3 // ret
#endif
};
#if defined(_M_IX86) || defined(__i386__)
// required for x86 ONLY!
* reinterpret_cast<uint16_t*>(&shellcode[15]) = ::syscall::get_return_code_from_export(exported_address);
*reinterpret_cast<int*>(&shellcode[1]) = syscall_table_id;
#else
* reinterpret_cast<int*>(&shellcode[4]) = syscall_table_id;
#endif
this->_allocated_memory = VirtualAlloc(nullptr,
sizeof(shellcode),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (!this->_allocated_memory) {
return;
}
memcpy(this->_allocated_memory, shellcode.data(), sizeof(shellcode));
*reinterpret_cast<void**>(&this->_function) = this->_allocated_memory;
}
SYSCALL_FORCEINLINE bool is_valid_address() noexcept
{
return this->_function != nullptr;
}
template<typename T, typename... Args>
SYSCALL_FORCEINLINE T invoke_call(Args... arguments) noexcept
{
return reinterpret_cast<T(__stdcall*)(Args...)>(this->_function)(arguments...);
}
};
template<typename T, typename... Args>
SYSCALL_FORCEINLINE T invoke_syscall(uint32_t export_hash, Args... arguments) noexcept
{
static auto syscall_function = ::syscall::create_function(export_hash);
if (!syscall_function.is_valid_address()) {
return NULL;
}
return syscall_function.invoke_call<T>(arguments...);
}
template<typename T, typename... Args>
SYSCALL_FORCEINLINE T invoke_lazy_import(uint32_t export_hash, Args... arguments) noexcept
{
static auto exported_function = ::syscall::win::force_find_export<uintptr_t>(export_hash);
if (exported_function)
return reinterpret_cast<T(__stdcall*)(Args...)>(exported_function)(arguments...);
}
}// namespace syscall
#endif// DIRECT_SYSCALL_HPP

View File

@@ -0,0 +1,189 @@
/******************************************************************************
Header: VirtualizerSDKCustomVMsMacros.h
Description: Definition of CustomVM macros
Author/s: Oreans Technologies
(c) 2015 Oreans Technologies
--- File generated automatically from Oreans VM Generator (16/6/2015) ---
******************************************************************************/
// ****************************************************************************
// Declaration of Custom VM macros
// ****************************************************************************
#define PLATFORM_X64 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined(PLATFORM_X32)
void __stdcall VIRTUALIZER_TIGER_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_TIGER_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_TIGER_RED_START_ASM32();
void __stdcall VIRTUALIZER_TIGER_RED_END_ASM32();
void __stdcall VIRTUALIZER_TIGER_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_TIGER_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_FISH_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_FISH_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_FISH_RED_START_ASM32();
void __stdcall VIRTUALIZER_FISH_RED_END_ASM32();
void __stdcall VIRTUALIZER_FISH_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_FISH_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_PUMA_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_PUMA_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_PUMA_RED_START_ASM32();
void __stdcall VIRTUALIZER_PUMA_RED_END_ASM32();
void __stdcall VIRTUALIZER_PUMA_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_PUMA_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_SHARK_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_SHARK_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_SHARK_RED_START_ASM32();
void __stdcall VIRTUALIZER_SHARK_RED_END_ASM32();
void __stdcall VIRTUALIZER_SHARK_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_SHARK_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_RED_START_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_RED_END_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_DOLPHIN_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_EAGLE_WHITE_START_ASM32();
void __stdcall VIRTUALIZER_EAGLE_WHITE_END_ASM32();
void __stdcall VIRTUALIZER_EAGLE_RED_START_ASM32();
void __stdcall VIRTUALIZER_EAGLE_RED_END_ASM32();
void __stdcall VIRTUALIZER_EAGLE_BLACK_START_ASM32();
void __stdcall VIRTUALIZER_EAGLE_BLACK_END_ASM32();
void __stdcall VIRTUALIZER_MUTATE_ONLY_START_ASM32();
void __stdcall VIRTUALIZER_MUTATE_ONLY_END_ASM32();
#define VIRTUALIZER_TIGER_WHITE_START VIRTUALIZER_TIGER_WHITE_START_ASM32();
#define VIRTUALIZER_TIGER_WHITE_END VIRTUALIZER_TIGER_WHITE_END_ASM32();
#define VIRTUALIZER_TIGER_RED_START VIRTUALIZER_TIGER_RED_START_ASM32();
#define VIRTUALIZER_TIGER_RED_END VIRTUALIZER_TIGER_RED_END_ASM32();
#define VIRTUALIZER_TIGER_BLACK_START VIRTUALIZER_TIGER_BLACK_START_ASM32();
#define VIRTUALIZER_TIGER_BLACK_END VIRTUALIZER_TIGER_BLACK_END_ASM32();
#define VIRTUALIZER_FISH_WHITE_START VIRTUALIZER_FISH_WHITE_START_ASM32();
#define VIRTUALIZER_FISH_WHITE_END VIRTUALIZER_FISH_WHITE_END_ASM32();
#define VIRTUALIZER_FISH_RED_START VIRTUALIZER_FISH_RED_START_ASM32();
#define VIRTUALIZER_FISH_RED_END VIRTUALIZER_FISH_RED_END_ASM32();
#define VIRTUALIZER_FISH_BLACK_START VIRTUALIZER_FISH_BLACK_START_ASM32();
#define VIRTUALIZER_FISH_BLACK_END VIRTUALIZER_FISH_BLACK_END_ASM32();
#define VIRTUALIZER_PUMA_WHITE_START VIRTUALIZER_PUMA_WHITE_START_ASM32();
#define VIRTUALIZER_PUMA_WHITE_END VIRTUALIZER_PUMA_WHITE_END_ASM32();
#define VIRTUALIZER_PUMA_RED_START VIRTUALIZER_PUMA_RED_START_ASM32();
#define VIRTUALIZER_PUMA_RED_END VIRTUALIZER_PUMA_RED_END_ASM32();
#define VIRTUALIZER_PUMA_BLACK_START VIRTUALIZER_PUMA_BLACK_START_ASM32();
#define VIRTUALIZER_PUMA_BLACK_END VIRTUALIZER_PUMA_BLACK_END_ASM32();
#define VIRTUALIZER_SHARK_WHITE_START VIRTUALIZER_SHARK_WHITE_START_ASM32();
#define VIRTUALIZER_SHARK_WHITE_END VIRTUALIZER_SHARK_WHITE_END_ASM32();
#define VIRTUALIZER_SHARK_RED_START VIRTUALIZER_SHARK_RED_START_ASM32();
#define VIRTUALIZER_SHARK_RED_END VIRTUALIZER_SHARK_RED_END_ASM32();
#define VIRTUALIZER_SHARK_BLACK_START VIRTUALIZER_SHARK_BLACK_START_ASM32();
#define VIRTUALIZER_SHARK_BLACK_END VIRTUALIZER_SHARK_BLACK_END_ASM32();
#define VIRTUALIZER_DOLPHIN_WHITE_START VIRTUALIZER_DOLPHIN_WHITE_START_ASM32();
#define VIRTUALIZER_DOLPHIN_WHITE_END VIRTUALIZER_DOLPHIN_WHITE_END_ASM32();
#define VIRTUALIZER_DOLPHIN_RED_START VIRTUALIZER_DOLPHIN_RED_START_ASM32();
#define VIRTUALIZER_DOLPHIN_RED_END VIRTUALIZER_DOLPHIN_RED_END_ASM32();
#define VIRTUALIZER_DOLPHIN_BLACK_START VIRTUALIZER_DOLPHIN_BLACK_START_ASM32();
#define VIRTUALIZER_DOLPHIN_BLACK_END VIRTUALIZER_DOLPHIN_BLACK_END_ASM32();
#define VIRTUALIZER_EAGLE_WHITE_START VIRTUALIZER_EAGLE_WHITE_START_ASM32();
#define VIRTUALIZER_EAGLE_WHITE_END VIRTUALIZER_EAGLE_WHITE_END_ASM32();
#define VIRTUALIZER_EAGLE_RED_START VIRTUALIZER_EAGLE_RED_START_ASM32();
#define VIRTUALIZER_EAGLE_RED_END VIRTUALIZER_EAGLE_RED_END_ASM32();
#define VIRTUALIZER_EAGLE_BLACK_START VIRTUALIZER_EAGLE_BLACK_START_ASM32();
#define VIRTUALIZER_EAGLE_BLACK_END VIRTUALIZER_EAGLE_BLACK_END_ASM32();
#define VIRTUALIZER_MUTATE_ONLY_START VIRTUALIZER_MUTATE_ONLY_START_ASM32();
#define VIRTUALIZER_MUTATE_ONLY_END VIRTUALIZER_MUTATE_ONLY_END_ASM32();
#endif
#if defined(PLATFORM_X64)
void __stdcall VIRTUALIZER_TIGER_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_TIGER_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_TIGER_RED_START_ASM64();
void __stdcall VIRTUALIZER_TIGER_RED_END_ASM64();
void __stdcall VIRTUALIZER_TIGER_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_TIGER_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_FISH_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_FISH_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_FISH_RED_START_ASM64();
void __stdcall VIRTUALIZER_FISH_RED_END_ASM64();
void __stdcall VIRTUALIZER_FISH_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_FISH_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_PUMA_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_PUMA_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_PUMA_RED_START_ASM64();
void __stdcall VIRTUALIZER_PUMA_RED_END_ASM64();
void __stdcall VIRTUALIZER_PUMA_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_PUMA_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_SHARK_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_SHARK_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_SHARK_RED_START_ASM64();
void __stdcall VIRTUALIZER_SHARK_RED_END_ASM64();
void __stdcall VIRTUALIZER_SHARK_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_SHARK_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_RED_START_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_RED_END_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_DOLPHIN_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_EAGLE_WHITE_START_ASM64();
void __stdcall VIRTUALIZER_EAGLE_WHITE_END_ASM64();
void __stdcall VIRTUALIZER_EAGLE_RED_START_ASM64();
void __stdcall VIRTUALIZER_EAGLE_RED_END_ASM64();
void __stdcall VIRTUALIZER_EAGLE_BLACK_START_ASM64();
void __stdcall VIRTUALIZER_EAGLE_BLACK_END_ASM64();
void __stdcall VIRTUALIZER_MUTATE_ONLY_START_ASM64();
void __stdcall VIRTUALIZER_MUTATE_ONLY_END_ASM64();
#define VIRTUALIZER_TIGER_WHITE_START VIRTUALIZER_TIGER_WHITE_START_ASM64();
#define VIRTUALIZER_TIGER_WHITE_END VIRTUALIZER_TIGER_WHITE_END_ASM64();
#define VIRTUALIZER_TIGER_RED_START VIRTUALIZER_TIGER_RED_START_ASM64();
#define VIRTUALIZER_TIGER_RED_END VIRTUALIZER_TIGER_RED_END_ASM64();
#define VIRTUALIZER_TIGER_BLACK_START VIRTUALIZER_TIGER_BLACK_START_ASM64();
#define VIRTUALIZER_TIGER_BLACK_END VIRTUALIZER_TIGER_BLACK_END_ASM64();
#define VIRTUALIZER_FISH_WHITE_START VIRTUALIZER_FISH_WHITE_START_ASM64();
#define VIRTUALIZER_FISH_WHITE_END VIRTUALIZER_FISH_WHITE_END_ASM64();
#define VIRTUALIZER_FISH_RED_START VIRTUALIZER_FISH_RED_START_ASM64();
#define VIRTUALIZER_FISH_RED_END VIRTUALIZER_FISH_RED_END_ASM64();
#define VIRTUALIZER_FISH_BLACK_START VIRTUALIZER_FISH_BLACK_START_ASM64();
#define VIRTUALIZER_FISH_BLACK_END VIRTUALIZER_FISH_BLACK_END_ASM64();
#define VIRTUALIZER_PUMA_WHITE_START VIRTUALIZER_PUMA_WHITE_START_ASM64();
#define VIRTUALIZER_PUMA_WHITE_END VIRTUALIZER_PUMA_WHITE_END_ASM64();
#define VIRTUALIZER_PUMA_RED_START VIRTUALIZER_PUMA_RED_START_ASM64();
#define VIRTUALIZER_PUMA_RED_END VIRTUALIZER_PUMA_RED_END_ASM64();
#define VIRTUALIZER_PUMA_BLACK_START VIRTUALIZER_PUMA_BLACK_START_ASM64();
#define VIRTUALIZER_PUMA_BLACK_END VIRTUALIZER_PUMA_BLACK_END_ASM64();
#define VIRTUALIZER_SHARK_WHITE_START VIRTUALIZER_SHARK_WHITE_START_ASM64();
#define VIRTUALIZER_SHARK_WHITE_END VIRTUALIZER_SHARK_WHITE_END_ASM64();
#define VIRTUALIZER_SHARK_RED_START VIRTUALIZER_SHARK_RED_START_ASM64();
#define VIRTUALIZER_SHARK_RED_END VIRTUALIZER_SHARK_RED_END_ASM64();
#define VIRTUALIZER_SHARK_BLACK_START VIRTUALIZER_SHARK_BLACK_START_ASM64();
#define VIRTUALIZER_SHARK_BLACK_END VIRTUALIZER_SHARK_BLACK_END_ASM64();
#define VIRTUALIZER_DOLPHIN_WHITE_START VIRTUALIZER_DOLPHIN_WHITE_START_ASM64();
#define VIRTUALIZER_DOLPHIN_WHITE_END VIRTUALIZER_DOLPHIN_WHITE_END_ASM64();
#define VIRTUALIZER_DOLPHIN_RED_START VIRTUALIZER_DOLPHIN_RED_START_ASM64();
#define VIRTUALIZER_DOLPHIN_RED_END VIRTUALIZER_DOLPHIN_RED_END_ASM64();
#define VIRTUALIZER_DOLPHIN_BLACK_START VIRTUALIZER_DOLPHIN_BLACK_START_ASM64();
#define VIRTUALIZER_DOLPHIN_BLACK_END VIRTUALIZER_DOLPHIN_BLACK_END_ASM64();
#define VIRTUALIZER_EAGLE_WHITE_START VIRTUALIZER_EAGLE_WHITE_START_ASM64();
#define VIRTUALIZER_EAGLE_WHITE_END VIRTUALIZER_EAGLE_WHITE_END_ASM64();
#define VIRTUALIZER_EAGLE_RED_START VIRTUALIZER_EAGLE_RED_START_ASM64();
#define VIRTUALIZER_EAGLE_RED_END VIRTUALIZER_EAGLE_RED_END_ASM64();
#define VIRTUALIZER_EAGLE_BLACK_START VIRTUALIZER_EAGLE_BLACK_START_ASM64();
#define VIRTUALIZER_EAGLE_BLACK_END VIRTUALIZER_EAGLE_BLACK_END_ASM64();
#define VIRTUALIZER_MUTATE_ONLY_START VIRTUALIZER_MUTATE_ONLY_START_ASM64();
#define VIRTUALIZER_MUTATE_ONLY_END VIRTUALIZER_MUTATE_ONLY_END_ASM64();
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,394 @@
; ******************************************************************************
; Header: VirtualizerSDK_CustomVMs_masm64.inc
; Description: MASM64 macros definitions
;
; Author/s: Oreans Technologies
; (c) 2015 Oreans Technologies
;
; --- File generated automatically from Oreans VM Generator (16/6/2015) ---
; ******************************************************************************
; ******************************************************************************
; Macros definition
; ******************************************************************************
VIRTUALIZER_TIGER_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 103
dd 0
dd 20205643h
ENDM
VIRTUALIZER_TIGER_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 503
dd 0
dd 20205643h
ENDM
VIRTUALIZER_TIGER_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 104
dd 0
dd 20205643h
ENDM
VIRTUALIZER_TIGER_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 504
dd 0
dd 20205643h
ENDM
VIRTUALIZER_TIGER_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 105
dd 0
dd 20205643h
ENDM
VIRTUALIZER_TIGER_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 505
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 107
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 507
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 109
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 509
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 111
dd 0
dd 20205643h
ENDM
VIRTUALIZER_FISH_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 511
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 113
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 513
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 115
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 515
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 117
dd 0
dd 20205643h
ENDM
VIRTUALIZER_PUMA_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 517
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 119
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 519
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 121
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 521
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 123
dd 0
dd 20205643h
ENDM
VIRTUALIZER_SHARK_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 523
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 135
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 535
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 137
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 537
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 139
dd 0
dd 20205643h
ENDM
VIRTUALIZER_DOLPHIN_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 539
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_WHITE_START MACRO
db 0ebh, 10h
dd 20205643h
dd 147
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_WHITE_END MACRO
db 0ebh, 10h
dd 20205643h
dd 547
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_RED_START MACRO
db 0ebh, 10h
dd 20205643h
dd 149
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_RED_END MACRO
db 0ebh, 10h
dd 20205643h
dd 549
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_BLACK_START MACRO
db 0ebh, 10h
dd 20205643h
dd 151
dd 0
dd 20205643h
ENDM
VIRTUALIZER_EAGLE_BLACK_END MACRO
db 0ebh, 10h
dd 20205643h
dd 551
dd 0
dd 20205643h
ENDM
VIRTUALIZER_MUTATE_ONLY_START MACRO
db 0ebh, 10h
dd 20205643h
dd 16
dd 0
dd 20205643h
ENDM
VIRTUALIZER_MUTATE_ONLY_END MACRO
db 0ebh, 10h
dd 20205643h
dd 17
dd 0
dd 20205643h
ENDM

View File

@@ -0,0 +1,226 @@
/**
* @file stb.hh
* @author Cristei Gabriel-Marian (cristei.g772@gmail.com)
* @brief Compile-time String To Bytes (STB)
* @version 1.0
* @date 2023-03-23
*
* Last update: 03/23/2023 (mm/dd/yyyy): [Breaking update]
* Modernize, undo some cancer, change some naming, file structure,
* implement tests directly in file.
*
*/
#ifndef STB_DEFINED
#define STB_DEFINED
#include <cstdint>
#include <array>
namespace stb {
namespace detail {
// detail methods assume null terminator.
template<std::size_t N>
constexpr auto find_first_of_start(std::array<char, N> const& data, std::size_t start, char ch) noexcept {
std::size_t idx = start;
while (data[idx] != ch && idx < N)
++idx;
return idx;
}
template<std::size_t N>
constexpr auto find_first_not_of_start(std::array<char, N> const& data, std::size_t start, char ch) noexcept {
if (start < N && data[start] != ch)
return start;
std::size_t idx = start;
while (data[idx] == ch && idx < N)
++idx;
return idx;
}
template<std::size_t N>
constexpr auto find_last_of(std::array<char, N> const& data, char ch) noexcept {
std::size_t idx = data.size() - 2;
while (data[idx] != ch && idx >= 0)
--idx;
return idx;
}
template<std::size_t N>
constexpr auto find_last_not_of(std::array<char, N> const& data, char ch) noexcept {
std::size_t idx = data.size() - 2;
while (data[idx] == ch && idx >= 0)
--idx;
return idx;
}
constexpr auto char_to_hex(char ch) noexcept {
if (ch >= '0' && ch <= '9')
return ch - '0';
if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
return ch - 'a' + 10;
}
template<typename T, T F = 16>
constexpr T concat_hex(T lhs, T rhs) noexcept {
return F * lhs + rhs;
}
} // namespace detail
template<auto V>
struct consteval_value {
constexpr static decltype(V) value = V;
};
template<std::size_t N>
struct fixed_string: public std::array<char, N + 1> {
using std::array<char, N + 1>::array;
constexpr fixed_string(const char* str) noexcept
: std::array<char, N + 1>() {
for (auto i = 0; i != N; ++i)
(*this)[i] = str[i];
}
};
template<std::size_t N>
fixed_string(const char (&)[N]) noexcept -> fixed_string<N - 1>;
template<char delimiter, char mask, typename element_type, element_type masked>
struct basic_hex_string_array_conversion {
template<fixed_string str>
struct build {
private:
struct parse {
struct result {
std::size_t delimiter_count;
std::size_t start;
std::size_t next;
std::size_t end;
};
constexpr static auto get() noexcept {
std::size_t count = 1;
constexpr std::size_t start = detail::find_first_not_of_start(str, 0, delimiter);
constexpr std::size_t next = detail::find_first_of_start(str, start, delimiter);
constexpr std::size_t end = detail::find_last_not_of(str, delimiter);
bool previous_delimiter = false;
for (auto i = next; i < end; ++i) {
if (str[i] == delimiter) {
if (!previous_delimiter)
++count;
previous_delimiter = true;
} else
previous_delimiter = false;
}
return result {
count,
start,
next,
end};
}
};
constexpr static auto make() noexcept {
constexpr auto data = parse::get();
constexpr auto count = data.delimiter_count;
constexpr auto start = data.start;
constexpr auto next = data.next;
constexpr auto end = data.end;
std::array<element_type, count> result = {};
std::array<std::size_t, count> skips = {};
std::size_t skipped = 0;
std::size_t traversed = start;
bool previous_skip = false;
for (auto i = start; i < end; ++i) {
if (str[i] == delimiter) {
if (!previous_skip)
skips[skipped++] = traversed;
previous_skip = true;
} else
previous_skip = false;
++traversed;
}
bool one_char = str[start + 1] == delimiter;
result[0] = static_cast<element_type>(str[start] == mask ? masked : (one_char ? detail::char_to_hex(str[start]) : detail::concat_hex(detail::char_to_hex(str[start]), detail::char_to_hex(str[start + 1]))));
std::size_t conversions = 1;
for (auto i = next; i < end; ++i) {
for (auto entry : skips) {
if (entry == i && entry < end) {
std::size_t idx = detail::find_first_not_of_start(str, i + 1, delimiter);
one_char = str[idx + 1] == delimiter;
result[conversions++] = static_cast<element_type>(str[idx] == mask ? masked : (one_char ? detail::char_to_hex(str[idx]) : detail::concat_hex(detail::char_to_hex(str[idx]), detail::char_to_hex(str[idx + 1]))));
}
}
}
return result;
}
public:
constexpr static auto value = consteval_value<make()>::value;
};
};
using hex_string_array_conversion = basic_hex_string_array_conversion<' ', '?', int, -1>;
using simple_conversion = hex_string_array_conversion;
} // namespace stb
#ifndef STB_OMIT_TESTS
struct _ignore_me_stb_compliance_tests {
using conv_type = stb::simple_conversion;
constexpr static auto value_1 = conv_type::build<"AA BB CC DD EE FF">::value;
static_assert(value_1[0] == 0xAA);
static_assert(value_1[1] == 0xBB);
static_assert(value_1[2] == 0xCC);
static_assert(value_1[3] == 0xDD);
static_assert(value_1[4] == 0xEE);
static_assert(value_1[5] == 0xFF);
static_assert(value_1.size() == 6);
constexpr static auto value_2 = conv_type::build<" C 0f C a B ef ">::value;
static_assert(value_2[0] == 0x0C);
static_assert(value_2[1] == 0x0F);
static_assert(value_2[2] == 0x0C);
static_assert(value_2[3] == 0x0A);
static_assert(value_2[4] == 0x0B);
static_assert(value_2[5] == 0xEF);
static_assert(value_2.size() == 6);
constexpr static auto value_3 = conv_type::build<"AA bb CC dd ">::value;
static_assert(value_3[0] == 0xAA);
static_assert(value_3[1] == 0xBB);
static_assert(value_3[2] == 0xCC);
static_assert(value_3[3] == 0xDD);
static_assert(value_3.size() == 4);
constexpr static auto value_4 = conv_type::build<" aa bb ee ff">::value;
static_assert(value_4[0] == 0xAA);
static_assert(value_4[1] == 0xBB);
static_assert(value_4[2] == 0xEE);
static_assert(value_4[3] == 0xFF);
static_assert(value_4.size() == 4);
};
#endif
#endif

View File

@@ -0,0 +1,129 @@
#pragma once
// File: 'sesame_icons.ttf' (5736 bytes)
// Exported using binary_to_compressed_c.cpp
static const unsigned int sesame_icons_size = 5736;
static const unsigned int sesame_icons_data[5736/4] =
{
0x00000100, 0x80000e00, 0x60000300, 0x4d544646, 0xe7b54b8c, 0x4c160000, 0x1c000000, 0x46454447, 0x30002700, 0x24160000, 0x26000000, 0x322f534f,
0xe0616f59, 0x68010000, 0x60000000, 0x70616d63, 0xfc091d0c, 0xe4010000, 0x42010000, 0x20747663, 0x79022100, 0x28030000, 0x04000000, 0x70736167,
0x0300ffff, 0x1c160000, 0x08000000, 0x66796c67, 0x9cc4ea26, 0x44030000, 0x5c100000, 0x64616568, 0x8660bc19, 0xec000000, 0x36000000, 0x61656868,
0x44037d07, 0x24010000, 0x24000000, 0x78746d68, 0xa000390c, 0xc8010000, 0x1c000000, 0x61636f6c, 0x560d9611, 0x2c030000, 0x16000000, 0x7078616d,
0x53015300, 0x48010000, 0x20000000, 0x656d616e, 0x2d4afe67, 0xa0130000, 0x43020000, 0x74736f70, 0xaa00faff, 0xe4150000, 0x36000000, 0x00000100,
0x00000100, 0x594a76cc, 0xf53c0f5f, 0xe8031f00, 0x00000000, 0x308953db, 0x00000000, 0xdb9353db, 0x57fffdff, 0x3f03e503, 0x08000000, 0x00000200,
0x00000000, 0x00000100, 0x57ff3f03, 0xe8035a00, 0x0000fdff, 0x0100e503, 0x00000000, 0x00000000, 0x00000000, 0x04000000, 0x00000100, 0x22010a00,
0x00000700, 0x02000000, 0x01000000, 0x00000100, 0x2e004000, 0x00000000, 0xe8030400, 0x05009001, 0x8a020000, 0x0000bb02, 0x8a028c00, 0x0000bb02,
0x3100df01, 0x00000201, 0x09050002, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x66500000, 0x80006445, 0x47004100, 0x38ff2003,
0x3f035a00, 0x0000a900, 0x00000100, 0x00000000, 0x00000d03, 0x01002000, 0x2100e803, 0x00000000, 0x0000e803, 0x1900e803, 0x2c002400, 0xfdff2600,
0x3d003600, 0x03000000, 0x03000000, 0x1c000000, 0x00000100, 0x3c000000, 0x01000300, 0x1c000000, 0x20000400, 0x04000000, 0x01000400, 0x47000000,
0x0000ffff, 0xffff4100, 0x0100c2ff, 0x00000000, 0x06010000, 0x00010000, 0x00000000, 0x02010000, 0x02000000, 0x00000000, 0x00000000, 0x00000000,
0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x03000000, 0x07060504, 0x00000908,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x79022100, 0x2a000000,
0x2a002a00, 0x34022401, 0x1204fe02, 0xbc061c05, 0x00002e08, 0x21000200, 0x2a010000, 0x03009a02, 0x2e000700, 0x2f0001b1, 0x0407b23c, 0xb132ed00,
0x3cdc0506, 0x000203b2, 0xb10032ed, 0x3c2f0003, 0x000405b2, 0x07b232ed, 0x3cfc0106, 0x000201b2, 0x113332ed, 0x33271121, 0x01212311, 0xc7c7e809,
0x66fd9a02, 0x00580221, 0x19000400, 0xcf0365ff, 0x48001f03, 0xa1009000, 0x0000ad00, 0x16173601, 0x1617011d, 0x17011e17, 0x17161716, 0x16173216,
0x06071615, 0x010e020f, 0x0f010e07, 0x06070604, 0x2f352627, 0x26272601, 0x2726022f, 0x37343726, 0x37013b36, 0x013e3736, 0x3f333637, 0x36373601,
0x22273407, 0x07010e07, 0x3216010e, 0x07141617, 0x14152206, 0x17011e17, 0x34363716, 0x17323637, 0x32331416, 0x37013e37, 0x23013d36, 0x34262722,
0x013b3637, 0x27263435, 0x27262726, 0x27232622, 0x0e071415, 0x012e2701, 0x16173623, 0x07060714, 0x27060706, 0x37343526, 0x17360736, 0x010e0716,
0x34352622, 0x12fb0136, 0x1f06040c, 0x23673811, 0x02030c3b, 0x0c065902, 0x31050d01, 0x24060230, 0x47772a19, 0x08010111, 0x09140508, 0x7a190104,
0x03135056, 0x0d053536, 0x33060d01, 0x05040332, 0x126ba01a, 0x01010708, 0x010b0604, 0x895a1102, 0x02070318, 0x0d0d063d, 0x1a0d3b06, 0x0317527f,
0x20080403, 0x12030408, 0x185f3a27, 0x06222217, 0x24060d0d, 0x210b1324, 0x02443d36, 0x04050209, 0x0a091706, 0x06174b04, 0x0d030303, 0x050c2427,
0x5a21100b, 0x0c080808, 0x080c0607, 0x051a0312, 0x2d2d0612, 0x0e050501, 0x614e2f44, 0x0401021a, 0x090e0f09, 0x0f010104, 0x38215525, 0x37030c47,
0x01070738, 0x36050c01, 0x56100436, 0x01116f50, 0x0e090401, 0x1a04090f, 0x9268141c, 0x2e010311, 0xca08062e, 0x0c020125, 0x2c0d5979, 0x20080406,
0x0e030408, 0x0e6b4e25, 0x39010104, 0x060e0e06, 0x55140d38, 0x05193337, 0x08200804, 0x44140804, 0x2e2a4117, 0x2501020b, 0x060a0624, 0x08100606,
0x030c0406, 0x1d0d0503, 0x0a030109, 0x601a0e08, 0x1b070504, 0x0607080e, 0x00002406, 0x24000600, 0x99037bff, 0x4900f602, 0x71005d00, 0x9d008700,
0x0000b600, 0x16173601, 0x06071415, 0x07010e07, 0x030f010e, 0x0607011d, 0x0f000607, 0x22262701, 0x1417010f, 0x1715011e, 0x010f0607, 0x3f342627,
0x1f161701, 0x27013f01, 0x36373426, 0x36373637, 0x3e37013b, 0x013e3701, 0x36373637, 0x31223407, 0x07060722, 0x06020f06, 0x3f011f14, 0x27073602,
0x07010e23, 0x14060706, 0x3637011f, 0x36373637, 0x3400013d, 0x0607012f, 0x23012e27, 0x14150622, 0x013f011f, 0x34272627, 0x16173601, 0x07061617,
0x06020f06, 0x37260607, 0x36023f36, 0x32333607, 0x07011e17, 0x07222306, 0x0607010e, 0x26272627, 0x37363736, 0x0e760336, 0x0d0c080d, 0x02060104,
0x06014404, 0x06032928, 0xe2fe0309, 0x0e0d070c, 0x04030202, 0x19020103, 0x8b060617, 0x091d1d8a, 0x040d0c0b, 0x970d0e03, 0x0f0c0798, 0x27223211,
0x0a12101f, 0x50050220, 0x02010b5c, 0x1705564f, 0x22220d01, 0x22223738, 0x40f93131, 0x09112128, 0x708b8b06, 0x0587886f, 0xfe010406, 0x0b5354a9,
0x2702020a, 0x6f100102, 0x0408096f, 0x9f010104, 0x03040808, 0x03050204, 0x17171311, 0x02100a05, 0x131a1902, 0x110ae613, 0x0108040f, 0x220f0704,
0x04d90408, 0x02090808, 0x715b1801, 0xf1020904, 0x0c090c05, 0x091b1a07, 0x0a020e02, 0x280c0390, 0x0a2b2c29, 0xfe030d12, 0x0e060bdf, 0x1103030d,
0x01070b03, 0x07171906, 0x028b8b05, 0x02031e1d, 0x03040303, 0x97010e0e, 0x05090597, 0x0d1f2705, 0x010f0508, 0x322b2602, 0x02282601, 0x2206010b,
0x38370221, 0x67682222, 0x010140f7, 0x8a8a0404, 0x876f6f02, 0x0d080687, 0xfe272707, 0x53540181, 0x01010b0a, 0x01020e07, 0x09086f6f, 0x02031415,
0x04046a02, 0x10050502, 0x0a0a0105, 0x02021717, 0x19050a10, 0x820a0b1a, 0x12050201, 0x02040706, 0x040401d9, 0x1b070a05, 0x0502705b, 0x2c000600,
0xbd0388ff, 0x48000603, 0x61005800, 0x78006b00, 0x00008200, 0x1e173601, 0x17161701, 0x0607011e, 0x0e070607, 0x27222301, 0x3e37012e, 0x37363701,
0x3637013e, 0x2e273635, 0x07262701, 0x07060706, 0x17011e30, 0x1617011e, 0x010e0706, 0x26272627, 0x37013e35, 0x1e17013e, 0x37011f01, 0x23260636,
0x30150622, 0x16010e07, 0x013e3736, 0x16360335, 0x27010e07, 0x3617012e, 0x07141617, 0x3626010e, 0x16173617, 0x14151617, 0x35262706, 0x17361734,
0x06070616, 0x01262726, 0x0f86a9e9, 0x12440d2f, 0x16030103, 0x33252269, 0x05133a7b, 0x04040408, 0x4b58160f, 0x0d15684a, 0xae190a01, 0x4f393a77,
0x072a1f40, 0x0b16070c, 0x0f110201, 0x1f0aa709, 0x1a01060d, 0x11200704, 0x1c16150d, 0x86547113, 0x0d070202, 0x1605030a, 0x9b173e3b, 0x050a1b10,
0x010c0813, 0x030c114e, 0x0f1a0703, 0x08066808, 0x1c050507, 0x0e7c070d, 0x0d020c0e, 0x0502160a, 0x6908fe02, 0x5b11300d, 0x134e1571, 0x1823699a,
0x05022522, 0x05070913, 0x26280501, 0x34304f82, 0xa6742a2f, 0x0a080a16, 0x07221124, 0x1316070d, 0x071d100f, 0x03021d05, 0x0f0d0c1b, 0x130f089c,
0x170e0102, 0xdf5c0f1b, 0x50010585, 0x0305163a, 0x06060b0a, 0x1c0aaefe, 0x04050710, 0x05641d06, 0x05110411, 0x1815010a, 0x02020153, 0x11090606,
0x08070d0c, 0x09093714, 0x04051e07, 0x00110b09, 0x26000700, 0xc8037dff, 0x48001603, 0x76005a00, 0x9c008100, 0xb900ab00, 0x36010000, 0x011e1732,
0x06071617, 0x010f0607, 0x14151617, 0x2f260607, 0x27060701, 0x07010e14, 0x0e222306, 0x27222302, 0x37343526, 0x3e30023e, 0x35363703, 0x37363734,
0x26273436, 0x37362627, 0x37011f36, 0x17363736, 0x07222726, 0x010e0706, 0x32331614, 0x35363700, 0x012e0134, 0x07230607, 0x010e0716, 0x16171617,
0x37320607, 0x17161736, 0x2f363716, 0x23260601, 0x14150622, 0x3637013b, 0x23273707, 0x06070607, 0x06070607, 0x15010e07, 0x36161714, 0x33013e37,
0x01363732, 0x07161736, 0x010e0706, 0x37262223, 0x3607013e, 0x010e0716, 0x27260607, 0x36373634, 0x38072803, 0x082b1d08, 0x12060809, 0x057e7c07,
0x270f1a0d, 0x18180711, 0x067f7902, 0x1e1c1d1d, 0x14130f2d, 0x010c1a0a, 0x03010103, 0x23020403, 0x92920815, 0x03040903, 0x26240c0c, 0x0b7d7f08,
0x120d5a0f, 0x070c0c13, 0x0272fd07, 0x03010102, 0x479cfe0a, 0x02070b1a, 0x03030103, 0x26020201, 0x01010126, 0x2f2e0201, 0x0c0c0c06, 0x735d0101,
0x74b50101, 0xc4212273, 0x2375745d, 0x020d0423, 0x18060f02, 0x0a09060e, 0x2b190f10, 0x07131d1e, 0x08093902, 0x4301030b, 0x0a051431, 0x7b06060c,
0x021109a0, 0x09061f01, 0x0e050112, 0x03130313, 0x1c2d0803, 0x14191e20, 0x067e7c09, 0x141e1411, 0x060b010b, 0x02011818, 0x13047d7b, 0x06082b0e,
0x0d171f11, 0x01020301, 0x02040303, 0x1d2f1e22, 0x0492920b, 0x0e160802, 0x1b1e0a1f, 0x087e7f07, 0x0106200b, 0x04040504, 0x017204fd, 0x18120603,
0x47b9fe33, 0x02010316, 0x0f050501, 0x26260405, 0x01010102, 0x0602302f, 0x0a120606, 0x01b6721c, 0xc4212202, 0x2323015d, 0x22271205, 0x0f190a16,
0x050d0608, 0x1b0f0705, 0x02050e14, 0x08050496, 0x3143050b, 0x08071311, 0x1004a37b, 0x05200409, 0x060a0a06, 0x00130e07, 0xfdff0400, 0xe50357ff,
0x41003f03, 0xab007400, 0x0000b400, 0x32173601, 0x011e1716, 0x15321415, 0x17161714, 0x14161716, 0x14150607, 0x17222306, 0x14222316, 0x07141522,
0x010e0106, 0x2f012e27, 0x060e0701, 0x012e2726, 0x26273427, 0x37360136, 0x2f261700, 0x17010901, 0x3637011e, 0x37013e37, 0x3637013e, 0x36373637,
0x36373637, 0x37013e37, 0x32333634, 0x33363435, 0x2e273436, 0x23262702, 0x17223422, 0x06072634, 0x06070607, 0x07061415, 0x010e0706, 0x06070607,
0x07010e07, 0x0607010e, 0x23010e07, 0x26271422, 0x15010e07, 0x37011f14, 0x3637023e, 0x3e373637, 0x2f370101, 0x14060701, 0x5c033216, 0x0a02060e,
0x092f0701, 0x02010707, 0x07111107, 0x02040306, 0x09040503, 0xdefe1809, 0x120b1e3f, 0x851d1915, 0x1526251e, 0x0a0e0c16, 0x054e1106, 0x015c0601,
0x0112221d, 0x0e0238a6, 0xfefafe0e, 0x0f1a25fb, 0x1d1e070b, 0x1702031a, 0x23250f11, 0x0805130b, 0x09082059, 0x05090110, 0x060c2c04, 0x03040107,
0x04030301, 0x0c052b08, 0x03020616, 0x0a082503, 0x04191d29, 0x18030202, 0x241f180e, 0x08020319, 0x05051906, 0x03030404, 0xb617162c, 0x0333632a,
0x0e0a060e, 0x4afd0905, 0x87242586, 0x03094086, 0x02030936, 0x042e0201, 0x07070605, 0x0d090608, 0x0d217a22, 0x050d0603, 0x04050d04, 0xe2fe1e0a,
0x0101183e, 0x841d180c, 0x1324251e, 0x02040611, 0x104d0501, 0x65150301, 0x13211c01, 0x073ca401, 0xf8fe0b0b, 0x1a25f8fe, 0x0302010a, 0x17251f02,
0x060a0a2b, 0x2e0d0804, 0x03040a53, 0x13122503, 0x1e080620, 0x03110701, 0x0702080d, 0x030f860e, 0x14290d06, 0x03020910, 0x05070424, 0x15181604,
0x0f1a1510, 0x1a04040a, 0x0d121723, 0x03030a1b, 0x03060405, 0xb6161603, 0x0333622a, 0x200f090f, 0xb9fd300c, 0x87242586, 0x00400986, 0x36000400,
0x8203a8ff, 0x7700f402, 0x0901f100, 0x00002101, 0x32373601, 0x3b011f16, 0x013e3701, 0x17163233, 0x011e1716, 0x15010e07, 0x33161707, 0x16363732,
0x16171617, 0x1d010f06, 0x011e1701, 0x0e070607, 0x2f262701, 0x17010f01, 0x06161716, 0x06070607, 0x2b012f26, 0x010e0701, 0x2e272627, 0x35363701,
0x07012f34, 0x0607010e, 0x27262726, 0x36343526, 0x013d013f, 0x37012e27, 0x013e3736, 0x32331617, 0x27343536, 0x36373626, 0x22072616, 0x15010e07,
0x07161714, 0x0607010e, 0x22232627, 0x06070607, 0x011e1415, 0x07060714, 0x17143106, 0x37011f16, 0x17363736, 0x1617011e, 0x14150607, 0x16171617,
0x013e3233, 0x33011e32, 0x3f363732, 0x27263501, 0x013e3726, 0x16173637, 0x3637011f, 0x30353637, 0x3e34012e, 0x27343501, 0x23262726, 0x27060722,
0x2627012e, 0x34353637, 0x23262726, 0x07060722, 0x36172206, 0x16171617, 0x16171617, 0x07060714, 0x27262706, 0x37363726, 0x2617013e, 0x07010e07,
0x17141506, 0x17161716, 0x36373216, 0x34353637, 0x70012627, 0x09070516, 0x2121110f, 0x07090e11, 0x2c0e2e06, 0x04030f26, 0x17020501, 0x26040316,
0x240a0b13, 0x19070412, 0x07191b1b, 0x0a241204, 0x0519150c, 0x0217180a, 0x04040501, 0x12493a0f, 0x2111110b, 0x0c101221, 0x103a4911, 0x17080404,
0x15030a17, 0x0a0b1606, 0x09111018, 0x1b1a1a16, 0x25100605, 0x25130c08, 0x082d0304, 0x3b0e0404, 0x04012171, 0x063c1a19, 0x43010306, 0x181e0603,
0x15060203, 0x0531080d, 0x171a0302, 0x06150d08, 0x1b160505, 0x01430306, 0x1a060603, 0x021c1f1c, 0x61082101, 0x03012108, 0x0726281b, 0x03060501,
0x05034301, 0x0504171c, 0x080d1605, 0x31040431, 0x04160d08, 0x1e180303, 0x01430306, 0x24070402, 0x010c2f14, 0x0404120f, 0x0f0e2261, 0x1216191c,
0x10110c13, 0x46462e17, 0x05201723, 0x41130c03, 0x1f161552, 0x02080c31, 0x341a0805, 0x3a071f07, 0x15070d19, 0x0105ee02, 0x1a1a150a, 0x050d0a15,
0x0c091810, 0x02160615, 0x0817170a, 0x3a0f0504, 0x110c1149, 0x11212111, 0x49110c11, 0x0504103a, 0x18020105, 0x18060a17, 0x24090c16, 0x19080512,
0x08191a1a, 0x09241205, 0x0425130c, 0x02171703, 0x05010401, 0x2d260f04, 0x09071030, 0x2121110f, 0x1a0c1211, 0x050d3c3f, 0x032c0804, 0x0b132604,
0x32442409, 0x1d080801, 0x1e1a0105, 0x01430306, 0x09050602, 0x031a2924, 0x61092001, 0x10110503, 0x24291a03, 0x0401010a, 0x43010206, 0x1a1e0504,
0x0f0d0302, 0x0531090a, 0x0c093105, 0x05050417, 0x03041c17, 0x06020243, 0x07010104, 0x031c2727, 0x09610821, 0x1b030120, 0x05072529, 0x43020206,
0x20170503, 0x08130303, 0x031a1714, 0x0202ad02, 0x120b0c02, 0x48221712, 0x24172e21, 0x2f201124, 0x25191f36, 0x0305232d, 0x151c2705, 0x14091118,
0x020b2d0d, 0x1a330c01, 0x3c11151b, 0x3d000600, 0xc703a3ff, 0x3300e702, 0x9a005100, 0xe600b400, 0x00000101, 0x20053613, 0x16171617, 0x14151617,
0x16171617, 0x14060706, 0x06070607, 0x012e2704, 0x26272627, 0x26342627, 0x36372627, 0x36373637, 0x34353637, 0x36373233, 0x01292605, 0x06070607,
0x06070607, 0x16171617, 0x20211617, 0x34353637, 0x22232627, 0x36052627, 0x16172021, 0x32331432, 0x32161716, 0x15163216, 0x06141614, 0x0e071415,
0x06141502, 0x22230607, 0x20211415, 0x26272627, 0x27342223, 0x2627012e, 0x34352223, 0x37342627, 0x33343536, 0x013e3732, 0x33343637, 0x26043632,
0x22230620, 0x17140607, 0x16323316, 0x37323620, 0x34363736, 0x26272627, 0x17203604, 0x1714011e, 0x1415011e, 0x07011e17, 0x22060706, 0x06071415,
0x20210607, 0x22262726, 0x26273427, 0x26272627, 0x32362627, 0x37363435, 0x26053736, 0x0e070620, 0x16060701, 0x16171617, 0x2025011f, 0x34323437,
0x35363233, 0x01049834, 0x036c016b, 0x0f110a06, 0x0a06010b, 0x050d0c04, 0x0914150c, 0x02022ffd, 0x0b010111, 0x03070e1b, 0x02070402, 0x0d100603,
0x02020407, 0xda020b05, 0xfea0fe06, 0x050a0aa0, 0x02020105, 0x0d090803, 0x01010105, 0x06620163, 0x050c021e, 0xfd040302, 0x5c010b2d, 0x02067601,
0x22050306, 0x03030102, 0x04040603, 0x09030108, 0x04100712, 0xfe88fe03, 0x091010a8, 0x0302020a, 0x01011a04, 0x08040202, 0x02020408, 0x04190101,
0x14020204, 0xfd02d302, 0x0f030348, 0x0d06060d, 0x0202040f, 0x050a02b8, 0x02020b0d, 0xfd050d0b, 0xd402022d, 0x06130101, 0x0a051c05, 0x0502010d,
0x0e0d0308, 0x93fe0520, 0x0c54ddfe, 0x0a010405, 0x03010b18, 0x05030202, 0x18081203, 0x07de0214, 0x05023bfd, 0x02021206, 0x05010302, 0x010a0906,
0x01660165, 0x0e060206, 0x0101e602, 0x09050302, 0x02030b0e, 0x11240201, 0x02070d34, 0x02051109, 0x03010201, 0x0d060101, 0x02050b1d, 0x030f2410,
0x0e0f0e09, 0x02020102, 0x02390502, 0x07070505, 0x150b0101, 0x0102110e, 0x0f030102, 0x18040a1d, 0x02fb0304, 0x1d040106, 0x130b0406, 0x20020504,
0x06110502, 0x01090901, 0x0a041202, 0x01020601, 0x02030505, 0x04031a01, 0x110a0102, 0x02091132, 0x19040402, 0x0a030201, 0x1603033a, 0x16091e09,
0x07030303, 0x04140416, 0xfd030716, 0x03010203, 0x14020203, 0x0b070102, 0x0d150f2a, 0x0c030213, 0x01020f0f, 0x02010207, 0x05191006, 0x0f0f0307,
0x1c040423, 0x3b041607, 0x01010303, 0x19080c12, 0x07070102, 0x03010505, 0x0b1b0402, 0x0000001e, 0x0e000000, 0x0100ae00, 0x00000000, 0x1e000000,
0x01003e00, 0x00000000, 0x0c000100, 0x01007700, 0x00000000, 0x07000200, 0x01009400, 0x00000000, 0x27000300, 0x0100ec00, 0x00000000, 0x0c000400,
0x01002e01, 0x00000000, 0x10000500, 0x01005d01, 0x00000000, 0x0c000600, 0x03008801, 0x09040100, 0x3c000000, 0x03000000, 0x09040100, 0x18000100,
0x03005d00, 0x09040100, 0x0e000200, 0x03008400, 0x09040100, 0x4e000300, 0x03009c00, 0x09040100, 0x18000400, 0x03001401, 0x09040100, 0x20000500,
0x03003b01, 0x09040100, 0x18000600, 0x43006e01, 0x70006f00, 0x72007900, 0x67006900, 0x74006800, 0x28002000, 0x29006300, 0x32002000, 0x32003000,
0x2c003000, 0x73002000, 0x73006500, 0x6d006100, 0x2e006500, 0x6e006f00, 0x00006500, 0x79706f43, 0x68676972, 0x63282074, 0x30322029, 0x202c3032,
0x61736573, 0x6f2e656d, 0x0000656e, 0x00650073, 0x00610073, 0x0065006d, 0x0069005f, 0x006f0063, 0x0073006e, 0x73657300, 0x5f656d61, 0x6e6f6369,
0x52000073, 0x67006500, 0x6c007500, 0x72006100, 0x65520000, 0x616c7567, 0x46000072, 0x6e006f00, 0x46007400, 0x72006f00, 0x65006700, 0x32002000,
0x30002e00, 0x3a002000, 0x73002000, 0x73006500, 0x6d006100, 0x5f006500, 0x63006900, 0x6e006f00, 0x20007300, 0x20003a00, 0x2d003700, 0x2d003800,
0x30003200, 0x30003200, 0x6f460000, 0x6f46746e, 0x20656772, 0x20302e32, 0x6573203a, 0x656d6173, 0x6f63695f, 0x3a20736e, 0x382d3720, 0x3230322d,
0x73000030, 0x73006500, 0x6d006100, 0x5f006500, 0x63006900, 0x6e006f00, 0x00007300, 0x61736573, 0x695f656d, 0x736e6f63, 0x00560000, 0x00720065,
0x00690073, 0x006e006f, 0x00300020, 0x00310030, 0x0030002e, 0x00300030, 0x56000020, 0x69737265, 0x30206e6f, 0x302e3130, 0x00203030, 0x65007300,
0x61007300, 0x65006d00, 0x69005f00, 0x6f006300, 0x73006e00, 0x65730000, 0x656d6173, 0x6f63695f, 0x0000736e, 0x00000200, 0x00000000, 0x320051ff,
0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000a00, 0x02000100, 0x25002400, 0x27002600, 0x29002800, 0x00002a00, 0x01000000,
0x0200ffff, 0x00000100, 0x00000c00, 0x1e001600, 0x01000200, 0x09000100, 0x04000100, 0x02000000, 0x01000000, 0x01000000, 0x00000000, 0x01000000,
0x00000000, 0xdb98a4d5, 0x00000000, 0x308953db, 0x00000000, 0xdb9353db,
};

View File

@@ -0,0 +1,446 @@
#pragma once
#include "config.h"
#include "../features.h"
#pragma region variables_combo_entries
using VisualOverlayBox_t = int;
enum EVisualOverlayBox : VisualOverlayBox_t
{
VISUAL_OVERLAY_BOX_NONE = 0,
VISUAL_OVERLAY_BOX_FULL,
VISUAL_OVERLAY_BOX_CORNERS,
VISUAL_OVERLAY_BOX_MAX
};
using VisualChamMaterial_t = int;
enum EVisualsChamMaterials : VisualChamMaterial_t
{
VISUAL_MATERIAL_PRIMARY_WHITE = 0,
glowproperty = 1,
glowproperty2 = 2,
VISUAL_MATERIAL_MAX
};
using MiscDpiScale_t = int;
enum EMiscDpiScale : MiscDpiScale_t
{
MISC_DPISCALE_DEFAULT = 0,
MISC_DPISCALE_125,
MISC_DPISCALE_150,
MISC_DPISCALE_175,
MISC_DPISCALE_200,
MISC_DPISCALE_MAX
};
#pragma endregion
#pragma region variables_multicombo_entries
using MenuAddition_t = unsigned int;
enum EMenuAddition : MenuAddition_t
{
MENU_ADDITION_NONE = 0U,
MENU_ADDITION_DIM_BACKGROUND = 1 << 0,
MENU_ADDITION_BACKGROUND_PARTICLE = 1 << 1,
MENU_ADDITION_GLOW = 1 << 2,
MENU_ADDITION_ALL = MENU_ADDITION_DIM_BACKGROUND | MENU_ADDITION_GLOW
};
using LegitCond_t = unsigned int;
enum LegitCond : LegitCond_t
{
LEGIT_NONE = 0U,
LEGIT_IN_AIR = 1 << 0,
LEGIT_FLASHED = 1 << 1,
LEGIT_IN_SMOKE = 1 << 2,
LEGIT_DELAY_SHOT = 1 << 3
};
using ESPFlags_t = unsigned int;
enum EESPFlags : ESPFlags_t
{
FLAGS_NONE = 0U,
FLAGS_ARMOR = 1 << 0,
FLAGS_DEFUSER = 1 << 1
};
#pragma endregion
struct rage_weapon_t {
};
struct Variables_t
{
#pragma region ragebot
C_ADD_VARIABLE_ARRAY(int, 7, rage_target_select, 0);
C_ADD_VARIABLE_ARRAY(int, 7, rage_minimum_damage, 0);
C_ADD_VARIABLE_ARRAY(int, 7, rage_minimum_hitchance, 0);
C_ADD_VARIABLE(bool, rage_enable, false);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_hitchance, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rapid_fire, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_penetration, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_safe_point, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_auto_stop, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_early_stop, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, rage_auto_scope, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, remove_weapon_accuracy_spread, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_head, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_neck, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_uppeer_chest, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_chest, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_stomach, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_legs, 0);
C_ADD_VARIABLE_ARRAY(bool, 7, hitbox_feet, 0);
#pragma endregion
#pragma region variables_world
C_ADD_VARIABLE(bool, bNightmode, false);
#pragma endregion
#pragma region variables_visuals
C_ADD_VARIABLE(bool, bVisualOverlay, false);
C_ADD_VARIABLE(bool, bRemoveChamsT, false);
C_ADD_VARIABLE(bool, bRemoveChamsOcclude, false);
C_ADD_VARIABLE(FrameOverlayVar_t, overlayBox, FrameOverlayVar_t(false));
C_ADD_VARIABLE(TextOverlayVar_t, overlayName, TextOverlayVar_t(false, false));
C_ADD_VARIABLE(BarOverlayVar_t, overlayHealthBar, BarOverlayVar_t(false, false, false, 2.1f, Color_t(0, 255, 155), Color_t(255, 0, 155)));
C_ADD_VARIABLE(BarOverlayVar_t, backgroundHealthbar, BarOverlayVar_t(false, false, false, 1.f, Color_t(0, 0, 0, 55), Color_t(0, 0, 0, 55)));
C_ADD_VARIABLE(BarOverlayVar_t, AmmoBar, BarOverlayVar_t(false, false, false, 1.f, Color_t(0, 255, 155), Color_t(255, 0, 155)));
C_ADD_VARIABLE(BarOverlayVar_t, AmmoBarBackground, BarOverlayVar_t(false, false, false, 1.f, Color_t(0, 0, 0, 55), Color_t(0, 0, 0, 55)));
bool full_update = false;
C_ADD_VARIABLE(bool, bVisualChams, false);
C_ADD_VARIABLE(bool, bSkeleton, false);
C_ADD_VARIABLE(int, nVisualChamMaterial, 0);
C_ADD_VARIABLE(bool, bVisualChamsIgnoreZ, false); // invisible chams
C_ADD_VARIABLE(bool, bNoShadow, false);
C_ADD_VARIABLE(ColorPickerVar_t, colVisualChams, ColorPickerVar_t(0, 255, 0));
C_ADD_VARIABLE(ColorPickerVar_t, colVisualChamsIgnoreZ, ColorPickerVar_t(255, 0, 0));
C_ADD_VARIABLE(ColorPickerVar_t, colModulate, ColorPickerVar_t(255, 0, 0));
#pragma endregion
#pragma region legit
C_ADD_VARIABLE(bool, legit_enable, false);
C_ADD_VARIABLE(int, legit_weapon_selection, 0);
C_ADD_VARIABLE(bool, legit_silent_aim, false);
C_ADD_VARIABLE(bool, legit_delay_aim, false);
C_ADD_VARIABLE(int, legit_delay_aim_ms, 0);
C_ADD_VARIABLE(int, legit_target_selection, 0);
C_ADD_VARIABLE(int, legit_target_selection_machinegun, 0);
C_ADD_VARIABLE(int, legit_target_selection_assultrifles, 0);
C_ADD_VARIABLE(int, legit_target_selection_snipers, 0);
C_ADD_VARIABLE(bool, legit_fov_visualize, false);
C_ADD_VARIABLE(ColorPickerVar_t, legit_fov_visualizeclr, ColorPickerVar_t(255, 88, 88));
C_ADD_VARIABLE(int, legit_smooth_pistol, 1);
C_ADD_VARIABLE(int, legit_smooth_machinegun, 1);
C_ADD_VARIABLE(int, legit_smooth_assultrifles, 1);
C_ADD_VARIABLE(int, legit_smooth_snipers, 1);
C_ADD_VARIABLE(int, legit_rcs_shots_pistol, 0);
C_ADD_VARIABLE(int, legit_rcs_shots_machinegun, 0);
C_ADD_VARIABLE(int, legit_rcs_shots_assultrifles, 0);
C_ADD_VARIABLE(int, legit_rcs_shots_snipers, 0);
C_ADD_VARIABLE(bool, legit_rcs_pistol, false);
C_ADD_VARIABLE(bool, legit_rcs_machinegun, false);
C_ADD_VARIABLE(bool, legit_rcs_assultrifles, false);
C_ADD_VARIABLE(bool, legit_rcs_snipers, false);
C_ADD_VARIABLE(bool, PunchRandomization_pistol, false);
C_ADD_VARIABLE(bool, PunchRandomization_machinegun, false);
C_ADD_VARIABLE(bool, PunchRandomization_assultrifles, false);
C_ADD_VARIABLE(bool, PunchRandomization_snipers, false);
C_ADD_VARIABLE(float, punch_y_pistol, 0);
C_ADD_VARIABLE(float, punch_x_pistol, 0);
C_ADD_VARIABLE(float, punch_y_snipers, 0);
C_ADD_VARIABLE(float, punch_x_snipers, 0);
C_ADD_VARIABLE(float, punch_y_machinegun, 0);
C_ADD_VARIABLE(float, punch_x_machinegun, 0);
C_ADD_VARIABLE(float, punch_x_assultrifles, 0);
C_ADD_VARIABLE(float, punch_y_assultrifles, 0);
C_ADD_VARIABLE(bool, legit_rcs_shots_enable_pistol, false);
C_ADD_VARIABLE(bool, legit_rcs_shots_enable_machinegun, false);
C_ADD_VARIABLE(bool, legit_rcs_shots_enable_assultrifles, false);
C_ADD_VARIABLE(bool, legit_rcs_shots_enable_snipers, false);
C_ADD_VARIABLE(float, legit_rcs_smoothx_pistol, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothx_machinegun, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothx_assultrifles, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothx_snipers, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothy_pistol, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothy_machinegun, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothy_assultrifles, 0.f);
C_ADD_VARIABLE(float, legit_rcs_smoothy_snipers, 0.f);
C_ADD_VARIABLE(bool, legit_no_scope, false);
C_ADD_VARIABLE(bool, legit_visibility_check_pistol, true);
C_ADD_VARIABLE(bool, legit_visibility_check_machinegun, true);
C_ADD_VARIABLE(bool, legit_visibility_check_assultrifles, true);
C_ADD_VARIABLE(bool, legit_visibility_check_snipers, true);
C_ADD_VARIABLE(bool, hitbox_head_pistol, false);
C_ADD_VARIABLE(bool, hitbox_head_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_head_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_head_snipers, false);
C_ADD_VARIABLE(bool, hitbox_neck_pistol, false);
C_ADD_VARIABLE(bool, hitbox_neck_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_neck_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_neck_snipers, false);
C_ADD_VARIABLE(bool, hitbox_uppeer_chest_pistol, false);
C_ADD_VARIABLE(bool, hitbox_uppeer_chest_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_uppeer_chest_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_uppeer_chest_snipers, false);
C_ADD_VARIABLE(float, max_lagcompensation_time, 0.f);
C_ADD_VARIABLE(bool, hitbox_chest_pistol, false);
C_ADD_VARIABLE(bool, hitbox_chest_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_chest_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_chest_snipers, false);
C_ADD_VARIABLE(bool, hitbox_stomach_pistol, false);
C_ADD_VARIABLE(bool, hitbox_stomach_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_stomach_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_stomach_snipers, false);
C_ADD_VARIABLE(bool, hitbox_leg_l_pistol, false);
C_ADD_VARIABLE(bool, hitbox_leg_l_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_leg_l_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_leg_l_snipers, false);
C_ADD_VARIABLE(bool, hitbox_leg_r_pistol, false);
C_ADD_VARIABLE(bool, hitbox_leg_r_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_leg_r_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_leg_r_snipers, false);
C_ADD_VARIABLE(bool, trigger_enable_p, false);
C_ADD_VARIABLE(bool, trigger_on_key, false);
C_ADD_VARIABLE(int, trigger_hitchance_p, 0);
C_ADD_VARIABLE(bool, trigger_enable_a, false);
C_ADD_VARIABLE(int, trigger_hitchance_a, 0);
C_ADD_VARIABLE(bool, trigger_enable_m, false);
C_ADD_VARIABLE(int, trigger_hitchance_m, 0);
C_ADD_VARIABLE(bool, trigger_enable_s, false);
C_ADD_VARIABLE(int, trigger_hitchance_s, 0);
// PISTOL
C_ADD_VARIABLE(int, legit_fov_pistol, 0);
C_ADD_VARIABLE(KeyBind_t, legit_key_pistol, 0);
C_ADD_VARIABLE(KeyBind_t, edge_bug_key, 0);
// MACHINESGUN
C_ADD_VARIABLE(int, legit_fov_machinegun, 0);
C_ADD_VARIABLE(KeyBind_t, legit_key_machinegun, 0);
// ASSULTRIFLES
C_ADD_VARIABLE(int, legit_fov_assultrifles, 0);
C_ADD_VARIABLE(KeyBind_t, legit_key_assultrifles, 0);
// SNIPERS
C_ADD_VARIABLE(int, legit_fov_snipers, 0);
C_ADD_VARIABLE(KeyBind_t, legit_key_snipers, 0);
#pragma endregion
#pragma region antiaim
C_ADD_VARIABLE(bool, bAntiAim, false);
C_ADD_VARIABLE(int, iBaseYawType, 0);
C_ADD_VARIABLE(int, iPitchType, 0);
#pragma endregion
#pragma region rage
C_ADD_VARIABLE(int, rage_weapon_selection, 0);
C_ADD_VARIABLE(bool, rage_silent_aim, false);
C_ADD_VARIABLE(bool, rage_delay_aim, false);
C_ADD_VARIABLE(int, rage_delay_aim_ms, 0);
C_ADD_VARIABLE(int, rage_target_selection, 0);
C_ADD_VARIABLE(int, rage_target_selection_machinegun, 0);
C_ADD_VARIABLE(int, rage_target_selection_assultrifles, 0);
C_ADD_VARIABLE(int, rage_target_selection_snipers, 0);
C_ADD_VARIABLE(bool, rage_fov_visualize, false);
C_ADD_VARIABLE(ColorPickerVar_t, rage_fov_visualizeclr, ColorPickerVar_t(255, 88, 88));
C_ADD_VARIABLE(bool, remove_weapon_accuracy_spread_rage, false);
C_ADD_VARIABLE(int, rage_hitchance_p, 1);
C_ADD_VARIABLE(int, rage_hitchance_m, 1);
C_ADD_VARIABLE(int, rage_hitchance_a, 1);
C_ADD_VARIABLE(float, rage_hitchance_s, 1.f);
C_ADD_VARIABLE(int, rage_rcs_shots_pistol, 0);
C_ADD_VARIABLE(int, rage_rcs_shots_machinegun, 0);
C_ADD_VARIABLE(int, rage_rcs_shots_assultrifles, 0);
C_ADD_VARIABLE(int, rage_rcs_shots_snipers, 0);
C_ADD_VARIABLE(bool, rage_rcs_pistol, false);
C_ADD_VARIABLE(bool, rage_rcs_machinegun, false);
C_ADD_VARIABLE(bool, rage_rcs_assultrifles, false);
C_ADD_VARIABLE(bool, rage_rcs_snipers, false);
C_ADD_VARIABLE(bool, PunchRandomization_rage_pistol, false);
C_ADD_VARIABLE(bool, PunchRandomization_rage_machinegun, false);
C_ADD_VARIABLE(bool, PunchRandomization_rage_assultrifles, false);
C_ADD_VARIABLE(bool, PunchRandomization_rage_snipers, false);
C_ADD_VARIABLE(float, punch_y_rage_pistol, 0);
C_ADD_VARIABLE(float, punch_x_rage_pistol, 0);
C_ADD_VARIABLE(float, punch_y_rage_snipers, 0);
C_ADD_VARIABLE(float, punch_x_rage_snipers, 0);
C_ADD_VARIABLE(float, punch_y_rage_machinegun, 0);
C_ADD_VARIABLE(float, punch_x_rage_machinegun, 0);
C_ADD_VARIABLE(float, punch_x_rage_assultrifles, 0);
C_ADD_VARIABLE(float, punch_y_rage_assultrifles, 0);
C_ADD_VARIABLE(bool, rage_rcs_shots_enable_pistol, false);
C_ADD_VARIABLE(bool, rage_rcs_shots_enable_machinegun, false);
C_ADD_VARIABLE(bool, rage_rcs_shots_enable_assultrifles, false);
C_ADD_VARIABLE(bool, rage_rcs_shots_enable_snipers, false);
C_ADD_VARIABLE(float, rage_rcs_smoothx_pistol, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothx_machinegun, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothx_assultrifles, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothx_snipers, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothy_pistol, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothy_machinegun, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothy_assultrifles, 0.f);
C_ADD_VARIABLE(float, rage_rcs_smoothy_snipers, 0.f);
C_ADD_VARIABLE(bool, rage_no_scope, false);
C_ADD_VARIABLE(bool, rage_visibility_check_pistol, true);
C_ADD_VARIABLE(bool, rage_visibility_check_machinegun, true);
C_ADD_VARIABLE(bool, rage_visibility_check_assultrifles, true);
C_ADD_VARIABLE(bool, rage_visibility_check_snipers, true);
C_ADD_VARIABLE(bool, hitbox_head_rage_pistol, false);
C_ADD_VARIABLE(bool, hitbox_head_rage_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_head_rage_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_head_rage_snipers, false);
C_ADD_VARIABLE(bool, hitbox_neck_rage_pistol, false);
C_ADD_VARIABLE(bool, hitbox_neck_rage_machinegun, false);
C_ADD_VARIABLE(bool, hitbox_neck_rage_assultrifles, false);
C_ADD_VARIABLE(bool, hitbox_neck_rage_snipers, false);
// ... Repeat the same pattern for other hitbox variables
C_ADD_VARIABLE(bool, trigger_enable_r, false);
C_ADD_VARIABLE(bool, trigger_on_key_r, false);
C_ADD_VARIABLE(int, trigger_hitchance_r, 0);
// PISTOL
C_ADD_VARIABLE(int, rage_fov_pistol, 0);
C_ADD_VARIABLE(KeyBind_t, rage_key_pistol, 0);
// MACHINESGUN
C_ADD_VARIABLE(int, rage_fov_machinegun, 0);
C_ADD_VARIABLE(KeyBind_t, rage_key_machinegun, 0);
// ASSULTRIFLES
C_ADD_VARIABLE(int, rage_fov_assultrifles, 0);
C_ADD_VARIABLE(KeyBind_t, rage_key_assultrifles, 0);
// SNIPERS
C_ADD_VARIABLE(int, rage_fov_snipers, 0);
C_ADD_VARIABLE(KeyBind_t, rage_key_snipers, 0);
#pragma endregion
#pragma region variables_misc
C_ADD_VARIABLE(bool, bAntiUntrusted, true);
C_ADD_VARIABLE(bool, bWatermark, true);
C_ADD_VARIABLE(bool, bFOV, false);
C_ADD_VARIABLE(bool, bSetViewModelFOV, false);
C_ADD_VARIABLE(bool, bAutostrafe, false);
C_ADD_VARIABLE(bool, bAutostrafeAssistance, false);
C_ADD_VARIABLE(bool, bAutoBHop, false);
C_ADD_VARIABLE(bool, bThirdperson, false);
C_ADD_VARIABLE(float, flThirdperson, 90.0f);
C_ADD_VARIABLE(float, flSetViewModelFOV, 40.0f);
C_ADD_VARIABLE(float, fFOVAmount, 30.0f);
C_ADD_VARIABLE(bool, bThirdpersonNoInterp, true);
C_ADD_VARIABLE(int, nAutoBHopChance, 100);
C_ADD_VARIABLE(unsigned int, bAutostrafeMode, 0);
C_ADD_VARIABLE(float, autostrafe_smooth, 99);
C_ADD_VARIABLE(bool, edge_bug, false);
#pragma endregion
#pragma region variables_menu
C_ADD_VARIABLE(unsigned int, nMenuKey, VK_INSERT);
C_ADD_VARIABLE(unsigned int, nPanicKey, VK_END);
C_ADD_VARIABLE(int, nDpiScale, 0);
C_ADD_VARIABLE(KeyBind_t, OverlayKey, 0);
C_ADD_VARIABLE(int, OverlayKeyCurrent, 0);
C_ADD_VARIABLE(int, OverlayKeyStyle, 0);
/*
* color navigation:
* [definition N][purpose]
* 1. primitive:
* - primtv 0 (text)
* - primtv 1 (background)
* - primtv 2 (disabled)
* - primtv 3 (control bg)
* - primtv 4 (border)
* - primtv 5 (hover)
*
* 2. accents:
* - accent 0 (main)
* - accent 1 (dark)
* - accent 2 (darker)
*/
C_ADD_VARIABLE(unsigned int, legit_conditions, LEGIT_NONE);
C_ADD_VARIABLE(unsigned int, pEspFlags, FLAGS_NONE);
C_ADD_VARIABLE(TextOverlayVar_t, HKFlag, TextOverlayVar_t(true, false));
C_ADD_VARIABLE(TextOverlayVar_t, KitFlag, TextOverlayVar_t(true, false));
C_ADD_VARIABLE(unsigned int, bMenuAdditional, MENU_ADDITION_ALL);
C_ADD_VARIABLE(float, flAnimationSpeed, 1.f);
C_ADD_VARIABLE(TextOverlayVar_t, Weaponesp, TextOverlayVar_t(false, true));
C_ADD_VARIABLE(ColorPickerVar_t, colSkeleton, ColorPickerVar_t(88, 88, 88)); // (text)
C_ADD_VARIABLE(ColorPickerVar_t, colSkeletonOutline, ColorPickerVar_t(0, 0, 0)); // (text)
C_ADD_VARIABLE(ColorPickerVar_t, colPrimtv0, ColorPickerVar_t(255, 255, 255)); // (text)
C_ADD_VARIABLE(ColorPickerVar_t, colPrimtv1, ColorPickerVar_t(50, 55, 70)); // (background)
C_ADD_VARIABLE(ColorPickerVar_t, colPrimtv2, ColorPickerVar_t(190, 190, 190)); // (disabled)
C_ADD_VARIABLE(ColorPickerVar_t, colPrimtv3, ColorPickerVar_t(20, 20, 30)); // (control bg)
C_ADD_VARIABLE(ColorPickerVar_t, colPrimtv4, ColorPickerVar_t(0, 0, 0)); // (border)
C_ADD_VARIABLE(ColorPickerVar_t, colAccent0, ColorPickerVar_t(85, 90, 160)); // (main)
C_ADD_VARIABLE(ColorPickerVar_t, colAccent1, ColorPickerVar_t(100, 105, 175)); // (dark)
C_ADD_VARIABLE(ColorPickerVar_t, colAccent2, ColorPickerVar_t(115, 120, 190)); // (darker)
#pragma endregion
};
inline Variables_t Vars = {};