фыв
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,131 @@
|
||||
|
||||
#include "../pointer/pointer.hpp"
|
||||
#include "cmodule.hpp"
|
||||
#include "../fnv1a.hpp"
|
||||
#include <wtypes.h>
|
||||
#include <Psapi.h>
|
||||
CModule::CModule(const char* name) {
|
||||
m_Name = name;
|
||||
m_Hash = fnv1a::Hash(name);
|
||||
m_Handle = nullptr;
|
||||
|
||||
m_Begin = m_Size = 0;
|
||||
}
|
||||
|
||||
CModule::~CModule() {
|
||||
if (!m_Handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
dlclose(m_Handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CModule::Retrieve() {
|
||||
if (m_Handle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
InitializeHandle();
|
||||
InitializeBounds();
|
||||
|
||||
return m_Handle != nullptr;
|
||||
}
|
||||
|
||||
uintptr_t CModule::GetInterface(const char* version) {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
CPointer pCreateInterface = GetProcAddress("CreateInterface");
|
||||
if (!pCreateInterface.IsValid()) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Used internally to register classes.
|
||||
struct InterfaceReg {
|
||||
std::add_pointer_t<uintptr_t()> m_CreateFn;
|
||||
const char* m_pName;
|
||||
InterfaceReg* m_pNext; // For the global list.
|
||||
};
|
||||
|
||||
InterfaceReg* s_pInterfaceRegs =
|
||||
#ifdef _WIN32
|
||||
pCreateInterface.Absolute(3, 0).Dereference(1).Get<InterfaceReg*>()
|
||||
#elif __linux__
|
||||
pCreateInterface.Absolute(1, 0).Absolute(19, 0).Dereference(1).Get<InterfaceReg*>()
|
||||
#endif
|
||||
;
|
||||
|
||||
uint32_t versionHash = fnv1a::Hash(version);
|
||||
for (; s_pInterfaceRegs; s_pInterfaceRegs = s_pInterfaceRegs->m_pNext) {
|
||||
if (fnv1a::Hash(s_pInterfaceRegs->m_pName) == versionHash) {
|
||||
rv = s_pInterfaceRegs->m_CreateFn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
uintptr_t CModule::GetProcAddress(const char* procName) {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
rv = reinterpret_cast<uintptr_t>(::GetProcAddress(static_cast<HMODULE>(m_Handle), procName));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
uintptr_t CModule::FindPattern(const std::span<const int>& pattern) const {
|
||||
uintptr_t rv = 0;
|
||||
if (m_Handle) {
|
||||
uint8_t* bytes = reinterpret_cast<uint8_t*>(m_Begin);
|
||||
|
||||
// Faster than pattern[] in debug builds because of _STL_VERIFY.
|
||||
const int* patternData = pattern.data();
|
||||
const size_t patternSize = pattern.size();
|
||||
|
||||
for (size_t i = 0; i < m_Size - patternSize; ++i) {
|
||||
bool found = true;
|
||||
for (size_t j = 0; j < patternSize; ++j) {
|
||||
if (bytes[i + j] != patternData[j] && patternData[j] != -1) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
rv = reinterpret_cast<uintptr_t>(&bytes[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void CModule::InitializeHandle() {
|
||||
#ifdef _WIN32
|
||||
m_Handle = GetModuleHandle(GetName());
|
||||
#else
|
||||
m_Handle = dlopen(GetName(), RTLD_LAZY | RTLD_NOLOAD);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CModule::InitializeBounds() {
|
||||
if (!m_Handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
MODULEINFO mi;
|
||||
BOOL status = GetModuleInformation(GetCurrentProcess(), static_cast<HMODULE>(m_Handle), &mi, sizeof(mi));
|
||||
if (status != 0) {
|
||||
SetBounds(reinterpret_cast<uintptr_t>(m_Handle), mi.SizeOfImage);
|
||||
}
|
||||
}
|
||||
|
||||
void CModule::SetBounds(uintptr_t begin, uintptr_t size) {
|
||||
m_Begin = begin;
|
||||
m_Size = size;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string>
|
||||
class CModule {
|
||||
public:
|
||||
CModule(const char* name);
|
||||
~CModule();
|
||||
|
||||
auto GetHash() const { return m_Hash; }
|
||||
auto GetHandle() const { return m_Handle; }
|
||||
auto GetName() const { return m_Name.c_str(); }
|
||||
|
||||
// Returns false if module not loaded.
|
||||
bool Retrieve();
|
||||
|
||||
uintptr_t GetInterface(const char* version);
|
||||
uintptr_t GetProcAddress(const char* procName);
|
||||
uintptr_t FindPattern(const std::span<const int>& pattern) const;
|
||||
|
||||
private:
|
||||
void InitializeHandle();
|
||||
void InitializeBounds();
|
||||
|
||||
void SetBounds(uintptr_t begin, uintptr_t size);
|
||||
|
||||
// Module name.
|
||||
std::string m_Name;
|
||||
|
||||
// Module name fnv1a hash.
|
||||
uint32_t m_Hash;
|
||||
|
||||
// Module handle.
|
||||
void* m_Handle;
|
||||
|
||||
// Used for pattern scanning.
|
||||
uintptr_t m_Begin, m_Size;
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
@@ -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"; }
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {};
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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
|
||||
@@ -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...);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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 = {};
|
||||
Reference in New Issue
Block a user