This commit is contained in:
Oscar 2025-07-17 13:52:06 +03:00
commit 2f50c8a911
206 changed files with 246874 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/.vs
/TempleWare-CS2/x64/Debug
/x64/Debug
/TempleWare-CS2/x64/Release
/x64/Release

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Temple Enterprise LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

44
README.md Normal file
View File

@ -0,0 +1,44 @@
<p align="center">
<a href="https://templecheats.xyz">
<img src="github/images/logo.png">
</a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/C%2B%2B-9B59B6?style=for-the-badge&logo=c%2B%2B&logoColor=white">
<img src="https://img.shields.io/badge/Visual_Studio-8E44AD?style=for-the-badge&logo=visual%20studio&logoColor=white">
<img src="https://img.shields.io/badge/Windows-7D3F9C?style=for-the-badge&logo=windows&logoColor=white">
<a href="https://discord.gg/j6hTUB5GBx" style="text-decoration: none;">
<img src="https://img.shields.io/badge/Discord-9B59B6?style=for-the-badge&logo=discord&logoColor=white">
</a>
<img src="https://img.shields.io/badge/license-MIT-8E44AD?style=for-the-badge&logo=&logoColor=white">
<img src="https://img.shields.io/badge/CS2-9B59B6?style=for-the-badge&logo=counter-strike&logoColor=white">
</p>
---
### TempleWare Legacy is a free C++-based internal for Counter-Strike 2.
---
### How to Launch TempleWare
1. **Build the DLL:**
- Open the project in Visual Studio.
- Set the build configuration to **Release x64**.
- Build the solution (`Build` > `Build Solution`).
2. **Inject the DLL:**
- Find the `TempleWare.dll` in the `\Release\x64\` folder.
- Use a DLL injector (e.g., [Extreme Injector](https://github.com/master131/ExtremeInjector)) to inject `TempleWare.dll` into `cs2.exe`.
3. **Play CS2:**
- Launch `Counter-Strike 2` and start using TempleWare.
- Menu Bind `END`
---
## Screenshots
| Description | Image |
|-------------|-------|
| **Showcase** | <img src="./github/images/showcase.png" alt="Showcase" width="600"> |
| **Menu** | <img src="./github/images/menu.png" alt="Menu" width="600"> |

31
TempleWare-CS2.sln Normal file
View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.202
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TempleWare-CS2", "TempleWare-CS2\TempleWare-CS2.vcxproj", "{04B17470-CB82-4724-904B-25445926AB86}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{04B17470-CB82-4724-904B-25445926AB86}.Debug|x64.ActiveCfg = Debug|x64
{04B17470-CB82-4724-904B-25445926AB86}.Debug|x64.Build.0 = Debug|x64
{04B17470-CB82-4724-904B-25445926AB86}.Debug|x86.ActiveCfg = Debug|Win32
{04B17470-CB82-4724-904B-25445926AB86}.Debug|x86.Build.0 = Debug|Win32
{04B17470-CB82-4724-904B-25445926AB86}.Release|x64.ActiveCfg = Release|x64
{04B17470-CB82-4724-904B-25445926AB86}.Release|x64.Build.0 = Release|x64
{04B17470-CB82-4724-904B-25445926AB86}.Release|x86.ActiveCfg = Release|Win32
{04B17470-CB82-4724-904B-25445926AB86}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B53701D3-2EBE-4435-A1B6-C5BDFE16D1A9}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="kiero">
<UniqueIdentifier>{c914abae-6128-4a2a-8821-07a38f656930}</UniqueIdentifier>
</Filter>
<Filter Include="imgui">
<UniqueIdentifier>{3ba57e14-8ac2-485a-b12c-f06690c43d6e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="kiero\minhook\src\buffer.c">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="kiero\minhook\src\hde\hde32.c">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="kiero\minhook\src\hde\hde64.c">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="kiero\minhook\src\hook.c">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="kiero\kiero.cpp">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="kiero\minhook\src\trampoline.c">
<Filter>kiero</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_demo.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_draw.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_impl_dx11.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_impl_win32.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_widgets.cpp">
<Filter>imgui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="kiero\minhook\dll_resources\MinHook.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="kiero\minhook\src\buffer.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\hde\hde32.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\hde\hde64.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\kiero.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\include\MinHook.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\hde\pstdint.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\hde\table32.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\hde\table64.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="kiero\minhook\src\trampoline.h">
<Filter>kiero</Filter>
</ClInclude>
<ClInclude Include="imgui\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imgui_impl_dx11.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imgui_impl_win32.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imgui_internal.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imstb_rectpack.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imstb_textedit.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="imgui\imstb_truetype.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="includes.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="kiero\minhook\dll_resources\MinHook.def">
<Filter>kiero</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{04B17470-CB82-4724-904B-25445926AB86}</ProjectGuid>
<RootNamespace>TempleWare-CS2</RootNamespace>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
<TargetName>TempleWare</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
<TargetName>TempleWare</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>d3d11.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="external\imgui\imgui.cpp" />
<ClCompile Include="external\imgui\imgui_demo.cpp" />
<ClCompile Include="external\imgui\imgui_draw.cpp" />
<ClCompile Include="external\imgui\imgui_impl_dx11.cpp" />
<ClCompile Include="external\imgui\imgui_impl_win32.cpp" />
<ClCompile Include="external\imgui\imgui_widgets.cpp" />
<ClCompile Include="external\kiero\kiero.cpp" />
<ClCompile Include="external\kiero\minhook\src\buffer.c" />
<ClCompile Include="external\kiero\minhook\src\hde\hde32.c" />
<ClCompile Include="external\kiero\minhook\src\hde\hde64.c" />
<ClCompile Include="external\kiero\minhook\src\hook.c" />
<ClCompile Include="external\kiero\minhook\src\trampoline.c" />
<ClCompile Include="source\cs2\datatypes\cutlbuffer\cutlbuffer.cpp" />
<ClCompile Include="source\cs2\datatypes\cutl\utlhash\utlhash.cpp" />
<ClCompile Include="source\cs2\datatypes\keyvalues\keyvalues.cpp" />
<ClCompile Include="source\cs2\datatypes\schema\ISchemaClass\ISchemaClass.cpp" />
<ClCompile Include="source\cs2\entity\CCSPlayerController\CCSPlayerController.cpp" />
<ClCompile Include="source\cs2\entity\C_CSPlayerPawn\C_CSPlayerPawn.cpp" />
<ClCompile Include="source\cs2\entity\C_CSWeaponBase\C_CSWeaponBase.cpp" />
<ClCompile Include="source\templeware\features\aim\aim.cpp" />
<ClCompile Include="source\templeware\features\chams\chams.cpp" />
<ClCompile Include="source\templeware\features\visuals\antiflash\antiflash.cpp" />
<ClCompile Include="source\templeware\features\visuals\fov\fov.cpp" />
<ClCompile Include="source\templeware\interfaces\CGameEntitySystem\CGameEntitySystem.cpp" />
<ClCompile Include="source\templeware\interfaces\interfaces.cpp" />
<ClCompile Include="source\debug\debug.cpp" />
<ClCompile Include="source\templeware\config\config.cpp" />
<ClCompile Include="source\templeware\features\world\world.cpp" />
<ClCompile Include="source\templeware\hooks\hooks.cpp" />
<ClCompile Include="source\templeware\keybinds\keybinds.cpp" />
<ClCompile Include="source\templeware\menu\hud.cpp" />
<ClCompile Include="source\templeware\utils\logging\log.cpp" />
<ClCompile Include="source\templeware\utils\math\math.cpp" />
<ClCompile Include="source\templeware\utils\math\vector\vector.cpp" />
<ClCompile Include="source\templeware\utils\math\viewmatrix\viewmatrix.cpp" />
<ClCompile Include="source\templeware\utils\memory\gaa\gaa.cpp" />
<ClCompile Include="source\templeware\utils\memory\patternscan\patternscan.cpp" />
<ClCompile Include="source\templeware\utils\module\module.cpp" />
<ClCompile Include="source\templeware\players\hook\playerHook.cpp" />
<ClCompile Include="source\templeware\players\players.cpp" />
<ClCompile Include="source\templeware\templeware.cpp" />
<ClCompile Include="source\main.cpp" />
<ClCompile Include="source\templeware\menu\menu.cpp" />
<ClCompile Include="source\templeware\features\visuals\visuals.cpp" />
<ClCompile Include="source\templeware\utils\schema\schema.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="external\kiero\minhook\dll_resources\MinHook.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="external\kiero\minhook\dll_resources\MinHook.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="external\imgui\imconfig.h" />
<ClInclude Include="external\imgui\imgui.h" />
<ClInclude Include="external\imgui\imgui_impl_dx11.h" />
<ClInclude Include="external\imgui\imgui_impl_win32.h" />
<ClInclude Include="external\imgui\imgui_internal.h" />
<ClInclude Include="external\imgui\imstb_rectpack.h" />
<ClInclude Include="external\imgui\imstb_textedit.h" />
<ClInclude Include="external\imgui\imstb_truetype.h" />
<ClInclude Include="external\json\json.hpp" />
<ClInclude Include="source\cs2\datatypes\cutlbuffer\cutlbuffer.h" />
<ClInclude Include="source\cs2\datatypes\cutl\utlhash\utlhash.h" />
<ClInclude Include="source\cs2\datatypes\keyvalues\keyvalues.h" />
<ClInclude Include="source\cs2\datatypes\schema\ISchemaClass\ISchemaClass.h" />
<ClInclude Include="source\cs2\datatypes\viewmatrix\viewmatrix.h" />
<ClInclude Include="source\cs2\entity\C_AggregateSceneObject\C_AggregateSceneObject.h" />
<ClInclude Include="source\cs2\entity\C_BaseEntity\C_BaseEntity.h" />
<ClInclude Include="source\cs2\entity\CCSPlayerController\CCSPlayerController.h" />
<ClInclude Include="source\cs2\entity\C_CSPlayerPawn\C_CSPlayerPawn.h" />
<ClInclude Include="source\cs2\entity\C_CSWeaponBase\C_CSWeaponBase.h" />
<ClInclude Include="source\cs2\entity\C_EntityInstance\C_EntityInstance.h" />
<ClInclude Include="source\cs2\entity\C_Material\C_Material.h" />
<ClInclude Include="source\cs2\entity\handle.h" />
<ClInclude Include="source\templeware\features\aim\aim.h" />
<ClInclude Include="source\templeware\features\chams\chams.h" />
<ClInclude Include="source\templeware\interfaces\CGameEntitySystem\CGameEntitySystem.h" />
<ClInclude Include="source\templeware\interfaces\IEngineClient\IEngineClient.h" />
<ClInclude Include="source\templeware\interfaces\interfaces.h" />
<ClInclude Include="source\debug\debug.h" />
<ClInclude Include="source\templeware\config\config.h" />
<ClInclude Include="source\templeware\config\configmanager.h" />
<ClInclude Include="source\templeware\hooks\hooks.h" />
<ClInclude Include="source\templeware\hooks\includeHooks.h" />
<ClInclude Include="source\templeware\keybinds\keybinds.h" />
<ClInclude Include="source\templeware\menu\hud.h" />
<ClInclude Include="source\templeware\offsets\offsets.h" />
<ClInclude Include="source\templeware\renderer\icons.h" />
<ClInclude Include="source\templeware\utils\fnv1a\fnv1a.h" />
<ClInclude Include="source\templeware\utils\logging\log.h" />
<ClInclude Include="source\templeware\utils\math\math.h" />
<ClInclude Include="source\templeware\utils\math\utlmemory\utlmemory.h" />
<ClInclude Include="source\templeware\utils\math\utlstring\utlstring.h" />
<ClInclude Include="source\templeware\utils\math\utlstronghandle\utlstronghandle.h" />
<ClInclude Include="source\templeware\utils\math\utlvector\utlvector.h" />
<ClInclude Include="source\templeware\utils\math\vector\vector.h" />
<ClInclude Include="source\templeware\utils\math\viewmatrix\viewmatrix.h" />
<ClInclude Include="source\templeware\utils\memory\gaa\gaa.h" />
<ClInclude Include="source\templeware\utils\memory\Interface\Interface.h" />
<ClInclude Include="source\templeware\utils\memory\memorycommon.h" />
<ClInclude Include="source\templeware\utils\memory\patternscan\patternscan.h" />
<ClInclude Include="source\templeware\utils\memory\vfunc\vfunc.h" />
<ClInclude Include="source\templeware\utils\module\module.h" />
<ClInclude Include="source\templeware\players\hook\playerHook.h" />
<ClInclude Include="source\templeware\players\players.h" />
<ClInclude Include="source\templeware\renderer\renderer.h" />
<ClInclude Include="source\templeware\templeware.h" />
<ClInclude Include="source\features\visuals\visuals.h" />
<ClInclude Include="source\globals\globals.h" />
<ClInclude Include="source\offsets\offsets.h" />
<ClInclude Include="source\includes.h" />
<ClInclude Include="external\kiero\kiero.h" />
<ClInclude Include="external\kiero\minhook\include\MinHook.h" />
<ClInclude Include="external\kiero\minhook\src\buffer.h" />
<ClInclude Include="external\kiero\minhook\src\hde\hde32.h" />
<ClInclude Include="external\kiero\minhook\src\hde\hde64.h" />
<ClInclude Include="external\kiero\minhook\src\hde\pstdint.h" />
<ClInclude Include="external\kiero\minhook\src\hde\table32.h" />
<ClInclude Include="external\kiero\minhook\src\hde\table64.h" />
<ClInclude Include="external\kiero\minhook\src\trampoline.h" />
<ClInclude Include="source\templeware\menu\menu.h" />
<ClInclude Include="source\templeware\features\visuals\visuals.h" />
<ClInclude Include="source\templeware\utils\schema\schema.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommand>C:\Program Files %28x86%29\Steam\steamapps\common\Counter-Strike Global Offensive\game\bin\win64\cs2.exe</LocalDebuggerCommand>
<LocalDebuggerAttach>true</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,99 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h)
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include
// the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
//-----------------------------------------------------------------------------
#pragma once
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
// It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEMO_WINDOWS
//#define IMGUI_DISABLE_METRICS_WINDOW
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/

10106
TempleWare-CS2/external/imgui/imgui.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

2255
TempleWare-CS2/external/imgui/imgui.h vendored Normal file

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

View File

@ -0,0 +1,544 @@
// dear imgui: Renderer for DirectX11
// This needs to be used along with a Platform Binding (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp
// https://github.com/ocornut/imgui
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2016-05-07: DirectX11: Disabling depth-write.
#include "imgui.h"
#include "imgui_impl_dx11.h"
// DirectX
#include <stdio.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#ifdef _MSC_VER
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
// DirectX data
static ID3D11Device* g_pd3dDevice = NULL;
static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
static IDXGIFactory* g_pFactory = NULL;
static ID3D11Buffer* g_pVB = NULL;
static ID3D11Buffer* g_pIB = NULL;
static ID3D10Blob* g_pVertexShaderBlob = NULL;
static ID3D11VertexShader* g_pVertexShader = NULL;
static ID3D11InputLayout* g_pInputLayout = NULL;
static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
static ID3D10Blob* g_pPixelShaderBlob = NULL;
static ID3D11PixelShader* g_pPixelShader = NULL;
static ID3D11SamplerState* g_pFontSampler = NULL;
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11RasterizerState* g_pRasterizerState = NULL;
static ID3D11BlendState* g_pBlendState = NULL;
static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
struct VERTEX_CONSTANT_BUFFER
{
float mvp[4][4];
};
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
{
// Setup viewport
D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = draw_data->DisplaySize.x;
vp.Height = draw_data->DisplaySize.y;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp);
// Setup shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
ctx->IASetInputLayout(g_pInputLayout);
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(g_pVertexShader, NULL, 0);
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
ctx->PSSetShader(g_pPixelShader, NULL, 0);
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
ctx->GSSetShader(NULL, NULL, 0);
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
// Setup blend state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
ctx->RSSetState(g_pRasterizerState);
}
// Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
// Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
{
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert);
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0)
return;
}
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
{
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
return;
}
// Upload vertex/index data into a single contiguous GPU buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return;
if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
ctx->Unmap(g_pVB, 0);
ctx->Unmap(g_pIB, 0);
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{
D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
ctx->Unmap(g_pVertexConstantBuffer, 0);
}
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
struct BACKUP_DX11_STATE
{
UINT ScissorRectsCount, ViewportsCount;
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
ID3D11RasterizerState* RS;
ID3D11BlendState* BlendState;
FLOAT BlendFactor[4];
UINT SampleMask;
UINT StencilRef;
ID3D11DepthStencilState* DepthStencilState;
ID3D11ShaderResourceView* PSShaderResource;
ID3D11SamplerState* PSSampler;
ID3D11PixelShader* PS;
ID3D11VertexShader* VS;
ID3D11GeometryShader* GS;
UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout;
};
BACKUP_DX11_STATE old;
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout);
// Setup desired DX state
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
// Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_idx_offset = 0;
int global_vtx_offset = 0;
ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != NULL)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Apply scissor/clipping rectangle
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
}
}
global_idx_offset += cmd_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size;
}
// Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
}
static void ImGui_ImplDX11_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Upload texture to graphics system
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = width;
desc.Height = height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D *pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
pTexture->Release();
}
// Store our identifier
io.Fonts->TexID = (ImTextureID)g_pFontTextureView;
// Create texture sampler
{
D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
}
}
bool ImGui_ImplDX11_CreateDeviceObjects()
{
if (!g_pd3dDevice)
return false;
if (g_pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
// If you would like to use this DX11 sample code but remove this dependency you can:
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
// Create the vertex shader
{
static const char* vertexShader =
"cbuffer vertexBuffer : register(b0) \
{\
float4x4 ProjectionMatrix; \
};\
struct VS_INPUT\
{\
float2 pos : POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
\
PS_INPUT main(VS_INPUT input)\
{\
PS_INPUT output;\
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
output.col = input.col;\
output.uv = input.uv;\
return output;\
}";
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL);
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return false;
if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
return false;
// Create the input layout
D3D11_INPUT_ELEMENT_DESC local_layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
return false;
// Create the constant buffer
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
}
}
// Create the pixel shader
{
static const char* pixelShader =
"struct PS_INPUT\
{\
float4 pos : SV_POSITION;\
float4 col : COLOR0;\
float2 uv : TEXCOORD0;\
};\
sampler sampler0;\
Texture2D texture0;\
\
float4 main(PS_INPUT input) : SV_Target\
{\
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
return out_col; \
}";
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL);
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
return false;
if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
return false;
}
// Create the blending setup
{
D3D11_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState);
}
// Create the rasterizer state
{
D3D11_RASTERIZER_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.FillMode = D3D11_FILL_SOLID;
desc.CullMode = D3D11_CULL_NONE;
desc.ScissorEnable = true;
desc.DepthClipEnable = true;
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
}
// Create depth-stencil State
{
D3D11_DEPTH_STENCIL_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.DepthEnable = false;
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
desc.StencilEnable = false;
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
}
ImGui_ImplDX11_CreateFontsTexture();
return true;
}
void ImGui_ImplDX11_InvalidateDeviceObjects()
{
if (!g_pd3dDevice)
return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; }
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; }
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; }
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; }
}
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_dx11";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
// Get factory from device
IDXGIDevice* pDXGIDevice = NULL;
IDXGIAdapter* pDXGIAdapter = NULL;
IDXGIFactory* pFactory = NULL;
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
{
g_pd3dDevice = device;
g_pd3dDeviceContext = device_context;
g_pFactory = pFactory;
}
if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release();
g_pd3dDevice->AddRef();
g_pd3dDeviceContext->AddRef();
return true;
}
void ImGui_ImplDX11_Shutdown()
{
ImGui_ImplDX11_InvalidateDeviceObjects();
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
}
void ImGui_ImplDX11_NewFrame()
{
if (!g_pFontSampler)
ImGui_ImplDX11_CreateDeviceObjects();
}

View File

@ -0,0 +1,24 @@
// dear imgui: Renderer for DirectX11
// This needs to be used along with a Platform Binding (e.g. Win32)
// Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
#pragma once
struct ID3D11Device;
struct ID3D11DeviceContext;
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();

View File

@ -0,0 +1,325 @@
// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications)
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// Implemented features:
// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
#include "imgui.h"
#include "imgui_impl_win32.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <XInput.h>
#include <tchar.h>
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
// 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
// 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
// 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
// 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
// 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
// 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.
// Win32 Data
static HWND g_hWnd = 0;
static INT64 g_Time = 0;
static INT64 g_TicksPerSecond = 0;
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
static bool g_HasGamepad = false;
static bool g_WantUpdateHasGamepad = true;
// Functions
bool ImGui_ImplWin32_Init(void* hwnd)
{
if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond))
return false;
if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time))
return false;
// Setup back-end capabilities flags
g_hWnd = (HWND)hwnd;
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = hwnd;
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
io.KeyMap[ImGuiKey_Home] = VK_HOME;
io.KeyMap[ImGuiKey_End] = VK_END;
io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';
io.KeyMap[ImGuiKey_X] = 'X';
io.KeyMap[ImGuiKey_Y] = 'Y';
io.KeyMap[ImGuiKey_Z] = 'Z';
return true;
}
void ImGui_ImplWin32_Shutdown()
{
g_hWnd = (HWND)0;
}
static bool ImGui_ImplWin32_UpdateMouseCursor()
{
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return false;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
::SetCursor(NULL);
}
else
{
// Show OS mouse cursor
LPTSTR win32_cursor = IDC_ARROW;
switch (imgui_cursor)
{
case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
}
::SetCursor(::LoadCursor(NULL, win32_cursor));
}
return true;
}
static void ImGui_ImplWin32_UpdateMousePos()
{
ImGuiIO& io = ImGui::GetIO();
// Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos)
{
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
::ClientToScreen(g_hWnd, &pos);
::SetCursorPos(pos.x, pos.y);
}
// Set mouse position
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
POINT pos;
if (HWND active_window = ::GetForegroundWindow())
if (active_window == g_hWnd || ::IsChild(active_window, g_hWnd))
if (::GetCursorPos(&pos) && ::ScreenToClient(g_hWnd, &pos))
io.MousePos = ImVec2((float)pos.x, (float)pos.y);
}
#ifdef _MSC_VER
#pragma comment(lib, "xinput")
#endif
// Gamepad navigation mapping
static void ImGui_ImplWin32_UpdateGamepads()
{
ImGuiIO& io = ImGui::GetIO();
memset(io.NavInputs, 0, sizeof(io.NavInputs));
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
return;
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
if (g_WantUpdateHasGamepad)
{
XINPUT_CAPABILITIES caps;
g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS);
g_WantUpdateHasGamepad = false;
}
XINPUT_STATE xinput_state;
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
{
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
}
}
void ImGui_ImplWin32_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
// Setup display size (every frame to accommodate for window resizing)
RECT rect;
::GetClientRect(g_hWnd, &rect);
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
// Setup time step
INT64 current_time;
::QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond;
g_Time = current_time;
// Read keyboard modifiers inputs
io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
io.KeySuper = false;
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
// Update OS mouse position
ImGui_ImplWin32_UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
if (g_LastMouseCursor != mouse_cursor)
{
g_LastMouseCursor = mouse_cursor;
ImGui_ImplWin32_UpdateMouseCursor();
}
// Update game controllers (if enabled and available)
ImGui_ImplWin32_UpdateGamepads();
}
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef DBT_DEVNODES_CHANGED
#define DBT_DEVNODES_CHANGED 0x0007
#endif
// Process Win32 mouse/keyboard inputs.
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (ImGui::GetCurrentContext() == NULL)
return 0;
ImGuiIO& io = ImGui::GetIO();
switch (msg)
{
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
{
int button = 0;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
::SetCapture(hwnd);
io.MouseDown[button] = true;
return 0;
}
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
{
int button = 0;
if (msg == WM_LBUTTONUP) { button = 0; }
if (msg == WM_RBUTTONUP) { button = 1; }
if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
io.MouseDown[button] = false;
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
::ReleaseCapture();
return 0;
}
case WM_MOUSEWHEEL:
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
return 0;
case WM_MOUSEHWHEEL:
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
return 0;
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (wParam < 256)
io.KeysDown[wParam] = 1;
return 0;
case WM_KEYUP:
case WM_SYSKEYUP:
if (wParam < 256)
io.KeysDown[wParam] = 0;
return 0;
case WM_CHAR:
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
io.AddInputCharacter((unsigned int)wParam);
return 0;
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
return 1;
return 0;
case WM_DEVICECHANGE:
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
g_WantUpdateHasGamepad = true;
return 0;
}
return 0;
}

View File

@ -0,0 +1,21 @@
// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications)
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
// Implemented features:
// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
#pragma once
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
// Handler for Win32 messages, update mouse/keyboard data.
// You may or not need this for your implementation, but it can serve as reference for handling inputs.
// Intentionally commented out to avoid dragging dependencies on <windows.h> types. You can COPY this line into your .cpp code instead.
/*
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,639 @@
// [DEAR IMGUI]
// This is a slightly modified version of stb_rect_pack.h 1.00.
// Those changes would need to be pushed into nothings/stb:
// - Added STBRP__CDECL
// Grep for [DEAR IMGUI] to find the changes.
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
//
// Has only had a few tests run, may have issues.
//
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
// Please note: better rectangle packers are welcome! Please
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
//
// LICENSE
//
// See end of file for license information.
//////////////////////////////////////////////////////////////////////////////
//
// INCLUDE SECTION
//
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
#define STB_RECT_PACK_VERSION 1
#ifdef STBRP_STATIC
#define STBRP_DEF static
#else
#define STBRP_DEF extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord;
#else
typedef unsigned short stbrp_coord;
#endif
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call stbrp_init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
struct stbrp_rect
{
// reserved for your use:
int id;
// input:
stbrp_coord w, h;
// output:
stbrp_coord x, y;
int was_packed; // non-zero if valid packing
}; // 16 bytes, nominally
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following stbrp_pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
};
//////////////////////////////////////////////////////////////////////////////
//
// the details of the following structures don't matter to you, but they must
// be visible so you can handle the memory allocations for them
struct stbrp_node
{
stbrp_coord x,y;
stbrp_node *next;
};
struct stbrp_context
{
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
};
#ifdef __cplusplus
}
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
//
// IMPLEMENTATION SECTION
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
#include <stdlib.h>
#define STBRP_SORT qsort
#endif
#ifndef STBRP_ASSERT
#include <assert.h>
#define STBRP_ASSERT assert
#endif
// [DEAR IMGUI] Added STBRP__CDECL
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif
enum
{
STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
STBRP_ASSERT(0);
}
}
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem)
// if it's ok to run out of memory, then don't bother aligning them;
// this gives better packing, but may fail due to OOM (even though
// the rectangles easily fit). @TODO a smarter approach would be to only
// quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
else {
// if it's not ok to run out of memory, then quantize the widths
// so that num_nodes is always enough nodes.
//
// I.e. num_nodes * align >= width
// align >= width / num_nodes
// align = ceil(width/num_nodes)
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
#endif
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30);
#else
context->extra[1].y = 65535;
#endif
context->extra[1].next = NULL;
}
// find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
STBRP__NOTUSED(c);
STBRP_ASSERT(first->x <= x0);
#if 0
// skip in case we're past the node
while (node->next->x <= x0)
++node;
#else
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
#endif
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
// raise min_y higher.
// we've accounted for all waste up to min_y,
// but we'll now add more waste for everything we've visted
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
// the first time through, visited_width might be reduced
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
// add waste area
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
// align to multiple of c->align
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
// bottom left
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
// best-fit
if (y + height <= c->height) {
// can only use it if it first vertically
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
// if doing best-fit (BF), we also have to try aligning right edge to each node position
//
// e.g, if fitting
//
// ____________________
// |____________________|
//
// into
//
// | |
// | ____________|
// |____________|
//
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
//
// This makes BF take about 2x the time
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
// find first node that's admissible
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
// find the left position that matches this
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
STBRP_ASSERT(y <= best_y);
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
// find best position according to heuristic
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
// bail if:
// 1. it failed
// 2. the best node doesn't fit (we don't always check this)
// 3. we're out of memory
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
// on success, create new node
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
// insert the new node into the right starting point, and
// let 'cur' point to the remaining nodes needing to be
// stiched back in
cur = *res.prev_link;
if (cur->x < res.x) {
// preserve the existing one, so start testing with the next one
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
// from here, traverse cur and free the nodes, until we get to one
// that shouldn't be freed
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
// move the current node to the free list
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
// stitch the list back in
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifdef _DEBUG
cur = context->active_head;
while (cur->x < context->width) {
STBRP_ASSERT(cur->x < cur->next->x);
cur = cur->next;
}
STBRP_ASSERT(cur->next == NULL);
{
int count=0;
cur = context->active_head;
while (cur) {
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
cur = cur->next;
++count;
}
STBRP_ASSERT(count == context->num_nodes+2);
}
#endif
return res;
}
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
return (p->w > q->w) ? -1 : (p->w < q->w);
}
// [DEAR IMGUI] Added STBRP__CDECL
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
#ifdef STBRP_LARGE_RECTS
#define STBRP__MAXVAL 0xffffffff
#else
#define STBRP__MAXVAL 0xffff
#endif
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
}
// sort according to heuristic
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags and all_rects_packed status
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}
#endif
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

24764
TempleWare-CS2/external/json/json.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

720
TempleWare-CS2/external/kiero/kiero.cpp vendored Normal file
View File

@ -0,0 +1,720 @@
#include "kiero.h"
#include <Windows.h>
#include <assert.h>
#if KIERO_INCLUDE_D3D9
# include <d3d9.h>
#endif
#if KIERO_INCLUDE_D3D10
# include <dxgi.h>
# include <d3d10_1.h>
# include <d3d10.h>
#endif
#if KIERO_INCLUDE_D3D11
# include <dxgi.h>
# include <d3d11.h>
#endif
#if KIERO_INCLUDE_D3D12
# include <dxgi.h>
# include <d3d12.h>
#endif
#if KIERO_INCLUDE_OPENGL
# include <gl/GL.h>
#endif
#if KIERO_INCLUDE_VULKAN
# include <vulkan/vulkan.h>
#endif
#if KIERO_USE_MINHOOK
# include "minhook/include/MinHook.h"
#endif
#ifdef _UNICODE
# define KIERO_TEXT(text) L##text
#else
# define KIERO_TEXT(text) text
#endif
#define KIERO_ARRAY_SIZE(arr) ((size_t)(sizeof(arr)/sizeof(arr[0])))
static kiero::RenderType::Enum g_renderType = kiero::RenderType::None;
static uint150_t* g_methodsTable = NULL;
kiero::Status::Enum kiero::init(RenderType::Enum _renderType)
{
if (g_renderType != RenderType::None)
{
return Status::AlreadyInitializedError;
}
if (_renderType != RenderType::None)
{
if (_renderType >= RenderType::D3D9 && _renderType <= RenderType::D3D12)
{
WNDCLASSEX windowClass;
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = DefWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = GetModuleHandle(NULL);
windowClass.hIcon = NULL;
windowClass.hCursor = NULL;
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = KIERO_TEXT("Kiero");
windowClass.hIconSm = NULL;
::RegisterClassEx(&windowClass);
HWND window = ::CreateWindow(windowClass.lpszClassName, KIERO_TEXT("Kiero DirectX Window"), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, windowClass.hInstance, NULL);
if (_renderType == RenderType::D3D9)
{
#if KIERO_INCLUDE_D3D9
HMODULE libD3D9;
if ((libD3D9 = ::GetModuleHandle(KIERO_TEXT("d3d9.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* Direct3DCreate9;
if ((Direct3DCreate9 = ::GetProcAddress(libD3D9, "Direct3DCreate9")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
LPDIRECT3D9 direct3D9;
if ((direct3D9 = ((LPDIRECT3D9(__stdcall*)(uint32_t))(Direct3DCreate9))(D3D_SDK_VERSION)) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3DDISPLAYMODE displayMode;
if (direct3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3DPRESENT_PARAMETERS params;
params.BackBufferWidth = 0;
params.BackBufferHeight = 0;
params.BackBufferFormat = displayMode.Format;
params.BackBufferCount = 0;
params.MultiSampleType = D3DMULTISAMPLE_NONE;
params.MultiSampleQuality = NULL;
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
params.hDeviceWindow = window;
params.Windowed = 1;
params.EnableAutoDepthStencil = 0;
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
params.Flags = NULL;
params.FullScreen_RefreshRateInHz = 0;
params.PresentationInterval = 0;
LPDIRECT3DDEVICE9 device;
if (direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, &params, &device) < 0)
{
direct3D9->Release();
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(119, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)device, 119 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
direct3D9->Release();
direct3D9 = NULL;
device->Release();
device = NULL;
g_renderType = RenderType::D3D9;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D10)
{
#if KIERO_INCLUDE_D3D10
HMODULE libDXGI;
HMODULE libD3D10;
if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* CreateDXGIFactory;
if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIFactory* factory;
if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIAdapter* adapter;
if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
void* D3D10CreateDeviceAndSwapChain;
if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
ID3D10Device* device;
if (((long(__stdcall*)(
IDXGIAdapter*,
D3D10_DRIVER_TYPE,
HMODULE,
UINT,
UINT,
DXGI_SWAP_CHAIN_DESC*,
IDXGISwapChain**,
ID3D10Device**))(D3D10CreateDeviceAndSwapChain))(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(116, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18, *(uint150_t**)device, 98 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
swapChain->Release();
swapChain = NULL;
device->Release();
device = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D10;
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D11)
{
#if KIERO_INCLUDE_D3D11
HMODULE libD3D11;
if ((libD3D11 = ::GetModuleHandle(KIERO_TEXT("d3d11.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* D3D11CreateDeviceAndSwapChain;
if ((D3D11CreateDeviceAndSwapChain = ::GetProcAddress(libD3D11, "D3D11CreateDeviceAndSwapChain")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0 };
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
ID3D11Device* device;
ID3D11DeviceContext* context;
if (((long(__stdcall*)(
IDXGIAdapter*,
D3D_DRIVER_TYPE,
HMODULE,
UINT,
const D3D_FEATURE_LEVEL*,
UINT,
UINT,
const DXGI_SWAP_CHAIN_DESC*,
IDXGISwapChain**,
ID3D11Device**,
D3D_FEATURE_LEVEL*,
ID3D11DeviceContext**))(D3D11CreateDeviceAndSwapChain))(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &context) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(205, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18, *(uint150_t**)device, 43 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18 + 43, *(uint150_t**)context, 144 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
swapChain->Release();
swapChain = NULL;
device->Release();
device = NULL;
context->Release();
context = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D11;
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D12)
{
#if KIERO_INCLUDE_D3D12
HMODULE libDXGI;
HMODULE libD3D12;
if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D12 = ::GetModuleHandle(KIERO_TEXT("d3d12.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* CreateDXGIFactory;
if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIFactory* factory;
if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIAdapter* adapter;
if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
void* D3D12CreateDevice;
if ((D3D12CreateDevice = ::GetProcAddress(libD3D12, "D3D12CreateDevice")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12Device* device;
if (((long(__stdcall*)(IUnknown*, D3D_FEATURE_LEVEL, const IID&, void**))(D3D12CreateDevice))(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&device) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3D12_COMMAND_QUEUE_DESC queueDesc;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Priority = 0;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.NodeMask = 0;
ID3D12CommandQueue* commandQueue;
if (device->CreateCommandQueue(&queueDesc, __uuidof(ID3D12CommandQueue), (void**)&commandQueue) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12CommandAllocator* commandAllocator;
if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&commandAllocator) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12GraphicsCommandList* commandList;
if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator, NULL, __uuidof(ID3D12GraphicsCommandList), (void**)&commandList) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
if (factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(150, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)device, 44 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44, *(uint150_t**)commandQueue, 19 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19, *(uint150_t**)commandAllocator, 9 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19 + 9, *(uint150_t**)commandList, 60 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
device->Release();
device = NULL;
commandQueue->Release();
commandQueue = NULL;
commandAllocator->Release();
commandAllocator = NULL;
commandList->Release();
commandList = NULL;
swapChain->Release();
swapChain = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D12;
return Status::Success;
#endif
}
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::NotSupportedError;
}
else if (_renderType == RenderType::OpenGL)
{
#if KIERO_INCLUDE_OPENGL
HMODULE libOpenGL32;
if ((libOpenGL32 = ::GetModuleHandle(KIERO_TEXT("opengl32.dll"))) == NULL)
{
return Status::ModuleNotFoundError;
}
const char* const methodsNames[] = {
"glAccum", "glAlphaFunc", "glAreTexturesResident", "glArrayElement", "glBegin", "glBindTexture", "glBitmap", "glBlendFunc", "glCallList", "glCallLists", "glClear", "glClearAccum",
"glClearColor", "glClearDepth", "glClearIndex", "glClearStencil", "glClipPlane", "glColor3b", "glColor3bv", "glColor3d", "glColor3dv", "glColor3f", "glColor3fv", "glColor3i", "glColor3iv",
"glColor3s", "glColor3sv", "glColor3ub", "glColor3ubv", "glColor3ui", "glColor3uiv", "glColor3us", "glColor3usv", "glColor4b", "glColor4bv", "glColor4d", "glColor4dv", "glColor4f",
"glColor4fv", "glColor4i", "glColor4iv", "glColor4s", "glColor4sv", "glColor4ub", "glColor4ubv", "glColor4ui", "glColor4uiv", "glColor4us", "glColor4usv", "glColorMask", "glColorMaterial",
"glColorPointer", "glCopyPixels", "glCopyTexImage1D", "glCopyTexImage2D", "glCopyTexSubImage1D", "glCopyTexSubImage2D", "glCullFaceglCullFace", "glDeleteLists", "glDeleteTextures",
"glDepthFunc", "glDepthMask", "glDepthRange", "glDisable", "glDisableClientState", "glDrawArrays", "glDrawBuffer", "glDrawElements", "glDrawPixels", "glEdgeFlag", "glEdgeFlagPointer",
"glEdgeFlagv", "glEnable", "glEnableClientState", "glEnd", "glEndList", "glEvalCoord1d", "glEvalCoord1dv", "glEvalCoord1f", "glEvalCoord1fv", "glEvalCoord2d", "glEvalCoord2dv",
"glEvalCoord2f", "glEvalCoord2fv", "glEvalMesh1", "glEvalMesh2", "glEvalPoint1", "glEvalPoint2", "glFeedbackBuffer", "glFinish", "glFlush", "glFogf", "glFogfv", "glFogi", "glFogiv",
"glFrontFace", "glFrustum", "glGenLists", "glGenTextures", "glGetBooleanv", "glGetClipPlane", "glGetDoublev", "glGetError", "glGetFloatv", "glGetIntegerv", "glGetLightfv", "glGetLightiv",
"glGetMapdv", "glGetMapfv", "glGetMapiv", "glGetMaterialfv", "glGetMaterialiv", "glGetPixelMapfv", "glGetPixelMapuiv", "glGetPixelMapusv", "glGetPointerv", "glGetPolygonStipple",
"glGetString", "glGetTexEnvfv", "glGetTexEnviv", "glGetTexGendv", "glGetTexGenfv", "glGetTexGeniv", "glGetTexImage", "glGetTexLevelParameterfv", "glGetTexLevelParameteriv",
"glGetTexParameterfv", "glGetTexParameteriv", "glHint", "glIndexMask", "glIndexPointer", "glIndexd", "glIndexdv", "glIndexf", "glIndexfv", "glIndexi", "glIndexiv", "glIndexs", "glIndexsv",
"glIndexub", "glIndexubv", "glInitNames", "glInterleavedArrays", "glIsEnabled", "glIsList", "glIsTexture", "glLightModelf", "glLightModelfv", "glLightModeli", "glLightModeliv", "glLightf",
"glLightfv", "glLighti", "glLightiv", "glLineStipple", "glLineWidth", "glListBase", "glLoadIdentity", "glLoadMatrixd", "glLoadMatrixf", "glLoadName", "glLogicOp", "glMap1d", "glMap1f",
"glMap2d", "glMap2f", "glMapGrid1d", "glMapGrid1f", "glMapGrid2d", "glMapGrid2f", "glMaterialf", "glMaterialfv", "glMateriali", "glMaterialiv", "glMatrixMode", "glMultMatrixd",
"glMultMatrixf", "glNewList", "glNormal3b", "glNormal3bv", "glNormal3d", "glNormal3dv", "glNormal3f", "glNormal3fv", "glNormal3i", "glNormal3iv", "glNormal3s", "glNormal3sv",
"glNormalPointer", "glOrtho", "glPassThrough", "glPixelMapfv", "glPixelMapuiv", "glPixelMapusv", "glPixelStoref", "glPixelStorei", "glPixelTransferf", "glPixelTransferi", "glPixelZoom",
"glPointSize", "glPolygonMode", "glPolygonOffset", "glPolygonStipple", "glPopAttrib", "glPopClientAttrib", "glPopMatrix", "glPopName", "glPrioritizeTextures", "glPushAttrib",
"glPushClientAttrib", "glPushMatrix", "glPushName", "glRasterPos2d", "glRasterPos2dv", "glRasterPos2f", "glRasterPos2fv", "glRasterPos2i", "glRasterPos2iv", "glRasterPos2s",
"glRasterPos2sv", "glRasterPos3d", "glRasterPos3dv", "glRasterPos3f", "glRasterPos3fv", "glRasterPos3i", "glRasterPos3iv", "glRasterPos3s", "glRasterPos3sv", "glRasterPos4d",
"glRasterPos4dv", "glRasterPos4f", "glRasterPos4fv", "glRasterPos4i", "glRasterPos4iv", "glRasterPos4s", "glRasterPos4sv", "glReadBuffer", "glReadPixels", "glRectd", "glRectdv", "glRectf",
"glRectfv", "glRecti", "glRectiv", "glRects", "glRectsv", "glRenderMode", "glRotated", "glRotatef", "glScaled", "glScalef", "glScissor", "glSelectBuffer", "glShadeModel", "glStencilFunc",
"glStencilMask", "glStencilOp", "glTexCoord1d", "glTexCoord1dv", "glTexCoord1f", "glTexCoord1fv", "glTexCoord1i", "glTexCoord1iv", "glTexCoord1s", "glTexCoord1sv", "glTexCoord2d",
"glTexCoord2dv", "glTexCoord2f", "glTexCoord2fv", "glTexCoord2i", "glTexCoord2iv", "glTexCoord2s", "glTexCoord2sv", "glTexCoord3d", "glTexCoord3dv", "glTexCoord3f", "glTexCoord3fv",
"glTexCoord3i", "glTexCoord3iv", "glTexCoord3s", "glTexCoord3sv", "glTexCoord4d", "glTexCoord4dv", "glTexCoord4f", "glTexCoord4fv", "glTexCoord4i", "glTexCoord4iv", "glTexCoord4s",
"glTexCoord4sv", "glTexCoordPointer", "glTexEnvf", "glTexEnvfv", "glTexEnvi", "glTexEnviv", "glTexGend", "glTexGendv", "glTexGenf", "glTexGenfv", "glTexGeni", "glTexGeniv", "glTexImage1D",
"glTexImage2D", "glTexParameterf", "glTexParameterfv", "glTexParameteri", "glTexParameteriv", "glTexSubImage1D", "glTexSubImage2D", "glTranslated", "glTranslatef", "glVertex2d",
"glVertex2dv", "glVertex2f", "glVertex2fv", "glVertex2i", "glVertex2iv", "glVertex2s", "glVertex2sv", "glVertex3d", "glVertex3dv", "glVertex3f", "glVertex3fv", "glVertex3i", "glVertex3iv",
"glVertex3s", "glVertex3sv", "glVertex4d", "glVertex4dv", "glVertex4f", "glVertex4fv", "glVertex4i", "glVertex4iv", "glVertex4s", "glVertex4sv", "glVertexPointer", "glViewport"
};
size_t size = KIERO_ARRAY_SIZE(methodsNames);
g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t));
for (int i = 0; i < size; i++)
{
g_methodsTable[i] = (uint150_t)::GetProcAddress(libOpenGL32, methodsNames[i]);
}
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
g_renderType = RenderType::OpenGL;
return Status::Success;
#endif
}
else if (_renderType == RenderType::Vulkan)
{
#if KIERO_INCLUDE_VULKAN
HMODULE libVulkan;
if ((libVulkan = GetModuleHandle(KIERO_TEXT("vulcan-1.dll"))) == NULL)
{
return Status::ModuleNotFoundError;
}
const char* const methodsNames[] = {
"vkCreateInstance", "vkDestroyInstance", "vkEnumeratePhysicalDevices", "vkGetPhysicalDeviceFeatures", "vkGetPhysicalDeviceFormatProperties", "vkGetPhysicalDeviceImageFormatProperties",
"vkGetPhysicalDeviceProperties", "vkGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceMemoryProperties", "vkGetInstanceProcAddr", "vkGetDeviceProcAddr", "vkCreateDevice",
"vkDestroyDevice", "vkEnumerateInstanceExtensionProperties", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkGetDeviceQueue", "vkQueueSubmit", "vkQueueWaitIdle",
"vkDeviceWaitIdle", "vkAllocateMemory", "vkFreeMemory", "vkMapMemory", "vkUnmapMemory", "vkFlushMappedMemoryRanges", "vkInvalidateMappedMemoryRanges", "vkGetDeviceMemoryCommitment",
"vkBindBufferMemory", "vkBindImageMemory", "vkGetBufferMemoryRequirements", "vkGetImageMemoryRequirements", "vkGetImageSparseMemoryRequirements", "vkGetPhysicalDeviceSparseImageFormatProperties",
"vkQueueBindSparse", "vkCreateFence", "vkDestroyFence", "vkResetFences", "vkGetFenceStatus", "vkWaitForFences", "vkCreateSemaphore", "vkDestroySemaphore", "vkCreateEvent", "vkDestroyEvent",
"vkGetEventStatus", "vkSetEvent", "vkResetEvent", "vkCreateQueryPool", "vkDestroyQueryPool", "vkGetQueryPoolResults", "vkCreateBuffer", "vkDestroyBuffer", "vkCreateBufferView", "vkDestroyBufferView",
"vkCreateImage", "vkDestroyImage", "vkGetImageSubresourceLayout", "vkCreateImageView", "vkDestroyImageView", "vkCreateShaderModule", "vkDestroyShaderModule", "vkCreatePipelineCache",
"vkDestroyPipelineCache", "vkGetPipelineCacheData", "vkMergePipelineCaches", "vkCreateGraphicsPipelines", "vkCreateComputePipelines", "vkDestroyPipeline", "vkCreatePipelineLayout",
"vkDestroyPipelineLayout", "vkCreateSampler", "vkDestroySampler", "vkCreateDescriptorSetLayout", "vkDestroyDescriptorSetLayout", "vkCreateDescriptorPool", "vkDestroyDescriptorPool",
"vkResetDescriptorPool", "vkAllocateDescriptorSets", "vkFreeDescriptorSets", "vkUpdateDescriptorSets", "vkCreateFramebuffer", "vkDestroyFramebuffer", "vkCreateRenderPass", "vkDestroyRenderPass",
"vkGetRenderAreaGranularity", "vkCreateCommandPool", "vkDestroyCommandPool", "vkResetCommandPool", "vkAllocateCommandBuffers", "vkFreeCommandBuffers", "vkBeginCommandBuffer", "vkEndCommandBuffer",
"vkResetCommandBuffer", "vkCmdBindPipeline", "vkCmdSetViewport", "vkCmdSetScissor", "vkCmdSetLineWidth", "vkCmdSetDepthBias", "vkCmdSetBlendConstants", "vkCmdSetDepthBounds",
"vkCmdSetStencilCompareMask", "vkCmdSetStencilWriteMask", "vkCmdSetStencilReference", "vkCmdBindDescriptorSets", "vkCmdBindIndexBuffer", "vkCmdBindVertexBuffers", "vkCmdDraw", "vkCmdDrawIndexed",
"vkCmdDrawIndirect", "vkCmdDrawIndexedIndirect", "vkCmdDispatch", "vkCmdDispatchIndirect", "vkCmdCopyBuffer", "vkCmdCopyImage", "vkCmdBlitImage", "vkCmdCopyBufferToImage", "vkCmdCopyImageToBuffer",
"vkCmdUpdateBuffer", "vkCmdFillBuffer", "vkCmdClearColorImage", "vkCmdClearDepthStencilImage", "vkCmdClearAttachments", "vkCmdResolveImage", "vkCmdSetEvent", "vkCmdResetEvent", "vkCmdWaitEvents",
"vkCmdPipelineBarrier", "vkCmdBeginQuery", "vkCmdEndQuery", "vkCmdResetQueryPool", "vkCmdWriteTimestamp", "vkCmdCopyQueryPoolResults", "vkCmdPushConstants", "vkCmdBeginRenderPass", "vkCmdNextSubpass",
"vkCmdEndRenderPass", "vkCmdExecuteCommands"
};
size_t size = KIERO_ARRAY_SIZE(methodsNames);
g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t));
for (int i = 0; i < size; i++)
{
g_methodsTable[i] = (uint150_t)::GetProcAddress(libVulkan, methodsNames[i]);
}
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
g_renderType = RenderType::Vulkan;
return Status::Success;
#endif
}
else if (_renderType == RenderType::Auto)
{
RenderType::Enum type = RenderType::None;
if (::GetModuleHandle(KIERO_TEXT("d3d9.dll")) != NULL)
{
type = RenderType::D3D9;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d10.dll")) != NULL)
{
type = RenderType::D3D10;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d11.dll")) != NULL)
{
type = RenderType::D3D11;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d12.dll")) != NULL)
{
type = RenderType::D3D12;
}
else if (::GetModuleHandle(KIERO_TEXT("opengl32.dll")) != NULL)
{
type = RenderType::OpenGL;
}
else if (::GetModuleHandle(KIERO_TEXT("vulcan-1.dll")) != NULL)
{
type = RenderType::Vulkan;
}
return init(type);
}
}
return Status::Success;
}
void kiero::shutdown()
{
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
MH_DisableHook(MH_ALL_HOOKS);
#endif
::free(g_methodsTable);
g_methodsTable = NULL;
g_renderType = RenderType::None;
}
}
kiero::Status::Enum kiero::bind(uint16_t _index, void** _original, void* _function)
{
// TODO: Need own detour function
assert(_index >= 0 && _original != NULL && _function != NULL);
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
void* target = (void*)g_methodsTable[_index];
if (MH_CreateHook(target, _function, _original) != MH_OK || MH_EnableHook(target) != MH_OK)
{
return Status::UnknownError;
}
#endif
return Status::Success;
}
return Status::NotInitializedError;
}
void kiero::unbind(uint16_t _index)
{
assert(_index >= 0);
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
MH_DisableHook((void*)g_methodsTable[_index]);
#endif
}
}
kiero::RenderType::Enum kiero::getRenderType()
{
return g_renderType;
}
uint150_t* kiero::getMethodsTable()
{
return g_methodsTable;
}

78
TempleWare-CS2/external/kiero/kiero.h vendored Normal file
View File

@ -0,0 +1,78 @@
#ifndef __KIERO_H__
#define __KIERO_H__
#include <stdint.h>
#define KIERO_VERSION "1.2.6"
#define KIERO_INCLUDE_D3D9 0 // 1 if you need D3D9 hook
#define KIERO_INCLUDE_D3D10 0 // 1 if you need D3D10 hook
#define KIERO_INCLUDE_D3D11 1 // 1 if you need D3D11 hook
#define KIERO_INCLUDE_D3D12 0 // 1 if you need D3D12 hook
#define KIERO_INCLUDE_OPENGL 0 // 1 if you need OpenGL hook
#define KIERO_INCLUDE_VULKAN 0 // 1 if you need Vulkan hook
#define KIERO_USE_MINHOOK 1 // 1 if you will use kiero::bind function
#define KIERO_ARCH_X64 0
#define KIERO_ARCH_X86 0
#if defined(_M_X64)
# undef KIERO_ARCH_X64
# define KIERO_ARCH_X64 1
#else
# undef KIERO_ARCH_X86
# define KIERO_ARCH_X86 1
#endif
#if KIERO_ARCH_X64
typedef uint64_t uint150_t;
#else
typedef uint32_t uint150_t;
#endif
namespace kiero
{
struct Status
{
enum Enum
{
UnknownError = -1,
NotSupportedError = -2,
ModuleNotFoundError = -3,
AlreadyInitializedError = -4,
NotInitializedError = -5,
Success = 0,
};
};
struct RenderType
{
enum Enum
{
None,
D3D9,
D3D10,
D3D11,
D3D12,
OpenGL,
Vulkan,
Auto
};
};
Status::Enum init(RenderType::Enum renderType);
void shutdown();
Status::Enum bind(uint16_t index, void** original, void* function);
void unbind(uint16_t index);
RenderType::Enum getRenderType();
uint150_t* getMethodsTable();
}
#endif // __KIERO_H__

View File

@ -0,0 +1,14 @@
EXPORTS
MH_Initialize
MH_Uninitialize
MH_CreateHook
MH_CreateHookApi
MH_CreateHookApiEx
MH_RemoveHook
MH_EnableHook
MH_DisableHook
MH_QueueEnableHook
MH_QueueDisableHook
MH_ApplyQueued
MH_StatusToString

View File

@ -0,0 +1,32 @@
1 VERSIONINFO
FILEVERSION 1,3,3,0
PRODUCTVERSION 1,3,3,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Tsuda Kageyu"
VALUE "FileDescription", "MinHook - The Minimalistic API Hook Library for x64/x86"
VALUE "FileVersion", "1.3.3.0"
VALUE "InternalName", "MinHookD"
VALUE "LegalCopyright", "Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved."
VALUE "LegalTrademarks", "Tsuda Kageyu"
VALUE "ProductName", "MinHook DLL"
VALUE "ProductVersion", "1.3.3.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View File

@ -0,0 +1,186 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
#error MinHook supports only x86 and x64 systems.
#endif
#include <windows.h>
// MinHook Error Codes.
typedef enum MH_STATUS
{
// Unknown error. Should not be returned.
MH_UNKNOWN = -1,
// Successful.
MH_OK = 0,
// MinHook is already initialized.
MH_ERROR_ALREADY_INITIALIZED,
// MinHook is not initialized yet, or already uninitialized.
MH_ERROR_NOT_INITIALIZED,
// The hook for the specified target function is already created.
MH_ERROR_ALREADY_CREATED,
// The hook for the specified target function is not created yet.
MH_ERROR_NOT_CREATED,
// The hook for the specified target function is already enabled.
MH_ERROR_ENABLED,
// The hook for the specified target function is not enabled yet, or already
// disabled.
MH_ERROR_DISABLED,
// The specified pointer is invalid. It points the address of non-allocated
// and/or non-executable region.
MH_ERROR_NOT_EXECUTABLE,
// The specified target function cannot be hooked.
MH_ERROR_UNSUPPORTED_FUNCTION,
// Failed to allocate memory.
MH_ERROR_MEMORY_ALLOC,
// Failed to change the memory protection.
MH_ERROR_MEMORY_PROTECT,
// The specified module is not loaded.
MH_ERROR_MODULE_NOT_FOUND,
// The specified function is not found.
MH_ERROR_FUNCTION_NOT_FOUND
}
MH_STATUS;
// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
// MH_QueueEnableHook or MH_QueueDisableHook.
#define MH_ALL_HOOKS NULL
#ifdef __cplusplus
extern "C" {
#endif
// Initialize the MinHook library. You must call this function EXACTLY ONCE
// at the beginning of your program.
MH_STATUS WINAPI MH_Initialize(VOID);
// Uninitialize the MinHook library. You must call this function EXACTLY
// ONCE at the end of your program.
MH_STATUS WINAPI MH_Uninitialize(VOID);
// Creates a Hook for the specified target function, in disabled state.
// Parameters:
// pTarget [in] A pointer to the target function, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
// Creates a Hook for the specified API function, in disabled state.
// Parameters:
// pszModule [in] A pointer to the loaded module name which contains the
// target function.
// pszTarget [in] A pointer to the target function name, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHookApi(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
// Creates a Hook for the specified API function, in disabled state.
// Parameters:
// pszModule [in] A pointer to the loaded module name which contains the
// target function.
// pszTarget [in] A pointer to the target function name, which will be
// overridden by the detour function.
// pDetour [in] A pointer to the detour function, which will override
// the target function.
// ppOriginal [out] A pointer to the trampoline function, which will be
// used to call the original target function.
// This parameter can be NULL.
// ppTarget [out] A pointer to the target function, which will be used
// with other functions.
// This parameter can be NULL.
MH_STATUS WINAPI MH_CreateHookApiEx(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
// Removes an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
// Enables an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// enabled in one go.
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
// Disables an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// disabled in one go.
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
// Queues to enable an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// queued to be enabled.
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
// Queues to disable an already created hook.
// Parameters:
// pTarget [in] A pointer to the target function.
// If this parameter is MH_ALL_HOOKS, all created hooks are
// queued to be disabled.
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
// Applies all queued changes in one go.
MH_STATUS WINAPI MH_ApplyQueued(VOID);
// Translates the MH_STATUS to its name as a string.
const char * WINAPI MH_StatusToString(MH_STATUS status);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,312 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#include "buffer.h"
// Size of each memory block. (= page size of VirtualAlloc)
#define MEMORY_BLOCK_SIZE 0x1000
// Max range for seeking a memory block. (= 1024MB)
#define MAX_MEMORY_RANGE 0x40000000
// Memory protection flags to check the executable address.
#define PAGE_EXECUTE_FLAGS \
(PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
// Memory slot.
typedef struct _MEMORY_SLOT
{
union
{
struct _MEMORY_SLOT *pNext;
UINT8 buffer[MEMORY_SLOT_SIZE];
};
} MEMORY_SLOT, *PMEMORY_SLOT;
// Memory block info. Placed at the head of each block.
typedef struct _MEMORY_BLOCK
{
struct _MEMORY_BLOCK *pNext;
PMEMORY_SLOT pFree; // First element of the free slot list.
UINT usedCount;
} MEMORY_BLOCK, *PMEMORY_BLOCK;
//-------------------------------------------------------------------------
// Global Variables:
//-------------------------------------------------------------------------
// First element of the memory block list.
PMEMORY_BLOCK g_pMemoryBlocks;
//-------------------------------------------------------------------------
VOID InitializeBuffer(VOID)
{
// Nothing to do for now.
}
//-------------------------------------------------------------------------
VOID UninitializeBuffer(VOID)
{
PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
g_pMemoryBlocks = NULL;
while (pBlock)
{
PMEMORY_BLOCK pNext = pBlock->pNext;
VirtualFree(pBlock, 0, MEM_RELEASE);
pBlock = pNext;
}
}
//-------------------------------------------------------------------------
#if defined(_M_X64) || defined(__x86_64__)
static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity)
{
ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
// Round down to the allocation granularity.
tryAddr -= tryAddr % dwAllocationGranularity;
// Start from the previous allocation granularity multiply.
tryAddr -= dwAllocationGranularity;
while (tryAddr >= (ULONG_PTR)pMinAddr)
{
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
break;
if (mbi.State == MEM_FREE)
return (LPVOID)tryAddr;
if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity)
break;
tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity;
}
return NULL;
}
#endif
//-------------------------------------------------------------------------
#if defined(_M_X64) || defined(__x86_64__)
static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity)
{
ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
// Round down to the allocation granularity.
tryAddr -= tryAddr % dwAllocationGranularity;
// Start from the next allocation granularity multiply.
tryAddr += dwAllocationGranularity;
while (tryAddr <= (ULONG_PTR)pMaxAddr)
{
MEMORY_BASIC_INFORMATION mbi;
if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
break;
if (mbi.State == MEM_FREE)
return (LPVOID)tryAddr;
tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
// Round up to the next allocation granularity.
tryAddr += dwAllocationGranularity - 1;
tryAddr -= tryAddr % dwAllocationGranularity;
}
return NULL;
}
#endif
//-------------------------------------------------------------------------
static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin)
{
PMEMORY_BLOCK pBlock;
#if defined(_M_X64) || defined(__x86_64__)
ULONG_PTR minAddr;
ULONG_PTR maxAddr;
SYSTEM_INFO si;
GetSystemInfo(&si);
minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress;
maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress;
// pOrigin ± 512MB
if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE)
minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE;
if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE)
maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE;
// Make room for MEMORY_BLOCK_SIZE bytes.
maxAddr -= MEMORY_BLOCK_SIZE - 1;
#endif
// Look the registered blocks for a reachable one.
for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext)
{
#if defined(_M_X64) || defined(__x86_64__)
// Ignore the blocks too far.
if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr)
continue;
#endif
// The block has at least one unused slot.
if (pBlock->pFree != NULL)
return pBlock;
}
#if defined(_M_X64) || defined(__x86_64__)
// Alloc a new block above if not found.
{
LPVOID pAlloc = pOrigin;
while ((ULONG_PTR)pAlloc >= minAddr)
{
pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity);
if (pAlloc == NULL)
break;
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pBlock != NULL)
break;
}
}
// Alloc a new block below if not found.
if (pBlock == NULL)
{
LPVOID pAlloc = pOrigin;
while ((ULONG_PTR)pAlloc <= maxAddr)
{
pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity);
if (pAlloc == NULL)
break;
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pBlock != NULL)
break;
}
}
#else
// In x86 mode, a memory block can be placed anywhere.
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
#endif
if (pBlock != NULL)
{
// Build a linked list of all the slots.
PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1;
pBlock->pFree = NULL;
pBlock->usedCount = 0;
do
{
pSlot->pNext = pBlock->pFree;
pBlock->pFree = pSlot;
pSlot++;
} while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE);
pBlock->pNext = g_pMemoryBlocks;
g_pMemoryBlocks = pBlock;
}
return pBlock;
}
//-------------------------------------------------------------------------
LPVOID AllocateBuffer(LPVOID pOrigin)
{
PMEMORY_SLOT pSlot;
PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin);
if (pBlock == NULL)
return NULL;
// Remove an unused slot from the list.
pSlot = pBlock->pFree;
pBlock->pFree = pSlot->pNext;
pBlock->usedCount++;
#ifdef _DEBUG
// Fill the slot with INT3 for debugging.
memset(pSlot, 0xCC, sizeof(MEMORY_SLOT));
#endif
return pSlot;
}
//-------------------------------------------------------------------------
VOID FreeBuffer(LPVOID pBuffer)
{
PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
PMEMORY_BLOCK pPrev = NULL;
ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE;
while (pBlock != NULL)
{
if ((ULONG_PTR)pBlock == pTargetBlock)
{
PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer;
#ifdef _DEBUG
// Clear the released slot for debugging.
memset(pSlot, 0x00, sizeof(*pSlot));
#endif
// Restore the released slot to the list.
pSlot->pNext = pBlock->pFree;
pBlock->pFree = pSlot;
pBlock->usedCount--;
// Free if unused.
if (pBlock->usedCount == 0)
{
if (pPrev)
pPrev->pNext = pBlock->pNext;
else
g_pMemoryBlocks = pBlock->pNext;
VirtualFree(pBlock, 0, MEM_RELEASE);
}
break;
}
pPrev = pBlock;
pBlock = pBlock->pNext;
}
}
//-------------------------------------------------------------------------
BOOL IsExecutableAddress(LPVOID pAddress)
{
MEMORY_BASIC_INFORMATION mi;
VirtualQuery(pAddress, &mi, sizeof(mi));
return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS));
}

View File

@ -0,0 +1,42 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
// Size of each memory slot.
#if defined(_M_X64) || defined(__x86_64__)
#define MEMORY_SLOT_SIZE 64
#else
#define MEMORY_SLOT_SIZE 32
#endif
VOID InitializeBuffer(VOID);
VOID UninitializeBuffer(VOID);
LPVOID AllocateBuffer(LPVOID pOrigin);
VOID FreeBuffer(LPVOID pBuffer);
BOOL IsExecutableAddress(LPVOID pAddress);

View File

@ -0,0 +1,326 @@
/*
* Hacker Disassembler Engine 32 C
* Copyright (c) 2008-2009, Vyacheslav Patkov.
* All rights reserved.
*
*/
#if defined(_M_IX86) || defined(__i386__)
#include "hde32.h"
#include "table32.h"
unsigned int hde32_disasm(const void *code, hde32s *hs)
{
uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0;
// Avoid using memset to reduce the footprint.
#ifndef _MSC_VER
memset((LPBYTE)hs, 0, sizeof(hde32s));
#else
__stosb((LPBYTE)hs, 0, sizeof(hde32s));
#endif
for (x = 16; x; x--)
switch (c = *p++) {
case 0xf3:
hs->p_rep = c;
pref |= PRE_F3;
break;
case 0xf2:
hs->p_rep = c;
pref |= PRE_F2;
break;
case 0xf0:
hs->p_lock = c;
pref |= PRE_LOCK;
break;
case 0x26: case 0x2e: case 0x36:
case 0x3e: case 0x64: case 0x65:
hs->p_seg = c;
pref |= PRE_SEG;
break;
case 0x66:
hs->p_66 = c;
pref |= PRE_66;
break;
case 0x67:
hs->p_67 = c;
pref |= PRE_67;
break;
default:
goto pref_done;
}
pref_done:
hs->flags = (uint32_t)pref << 23;
if (!pref)
pref |= PRE_NONE;
if ((hs->opcode = c) == 0x0f) {
hs->opcode2 = c = *p++;
ht += DELTA_OPCODES;
} else if (c >= 0xa0 && c <= 0xa3) {
if (pref & PRE_67)
pref |= PRE_66;
else
pref &= ~PRE_66;
}
opcode = c;
cflags = ht[ht[opcode / 4] + (opcode % 4)];
if (cflags == C_ERROR) {
hs->flags |= F_ERROR | F_ERROR_OPCODE;
cflags = 0;
if ((opcode & -3) == 0x24)
cflags++;
}
x = 0;
if (cflags & C_GROUP) {
uint16_t t;
t = *(uint16_t *)(ht + (cflags & 0x7f));
cflags = (uint8_t)t;
x = (uint8_t)(t >> 8);
}
if (hs->opcode2) {
ht = hde32_table + DELTA_PREFIXES;
if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
hs->flags |= F_ERROR | F_ERROR_OPCODE;
}
if (cflags & C_MODRM) {
hs->flags |= F_MODRM;
hs->modrm = c = *p++;
hs->modrm_mod = m_mod = c >> 6;
hs->modrm_rm = m_rm = c & 7;
hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
if (x && ((x << m_reg) & 0x80))
hs->flags |= F_ERROR | F_ERROR_OPCODE;
if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
uint8_t t = opcode - 0xd9;
if (m_mod == 3) {
ht = hde32_table + DELTA_FPU_MODRM + t*8;
t = ht[m_reg] << m_rm;
} else {
ht = hde32_table + DELTA_FPU_REG;
t = ht[t] << m_reg;
}
if (t & 0x80)
hs->flags |= F_ERROR | F_ERROR_OPCODE;
}
if (pref & PRE_LOCK) {
if (m_mod == 3) {
hs->flags |= F_ERROR | F_ERROR_LOCK;
} else {
uint8_t *table_end, op = opcode;
if (hs->opcode2) {
ht = hde32_table + DELTA_OP2_LOCK_OK;
table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
} else {
ht = hde32_table + DELTA_OP_LOCK_OK;
table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
op &= -2;
}
for (; ht != table_end; ht++)
if (*ht++ == op) {
if (!((*ht << m_reg) & 0x80))
goto no_lock_error;
else
break;
}
hs->flags |= F_ERROR | F_ERROR_LOCK;
no_lock_error:
;
}
}
if (hs->opcode2) {
switch (opcode) {
case 0x20: case 0x22:
m_mod = 3;
if (m_reg > 4 || m_reg == 1)
goto error_operand;
else
goto no_error_operand;
case 0x21: case 0x23:
m_mod = 3;
if (m_reg == 4 || m_reg == 5)
goto error_operand;
else
goto no_error_operand;
}
} else {
switch (opcode) {
case 0x8c:
if (m_reg > 5)
goto error_operand;
else
goto no_error_operand;
case 0x8e:
if (m_reg == 1 || m_reg > 5)
goto error_operand;
else
goto no_error_operand;
}
}
if (m_mod == 3) {
uint8_t *table_end;
if (hs->opcode2) {
ht = hde32_table + DELTA_OP2_ONLY_MEM;
table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM;
} else {
ht = hde32_table + DELTA_OP_ONLY_MEM;
table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
}
for (; ht != table_end; ht += 2)
if (*ht++ == opcode) {
if (*ht++ & pref && !((*ht << m_reg) & 0x80))
goto error_operand;
else
break;
}
goto no_error_operand;
} else if (hs->opcode2) {
switch (opcode) {
case 0x50: case 0xd7: case 0xf7:
if (pref & (PRE_NONE | PRE_66))
goto error_operand;
break;
case 0xd6:
if (pref & (PRE_F2 | PRE_F3))
goto error_operand;
break;
case 0xc5:
goto error_operand;
}
goto no_error_operand;
} else
goto no_error_operand;
error_operand:
hs->flags |= F_ERROR | F_ERROR_OPERAND;
no_error_operand:
c = *p++;
if (m_reg <= 1) {
if (opcode == 0xf6)
cflags |= C_IMM8;
else if (opcode == 0xf7)
cflags |= C_IMM_P66;
}
switch (m_mod) {
case 0:
if (pref & PRE_67) {
if (m_rm == 6)
disp_size = 2;
} else
if (m_rm == 5)
disp_size = 4;
break;
case 1:
disp_size = 1;
break;
case 2:
disp_size = 2;
if (!(pref & PRE_67))
disp_size <<= 1;
}
if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) {
hs->flags |= F_SIB;
p++;
hs->sib = c;
hs->sib_scale = c >> 6;
hs->sib_index = (c & 0x3f) >> 3;
if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
disp_size = 4;
}
p--;
switch (disp_size) {
case 1:
hs->flags |= F_DISP8;
hs->disp.disp8 = *p;
break;
case 2:
hs->flags |= F_DISP16;
hs->disp.disp16 = *(uint16_t *)p;
break;
case 4:
hs->flags |= F_DISP32;
hs->disp.disp32 = *(uint32_t *)p;
}
p += disp_size;
} else if (pref & PRE_LOCK)
hs->flags |= F_ERROR | F_ERROR_LOCK;
if (cflags & C_IMM_P66) {
if (cflags & C_REL32) {
if (pref & PRE_66) {
hs->flags |= F_IMM16 | F_RELATIVE;
hs->imm.imm16 = *(uint16_t *)p;
p += 2;
goto disasm_done;
}
goto rel32_ok;
}
if (pref & PRE_66) {
hs->flags |= F_IMM16;
hs->imm.imm16 = *(uint16_t *)p;
p += 2;
} else {
hs->flags |= F_IMM32;
hs->imm.imm32 = *(uint32_t *)p;
p += 4;
}
}
if (cflags & C_IMM16) {
if (hs->flags & F_IMM32) {
hs->flags |= F_IMM16;
hs->disp.disp16 = *(uint16_t *)p;
} else if (hs->flags & F_IMM16) {
hs->flags |= F_2IMM16;
hs->disp.disp16 = *(uint16_t *)p;
} else {
hs->flags |= F_IMM16;
hs->imm.imm16 = *(uint16_t *)p;
}
p += 2;
}
if (cflags & C_IMM8) {
hs->flags |= F_IMM8;
hs->imm.imm8 = *p++;
}
if (cflags & C_REL32) {
rel32_ok:
hs->flags |= F_IMM32 | F_RELATIVE;
hs->imm.imm32 = *(uint32_t *)p;
p += 4;
} else if (cflags & C_REL8) {
hs->flags |= F_IMM8 | F_RELATIVE;
hs->imm.imm8 = *p++;
}
disasm_done:
if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
hs->flags |= F_ERROR | F_ERROR_LENGTH;
hs->len = 15;
}
return (unsigned int)hs->len;
}
#endif // defined(_M_IX86) || defined(__i386__)

View File

@ -0,0 +1,105 @@
/*
* Hacker Disassembler Engine 32
* Copyright (c) 2006-2009, Vyacheslav Patkov.
* All rights reserved.
*
* hde32.h: C/C++ header file
*
*/
#ifndef _HDE32_H_
#define _HDE32_H_
/* stdint.h - C99 standard header
* http://en.wikipedia.org/wiki/stdint.h
*
* if your compiler doesn't contain "stdint.h" header (for
* example, Microsoft Visual C++), you can download file:
* http://www.azillionmonkeys.com/qed/pstdint.h
* and change next line to:
* #include "pstdint.h"
*/
#include "pstdint.h"
#define F_MODRM 0x00000001
#define F_SIB 0x00000002
#define F_IMM8 0x00000004
#define F_IMM16 0x00000008
#define F_IMM32 0x00000010
#define F_DISP8 0x00000020
#define F_DISP16 0x00000040
#define F_DISP32 0x00000080
#define F_RELATIVE 0x00000100
#define F_2IMM16 0x00000800
#define F_ERROR 0x00001000
#define F_ERROR_OPCODE 0x00002000
#define F_ERROR_LENGTH 0x00004000
#define F_ERROR_LOCK 0x00008000
#define F_ERROR_OPERAND 0x00010000
#define F_PREFIX_REPNZ 0x01000000
#define F_PREFIX_REPX 0x02000000
#define F_PREFIX_REP 0x03000000
#define F_PREFIX_66 0x04000000
#define F_PREFIX_67 0x08000000
#define F_PREFIX_LOCK 0x10000000
#define F_PREFIX_SEG 0x20000000
#define F_PREFIX_ANY 0x3f000000
#define PREFIX_SEGMENT_CS 0x2e
#define PREFIX_SEGMENT_SS 0x36
#define PREFIX_SEGMENT_DS 0x3e
#define PREFIX_SEGMENT_ES 0x26
#define PREFIX_SEGMENT_FS 0x64
#define PREFIX_SEGMENT_GS 0x65
#define PREFIX_LOCK 0xf0
#define PREFIX_REPNZ 0xf2
#define PREFIX_REPX 0xf3
#define PREFIX_OPERAND_SIZE 0x66
#define PREFIX_ADDRESS_SIZE 0x67
#pragma pack(push,1)
typedef struct {
uint8_t len;
uint8_t p_rep;
uint8_t p_lock;
uint8_t p_seg;
uint8_t p_66;
uint8_t p_67;
uint8_t opcode;
uint8_t opcode2;
uint8_t modrm;
uint8_t modrm_mod;
uint8_t modrm_reg;
uint8_t modrm_rm;
uint8_t sib;
uint8_t sib_scale;
uint8_t sib_index;
uint8_t sib_base;
union {
uint8_t imm8;
uint16_t imm16;
uint32_t imm32;
} imm;
union {
uint8_t disp8;
uint16_t disp16;
uint32_t disp32;
} disp;
uint32_t flags;
} hde32s;
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
/* __cdecl */
unsigned int hde32_disasm(const void *code, hde32s *hs);
#ifdef __cplusplus
}
#endif
#endif /* _HDE32_H_ */

View File

@ -0,0 +1,337 @@
/*
* Hacker Disassembler Engine 64 C
* Copyright (c) 2008-2009, Vyacheslav Patkov.
* All rights reserved.
*
*/
#if defined(_M_X64) || defined(__x86_64__)
#include "hde64.h"
#include "table64.h"
unsigned int hde64_disasm(const void *code, hde64s *hs)
{
uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
uint8_t op64 = 0;
// Avoid using memset to reduce the footprint.
#ifndef _MSC_VER
memset((LPBYTE)hs, 0, sizeof(hde64s));
#else
__stosb((LPBYTE)hs, 0, sizeof(hde64s));
#endif
for (x = 16; x; x--)
switch (c = *p++) {
case 0xf3:
hs->p_rep = c;
pref |= PRE_F3;
break;
case 0xf2:
hs->p_rep = c;
pref |= PRE_F2;
break;
case 0xf0:
hs->p_lock = c;
pref |= PRE_LOCK;
break;
case 0x26: case 0x2e: case 0x36:
case 0x3e: case 0x64: case 0x65:
hs->p_seg = c;
pref |= PRE_SEG;
break;
case 0x66:
hs->p_66 = c;
pref |= PRE_66;
break;
case 0x67:
hs->p_67 = c;
pref |= PRE_67;
break;
default:
goto pref_done;
}
pref_done:
hs->flags = (uint32_t)pref << 23;
if (!pref)
pref |= PRE_NONE;
if ((c & 0xf0) == 0x40) {
hs->flags |= F_PREFIX_REX;
if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
op64++;
hs->rex_r = (c & 7) >> 2;
hs->rex_x = (c & 3) >> 1;
hs->rex_b = c & 1;
if (((c = *p++) & 0xf0) == 0x40) {
opcode = c;
goto error_opcode;
}
}
if ((hs->opcode = c) == 0x0f) {
hs->opcode2 = c = *p++;
ht += DELTA_OPCODES;
} else if (c >= 0xa0 && c <= 0xa3) {
op64++;
if (pref & PRE_67)
pref |= PRE_66;
else
pref &= ~PRE_66;
}
opcode = c;
cflags = ht[ht[opcode / 4] + (opcode % 4)];
if (cflags == C_ERROR) {
error_opcode:
hs->flags |= F_ERROR | F_ERROR_OPCODE;
cflags = 0;
if ((opcode & -3) == 0x24)
cflags++;
}
x = 0;
if (cflags & C_GROUP) {
uint16_t t;
t = *(uint16_t *)(ht + (cflags & 0x7f));
cflags = (uint8_t)t;
x = (uint8_t)(t >> 8);
}
if (hs->opcode2) {
ht = hde64_table + DELTA_PREFIXES;
if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
hs->flags |= F_ERROR | F_ERROR_OPCODE;
}
if (cflags & C_MODRM) {
hs->flags |= F_MODRM;
hs->modrm = c = *p++;
hs->modrm_mod = m_mod = c >> 6;
hs->modrm_rm = m_rm = c & 7;
hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
if (x && ((x << m_reg) & 0x80))
hs->flags |= F_ERROR | F_ERROR_OPCODE;
if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
uint8_t t = opcode - 0xd9;
if (m_mod == 3) {
ht = hde64_table + DELTA_FPU_MODRM + t*8;
t = ht[m_reg] << m_rm;
} else {
ht = hde64_table + DELTA_FPU_REG;
t = ht[t] << m_reg;
}
if (t & 0x80)
hs->flags |= F_ERROR | F_ERROR_OPCODE;
}
if (pref & PRE_LOCK) {
if (m_mod == 3) {
hs->flags |= F_ERROR | F_ERROR_LOCK;
} else {
uint8_t *table_end, op = opcode;
if (hs->opcode2) {
ht = hde64_table + DELTA_OP2_LOCK_OK;
table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
} else {
ht = hde64_table + DELTA_OP_LOCK_OK;
table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
op &= -2;
}
for (; ht != table_end; ht++)
if (*ht++ == op) {
if (!((*ht << m_reg) & 0x80))
goto no_lock_error;
else
break;
}
hs->flags |= F_ERROR | F_ERROR_LOCK;
no_lock_error:
;
}
}
if (hs->opcode2) {
switch (opcode) {
case 0x20: case 0x22:
m_mod = 3;
if (m_reg > 4 || m_reg == 1)
goto error_operand;
else
goto no_error_operand;
case 0x21: case 0x23:
m_mod = 3;
if (m_reg == 4 || m_reg == 5)
goto error_operand;
else
goto no_error_operand;
}
} else {
switch (opcode) {
case 0x8c:
if (m_reg > 5)
goto error_operand;
else
goto no_error_operand;
case 0x8e:
if (m_reg == 1 || m_reg > 5)
goto error_operand;
else
goto no_error_operand;
}
}
if (m_mod == 3) {
uint8_t *table_end;
if (hs->opcode2) {
ht = hde64_table + DELTA_OP2_ONLY_MEM;
table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
} else {
ht = hde64_table + DELTA_OP_ONLY_MEM;
table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
}
for (; ht != table_end; ht += 2)
if (*ht++ == opcode) {
if (*ht++ & pref && !((*ht << m_reg) & 0x80))
goto error_operand;
else
break;
}
goto no_error_operand;
} else if (hs->opcode2) {
switch (opcode) {
case 0x50: case 0xd7: case 0xf7:
if (pref & (PRE_NONE | PRE_66))
goto error_operand;
break;
case 0xd6:
if (pref & (PRE_F2 | PRE_F3))
goto error_operand;
break;
case 0xc5:
goto error_operand;
}
goto no_error_operand;
} else
goto no_error_operand;
error_operand:
hs->flags |= F_ERROR | F_ERROR_OPERAND;
no_error_operand:
c = *p++;
if (m_reg <= 1) {
if (opcode == 0xf6)
cflags |= C_IMM8;
else if (opcode == 0xf7)
cflags |= C_IMM_P66;
}
switch (m_mod) {
case 0:
if (pref & PRE_67) {
if (m_rm == 6)
disp_size = 2;
} else
if (m_rm == 5)
disp_size = 4;
break;
case 1:
disp_size = 1;
break;
case 2:
disp_size = 2;
if (!(pref & PRE_67))
disp_size <<= 1;
}
if (m_mod != 3 && m_rm == 4) {
hs->flags |= F_SIB;
p++;
hs->sib = c;
hs->sib_scale = c >> 6;
hs->sib_index = (c & 0x3f) >> 3;
if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
disp_size = 4;
}
p--;
switch (disp_size) {
case 1:
hs->flags |= F_DISP8;
hs->disp.disp8 = *p;
break;
case 2:
hs->flags |= F_DISP16;
hs->disp.disp16 = *(uint16_t *)p;
break;
case 4:
hs->flags |= F_DISP32;
hs->disp.disp32 = *(uint32_t *)p;
}
p += disp_size;
} else if (pref & PRE_LOCK)
hs->flags |= F_ERROR | F_ERROR_LOCK;
if (cflags & C_IMM_P66) {
if (cflags & C_REL32) {
if (pref & PRE_66) {
hs->flags |= F_IMM16 | F_RELATIVE;
hs->imm.imm16 = *(uint16_t *)p;
p += 2;
goto disasm_done;
}
goto rel32_ok;
}
if (op64) {
hs->flags |= F_IMM64;
hs->imm.imm64 = *(uint64_t *)p;
p += 8;
} else if (!(pref & PRE_66)) {
hs->flags |= F_IMM32;
hs->imm.imm32 = *(uint32_t *)p;
p += 4;
} else
goto imm16_ok;
}
if (cflags & C_IMM16) {
imm16_ok:
hs->flags |= F_IMM16;
hs->imm.imm16 = *(uint16_t *)p;
p += 2;
}
if (cflags & C_IMM8) {
hs->flags |= F_IMM8;
hs->imm.imm8 = *p++;
}
if (cflags & C_REL32) {
rel32_ok:
hs->flags |= F_IMM32 | F_RELATIVE;
hs->imm.imm32 = *(uint32_t *)p;
p += 4;
} else if (cflags & C_REL8) {
hs->flags |= F_IMM8 | F_RELATIVE;
hs->imm.imm8 = *p++;
}
disasm_done:
if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
hs->flags |= F_ERROR | F_ERROR_LENGTH;
hs->len = 15;
}
return (unsigned int)hs->len;
}
#endif // defined(_M_X64) || defined(__x86_64__)

View File

@ -0,0 +1,112 @@
/*
* Hacker Disassembler Engine 64
* Copyright (c) 2008-2009, Vyacheslav Patkov.
* All rights reserved.
*
* hde64.h: C/C++ header file
*
*/
#ifndef _HDE64_H_
#define _HDE64_H_
/* stdint.h - C99 standard header
* http://en.wikipedia.org/wiki/stdint.h
*
* if your compiler doesn't contain "stdint.h" header (for
* example, Microsoft Visual C++), you can download file:
* http://www.azillionmonkeys.com/qed/pstdint.h
* and change next line to:
* #include "pstdint.h"
*/
#include "pstdint.h"
#define F_MODRM 0x00000001
#define F_SIB 0x00000002
#define F_IMM8 0x00000004
#define F_IMM16 0x00000008
#define F_IMM32 0x00000010
#define F_IMM64 0x00000020
#define F_DISP8 0x00000040
#define F_DISP16 0x00000080
#define F_DISP32 0x00000100
#define F_RELATIVE 0x00000200
#define F_ERROR 0x00001000
#define F_ERROR_OPCODE 0x00002000
#define F_ERROR_LENGTH 0x00004000
#define F_ERROR_LOCK 0x00008000
#define F_ERROR_OPERAND 0x00010000
#define F_PREFIX_REPNZ 0x01000000
#define F_PREFIX_REPX 0x02000000
#define F_PREFIX_REP 0x03000000
#define F_PREFIX_66 0x04000000
#define F_PREFIX_67 0x08000000
#define F_PREFIX_LOCK 0x10000000
#define F_PREFIX_SEG 0x20000000
#define F_PREFIX_REX 0x40000000
#define F_PREFIX_ANY 0x7f000000
#define PREFIX_SEGMENT_CS 0x2e
#define PREFIX_SEGMENT_SS 0x36
#define PREFIX_SEGMENT_DS 0x3e
#define PREFIX_SEGMENT_ES 0x26
#define PREFIX_SEGMENT_FS 0x64
#define PREFIX_SEGMENT_GS 0x65
#define PREFIX_LOCK 0xf0
#define PREFIX_REPNZ 0xf2
#define PREFIX_REPX 0xf3
#define PREFIX_OPERAND_SIZE 0x66
#define PREFIX_ADDRESS_SIZE 0x67
#pragma pack(push,1)
typedef struct {
uint8_t len;
uint8_t p_rep;
uint8_t p_lock;
uint8_t p_seg;
uint8_t p_66;
uint8_t p_67;
uint8_t rex;
uint8_t rex_w;
uint8_t rex_r;
uint8_t rex_x;
uint8_t rex_b;
uint8_t opcode;
uint8_t opcode2;
uint8_t modrm;
uint8_t modrm_mod;
uint8_t modrm_reg;
uint8_t modrm_rm;
uint8_t sib;
uint8_t sib_scale;
uint8_t sib_index;
uint8_t sib_base;
union {
uint8_t imm8;
uint16_t imm16;
uint32_t imm32;
uint64_t imm64;
} imm;
union {
uint8_t disp8;
uint16_t disp16;
uint32_t disp32;
} disp;
uint32_t flags;
} hde64s;
#pragma pack(pop)
#ifdef __cplusplus
extern "C" {
#endif
/* __cdecl */
unsigned int hde64_disasm(const void *code, hde64s *hs);
#ifdef __cplusplus
}
#endif
#endif /* _HDE64_H_ */

View File

@ -0,0 +1,39 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <windows.h>
// Integer types for HDE.
typedef INT8 int8_t;
typedef INT16 int16_t;
typedef INT32 int32_t;
typedef INT64 int64_t;
typedef UINT8 uint8_t;
typedef UINT16 uint16_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;

View File

@ -0,0 +1,73 @@
/*
* Hacker Disassembler Engine 32 C
* Copyright (c) 2008-2009, Vyacheslav Patkov.
* All rights reserved.
*
*/
#define C_NONE 0x00
#define C_MODRM 0x01
#define C_IMM8 0x02
#define C_IMM16 0x04
#define C_IMM_P66 0x10
#define C_REL8 0x20
#define C_REL32 0x40
#define C_GROUP 0x80
#define C_ERROR 0xff
#define PRE_ANY 0x00
#define PRE_NONE 0x01
#define PRE_F2 0x02
#define PRE_F3 0x04
#define PRE_66 0x08
#define PRE_67 0x10
#define PRE_LOCK 0x20
#define PRE_SEG 0x40
#define PRE_ALL 0xff
#define DELTA_OPCODES 0x4a
#define DELTA_FPU_REG 0xf1
#define DELTA_FPU_MODRM 0xf8
#define DELTA_PREFIXES 0x130
#define DELTA_OP_LOCK_OK 0x1a1
#define DELTA_OP2_LOCK_OK 0x1b9
#define DELTA_OP_ONLY_MEM 0x1cb
#define DELTA_OP2_ONLY_MEM 0x1da
unsigned char hde32_table[] = {
0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,
0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f,
0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3,
0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa,
0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90,
0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f,
0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d,
0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59,
0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,
0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0,
0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01,
0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11,
0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8,
0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca,
0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff,
0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03,
0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,
0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f,
0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a,
0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,
0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a,
0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06,
0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06,
0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08,
0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,
0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,
0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,
0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,
0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,
0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,
0xe7,0x08,0x00,0xf0,0x02,0x00
};

View File

@ -0,0 +1,74 @@
/*
* Hacker Disassembler Engine 64 C
* Copyright (c) 2008-2009, Vyacheslav Patkov.
* All rights reserved.
*
*/
#define C_NONE 0x00
#define C_MODRM 0x01
#define C_IMM8 0x02
#define C_IMM16 0x04
#define C_IMM_P66 0x10
#define C_REL8 0x20
#define C_REL32 0x40
#define C_GROUP 0x80
#define C_ERROR 0xff
#define PRE_ANY 0x00
#define PRE_NONE 0x01
#define PRE_F2 0x02
#define PRE_F3 0x04
#define PRE_66 0x08
#define PRE_67 0x10
#define PRE_LOCK 0x20
#define PRE_SEG 0x40
#define PRE_ALL 0xff
#define DELTA_OPCODES 0x4a
#define DELTA_FPU_REG 0xfd
#define DELTA_FPU_MODRM 0x104
#define DELTA_PREFIXES 0x13c
#define DELTA_OP_LOCK_OK 0x1ae
#define DELTA_OP2_LOCK_OK 0x1c6
#define DELTA_OP_ONLY_MEM 0x1d8
#define DELTA_OP2_ONLY_MEM 0x1e7
unsigned char hde64_table[] = {
0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
0x00,0xf0,0x02,0x00
};

View File

@ -0,0 +1,889 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#include <tlhelp32.h>
#include <limits.h>
#include "../include/MinHook.h"
#include "buffer.h"
#include "trampoline.h"
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
// Initial capacity of the HOOK_ENTRY buffer.
#define INITIAL_HOOK_CAPACITY 32
// Initial capacity of the thread IDs buffer.
#define INITIAL_THREAD_CAPACITY 128
// Special hook position values.
#define INVALID_HOOK_POS UINT_MAX
#define ALL_HOOKS_POS UINT_MAX
// Freeze() action argument defines.
#define ACTION_DISABLE 0
#define ACTION_ENABLE 1
#define ACTION_APPLY_QUEUED 2
// Thread access rights for suspending/resuming threads.
#define THREAD_ACCESS \
(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT)
// Hook information.
typedef struct _HOOK_ENTRY
{
LPVOID pTarget; // Address of the target function.
LPVOID pDetour; // Address of the detour or relay function.
LPVOID pTrampoline; // Address of the trampoline function.
UINT8 backup[8]; // Original prologue of the target function.
UINT8 patchAbove : 1; // Uses the hot patch area.
UINT8 isEnabled : 1; // Enabled.
UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled.
UINT nIP : 4; // Count of the instruction boundaries.
UINT8 oldIPs[8]; // Instruction boundaries of the target function.
UINT8 newIPs[8]; // Instruction boundaries of the trampoline function.
} HOOK_ENTRY, *PHOOK_ENTRY;
// Suspended threads for Freeze()/Unfreeze().
typedef struct _FROZEN_THREADS
{
LPDWORD pItems; // Data heap
UINT capacity; // Size of allocated data heap, items
UINT size; // Actual number of data items
} FROZEN_THREADS, *PFROZEN_THREADS;
//-------------------------------------------------------------------------
// Global Variables:
//-------------------------------------------------------------------------
// Spin lock flag for EnterSpinLock()/LeaveSpinLock().
volatile LONG g_isLocked = FALSE;
// Private heap handle. If not NULL, this library is initialized.
HANDLE g_hHeap = NULL;
// Hook entries.
struct
{
PHOOK_ENTRY pItems; // Data heap
UINT capacity; // Size of allocated data heap, items
UINT size; // Actual number of data items
} g_hooks;
//-------------------------------------------------------------------------
// Returns INVALID_HOOK_POS if not found.
static UINT FindHookEntry(LPVOID pTarget)
{
UINT i;
for (i = 0; i < g_hooks.size; ++i)
{
if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget)
return i;
}
return INVALID_HOOK_POS;
}
//-------------------------------------------------------------------------
static PHOOK_ENTRY AddHookEntry()
{
if (g_hooks.pItems == NULL)
{
g_hooks.capacity = INITIAL_HOOK_CAPACITY;
g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc(
g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY));
if (g_hooks.pItems == NULL)
return NULL;
}
else if (g_hooks.size >= g_hooks.capacity)
{
PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY));
if (p == NULL)
return NULL;
g_hooks.capacity *= 2;
g_hooks.pItems = p;
}
return &g_hooks.pItems[g_hooks.size++];
}
//-------------------------------------------------------------------------
static void DeleteHookEntry(UINT pos)
{
if (pos < g_hooks.size - 1)
g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1];
g_hooks.size--;
if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size)
{
PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY));
if (p == NULL)
return;
g_hooks.capacity /= 2;
g_hooks.pItems = p;
}
}
//-------------------------------------------------------------------------
static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
{
UINT i;
if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL)))
return (DWORD_PTR)pHook->pTarget;
for (i = 0; i < pHook->nIP; ++i)
{
if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]))
return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i];
}
#if defined(_M_X64) || defined(__x86_64__)
// Check relay function.
if (ip == (DWORD_PTR)pHook->pDetour)
return (DWORD_PTR)pHook->pTarget;
#endif
return 0;
}
//-------------------------------------------------------------------------
static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
{
UINT i;
for (i = 0; i < pHook->nIP; ++i)
{
if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]))
return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i];
}
return 0;
}
//-------------------------------------------------------------------------
static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action)
{
// If the thread suspended in the overwritten area,
// move IP to the proper address.
CONTEXT c;
#if defined(_M_X64) || defined(__x86_64__)
DWORD64 *pIP = &c.Rip;
#else
DWORD *pIP = &c.Eip;
#endif
UINT count;
c.ContextFlags = CONTEXT_CONTROL;
if (!GetThreadContext(hThread, &c))
return;
if (pos == ALL_HOOKS_POS)
{
pos = 0;
count = g_hooks.size;
}
else
{
count = pos + 1;
}
for (; pos < count; ++pos)
{
PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
BOOL enable;
DWORD_PTR ip;
switch (action)
{
case ACTION_DISABLE:
enable = FALSE;
break;
case ACTION_ENABLE:
enable = TRUE;
break;
default: // ACTION_APPLY_QUEUED
enable = pHook->queueEnable;
break;
}
if (pHook->isEnabled == enable)
continue;
if (enable)
ip = FindNewIP(pHook, *pIP);
else
ip = FindOldIP(pHook, *pIP);
if (ip != 0)
{
*pIP = ip;
SetThreadContext(hThread, &c);
}
}
}
//-------------------------------------------------------------------------
static VOID EnumerateThreads(PFROZEN_THREADS pThreads)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
if (Thread32First(hSnapshot, &te))
{
do
{
if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD))
&& te.th32OwnerProcessID == GetCurrentProcessId()
&& te.th32ThreadID != GetCurrentThreadId())
{
if (pThreads->pItems == NULL)
{
pThreads->capacity = INITIAL_THREAD_CAPACITY;
pThreads->pItems
= (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD));
if (pThreads->pItems == NULL)
break;
}
else if (pThreads->size >= pThreads->capacity)
{
LPDWORD p = (LPDWORD)HeapReAlloc(
g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD));
if (p == NULL)
break;
pThreads->capacity *= 2;
pThreads->pItems = p;
}
pThreads->pItems[pThreads->size++] = te.th32ThreadID;
}
te.dwSize = sizeof(THREADENTRY32);
} while (Thread32Next(hSnapshot, &te));
}
CloseHandle(hSnapshot);
}
}
//-------------------------------------------------------------------------
static VOID Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action)
{
pThreads->pItems = NULL;
pThreads->capacity = 0;
pThreads->size = 0;
EnumerateThreads(pThreads);
if (pThreads->pItems != NULL)
{
UINT i;
for (i = 0; i < pThreads->size; ++i)
{
HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
if (hThread != NULL)
{
SuspendThread(hThread);
ProcessThreadIPs(hThread, pos, action);
CloseHandle(hThread);
}
}
}
}
//-------------------------------------------------------------------------
static VOID Unfreeze(PFROZEN_THREADS pThreads)
{
if (pThreads->pItems != NULL)
{
UINT i;
for (i = 0; i < pThreads->size; ++i)
{
HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
if (hThread != NULL)
{
ResumeThread(hThread);
CloseHandle(hThread);
}
}
HeapFree(g_hHeap, 0, pThreads->pItems);
}
}
//-------------------------------------------------------------------------
static MH_STATUS EnableHookLL(UINT pos, BOOL enable)
{
PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
DWORD oldProtect;
SIZE_T patchSize = sizeof(JMP_REL);
LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget;
if (pHook->patchAbove)
{
pPatchTarget -= sizeof(JMP_REL);
patchSize += sizeof(JMP_REL_SHORT);
}
if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
return MH_ERROR_MEMORY_PROTECT;
if (enable)
{
PJMP_REL pJmp = (PJMP_REL)pPatchTarget;
pJmp->opcode = 0xE9;
pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL)));
if (pHook->patchAbove)
{
PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget;
pShortJmp->opcode = 0xEB;
pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL)));
}
}
else
{
if (pHook->patchAbove)
memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
else
memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL));
}
VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect);
// Just-in-case measure.
FlushInstructionCache(GetCurrentProcess(), pPatchTarget, patchSize);
pHook->isEnabled = enable;
pHook->queueEnable = enable;
return MH_OK;
}
//-------------------------------------------------------------------------
static MH_STATUS EnableAllHooksLL(BOOL enable)
{
MH_STATUS status = MH_OK;
UINT i, first = INVALID_HOOK_POS;
for (i = 0; i < g_hooks.size; ++i)
{
if (g_hooks.pItems[i].isEnabled != enable)
{
first = i;
break;
}
}
if (first != INVALID_HOOK_POS)
{
FROZEN_THREADS threads;
Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE);
for (i = first; i < g_hooks.size; ++i)
{
if (g_hooks.pItems[i].isEnabled != enable)
{
status = EnableHookLL(i, enable);
if (status != MH_OK)
break;
}
}
Unfreeze(&threads);
}
return status;
}
//-------------------------------------------------------------------------
static VOID EnterSpinLock(VOID)
{
SIZE_T spinCount = 0;
// Wait until the flag is FALSE.
while (InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE)
{
// No need to generate a memory barrier here, since InterlockedCompareExchange()
// generates a full memory barrier itself.
// Prevent the loop from being too busy.
if (spinCount < 32)
Sleep(0);
else
Sleep(1);
spinCount++;
}
}
//-------------------------------------------------------------------------
static VOID LeaveSpinLock(VOID)
{
// No need to generate a memory barrier here, since InterlockedExchange()
// generates a full memory barrier itself.
InterlockedExchange(&g_isLocked, FALSE);
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_Initialize(VOID)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap == NULL)
{
g_hHeap = HeapCreate(0, 0, 0);
if (g_hHeap != NULL)
{
// Initialize the internal function buffer.
InitializeBuffer();
}
else
{
status = MH_ERROR_MEMORY_ALLOC;
}
}
else
{
status = MH_ERROR_ALREADY_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_Uninitialize(VOID)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap != NULL)
{
status = EnableAllHooksLL(FALSE);
if (status == MH_OK)
{
// Free the internal function buffer.
// HeapFree is actually not required, but some tools detect a false
// memory leak without HeapFree.
UninitializeBuffer();
HeapFree(g_hHeap, 0, g_hooks.pItems);
HeapDestroy(g_hHeap);
g_hHeap = NULL;
g_hooks.pItems = NULL;
g_hooks.capacity = 0;
g_hooks.size = 0;
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap != NULL)
{
if (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour))
{
UINT pos = FindHookEntry(pTarget);
if (pos == INVALID_HOOK_POS)
{
LPVOID pBuffer = AllocateBuffer(pTarget);
if (pBuffer != NULL)
{
TRAMPOLINE ct;
ct.pTarget = pTarget;
ct.pDetour = pDetour;
ct.pTrampoline = pBuffer;
if (CreateTrampolineFunction(&ct))
{
PHOOK_ENTRY pHook = AddHookEntry();
if (pHook != NULL)
{
pHook->pTarget = ct.pTarget;
#if defined(_M_X64) || defined(__x86_64__)
pHook->pDetour = ct.pRelay;
#else
pHook->pDetour = ct.pDetour;
#endif
pHook->pTrampoline = ct.pTrampoline;
pHook->patchAbove = ct.patchAbove;
pHook->isEnabled = FALSE;
pHook->queueEnable = FALSE;
pHook->nIP = ct.nIP;
memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs));
memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs));
// Back up the target function.
if (ct.patchAbove)
{
memcpy(
pHook->backup,
(LPBYTE)pTarget - sizeof(JMP_REL),
sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
}
else
{
memcpy(pHook->backup, pTarget, sizeof(JMP_REL));
}
if (ppOriginal != NULL)
*ppOriginal = pHook->pTrampoline;
}
else
{
status = MH_ERROR_MEMORY_ALLOC;
}
}
else
{
status = MH_ERROR_UNSUPPORTED_FUNCTION;
}
if (status != MH_OK)
{
FreeBuffer(pBuffer);
}
}
else
{
status = MH_ERROR_MEMORY_ALLOC;
}
}
else
{
status = MH_ERROR_ALREADY_CREATED;
}
}
else
{
status = MH_ERROR_NOT_EXECUTABLE;
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap != NULL)
{
UINT pos = FindHookEntry(pTarget);
if (pos != INVALID_HOOK_POS)
{
if (g_hooks.pItems[pos].isEnabled)
{
FROZEN_THREADS threads;
Freeze(&threads, pos, ACTION_DISABLE);
status = EnableHookLL(pos, FALSE);
Unfreeze(&threads);
}
if (status == MH_OK)
{
FreeBuffer(g_hooks.pItems[pos].pTrampoline);
DeleteHookEntry(pos);
}
}
else
{
status = MH_ERROR_NOT_CREATED;
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap != NULL)
{
if (pTarget == MH_ALL_HOOKS)
{
status = EnableAllHooksLL(enable);
}
else
{
FROZEN_THREADS threads;
UINT pos = FindHookEntry(pTarget);
if (pos != INVALID_HOOK_POS)
{
if (g_hooks.pItems[pos].isEnabled != enable)
{
Freeze(&threads, pos, ACTION_ENABLE);
status = EnableHookLL(pos, enable);
Unfreeze(&threads);
}
else
{
status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED;
}
}
else
{
status = MH_ERROR_NOT_CREATED;
}
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget)
{
return EnableHook(pTarget, TRUE);
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget)
{
return EnableHook(pTarget, FALSE);
}
//-------------------------------------------------------------------------
static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable)
{
MH_STATUS status = MH_OK;
EnterSpinLock();
if (g_hHeap != NULL)
{
if (pTarget == MH_ALL_HOOKS)
{
UINT i;
for (i = 0; i < g_hooks.size; ++i)
g_hooks.pItems[i].queueEnable = queueEnable;
}
else
{
UINT pos = FindHookEntry(pTarget);
if (pos != INVALID_HOOK_POS)
{
g_hooks.pItems[pos].queueEnable = queueEnable;
}
else
{
status = MH_ERROR_NOT_CREATED;
}
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget)
{
return QueueHook(pTarget, TRUE);
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget)
{
return QueueHook(pTarget, FALSE);
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_ApplyQueued(VOID)
{
MH_STATUS status = MH_OK;
UINT i, first = INVALID_HOOK_POS;
EnterSpinLock();
if (g_hHeap != NULL)
{
for (i = 0; i < g_hooks.size; ++i)
{
if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable)
{
first = i;
break;
}
}
if (first != INVALID_HOOK_POS)
{
FROZEN_THREADS threads;
Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED);
for (i = first; i < g_hooks.size; ++i)
{
PHOOK_ENTRY pHook = &g_hooks.pItems[i];
if (pHook->isEnabled != pHook->queueEnable)
{
status = EnableHookLL(i, pHook->queueEnable);
if (status != MH_OK)
break;
}
}
Unfreeze(&threads);
}
}
else
{
status = MH_ERROR_NOT_INITIALIZED;
}
LeaveSpinLock();
return status;
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_CreateHookApiEx(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour,
LPVOID *ppOriginal, LPVOID *ppTarget)
{
HMODULE hModule;
LPVOID pTarget;
hModule = GetModuleHandleW(pszModule);
if (hModule == NULL)
return MH_ERROR_MODULE_NOT_FOUND;
pTarget = (LPVOID)GetProcAddress(hModule, pszProcName);
if (pTarget == NULL)
return MH_ERROR_FUNCTION_NOT_FOUND;
if(ppTarget != NULL)
*ppTarget = pTarget;
return MH_CreateHook(pTarget, pDetour, ppOriginal);
}
//-------------------------------------------------------------------------
MH_STATUS WINAPI MH_CreateHookApi(
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal)
{
return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL);
}
//-------------------------------------------------------------------------
const char * WINAPI MH_StatusToString(MH_STATUS status)
{
#define MH_ST2STR(x) \
case x: \
return #x;
switch (status) {
MH_ST2STR(MH_UNKNOWN)
MH_ST2STR(MH_OK)
MH_ST2STR(MH_ERROR_ALREADY_INITIALIZED)
MH_ST2STR(MH_ERROR_NOT_INITIALIZED)
MH_ST2STR(MH_ERROR_ALREADY_CREATED)
MH_ST2STR(MH_ERROR_NOT_CREATED)
MH_ST2STR(MH_ERROR_ENABLED)
MH_ST2STR(MH_ERROR_DISABLED)
MH_ST2STR(MH_ERROR_NOT_EXECUTABLE)
MH_ST2STR(MH_ERROR_UNSUPPORTED_FUNCTION)
MH_ST2STR(MH_ERROR_MEMORY_ALLOC)
MH_ST2STR(MH_ERROR_MEMORY_PROTECT)
MH_ST2STR(MH_ERROR_MODULE_NOT_FOUND)
MH_ST2STR(MH_ERROR_FUNCTION_NOT_FOUND)
}
#undef MH_ST2STR
return "(unknown)";
}

View File

@ -0,0 +1,316 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
#if defined(_M_X64) || defined(__x86_64__)
#include "./hde/hde64.h"
typedef hde64s HDE;
#define HDE_DISASM(code, hs) hde64_disasm(code, hs)
#else
#include "./hde/hde32.h"
typedef hde32s HDE;
#define HDE_DISASM(code, hs) hde32_disasm(code, hs)
#endif
#include "trampoline.h"
#include "buffer.h"
// Maximum size of a trampoline function.
#if defined(_M_X64) || defined(__x86_64__)
#define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS))
#else
#define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE
#endif
//-------------------------------------------------------------------------
static BOOL IsCodePadding(LPBYTE pInst, UINT size)
{
UINT i;
if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC)
return FALSE;
for (i = 1; i < size; ++i)
{
if (pInst[i] != pInst[0])
return FALSE;
}
return TRUE;
}
//-------------------------------------------------------------------------
BOOL CreateTrampolineFunction(PTRAMPOLINE ct)
{
#if defined(_M_X64) || defined(__x86_64__)
CALL_ABS call = {
0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8]
0xEB, 0x08, // EB 08: JMP +10
0x0000000000000000ULL // Absolute destination address
};
JMP_ABS jmp = {
0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
0x0000000000000000ULL // Absolute destination address
};
JCC_ABS jcc = {
0x70, 0x0E, // 7* 0E: J** +16
0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
0x0000000000000000ULL // Absolute destination address
};
#else
CALL_REL call = {
0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx
0x00000000 // Relative destination address
};
JMP_REL jmp = {
0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx
0x00000000 // Relative destination address
};
JCC_REL jcc = {
0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx
0x00000000 // Relative destination address
};
#endif
UINT8 oldPos = 0;
UINT8 newPos = 0;
ULONG_PTR jmpDest = 0; // Destination address of an internal jump.
BOOL finished = FALSE; // Is the function completed?
#if defined(_M_X64) || defined(__x86_64__)
UINT8 instBuf[16];
#endif
ct->patchAbove = FALSE;
ct->nIP = 0;
do
{
HDE hs;
UINT copySize;
LPVOID pCopySrc;
ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos;
ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos;
copySize = HDE_DISASM((LPVOID)pOldInst, &hs);
if (hs.flags & F_ERROR)
return FALSE;
pCopySrc = (LPVOID)pOldInst;
if (oldPos >= sizeof(JMP_REL))
{
// The trampoline function is long enough.
// Complete the function with the jump to the target function.
#if defined(_M_X64) || defined(__x86_64__)
jmp.address = pOldInst;
#else
jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp)));
#endif
pCopySrc = &jmp;
copySize = sizeof(jmp);
finished = TRUE;
}
#if defined(_M_X64) || defined(__x86_64__)
else if ((hs.modrm & 0xC7) == 0x05)
{
// Instructions using RIP relative addressing. (ModR/M = 00???101B)
// Modify the RIP relative address.
PUINT32 pRelAddr;
// Avoid using memcpy to reduce the footprint.
#ifndef _MSC_VER
memcpy(instBuf, (LPBYTE)pOldInst, copySize);
#else
__movsb(instBuf, (LPBYTE)pOldInst, copySize);
#endif
pCopySrc = instBuf;
// Relative address is stored at (instruction length - immediate value length - 4).
pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4);
*pRelAddr
= (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len));
// Complete the function if JMP (FF /4).
if (hs.opcode == 0xFF && hs.modrm_reg == 4)
finished = TRUE;
}
#endif
else if (hs.opcode == 0xE8)
{
// Direct relative CALL
ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32;
#if defined(_M_X64) || defined(__x86_64__)
call.address = dest;
#else
call.operand = (UINT32)(dest - (pNewInst + sizeof(call)));
#endif
pCopySrc = &call;
copySize = sizeof(call);
}
else if ((hs.opcode & 0xFD) == 0xE9)
{
// Direct relative JMP (EB or E9)
ULONG_PTR dest = pOldInst + hs.len;
if (hs.opcode == 0xEB) // isShort jmp
dest += (INT8)hs.imm.imm8;
else
dest += (INT32)hs.imm.imm32;
// Simply copy an internal jump.
if ((ULONG_PTR)ct->pTarget <= dest
&& dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
{
if (jmpDest < dest)
jmpDest = dest;
}
else
{
#if defined(_M_X64) || defined(__x86_64__)
jmp.address = dest;
#else
jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp)));
#endif
pCopySrc = &jmp;
copySize = sizeof(jmp);
// Exit the function If it is not in the branch
finished = (pOldInst >= jmpDest);
}
}
else if ((hs.opcode & 0xF0) == 0x70
|| (hs.opcode & 0xFC) == 0xE0
|| (hs.opcode2 & 0xF0) == 0x80)
{
// Direct relative Jcc
ULONG_PTR dest = pOldInst + hs.len;
if ((hs.opcode & 0xF0) == 0x70 // Jcc
|| (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ
dest += (INT8)hs.imm.imm8;
else
dest += (INT32)hs.imm.imm32;
// Simply copy an internal jump.
if ((ULONG_PTR)ct->pTarget <= dest
&& dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
{
if (jmpDest < dest)
jmpDest = dest;
}
else if ((hs.opcode & 0xFC) == 0xE0)
{
// LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported.
return FALSE;
}
else
{
UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F);
#if defined(_M_X64) || defined(__x86_64__)
// Invert the condition in x64 mode to simplify the conditional jump logic.
jcc.opcode = 0x71 ^ cond;
jcc.address = dest;
#else
jcc.opcode1 = 0x80 | cond;
jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc)));
#endif
pCopySrc = &jcc;
copySize = sizeof(jcc);
}
}
else if ((hs.opcode & 0xFE) == 0xC2)
{
// RET (C2 or C3)
// Complete the function if not in a branch.
finished = (pOldInst >= jmpDest);
}
// Can't alter the instruction length in a branch.
if (pOldInst < jmpDest && copySize != hs.len)
return FALSE;
// Trampoline function is too large.
if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE)
return FALSE;
// Trampoline function has too many instructions.
if (ct->nIP >= ARRAYSIZE(ct->oldIPs))
return FALSE;
ct->oldIPs[ct->nIP] = oldPos;
ct->newIPs[ct->nIP] = newPos;
ct->nIP++;
// Avoid using memcpy to reduce the footprint.
#ifndef _MSC_VER
memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
#else
__movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
#endif
newPos += copySize;
oldPos += hs.len;
}
while (!finished);
// Is there enough place for a long jump?
if (oldPos < sizeof(JMP_REL)
&& !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos))
{
// Is there enough place for a short jump?
if (oldPos < sizeof(JMP_REL_SHORT)
&& !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos))
{
return FALSE;
}
// Can we place the long jump above the function?
if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL)))
return FALSE;
if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL)))
return FALSE;
ct->patchAbove = TRUE;
}
#if defined(_M_X64) || defined(__x86_64__)
// Create a relay function.
jmp.address = (ULONG_PTR)ct->pDetour;
ct->pRelay = (LPBYTE)ct->pTrampoline + newPos;
memcpy(ct->pRelay, &jmp, sizeof(jmp));
#endif
return TRUE;
}

View File

@ -0,0 +1,105 @@
/*
* MinHook - The Minimalistic API Hooking Library for x64/x86
* Copyright (C) 2009-2017 Tsuda Kageyu.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#pragma pack(push, 1)
// Structs for writing x86/x64 instructions.
// 8-bit relative jump.
typedef struct _JMP_REL_SHORT
{
UINT8 opcode; // EB xx: JMP +2+xx
UINT8 operand;
} JMP_REL_SHORT, *PJMP_REL_SHORT;
// 32-bit direct relative jump/call.
typedef struct _JMP_REL
{
UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx
UINT32 operand; // Relative destination address
} JMP_REL, *PJMP_REL, CALL_REL;
// 64-bit indirect absolute jump.
typedef struct _JMP_ABS
{
UINT8 opcode0; // FF25 00000000: JMP [+6]
UINT8 opcode1;
UINT32 dummy;
UINT64 address; // Absolute destination address
} JMP_ABS, *PJMP_ABS;
// 64-bit indirect absolute call.
typedef struct _CALL_ABS
{
UINT8 opcode0; // FF15 00000002: CALL [+6]
UINT8 opcode1;
UINT32 dummy0;
UINT8 dummy1; // EB 08: JMP +10
UINT8 dummy2;
UINT64 address; // Absolute destination address
} CALL_ABS;
// 32-bit direct relative conditional jumps.
typedef struct _JCC_REL
{
UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx
UINT8 opcode1;
UINT32 operand; // Relative destination address
} JCC_REL;
// 64bit indirect absolute conditional jumps that x64 lacks.
typedef struct _JCC_ABS
{
UINT8 opcode; // 7* 0E: J** +16
UINT8 dummy0;
UINT8 dummy1; // FF25 00000000: JMP [+6]
UINT8 dummy2;
UINT32 dummy3;
UINT64 address; // Absolute destination address
} JCC_ABS;
#pragma pack(pop)
typedef struct _TRAMPOLINE
{
LPVOID pTarget; // [In] Address of the target function.
LPVOID pDetour; // [In] Address of the detour function.
LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function.
#if defined(_M_X64) || defined(__x86_64__)
LPVOID pRelay; // [Out] Address of the relay function.
#endif
BOOL patchAbove; // [Out] Should use the hot patch area?
UINT nIP; // [Out] Number of the instruction boundaries.
UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function.
UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function.
} TRAMPOLINE, *PTRAMPOLINE;
BOOL CreateTrampolineFunction(PTRAMPOLINE ct);

View File

@ -0,0 +1,13 @@
#include "utlhash.h"
int CUtlMemoryPool::Count() const {
return nBlocksAllocated;
}
int CUtlMemoryPool::PeakCount() const {
return nPeakAlloc;
}
int CUtlMemoryPool::BlockSize() const {
return nBlockSize;
}

View File

@ -0,0 +1,163 @@
#pragma once
#include "../../../../templeware/utils/memory/memorycommon.h"
#include <cstddef>
#include <cstdint>
#include <limits>
#include <cstdint>
class CUtlMemoryPool {
public:
int Count() const;
int PeakCount() const;
int BlockSize() const;
protected:
class CBlob {
public:
CBlob* pPrev;
CBlob* pNext;
int nNumBytes;
char Data[1];
char Padding[3];
};
int nBlockSize;
int nBlocksPerBlob;
int nGrowMode;
int nBlocksAllocated;
int nPeakAlloc;
unsigned short nAlignment;
unsigned short nNumBlobs;
void* pHeadOfFreeList;
void* pAllocOwner;
CBlob BlobHead;
};
using UtlTSHashHandle_t = std::uintptr_t;
inline unsigned HashIntConventional(const int n) {
unsigned hash = 0xAAAAAAAA + (n & 0xFF);
hash = (hash << 5) + hash + ((n >> 8) & 0xFF);
hash = (hash << 5) + hash + ((n >> 16) & 0xFF);
hash = (hash << 5) + hash + ((n >> 24) & 0xFF);
return hash;
}
template <int nBucketCount, class tKey = std::uintptr_t>
class CUtlTSHashGenericHash {
public:
static int Hash(const tKey& Key, int nBucketMask) {
int nHash = HashIntConventional(std::uintptr_t(Key));
if (nBucketCount <= UINT16_MAX) {
nHash ^= (nHash >> 16);
}
if (nBucketCount <= UINT8_MAX) {
nHash ^= (nHash >> 8);
}
return (nHash & nBucketMask);
}
static bool Compare(const tKey& lhs, const tKey& rhs) {
return lhs == rhs;
}
};
template <class tElement, int nBucketCount, class tKey = std::uintptr_t, class tHashFuncs = CUtlTSHashGenericHash<nBucketCount, tKey>, int nAlignment = 0>
class CUtlTSHash {
static constexpr int nBucketMask = nBucketCount - 1;
public:
static constexpr UtlTSHashHandle_t InvalidHandle() {
return static_cast<UtlTSHashHandle_t>(0);
}
UtlTSHashHandle_t Find(tKey uiKey) {
int iBucket = tHashFuncs::Hash(uiKey, nBucketCount);
const HashBucket_t& hashBucket = aBuckets[iBucket];
const UtlTSHashHandle_t hHash = Find(uiKey, hashBucket.pFirst, nullptr);
return hHash ? hHash : Find(uiKey, hashBucket.pFirstUncommited, hashBucket.pFirst);
}
int Count() const {
return EntryMemory.Count();
}
int GetElements(int nFirstElement, int nCount, UtlTSHashHandle_t* pHandles) const {
int nIndex = 0;
for (int nBucketIndex = 0; nBucketIndex < nBucketCount; nBucketIndex++) {
const HashBucket_t& hashBucket = aBuckets[nBucketIndex];
HashFixedData_t* pElement = hashBucket.pFirstUncommited;
for (; pElement; pElement = pElement->pNext) {
if (--nFirstElement >= 0)
continue;
pHandles[nIndex++] = reinterpret_cast<UtlTSHashHandle_t>(pElement);
if (nIndex >= nCount)
return nIndex;
}
}
return nIndex;
}
tElement Element(UtlTSHashHandle_t hHash) {
return ((HashFixedData_t*)(hHash))->Data;
}
const tElement& Element(UtlTSHashHandle_t hHash) const {
return reinterpret_cast<HashFixedData_t*>(hHash)->Data;
}
tElement& operator[](UtlTSHashHandle_t hHash) {
return reinterpret_cast<HashFixedData_t*>(hHash)->Data;
}
const tElement& operator[](UtlTSHashHandle_t hHash) const {
return reinterpret_cast<HashFixedData_t*>(hHash)->Data;
}
tKey GetID(UtlTSHashHandle_t hHash) const {
return reinterpret_cast<HashFixedData_t*>(hHash)->uiKey;
}
private:
template <typename tData>
struct HashFixedDataInternal_t {
tKey uiKey;
HashFixedDataInternal_t<tData>* pNext;
tData Data;
};
using HashFixedData_t = HashFixedDataInternal_t<tElement>;
struct HashBucket_t {
private:
// Swap the MEM_PADs in case of crash here, not sure exactly what this is all about -bas
//[[maybe_unused]] std::byte pad0[0x18];
MEM_PAD(0x18);
public:
HashFixedData_t* pFirst;
HashFixedData_t* pFirstUncommited;
};
UtlTSHashHandle_t Find(tKey uiKey, HashFixedData_t* pFirstElement, HashFixedData_t* pLastElement) {
for (HashFixedData_t* pElement = pFirstElement; pElement != pLastElement; pElement = pElement->pNext) {
if (tHashFuncs::Compare(pElement->uiKey, uiKey))
return reinterpret_cast<UtlTSHashHandle_t>(pElement);
}
return InvalidHandle();
}
CUtlMemoryPool EntryMemory;
MEM_PAD(0x40);
HashBucket_t aBuckets[nBucketCount];
bool bNeedsCommit;
};

View File

@ -0,0 +1,20 @@
#include "..\..\..\templeware\hooks\hooks.h"
#include "..\..\..\templeware\interfaces\interfaces.h"
#include "cutlbuffer.h"
CUtlBuffer::CUtlBuffer(int a1, int size, int a3)
{
I::ConstructUtlBuffer(this, a1, size, a3);
}
void CUtlBuffer::ensure(int size)
{
I::EnsureCapacityBuffer(this, size);
}
void CUtlBuffer::PutString(const char* szString)
{
I::PutUtlString(this, szString);
}

View File

@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
class CUtlBuffer
{
public:
char _pad[0x80];
CUtlBuffer(int a1 = 0, int size = 0, int a3 = 0);
void ensure(int size);
void PutString(const char* szString);
};

View File

@ -0,0 +1,40 @@
#pragma once
#include <cstdint>
#include "../cutlbuffer/cutlbuffer.h"
#include "keyvalues.h"
#include "../../../templeware/utils/memory/vfunc/vfunc.h"
#include "../../../templeware/utils/memory/patternscan/patternscan.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../cutl/utlhash/utlhash.h"
#include "..\..\..\templeware\utils\math\utlvector\utlvector.h"
#include "..\..\..\templeware\interfaces\interfaces.h"
void CKeyValues3::LoadFromBuffer(const char* szString)
{
CUtlBuffer buffer(0, (std::strlen(szString) + 10), 1);
buffer.PutString(szString);
this->LoadKV3(&buffer);
}
bool CKeyValues3::LoadKV3(CUtlBuffer* buffer)
{
using fnLoadKeyValues = bool(__fastcall*)(CKeyValues3*, void*, CUtlBuffer*, KV3ID_t*, void*, void*, void*, void*, const char*);
static const fnLoadKeyValues oLoadKeyValues = reinterpret_cast<fnLoadKeyValues>(M::abs(M::FindPattern("tier0.dll", "E8 ? ? ? ? EB 36 8B 43 10"), 0x1, 0x0));
const char* szName = ("");
KV3ID_t kv3ID = KV3ID_t(("generic"), 0x41B818518343427E, 0xB5F447C23C0CDF8C);
return oLoadKeyValues(this, nullptr, buffer, &kv3ID, nullptr, nullptr, nullptr, nullptr, (""));
}
CKeyValues3* CKeyValues3::create_material_from_resource()
{
using fnSetTypeKV3 = CKeyValues3 * (__fastcall*)(CKeyValues3*, unsigned int, unsigned int);
static const fnSetTypeKV3 oSetTypeKV3 = reinterpret_cast<fnSetTypeKV3>(M::FindPattern("tier0.dll", ("40 53 48 83 EC 30 48 8B D9 49")));
CKeyValues3* pKeyValue = new CKeyValues3[0x10];
return oSetTypeKV3(pKeyValue, 1U, 6U);
}

View File

@ -0,0 +1,29 @@
#pragma once
#include <cstdint>
#include "../../../templeware/utils/memory/vfunc/vfunc.h"
#include "../../../templeware/utils/memory/patternscan/patternscan.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../cutl/utlhash/utlhash.h"
#include "..\..\..\templeware\utils\math\utlvector\utlvector.h"
#include "..\cutlbuffer\cutlbuffer.h"
struct KV3ID_t
{
const char* szName;
std::uint64_t unk0;
std::uint64_t unk1;
};
class CKeyValues3
{
public:
char _pad[0x100];
std::uint64_t uKey;
void* pValue;
char _pad1[0x8];
void LoadFromBuffer(const char* szString);
bool LoadKV3(CUtlBuffer* buffer);
void LoadFromFile(const char* szString);
CKeyValues3* create_material_from_resource();
};

View File

@ -0,0 +1,55 @@
#include "ISchemaClass.h"
bool CSchemaType::GetSizes(int* pOutSize, uint8_t* unkPtr) {
return M::vfunc<bool, 3U>(this, pOutSize, unkPtr);
}
bool CSchemaType::GetSize(int* out_size) {
uint8_t smh = 0;
return GetSizes(out_size, &smh);
}
bool SchemaClassInfoData_t::InheritsFrom(SchemaClassInfoData_t* pClassInfo) {
if (pClassInfo == this && pClassInfo != nullptr)
return true;
else if (pBaseClasses == nullptr || pClassInfo == nullptr)
return false;
for (int i = 0; i < nBaseClassesCount; i++) {
auto& baseClass = pBaseClasses[i];
if (baseClass.pClass->InheritsFrom(pClassInfo))
return true;
}
return false;
}
void CSchemaSystemTypeScope::FindDeclaredClass(SchemaClassInfoData_t** pReturnClass, const char* szClassName) {
return M::vfunc<void, 2U>(this, pReturnClass, szClassName);
}
CSchemaType* CSchemaSystemTypeScope::FindSchemaTypeByName(const char* szName, std::uintptr_t* pSchema) {
return M::vfunc<CSchemaType*, 4U>(this, szName, pSchema);
}
CSchemaType* CSchemaSystemTypeScope::FindTypeDeclaredClass(const char* szName) {
return M::vfunc<CSchemaType*, 5U>(this, szName);
}
CSchemaType* CSchemaSystemTypeScope::FindTypeDeclaredEnum(const char* szName) {
return M::vfunc<CSchemaType*, 6U>(this, szName);
}
CSchemaClassBinding* CSchemaSystemTypeScope::FindRawClassBinding(const char* szName) {
return M::vfunc<CSchemaClassBinding*, 7U>(this, szName);
}
void GetSchemaClassInfo(uintptr_t address, SchemaClassInfoData_t** pReturn) {
return M::vfunc<void, 38U>(reinterpret_cast<void*>(address), pReturn);
}
CSchemaSystemTypeScope* ISchemaSystem::FindTypeScopeForModule(const char* m_module_name)
{
return M::vfunc<CSchemaSystemTypeScope*, 13U>(this, m_module_name, nullptr);
}

View File

@ -0,0 +1,158 @@
#pragma once
#include <cstdint>
#include "../../../../templeware/utils/memory/vfunc/vfunc.h"
#include "../../../../templeware/utils/memory/patternscan/patternscan.h"
#include "../../../../templeware/utils/memory/memorycommon.h"
#include "../../cutl/utlhash/utlhash.h"
#include "..\..\..\..\templeware\utils\math\utlvector\utlvector.h"
#define SCHEMASYSTEM_TYPE_SCOPES_OFFSET 0x188
#define SCHEMASYSTEMTYPESCOPE_OFF1 0x3F8
#define SCHEMASYSTEMTYPESCOPE_OFF2 0x8
using SchemaString_t = const char*;
struct SchemaMetadataEntryData_t;
class CSchemaSystemTypeScope;
class CSchemaType;
struct CSchemaClassBinding {
CSchemaClassBinding* pParent;
const char* szBinaryName; // ex: C_World
const char* szModuleName; // ex: libclient.so
const char* szClassName; // ex: client
void* pClassInfoOldSynthesized;
void* pClassInfo;
void* pThisModuleBindingPointer;
CSchemaType* pSchemaType;
};
class CSchemaType {
public:
bool GetSizes(int* pOutSize, uint8_t* unkPtr);
public:
bool GetSize(int* out_size);
public:
void* pVtable; // 0x0000
const char* szName; // 0x0008
CSchemaSystemTypeScope* pSystemTypeScope; // 0x0010
uint8_t nTypeCategory; // ETypeCategory 0x0018
uint8_t nAatomicCategory; // EAtomicCategory 0x0019
};
struct SchemaClassFieldData_t {
SchemaString_t szName; // 0x0000
CSchemaType* pSchemaType; // 0x0008
std::uint32_t nSingleInheritanceOffset; // 0x0010
std::int32_t nMetadataSize; // 0x0014
SchemaMetadataEntryData_t* pMetaData; // 0x0018
};
struct SchemaClassInfoData_t;
struct SchemaBaseClassInfoData_t {
int32_t nOffset;
SchemaClassInfoData_t* pClass;
};
struct SchemaClassInfoData_t {
private:
void* pVtable; // 0x0000
public:
const char* szName; // 0x0008
char* szDescription; // 0x0010
int m_nSize; // 0x0018
std::int16_t nFieldSize; // 0x001C
std::int16_t nStaticSize; // 0x001E
std::int16_t nMetadataSize; // 0x0020
std::uint8_t nAlignOf; // 0x0022
std::uint8_t nBaseClassesCount; // 0x0023
char pad2[0x4]; // 0x0024
SchemaClassFieldData_t* pFields; // 0x0028
char pad3[0x8]; // 0x0030
SchemaBaseClassInfoData_t* pBaseClasses; // 0x0038
char pad4[0x28]; // 0x0040
//public:
//SchemaClassFieldData_t* pFields; // 0x0028
bool InheritsFrom(SchemaClassInfoData_t* pClassInfo);
};
struct SchemaEnumeratorInfoData_t {
SchemaString_t szName;
union {
unsigned char value_char;
unsigned short value_short;
unsigned int value_int;
unsigned long long value;
};
MEM_PAD(0x10); // 0x0010
};
class CSchemaEnumInfo {
public:
SchemaEnumeratorInfoData_t enumInfoData;
};
class CSchemaEnumBinding {
public:
virtual const char* GetBindingName() = 0;
virtual CSchemaClassBinding* AsClassBinding() = 0;
virtual CSchemaEnumBinding* AsEnumBinding() = 0;
virtual const char* GetBinaryName() = 0;
virtual const char* GetProjectName() = 0;
public:
char* szBindingName_; // 0x0008
char* szDllName_; // 0x0010
std::int8_t nAlign_; // 0x0018
MEM_PAD(0x3); // 0x0019
std::int16_t nSize_; // 0x001C
std::int16_t nFlags_; // 0x001E
SchemaEnumeratorInfoData_t* pEnumInfo_;
MEM_PAD(0x8); // 0x0028
CSchemaSystemTypeScope* pTypeScope_; // 0x0030
MEM_PAD(0x8); // 0x0038
std::int32_t unk1_; // 0x0040
};
class CSchemaSystemTypeScope {
public:
void FindDeclaredClass(SchemaClassInfoData_t** pReturnClass, const char* szClassName);
CSchemaType* FindSchemaTypeByName(const char* szName, std::uintptr_t* pSchema);
CSchemaType* FindTypeDeclaredClass(const char* szName);
CSchemaType* FindTypeDeclaredEnum(const char* szName);
CSchemaClassBinding* FindRawClassBinding(const char* szName);
void* pVtable; // 0x0000
char szName[256U]; // 0x0008
MEM_PAD(SCHEMASYSTEMTYPESCOPE_OFF1); // 0x0108
CUtlTSHash<CSchemaClassBinding*, 256, unsigned int> hashClasses; // 0x0588
MEM_PAD(SCHEMASYSTEMTYPESCOPE_OFF2); // 0x05C8
CUtlTSHash<CSchemaEnumBinding*, 256, unsigned int> hashEnumes; // 0x2DD0
};
void GetSchemaClassInfo(uintptr_t address, SchemaClassInfoData_t** pReturn);
class ISchemaSystem
{
public:
CSchemaSystemTypeScope* FindTypeScopeForModule(const char* m_module_name);
private:
MEM_PAD(SCHEMASYSTEM_TYPE_SCOPES_OFFSET); // 0x0000
public:
CUtlVector<CSchemaSystemTypeScope*> vecTypeScopes; // SCHEMASYSTEM_TYPE_SCOPES_OFFSET
};

View File

@ -0,0 +1,8 @@
#pragma once
struct viewmatrix_t {
float* operator[ ](int index) {
return matrix[index];
}
float matrix[4][4];
};

View File

@ -0,0 +1,12 @@
#include "CCSPlayerController.h"
CCSPlayerController::CCSPlayerController(uintptr_t address) : address(address) {}
uintptr_t CCSPlayerController::getAddress() const {
return address;
}
const char* CCSPlayerController::getName() const {
if (!address) return nullptr;
return reinterpret_cast<const char*>(address + 0x660);
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
#pragma once
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "../../../templeware/utils/schema/schema.h"
#include "../C_CSWeaponBase/C_CSWeaponBase.h"
#include <cstdint>
class CCSPlayerController {
public:
CCSPlayerController(uintptr_t address);
const char* getName() const;
uintptr_t getAddress() const;
SCHEMA_ADD_OFFSET(bool, IsLocalPlayer, 0x6F0);
SCHEMA_ADD_OFFSET(CBaseHandle, m_hPawn, 0x62C);
SCHEMA_ADD_OFFSET(const char*, m_sSanitizedPlayerName, 0x778);
private:
uintptr_t address;
};

View File

@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include "..\C_EntityInstance\C_EntityInstance.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "..\..\..\..\source\templeware\utils\schema\schema.h"
#include "..\..\..\..\source\templeware\utils\memory\vfunc\vfunc.h"
#include "..\handle.h"
class C_AggregateSceneObjectData
{
private:
char pad_0000[0x38];
public:
std::uint8_t r;
std::uint8_t g;
std::uint8_t b;
private:
char pad_0038[0x9];
};
class C_AggregateSceneObject
{
private:
char pad_0000[0x120];
public:
int m_nCount;
private:
char pad_0120[0x4];
public:
C_AggregateSceneObjectData* m_pData;
};

View File

@ -0,0 +1,58 @@
#pragma once
#include <cstdint>
#include "../C_EntityInstance/C_EntityInstance.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "../../../../source/templeware/utils/schema/schema.h"
#include "../../../../source/templeware/utils/memory/vfunc/vfunc.h"
#include "../handle.h"
class C_BaseEntity : public CEntityInstance
{
public:
schema(int, m_iMaxHealth, "C_BaseEntity->m_iMaxHealth");
SCHEMA_ADD_OFFSET(int, m_iHealth, 0x344);
SCHEMA_ADD_OFFSET(int, m_iTeamNum, 0x3E3);
bool IsBasePlayer()
{
SchemaClassInfoData_t* pClassInfo;
dump_class_info(&pClassInfo);
if (pClassInfo == nullptr)
return false;
return hash_32_fnv1a_const(pClassInfo->szName) == hash_32_fnv1a_const("C_CSPlayerPawn");
}
bool IsViewmodelAttachment()
{
SchemaClassInfoData_t* pClassInfo;
dump_class_info(&pClassInfo);
if (pClassInfo == nullptr)
return false;
return hash_32_fnv1a_const(pClassInfo->szName) == hash_32_fnv1a_const("C_ViewmodelAttachmentModel");
}
bool IsViewmodel()
{
SchemaClassInfoData_t* pClassInfo;
dump_class_info(&pClassInfo);
if (pClassInfo == nullptr)
return false;
return hash_32_fnv1a_const(pClassInfo->szName) == hash_32_fnv1a_const("C_CSGOViewModel");
}
bool IsPlayerController()
{
SchemaClassInfoData_t* _class = nullptr;
dump_class_info(&_class);
if (!_class)
return false;
const uint32_t hash = hash_32_fnv1a_const(_class->szName);
return (hash == hash_32_fnv1a_const("CCSPlayerController"));
}
};

View File

@ -0,0 +1,50 @@
#include "C_CSPlayerPawn.h"
#include "../../../templeware/offsets/offsets.h"
#include "../../../templeware/interfaces/interfaces.h"
C_CSPlayerPawn::C_CSPlayerPawn(uintptr_t address) : address(address) {}
Vector_t C_CSPlayerPawn::getPosition() const {
return *(Vector_t*)(address + SchemaFinder::Get(hash_32_fnv1a_const("C_BasePlayerPawn->m_vOldOrigin")));
}
Vector_t C_CSPlayerPawn::getEyePosition() const {
return Vector_t();
}
C_CSWeaponBase* C_CSPlayerPawn::GetActiveWeapon() const {
if (!this)
return nullptr;
CCSPlayer_WeaponServices* weapon_services = this->GetWeaponServices();
if (weapon_services == nullptr)
return nullptr;
C_CSWeaponBase* active_weapon = I::GameEntity->Instance->Get<C_CSWeaponBase>(weapon_services->m_hActiveWeapon());
if (!active_weapon)
return nullptr;
return active_weapon;
}
CCSPlayer_WeaponServices* C_CSPlayerPawn::GetWeaponServices() const {
if (!address) return nullptr;
return reinterpret_cast<CCSPlayer_WeaponServices*>((uintptr_t)this + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_pWeaponServices")));
}
uintptr_t C_CSPlayerPawn::getAddress() const {
return address;
}
int C_CSPlayerPawn::getHealth() const {
return *reinterpret_cast<int*>((uintptr_t)this + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseEntity->m_iHealth")));
}
uint8_t C_CSPlayerPawn::getTeam() const {
return *reinterpret_cast<uint8_t*>((uintptr_t)this + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseEntity->m_iTeamNum")));
}
Vector_t C_CSPlayerPawn::getViewOffset() const {
return *reinterpret_cast<Vector_t*>((uintptr_t)this + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseModelEntity->m_vecViewOffset")));
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "../../../templeware/utils/schema/schema.h"
#include "../C_CSWeaponBase/C_CSWeaponBase.h"
#include "../C_BaseEntity/C_BaseEntity.h"
#include <cstdint>
class C_CSPlayerPawn : public C_BaseEntity {
public:
SCHEMA_ADD_OFFSET(Vector_t, m_vOldOrigin, 0x1324);
SCHEMA_ADD_OFFSET(Vector_t, m_vecViewOffset, 0xCB0);
SCHEMA_ADD_OFFSET(CCSPlayer_WeaponServices*, m_pWeaponServices, 0x11A8);
C_CSPlayerPawn(uintptr_t address);
C_CSWeaponBase* GetActiveWeapon()const;
CCSPlayer_WeaponServices* GetWeaponServices()const;
Vector_t getPosition() const;
Vector_t getEyePosition() const;
uintptr_t getAddress() const;
int getHealth() const;
uint8_t getTeam() const;
Vector_t getViewOffset() const;
private:
uintptr_t address;
};

View File

@ -0,0 +1,7 @@
#include "C_CSWeaponBase.h"
#include "..\..\..\templeware\hooks\hooks.h"
CCSWeaponBaseVData* C_CSWeaponBase::Data()
{
// return pointer to weapon data
return *reinterpret_cast<CCSWeaponBaseVData**>((uintptr_t)this + H::oGetWeaponData);
}

View File

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include "..\C_EntityInstance\C_EntityInstance.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "..\..\..\..\source\templeware\utils\schema\schema.h"
#include "..\..\..\..\source\templeware\utils\memory\vfunc\vfunc.h"
#include "..\handle.h"
class CCSPlayer_WeaponServices
{
public:
schema(bool, m_bAllowSwitchToNoWeapon, "CPlayer_WeaponServices->m_bAllowSwitchToNoWeapon");
schema(CBaseHandle, m_hMyWeapons, "CPlayer_WeaponServices->m_hMyWeapons");
schema(CBaseHandle, m_hActiveWeapon, "CPlayer_WeaponServices->m_hActiveWeapon");
schema(CBaseHandle, m_hLastWeapon, "CPlayer_WeaponServices->m_hLastWeapon");
schema(int, m_iAmmo, "CPlayer_WeaponServices->m_iAmmo");
schema(float, m_flNextAttack, "CCSPlayer_WeaponServices->m_flNextAttack");
schema(bool, m_bIsLookingAtWeapon, "CCSPlayer_WeaponServices->m_bIsLookingAtWeapon");
schema(bool, m_bIsHoldingLookAtWeapon, "CCSPlayer_WeaponServices->m_bIsHoldingLookAtWeapon");
};
class CCSWeaponBaseVData
{
public:
SCHEMA_ADD_OFFSET(const char*, m_szName, 0xD20);
};
class C_CSWeaponBase
{
public:
// @todo: add few schemas here
CCSWeaponBaseVData* Data();
};

View File

@ -0,0 +1,73 @@
#pragma once
#include "..\..\..\..\source\templeware\utils\schema\schema.h"
#include "..\..\..\..\source\templeware\utils\memory\vfunc\vfunc.h"
#include "..\handle.h"
class CEntityInstance;
class CEntityIdentity
{
public:
SCHEMA_ADD_OFFSET(std::uint32_t, index, 0x10);
schema(const char*, m_designerName, "CEntityIdentity->m_designerName");
schema( std::uint32_t, flags, "CEntityIdentity->m_flags");
std::string GetSchemaName() {
auto class_info = *(uintptr_t*)(std::uintptr_t(this) + 0x10);
auto name = *(const char*)(std::uintptr_t(this) + 0x20);
return std::to_string(name); // Return the string constructed from the char pointer
}
[[nodiscard]] bool valid()
{
return index() != INVALID_EHANDLE_INDEX;
}
[[nodiscard]] int get_index()
{
if (!valid())
return ENT_ENTRY_MASK;
return index() & ENT_ENTRY_MASK;
}
[[nodiscard]] int get_serial_number()
{
return index() >> NUM_SERIAL_NUM_SHIFT_BITS;
}
CEntityInstance* pInstance;
};
class CEntityInstance
{
public:
void dump_class_info(SchemaClassInfoData_t** pReturn)
{
return M::vfunc<void, 38U>(this, pReturn);
}
[[nodiscard]] std::uint32_t get_entity_by_handle()
{
CEntityIdentity* identity = m_pEntityIdentity();
if (identity == nullptr)
return 0;
return identity->get_index();
}
[[nodiscard]] CBaseHandle handle()
{
CEntityIdentity* identity = m_pEntityIdentity();
if (identity == nullptr)
return CBaseHandle();
return CBaseHandle(identity->get_index(), identity->get_serial_number() - (identity->flags() & 1));
}
schema(CEntityIdentity*, m_pEntityIdentity, "CEntityInstance->m_pEntity");
};

View File

@ -0,0 +1,77 @@
#pragma once
#include <cstdint>
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "../../../templeware/utils/schema/schema.h"
#include "../C_CSWeaponBase/C_CSWeaponBase.h"
#include <cstdint>
class CMaterial2
{
public:
virtual const char* GetName() = 0;
virtual const char* GetShareName() = 0;
};
struct MaterialKeyVar_t
{
std::uint64_t uKey;
const char* szName;
MaterialKeyVar_t(std::uint64_t uKey, const char* szName) :
uKey(uKey), szName(szName) { }
MaterialKeyVar_t(const char* szName, bool bShouldFindKey = false) :
szName(szName)
{
uKey = bShouldFindKey ? FindKey(szName) : 0x0;
}
std::uint64_t FindKey(const char* szName)
{
using fn = std::uint64_t(__fastcall*)(const char*, unsigned int, int);
static auto find = reinterpret_cast<fn>(M::patternScan("particles", ("48 89 5C 24 ? 57 48 81 EC ? ? ? ? 33 C0 8B DA")));
return find(szName, 0x12, 0x31415926);
}
};
class CObjectInfo
{
MEM_PAD(0xB0);
int nId;
};
class CSceneAnimatableObject {
public:
CBaseHandle Owner() const {
if (!this)
return CBaseHandle();
return *(CBaseHandle*)((std::uintptr_t)this + 0xB8);
}
};
struct Color {
std::uint8_t r = 0U, g = 0U, b = 0U, a = 0U;
};
class CMeshData
{
public:
private:
MEM_PAD(0x18); // 0x0
public:
CSceneAnimatableObject* pSceneAnimatableObject; // 0x18
CMaterial2* pMaterial; // 0x20
CMaterial2* pMaterialCopy; // 0x20
private:
MEM_PAD(0x10); // 0x28
public:
CObjectInfo* pObjectInfo;
private:
MEM_PAD(0x8);
public:
Color color;
};

View File

@ -0,0 +1,100 @@
#pragma once
#include <cstdint>
// @source: https://developer.valvesoftware.com/wiki/Entity_limit#Source_2_limits
#define INVALID_EHANDLE_INDEX 0xFFFFFFFF
#define ENT_ENTRY_MASK 0x7FFF
#define NUM_SERIAL_NUM_SHIFT_BITS 15
#define ENT_MAX_NETWORKED_ENTRY 16384
class CBaseEntity;
class CBaseHandle
{
public:
CBaseHandle() noexcept :
nIndex(INVALID_EHANDLE_INDEX) { }
CBaseHandle(const int nEntry, const int nSerial) noexcept
{
nIndex = nEntry | (nSerial << NUM_SERIAL_NUM_SHIFT_BITS);
}
bool operator!=(const CBaseHandle& other) const noexcept
{
return nIndex != other.nIndex;
}
bool operator==(const CBaseHandle& other) const noexcept
{
return nIndex == other.nIndex;
}
bool operator<(const CBaseHandle& other) const noexcept
{
return nIndex < other.nIndex;
}
[[nodiscard]] bool valid() const noexcept
{
return nIndex != INVALID_EHANDLE_INDEX;
}
[[nodiscard]] int index() const noexcept
{
return static_cast<int>(nIndex & ENT_ENTRY_MASK);
}
[[nodiscard]] int serial_number() const noexcept
{
return static_cast<int>(nIndex >> NUM_SERIAL_NUM_SHIFT_BITS);
}
private:
std::uint32_t nIndex;
};
class c_handle
{
public:
c_handle();
c_handle(const c_handle& other);
c_handle(unsigned long value);
c_handle(int iEntry, int iSerialNumber);
inline int get_index()
{
return handler & 0x7FFF;
}
inline unsigned long get_handle()
{
return handler;
}
inline bool is_valid()
{
if (handler <= 0 || handler == 0xffffffff)
return false;
return true;
}
protected:
std::uint32_t handler;
};
inline c_handle::c_handle()
{
handler = -1;
}
inline c_handle::c_handle(const c_handle& other)
{
handler = other.handler;
}
inline c_handle::c_handle(unsigned long value)
{
handler = value;
}

View File

@ -0,0 +1,15 @@
#include "debug.h"
#include <Windows.h>
#include <iostream>
void initDebug() {
if (AllocConsole()) {
FILE* pFile;
freopen_s(&pFile, "CONOUT$", "w", stdout);
freopen_s(&pFile, "CONOUT$", "w", stderr);
freopen_s(&pFile, "CONIN$", "r", stdin);
printf("Console allocated.\n\n");
} else {
MessageBoxA(NULL, "Failed to allocate console", "Error", MB_OK | MB_ICONERROR);
}
}

View File

@ -0,0 +1,3 @@
#pragma once
void initDebug();

View File

@ -0,0 +1,12 @@
#pragma once
#include <Windows.h>
#include <d3d11.h>
#include <dxgi.h>
#include "../external/kiero/kiero.h"
#include "../external/imgui/imgui.h"
#include "../external/imgui/imgui_impl_win32.h"
#include "../external/imgui/imgui_impl_dx11.h"
typedef HRESULT(__stdcall* Present) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
typedef LRESULT(CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
typedef uintptr_t PTR;

View File

@ -0,0 +1,174 @@
#include "debug/debug.h"
#include "includes.h"
#include "templeware/templeware.h"
#include "templeware/renderer/icons.h"
#include "../external/kiero/minhook/include/MinHook.h"
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
TempleWare templeWare;
Present oPresent;
HWND window = NULL;
WNDPROC oWndProc;
ID3D11Device* pDevice = NULL;
ID3D11DeviceContext* pContext = NULL;
ID3D11RenderTargetView* mainRenderTargetView;
LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) {
return true;
}
return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam);
}
bool init = false;
HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
if (!init)
{
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice)))
{
pDevice->GetImmediateContext(&pContext);
DXGI_SWAP_CHAIN_DESC sd;
pSwapChain->GetDesc(&sd);
window = sd.OutputWindow;
ID3D11Texture2D* pBackBuffer;
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView);
pBackBuffer->Release();
oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
#ifdef TEMPLEDEBUG
initDebug();
#endif
templeWare.init(window, pDevice, pContext, mainRenderTargetView);
init = true;
}
else
return oPresent(pSwapChain, SyncInterval, Flags);
}
ImFontConfig imIconsConfig;
imIconsConfig.RasterizerMultiply = 1.2f;
constexpr ImWchar wIconRanges[] =
{
0xE000, 0xF8FF, // Private Use Area
0
};
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
if (GetAsyncKeyState(VK_END) & 1) {
templeWare.renderer.menu.toggleMenu();
}
templeWare.renderer.menu.render();
templeWare.renderer.hud.render();
// Always call esp() to allow individual components to be rendered
templeWare.renderer.visuals.esp();
ImGui::Render();
pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
return oPresent(pSwapChain, SyncInterval, Flags);
}
void init_console() {
if (::AllocConsole()) {
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout); // Redirect stdout to console
freopen_s(&f, "CONOUT$", "w", stderr); // Redirect stderr to console
::SetConsoleTitleW(L"TempleWare");
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
printf(R"(___________ .__ __ __
\__ ___/___ _____ ______ | | ____/ \ / \_____ _______ ____
| |_/ __ \ / \\____ \| | _/ __ \ \/\/ /\__ \\_ __ \_/ __ \
| |\ ___/| Y Y \ |_> > |_\ ___/\ / / __ \| | \/\ ___/
|____| \___ >__|_| / __/|____/\___ >\__/\ / (____ /__| \___ >
\/ \/|__| \/ \/ \/ \/
)");
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("[");
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
printf("+");
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("] Console allocated successfully!\n");
}
}
DWORD WINAPI MainThread(LPVOID lpReserved)
{
bool init_hook = false;
do
{
init_console();
// hook hkPresent and init cheat
if (!init_hook) {
if (kiero::init(kiero::RenderType::D3D11) == kiero::Status::Success)
{
kiero::bind(8, (void**)&oPresent, hkPresent);
init_hook = true;
}
}
} while (!GetAsyncKeyState(VK_F4));
if (oWndProc != nullptr)
{
// restore wnd proc
SetWindowLongPtrW(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(oWndProc));
// invalidate old wnd proc
oWndProc = nullptr;
}
kiero::shutdown();
// destroy minhook
MH_DisableHook(MH_ALL_HOOKS);
MH_RemoveHook(MH_ALL_HOOKS);
MH_Uninitialize();
// free allocated memory for console
::FreeConsole();
// close console window
if (const HWND hConsoleWindow = ::GetConsoleWindow(); hConsoleWindow != nullptr)
::PostMessageW(hConsoleWindow, WM_CLOSE, 0U, 0L);
fclose(stdout);
fclose(stderr);
// close thread
FreeLibraryAndExitThread(reinterpret_cast<HMODULE>(lpReserved), EXIT_SUCCESS);
return TRUE;
}
BOOL WINAPI DllMain(HMODULE hMod, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hMod);
CreateThread(nullptr, 0, MainThread, hMod, 0, nullptr);
break;
case DLL_PROCESS_DETACH:
kiero::shutdown();
break;
}
return TRUE;
}

View File

@ -0,0 +1,52 @@
#include "config.h"
// CBA to make proper atm, it's 03:42 right now.
// For now just stores config values don't mind it too much
//
// (FYI THIS IS A HORRID SOLUTION BUT FUNCTIONS)
namespace Config {
bool esp = false;
bool glow = false;
bool showHealth = false;
bool teamCheck = false;
bool espFill = false;
bool showNameTags = false;
bool Night = false;
bool enemyChamsInvisible = false;
bool enemyChams = false;
bool teamChams = false;
bool teamChamsInvisible = false;
int chamsMaterial = 0;
bool armChams = false;
bool viewmodelChams = false;
ImVec4 colViewmodelChams = ImVec4(1, 0, 0, 1);
ImVec4 colArmChams = ImVec4(1, 0, 0, 1);
ImVec4 colVisualChams = ImVec4(1, 0, 0, 1);
ImVec4 colVisualChamsIgnoreZ = ImVec4(1, 0, 0, 1);
ImVec4 teamcolVisualChamsIgnoreZ = ImVec4(1, 0, 0, 1);
ImVec4 teamcolVisualChams = ImVec4(1, 0, 0, 1);
float espThickness = 1.0f;
float espFillOpacity = 0.5f;
ImVec4 espColor = ImVec4(1, 0, 0, 1);
bool fovEnabled = false;
float fov = 90.0f;
bool antiflash = false;
ImVec4 NightColor = ImVec4(0.1, 0.1, 0.1, 1);
bool aimbot = true;
float aimbot_fov = 90;
bool team_check = false;
bool rcs = 0;
bool fov_circle = 0;
ImVec4 fovCircleColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "../../../external/imgui/imgui.h"
// CBA to make proper atm, it's 03:42 right now.
// For now just stores config values don't mind it too much
//
// (FYI THIS IS A HORRID SOLUTION BUT FUNCTIONS)
namespace Config {
extern bool esp;
extern bool showHealth;
extern bool teamCheck;
extern bool espFill;
extern float espThickness;
extern float espFillOpacity;
extern ImVec4 espColor;
extern bool showNameTags;
extern bool Night;
extern ImVec4 NightColor;
extern bool enemyChamsInvisible;
extern bool enemyChams;
extern bool teamChams;
extern bool teamChamsInvisible;
extern int chamsMaterial;
extern ImVec4 colVisualChams;
extern ImVec4 colVisualChamsIgnoreZ;
extern ImVec4 teamcolVisualChamsIgnoreZ;
extern ImVec4 teamcolVisualChams;
extern bool armChams;
extern bool viewmodelChams;
extern ImVec4 colViewmodelChams;
extern ImVec4 colArmChams;
extern bool fovEnabled;
extern float fov;
extern bool antiflash;
extern bool Night;
extern bool aimbot;
extern float aimbot_fov;
extern bool team_check;
extern bool rcs;
extern bool fov_circle;
extern ImVec4 fovCircleColor;
}

View File

@ -0,0 +1,301 @@
#pragma once
#include <string>
#include <vector>
#include <filesystem>
#include <fstream>
#include <cstdlib>
#include "config.h"
#include "../../../external/json/json.hpp"
namespace internal_config
{
class ConfigManager
{
private:
static std::filesystem::path GetConfigFolder()
{
char* userProfile = nullptr;
size_t len = 0;
errno_t err = _dupenv_s(&userProfile, &len, "USERPROFILE");
std::filesystem::path folder;
if (err != 0 || userProfile == nullptr || len == 0)
{
folder = ".templeware";
}
else
{
folder = userProfile;
free(userProfile);
folder /= ".templeware";
}
folder /= "internal";
std::error_code ec;
std::filesystem::create_directories(folder, ec);
return folder;
}
static std::filesystem::path GetConfigPath(const std::string& configName)
{
auto folder = GetConfigFolder();
return folder / (configName + ".json");
}
public:
static std::vector<std::string> ListConfigs()
{
std::vector<std::string> list;
auto folder = GetConfigFolder();
if (!std::filesystem::exists(folder))
return list;
for (const auto& entry : std::filesystem::directory_iterator(folder))
{
if (entry.is_regular_file())
{
auto path = entry.path();
if (path.extension() == ".json")
{
list.push_back(path.stem().string());
}
}
}
return list;
}
static void Save(const std::string& configName)
{
nlohmann::json j;
j["esp"] = Config::esp;
j["showHealth"] = Config::showHealth;
j["teamCheck"] = Config::teamCheck;
j["espFill"] = Config::espFill;
j["espThickness"] = Config::espThickness;
j["espFillOpacity"] = Config::espFillOpacity;
j["fovEnabled"] = Config::fovEnabled;
j["fov"] = Config::fov;
j["espColor"] = {
Config::espColor.x,
Config::espColor.y,
Config::espColor.z,
Config::espColor.w
};
j["Night"] = Config::Night;
j["NightColor"] = {
Config::NightColor.x,
Config::NightColor.y,
Config::NightColor.z,
Config::NightColor.w
};
j["armChams"] = Config::armChams;
j["viewmodelChams"] = Config::viewmodelChams;
j["armChams_color"] = {
Config::colArmChams.x,
Config::colArmChams.y,
Config::colArmChams.z,
Config::colArmChams.w
};
j["viewmodelChams_color"] = {
Config::colViewmodelChams.x,
Config::colViewmodelChams.y,
Config::colViewmodelChams.z,
Config::colViewmodelChams.w
};
j["aimbot"] = Config::aimbot;
j["aimbot_fov"] = Config::aimbot_fov;
j["antiflash"] = Config::antiflash;
j["rcs"] = Config::rcs;
j["fov_circle"] = Config::fov_circle;
j["enemyChamsInvisible"] = Config::enemyChamsInvisible;
j["enemyChams"] = Config::enemyChams;
j["teamChams"] = Config::teamChams;
j["teamChamsInvisible"] = Config::teamChamsInvisible;
j["chamsMaterial"] = Config::chamsMaterial;
j["colVisualChams"] = {
Config::colVisualChams.x,
Config::colVisualChams.y,
Config::colVisualChams.z,
Config::colVisualChams.w
};
j["colVisualChamsIgnoreZ"] = {
Config::colVisualChamsIgnoreZ.x,
Config::colVisualChamsIgnoreZ.y,
Config::colVisualChamsIgnoreZ.z,
Config::colVisualChamsIgnoreZ.w
};
j["teamcolVisualChamsIgnoreZ"] = {
Config::teamcolVisualChamsIgnoreZ.x,
Config::teamcolVisualChamsIgnoreZ.y,
Config::teamcolVisualChamsIgnoreZ.z,
Config::teamcolVisualChamsIgnoreZ.w
};
j["teamcolVisualChams"] = {
Config::teamcolVisualChams.x,
Config::teamcolVisualChams.y,
Config::teamcolVisualChams.z,
Config::teamcolVisualChams.w
};
j["fovCircleColor"] = {
Config::fovCircleColor.x,
Config::fovCircleColor.y,
Config::fovCircleColor.z,
Config::fovCircleColor.w
};
auto filePath = GetConfigPath(configName);
std::ofstream ofs(filePath);
if (ofs.is_open())
{
ofs << j.dump(4);
ofs.close();
}
}
static void Load(const std::string& configName)
{
auto filePath = GetConfigPath(configName);
if (!std::filesystem::exists(filePath))
return;
std::ifstream ifs(filePath);
if (!ifs.is_open())
return;
nlohmann::json j;
ifs >> j;
Config::esp = j.value("esp", false);
Config::showHealth = j.value("showHealth", false);
Config::teamCheck = j.value("teamCheck", false);
Config::espFill = j.value("espFill", false);
Config::espThickness = j.value("espThickness", 1.0f);
Config::espFillOpacity = j.value("espFillOpacity", 0.5f);
Config::fovEnabled = j.value("fovEnabled", false);
Config::fov = j.value("fov", 90.0f);
if (j.contains("espColor") && j["espColor"].is_array() && j["espColor"].size() == 4)
{
auto arr = j["espColor"];
Config::espColor.x = arr[0].get<float>();
Config::espColor.y = arr[1].get<float>();
Config::espColor.z = arr[2].get<float>();
Config::espColor.w = arr[3].get<float>();
}
Config::Night = j.value("Night", false);
if (j.contains("NightColor") && j["NightColor"].is_array() && j["NightColor"].size() == 4)
{
auto arr = j["NightColor"];
Config::NightColor.x = arr[0].get<float>();
Config::NightColor.y = arr[1].get<float>();
Config::NightColor.z = arr[2].get<float>();
Config::NightColor.w = arr[3].get<float>();
}
Config::enemyChamsInvisible = j.value("enemyChamsInvisible", false);
Config::enemyChams = j.value("enemyChams", false);
Config::teamChams = j.value("teamChams", false);
Config::teamChamsInvisible = j.value("teamChamsInvisible", false);
Config::chamsMaterial = j.value("chamsMaterial", 0);
Config::fov_circle = j.value("fov_circle", false);
Config::aimbot = j.value("aimbot", false);
Config::rcs = j.value("rcs", false);
Config::aimbot_fov = j.value("aimbot_fov", 0.f);
Config::antiflash = j.value("antiflash", false);
Config::armChams = j.value("armChams", false);
Config::viewmodelChams = j.value("viewmodelChams", false);
if (j.contains("colArmChams") && j["colArmChams"].is_array() && j["colArmChams"].size() == 4)
{
auto arr = j["colArmChams"];
Config::colArmChams.x = arr[0].get<float>();
Config::colArmChams.y = arr[1].get<float>();
Config::colArmChams.z = arr[2].get<float>();
Config::colArmChams.w = arr[3].get<float>();
}
if (j.contains("colViewmodelChams") && j["colViewmodelChams"].is_array() && j["colViewmodelChams"].size() == 4)
{
auto arr = j["colViewmodelChams"];
Config::colViewmodelChams.x = arr[0].get<float>();
Config::colViewmodelChams.y = arr[1].get<float>();
Config::colViewmodelChams.z = arr[2].get<float>();
Config::colViewmodelChams.w = arr[3].get<float>();
}
if (j.contains("colVisualChams") && j["colVisualChams"].is_array() && j["colVisualChams"].size() == 4)
{
auto arr = j["colVisualChams"];
Config::colVisualChams.x = arr[0].get<float>();
Config::colVisualChams.y = arr[1].get<float>();
Config::colVisualChams.z = arr[2].get<float>();
Config::colVisualChams.w = arr[3].get<float>();
}
if (j.contains("colVisualChamsIgnoreZ") && j["colVisualChamsIgnoreZ"].is_array() && j["colVisualChamsIgnoreZ"].size() == 4)
{
auto arr = j["colVisualChamsIgnoreZ"];
Config::colVisualChamsIgnoreZ.x = arr[0].get<float>();
Config::colVisualChamsIgnoreZ.y = arr[1].get<float>();
Config::colVisualChamsIgnoreZ.z = arr[2].get<float>();
Config::colVisualChamsIgnoreZ.w = arr[3].get<float>();
}
if (j.contains("teamcolVisualChamsIgnoreZ") && j["teamcolVisualChamsIgnoreZ"].is_array() && j["teamcolVisualChamsIgnoreZ"].size() == 4)
{
auto arr = j["teamcolVisualChamsIgnoreZ"];
Config::teamcolVisualChamsIgnoreZ.x = arr[0].get<float>();
Config::teamcolVisualChamsIgnoreZ.y = arr[1].get<float>();
Config::teamcolVisualChamsIgnoreZ.z = arr[2].get<float>();
Config::teamcolVisualChamsIgnoreZ.w = arr[3].get<float>();
}
if (j.contains("teamcolVisualChams") && j["teamcolVisualChams"].is_array() && j["teamcolVisualChams"].size() == 4)
{
auto arr = j["teamcolVisualChams"];
Config::teamcolVisualChams.x = arr[0].get<float>();
Config::teamcolVisualChams.y = arr[1].get<float>();
Config::teamcolVisualChams.z = arr[2].get<float>();
Config::teamcolVisualChams.w = arr[3].get<float>();
}
if (j.contains("fovCircleColor") && j["fovCircleColor"].is_array() && j["fovCircleColor"].size() == 4) {
auto arr = j["fovCircleColor"];
Config::fovCircleColor.x = arr[0].get<float>();
Config::fovCircleColor.y = arr[1].get<float>();
Config::fovCircleColor.z = arr[2].get<float>();
Config::fovCircleColor.w = arr[3].get<float>();
}
ifs.close();
}
static void Remove(const std::string& configName)
{
auto filePath = GetConfigPath(configName);
if (std::filesystem::exists(filePath))
{
std::error_code ec;
std::filesystem::remove(filePath, ec);
}
}
};
}

View File

@ -0,0 +1,125 @@
#include "../../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
#include "../../../templeware/interfaces/CGameEntitySystem/CGameEntitySystem.h"
#include "../../../templeware/interfaces/interfaces.h"
#include "../../../templeware/hooks/hooks.h"
#include "../../../templeware/config/config.h"
#include <chrono>
#include <Windows.h>
#include "../../menu/hud.h"
// Literally the most autistic code ive ever written in my life
// Please dont ever make me do this again
Vector_t GetEntityEyePos(const C_CSPlayerPawn* Entity) {
if (!Entity)
return {};
uintptr_t game_scene_node = *reinterpret_cast<uintptr_t*>((uintptr_t)Entity + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseEntity->m_pGameSceneNode")));
auto Origin = *reinterpret_cast<Vector_t*>(game_scene_node + SchemaFinder::Get(hash_32_fnv1a_const("CGameSceneNode->m_vecAbsOrigin")));
auto ViewOffset = *reinterpret_cast<Vector_t*>((uintptr_t)Entity + SchemaFinder::Get(hash_32_fnv1a_const("C_BaseModelEntity->m_vecViewOffset")));
Vector_t Result = Origin + ViewOffset;
if (!std::isfinite(Result.x) || !std::isfinite(Result.y) || !std::isfinite(Result.z))
return {};
return Result;
}
inline QAngle_t CalcAngles(Vector_t viewPos, Vector_t aimPos)
{
QAngle_t angle = { 0, 0, 0 };
Vector_t delta = aimPos - viewPos;
angle.x = -asin(delta.z / delta.Length()) * (180.0f / 3.141592654f);
angle.y = atan2(delta.y, delta.x) * (180.0f / 3.141592654f);
return angle;
}
inline float GetFov(const QAngle_t& viewAngle, const QAngle_t& aimAngle)
{
QAngle_t delta = (aimAngle - viewAngle).Normalize();
return sqrtf(powf(delta.x, 2.0f) + powf(delta.y, 2.0f));
}
void Aimbot() {
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevAimbotState = false;
bool aimbotActive = Config::aimbot;
// Получаем локального игрока и viewangles всегда, чтобы не дублировать код
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
Vector_t lep = GetEntityEyePos(lp);
QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
// Если кнопка только что нажата (переход с false на true) — ищем новую цель
if (aimbotActive && !prevAimbotState) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = {0, 0, 0};
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
/* if (!Config::team_check && pawn->getTeam() == lp->getTeam())
continue;*/
Vector_t eye_pos = GetEntityEyePos(pawn);
QAngle_t angle = CalcAngles(eye_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
}
// Если кнопка отпущена — сбрасываем захват
if (!aimbotActive)
lockedTarget = nullptr;
// Если есть захваченная цель и кнопка удерживается
if (aimbotActive && lockedTarget) {
// Проверяем, что цель всё ещё валидна
if (!lockedTarget->handle().valid() || lockedTarget->getHealth() <= 0) {
lockedTarget = nullptr;
} else {
Vector_t eye_pos = GetEntityEyePos(lockedTarget);
QAngle_t angle = CalcAngles(eye_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (Config::rcs)
angle -= ang_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
*viewangles = angle;
}
}
prevAimbotState = aimbotActive;
}

View File

@ -0,0 +1,3 @@
#pragma once
void Aimbot();

View File

@ -0,0 +1,281 @@
#include <algorithm>
#include <iostream>
#include "chams.h"
#include "../../hooks/hooks.h"
#include "../../config/config.h"
#include "../../../../external/imgui/imgui.h"
#include "../../utils/math/utlstronghandle/utlstronghandle.h"
#include "../../../cs2/entity/C_Material/C_Material.h"
#include "../../interfaces/interfaces.h"
#include "../../interfaces/CGameEntitySystem/CGameEntitySystem.h"
#include "../../../cs2/datatypes/keyvalues/keyvalues.h"
#include "../../../cs2/datatypes/cutlbuffer/cutlbuffer.h"
CStrongHandle<CMaterial2> chams::create(const char* name, const char szVmatBuffer[])
{
CKeyValues3* pKeyValues3 = nullptr;
pKeyValues3 = pKeyValues3->create_material_from_resource();
pKeyValues3->LoadFromBuffer(szVmatBuffer);
CStrongHandle<CMaterial2> pCustomMaterial = {};
I::CreateMaterial(nullptr, &pCustomMaterial, name, pKeyValues3, 0, 1);
return pCustomMaterial;
}
struct resource_material_t
{
CStrongHandle<CMaterial2> mat;
CStrongHandle<CMaterial2> mat_invs;
};
static resource_material_t resourceMaterials[ChamsType::MAXCOUNT];
bool loaded_materials = false;
bool chams::Materials::init()
{
// flat
resourceMaterials[FLAT] = resource_material_t{
.mat = create("materials/dev/flat.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
Shader = "csgo_unlitgeneric.vfx"
F_IGNOREZ = 0
F_DISABLE_Z_WRITE = 0
F_DISABLE_Z_BUFFERING = 0
F_BLEND_MODE = 1
F_TRANSLUCENT = 1
F_RENDER_BACKFACES = 0
g_vColorTint = [1.000000, 1.000000, 1.000000, 1.000000]
g_vGlossinessRange = [0.000000, 1.000000, 0.000000, 0.000000]
g_vNormalTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_vTexCoordOffset = [0.000000, 0.000000, 0.000000, 0.000000]
g_vTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_tColor = resource:"materials/dev/primary_white_color_tga_f7b257f6.vtex"
g_tNormal = resource:"materials/default/default_normal_tga_7652cb.vtex"
})"),
.mat_invs = create("materials/dev/flat_i.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
Shader = "csgo_unlitgeneric.vfx"
F_IGNOREZ = 1
F_DISABLE_Z_WRITE = 1
F_DISABLE_Z_BUFFERING = 1
F_BLEND_MODE = 1
F_TRANSLUCENT = 1
g_vColorTint = [1.000000, 1.000000, 1.000000, 0.000000]
g_vGlossinessRange = [0.000000, 1.000000, 0.000000, 0.000000]
g_vNormalTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_vTexCoordOffset = [0.000000, 0.000000, 0.000000, 0.000000]
g_vTexCoordScale = [1.000000, 1.000000, 0.000000, 0.000000]
g_tColor = resource:"materials/dev/primary_white_color_tga_f7b257f6.vtex"
g_tNormal = resource:"materials/default/default_normal_tga_7652cb.vtex"
})")
};
resourceMaterials[ILLUMINATE] = resource_material_t{
.mat = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 1.000000 ]
g_flSelfIllumScale = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_flSelfIllumBrightness = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
})"),
.mat_invs = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_complex.vfx"
F_SELF_ILLUM = 1
F_PAINT_VERTEX_COLORS = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_BUFFERING = 1
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 1.000000 ]
g_flSelfIllumScale = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_flSelfIllumBrightness = [ 3.000000, 3.000000, 3.000000, 3.000000 ]
g_vSelfIllumTint = [ 10.000000, 10.000000, 10.000000, 10.000000 ]
g_tColor = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tNormal = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSelfIllumMask = resource:"materials/default/default_mask_tga_fde710a5.vtex"
TextureAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
g_tAmbientOcclusion = resource:"materials/debug/particleerror.vtex"
})")
};
resourceMaterials[GLOW] = resource_material_t{
.mat = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_effects.vfx"
g_flFresnelExponent = 7.0
g_flFresnelFalloff = 10.0
g_flFresnelMax = 0.1
g_flFresnelMin = 1.0
g_tColor = resource:"materials/dev/primary_white_color_tga_21186c76.vtex"
g_tMask1 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask2 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask3 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSceneDepth = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_flToolsVisCubemapReflectionRoughness = 1.0
g_flBeginMixingRoughness = 1.0
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 0 ]
F_IGNOREZ = 0
F_TRANSLUCENT = 1
F_DISABLE_Z_WRITE = 0
F_DISABLE_Z_BUFFERING = 1
F_RENDER_BACKFACES = 0
})"),
.mat_invs = create("materials/dev/primary_white.vmat", R"(<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
shader = "csgo_effects.vfx"
g_flFresnelExponent = 7.0
g_flFresnelFalloff = 10.0
g_flFresnelMax = 0.1
g_flFresnelMin = 1.0
g_tColor = resource:"materials/dev/primary_white_color_tga_21186c76.vtex"
g_tMask1 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask2 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tMask3 = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_tSceneDepth = resource:"materials/default/default_mask_tga_fde710a5.vtex"
g_flToolsVisCubemapReflectionRoughness = 1.0
g_flBeginMixingRoughness = 1.0
g_vColorTint = [ 1.000000, 1.000000, 1.000000, 0 ]
F_IGNOREZ = 1
F_TRANSLUCENT = 1
F_DISABLE_Z_WRITE = 1
F_DISABLE_Z_BUFFERING = 1
F_RENDER_BACKFACES = 0
})")
};
return true;
}
ChamsEntity chams::GetTargetType(C_BaseEntity* render_ent) noexcept {
auto local = H::oGetLocalPlayer(0);
if (!local)
return ChamsEntity::INVALID;
if (render_ent->IsViewmodelAttachment())
return ChamsEntity::HANDS;
if (render_ent->IsViewmodel())
return ChamsEntity::VIEWMODEL;
if (!render_ent->IsBasePlayer() && !render_ent->IsPlayerController())
return ChamsEntity::INVALID;
auto player = (C_CSPlayerPawn*)render_ent;
if (!player)
return ChamsEntity::INVALID;
auto alive = player->m_iHealth() > 0;
if (!alive)
return ChamsEntity::INVALID;
if (player->m_iTeamNum() == local->m_iTeamNum())
return ChamsEntity::INVALID;
return ChamsEntity::ENEMY;
}
CMaterial2* GetMaterial(int type, bool invisible) { return invisible ? resourceMaterials[type].mat_invs : resourceMaterials[type].mat; }
void __fastcall chams::hook(void* a1, void* a2, CMeshData* pMeshScene, int nMeshCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2)
{
static auto original = H::DrawArray.GetOriginal();
if (!I::EngineClient->valid())
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto local_player = H::oGetLocalPlayer(0);
if (!local_player)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!pMeshScene)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!pMeshScene->pSceneAnimatableObject)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (nMeshCount < 1)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
CMeshData* render_data = pMeshScene;
if (!render_data)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (!render_data->pSceneAnimatableObject)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto render_ent = render_data->pSceneAnimatableObject->Owner();
if (!render_ent.valid())
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
auto entity = I::GameEntity->Instance->Get(render_ent);
if (!entity)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
const auto target = GetTargetType(entity);
if (target == ChamsEntity::VIEWMODEL && Config::viewmodelChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colViewmodelChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colViewmodelChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colViewmodelChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colViewmodelChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (target == ChamsEntity::HANDS && Config::armChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colArmChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colArmChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colArmChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colArmChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (target != ENEMY)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
bool og = !Config::enemyChams && !Config::enemyChamsInvisible;
if (og)
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
if (Config::enemyChamsInvisible) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, true);
pMeshScene->color.r = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colVisualChamsIgnoreZ.w * 255.0f);
original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
if (Config::enemyChams) {
pMeshScene->pMaterial = GetMaterial(Config::chamsMaterial, false);
pMeshScene->color.r = static_cast<uint8_t>(Config::colVisualChams.x * 255.0f);
pMeshScene->color.g = static_cast<uint8_t>(Config::colVisualChams.y * 255.0f);
pMeshScene->color.b = static_cast<uint8_t>(Config::colVisualChams.z * 255.0f);
pMeshScene->color.a = static_cast<uint8_t>(Config::colVisualChams.w * 255.0f);
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}
// If we get here, neither chams type is enabled, so just render normally
return original(a1, a2, pMeshScene, nMeshCount, pSceneView, pSceneLayer, pUnk, pUnk2);
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <cstdint>
#include "../../../cs2/entity/C_BaseEntity/C_BaseEntity.h"
#include "../../../cs2/entity/C_Material/C_Material.h"
#include "../../utils/math/utlstronghandle/utlstronghandle.h"
// forward declarations
class CMeshData;
enum ChamsType {
FLAT,
ILLUMINATE,
GLOW,
MAXCOUNT
};
enum ChamsEntity : std::int32_t {
INVALID = 0,
ENEMY,
TEAM,
VIEWMODEL,
HANDS
};
enum MaterialType {
e_visible,
e_invisible,
e_max_material
};
namespace chams
{
class Materials {
public:
bool init();
};
static ChamsEntity GetTargetType(C_BaseEntity* entity) noexcept;
CStrongHandle<CMaterial2> create(const char* name, const char szVmatBuffer[]);
void __fastcall hook(void* pAnimatableSceneObjectDesc, void* pDx11, CMeshData* arrMeshDraw, int nDataCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2);
}

View File

@ -0,0 +1,7 @@
#include "../../../hooks/hooks.h"
#include "../../../config/config.h"
void __fastcall H::hkRenderFlashbangOverlay(void* a1, void* a2, void* a3, void* a4, void* a5) {
if (Config::antiflash) return;
return RenderFlashBangOverlay.GetOriginal()(a1, a2, a3, a4, a5);
}

View File

@ -0,0 +1,12 @@
#include "../../../hooks/hooks.h"
#include "../../../config/config.h"
float H::hkGetRenderFov(void* rcx) {
if (Config::fovEnabled) {
float flTargetFov = Config::fov;
g_flActiveFov = flTargetFov;
}else
g_flActiveFov = H::GetRenderFov.GetOriginal()(rcx);
return g_flActiveFov;
}

View File

@ -0,0 +1,268 @@
#include "visuals.h"
#include <algorithm>
#include <iostream>
#include "../../hooks/hooks.h"
#include "../../players/players.h"
#include "../../utils/memory/patternscan/patternscan.h"
#include "../../utils/memory/gaa/gaa.h"
#include "../../../../external/imgui/imgui.h"
#include "../../interfaces/interfaces.h"
#include "../../config/config.h"
#include "../../menu/menu.h"
using namespace Esp;
LocalPlayerCached cached_local;
std::vector<PlayerCache> cached_players;
void Visuals::init() {
viewMatrix.viewMatrix = (viewmatrix_t*)M::getAbsoluteAddress(M::patternScan("client", "48 8D 0D ? ? ? ? 48 C1 E0 06"), 3, 0);
}
void Esp::cache()
{
if (!I::EngineClient->valid())
return;
/* Old method READ ME
* @ // @here: manually cache once all existing entitys
// to avoid issues when injecting mid game and hkAddEnt not called by game on existing Entity's
int highest_index = I::GameEntity->Instance->GetHighestEntityIndex();
for (int i = 1; i <= highest_index; i++) {
auto entity = I::GameEntity->Instance->Get(i);
if (!entity)
continue;
uintptr_t entityPointer = reinterpret_cast<uintptr_t>(entity);
SchemaClassInfoData_t* entityInfo = nullptr;
GetSchemaClassInfo(entityPointer, &entityInfo);
if (!entityInfo) continue;
if (strcmp(entityInfo->szName, "C_CSPlayerPawn") == 0) {
bool exists = std::any_of(Players::pawns.begin(), Players::pawns.end(),
[&](const C_CSPlayerPawn& pawn) { return pawn.getAddress() == entityPointer; });
if (!exists) {
Players::pawns.emplace_back(entityPointer);
std::cout << "Added pawn " << Players::pawns.size() << "\n";
}
continue;
}
if (strcmp(entityInfo->szName, "CCSPlayerController") == 0) {
bool exists = std::any_of(Players::controllers.begin(), Players::controllers.end(),
[&](const CCSPlayerController& controller) { return controller.getAddress() == entityPointer; });
if (!exists) {
Players::controllers.emplace_back(entityPointer);
}
continue;
}
}*/
cached_players.clear();
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
for (int i = 1; i <= nMaxHighestEntity; i++)
{
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
PlayerType_t type = none;
if (hash == HASH("CCSPlayerController"))
{
type = none; int health = 0;
Vector_t position; Vector_t viewOffset;
const char* name = "none"; const char* weapon_name = "none";
CCSPlayerController* Controller = reinterpret_cast<CCSPlayerController*>(Entity);
if (!Controller)
continue;
if (!Controller->m_hPawn().valid())
continue;
//@handle caching local player
if (Controller->IsLocalPlayer()) {
auto LocalPlayer = I::GameEntity->Instance->Get<C_CSPlayerPawn>(Controller->m_hPawn().index());
if (!LocalPlayer) {
cached_local.reset();
continue;
}
cached_local.alive = LocalPlayer->m_iHealth() > 0;
if (LocalPlayer->m_iHealth() > 0) {
cached_local.poisition = LocalPlayer->m_vOldOrigin();
cached_local.health = LocalPlayer->m_iHealth();
cached_local.handle = LocalPlayer->handle().index();
cached_local.team = LocalPlayer->m_iTeamNum();
}
else {
cached_local.reset();
}
}
else // @handle only players
{
auto Player = I::GameEntity->Instance->Get<C_CSPlayerPawn>(Controller->m_hPawn().index());
if (!Player)
continue;
if (Player->m_iHealth() <= 0)
continue;
health = Player->m_iHealth();
name = Controller->m_sSanitizedPlayerName();
position = Player->m_vOldOrigin(); viewOffset = Player->m_vecViewOffset();
cached_players.emplace_back(Entity, Player, Player->handle(),
type, health, name,
weapon_name, position, viewOffset, Player->m_iTeamNum());
}
}
}
}
void Visuals::esp() {
// Only proceed if at least one ESP component is enabled
if (!Config::esp && !Config::showHealth && !Config::espFill && !Config::showNameTags) {
return; // Exit early if no component is enabled
}
//@better example of getting local pawn
C_CSPlayerPawn* localPawn = H::oGetLocalPlayer(0);
if (!localPawn) {
return;
}
if (cached_players.empty())
return;
for (const auto& Player : cached_players)
{
if (!Player.handle.valid() || Player.health <= 0 || Player.handle.index() == INVALID_EHANDLE_INDEX)
continue;
if (Config::teamCheck && (Player.team_num == cached_local.team))
continue;
ImDrawList* drawList = ImGui::GetBackgroundDrawList();
Vector_t feetPos = Player.position;
Vector_t headPos = Player.position + Player.viewOffset;
Vector_t feetScreen, headScreen;
if (!viewMatrix.WorldToScreen(feetPos, feetScreen) ||
!viewMatrix.WorldToScreen(headPos, headScreen))
continue;
float boxHeight = (feetScreen.y - headScreen.y) * 1.3f;
float boxWidth = boxHeight / 2.0f;
float centerX = (feetScreen.x + headScreen.x) / 2.0f;
float boxX = centerX - (boxWidth / 2.0f);
float boxY = headScreen.y - (boxHeight - (feetScreen.y - headScreen.y)) / 2.0f;
ImVec4 espColorWithAlpha = Config::espColor;
espColorWithAlpha.w = Config::espFillOpacity;
ImU32 boxColor = ImGui::ColorConvertFloat4ToU32(Config::espColor);
ImU32 fillColor = ImGui::ColorConvertFloat4ToU32(espColorWithAlpha);
// ESP Fill
if (Config::espFill) {
drawList->AddRectFilled(
ImVec2(boxX, boxY),
ImVec2(boxX + boxWidth, boxY + boxHeight),
fillColor
);
}
// ESP Box - only render if Config::esp is enabled
if (Config::esp) {
drawList->AddRect(
ImVec2(boxX, boxY),
ImVec2(boxX + boxWidth, boxY + boxHeight),
boxColor,
0.0f,
0,
Config::espThickness
);
}
// Health Bar
if (Config::showHealth) {
int health = Player.health;
float healthHeight = boxHeight * (static_cast<float>(health) / 100.0f);
float barWidth = 4.0f;
float barX = boxX - (barWidth + 2);
float barY = boxY + (boxHeight - healthHeight);
drawList->AddRectFilled(
ImVec2(barX, boxY),
ImVec2(barX + barWidth, boxY + boxHeight),
IM_COL32(70, 70, 70, 255)
);
ImU32 healthColor = IM_COL32(
static_cast<int>((100 - health) * 2.55f),
static_cast<int>(health * 2.55f),
0,
255
);
drawList->AddRectFilled(
ImVec2(barX, barY),
ImVec2(barX + barWidth, barY + healthHeight),
healthColor
);
std::string displayText = "[" + std::to_string(health) + "HP]";
ImVec2 textSize = ImGui::CalcTextSize(displayText.c_str());
float textX = boxX + (boxWidth - textSize.x) / 2;
float textY = boxY + boxHeight + 2;
drawList->AddText(
ImVec2(textX + 1, textY + 1),
IM_COL32(0, 0, 0, 255),
displayText.c_str()
);
drawList->AddText(
ImVec2(textX, textY),
IM_COL32(255, 255, 255, 255),
displayText.c_str()
);
}
if (Config::showNameTags) {
std::string playerName = Player.name;
ImVec2 nameSize = ImGui::CalcTextSize(playerName.c_str());
float nameX = boxX + (boxWidth - nameSize.x) / 2;
float nameY = boxY - nameSize.y - 2;
//@FIXME: shit method to do outline
drawList->AddText(
ImVec2(nameX + 1, nameY + 1),
IM_COL32(0, 0, 0, 255),
playerName.c_str()
);
drawList->AddText(
ImVec2(nameX, nameY),
IM_COL32(255, 255, 255, 255),
playerName.c_str()
);
}
}
}

View File

@ -0,0 +1,60 @@
#pragma once
#include "../../utils/math/viewmatrix/viewmatrix.h"
#include "..\..\..\cs2\entity\C_CSPlayerPawn\C_CSPlayerPawn.h"
#include "..\..\..\cs2\entity\C_BaseEntity\C_BaseEntity.h"
class LocalPlayerCached {
public:
int handle;
int health;
int team;
bool alive;
Vector_t poisition;
void reset() {
poisition = Vector_t();
team = 0;
health = 0;
handle = 0;
alive = false;
}
};
enum PlayerType_t : int
{
none = -1,
enemy = 0,
team = 1,
};
struct PlayerCache
{
PlayerCache(C_BaseEntity* a1, C_CSPlayerPawn* plyr, CBaseHandle hdl, PlayerType_t typ, int hp, const char* nm,
const char* wep_name, Vector_t pos, Vector_t viewOff, int teamnm) :
entity(a1), player(plyr), handle(hdl), type(typ), health(hp), name(nm),
weapon_name(wep_name), position(pos), viewOffset(viewOff), team_num(teamnm) { }
C_BaseEntity* entity;
C_CSPlayerPawn* player;
CBaseHandle handle;
PlayerType_t type;
int health;
const char* name;
const char* weapon_name;
Vector_t position;
Vector_t viewOffset;
int team_num;
};
namespace Esp {
class Visuals {
public:
void init();
void esp();
private:
ViewMatrix viewMatrix;
};
void cache();
}
extern LocalPlayerCached cached_local;
extern std::vector<PlayerCache> cached_players;

View File

@ -0,0 +1,43 @@
#include <algorithm>
#include <iostream>
#include "../../hooks/hooks.h"
#include "../../players/players.h"
#include "../../config/config.h"
#include "../../../../external/imgui/imgui.h"
void reset_walls(C_AggregateSceneObject* object) {
for (int i = 0; i < object->m_nCount; i++) {
object->m_pData[i].r = 255;
object->m_pData[i].g = 255;
object->m_pData[i].b = 255;
}
}
void apply_walls(C_AggregateSceneObject* object, ImVec4 colors) {
for (int i = 0; i < object->m_nCount; i++) {
object->m_pData[i].r = static_cast<uint8_t>(colors.x * 255.0f);
object->m_pData[i].g = static_cast<uint8_t>(colors.y * 255.0f);
object->m_pData[i].b = static_cast<uint8_t>(colors.z * 255.0f);
}
}
void* __fastcall H::hkUpdateSceneObject(C_AggregateSceneObject* object, void* unk)
{
static auto update_walls_object = UpdateWallsObject.GetOriginal();
auto result = update_walls_object(object, unk);
auto colors = Config::NightColor;
if (object) {
if (Config::Night) {
apply_walls(object, colors);
}
else {
reset_walls(object);
}
}
return result;
}

View File

@ -0,0 +1,56 @@
#include "hooks.h"
#include <iostream>
#include "../../../external/kiero/minhook/include/MinHook.h"
#include "../../templeware/utils/memory/Interface/Interface.h"
#include "../utils/memory/patternscan/patternscan.h"
#include "../utils/memory/gaa/gaa.h"
#include "../players/hook/playerHook.h"
#include "../features/visuals/visuals.h"
#include "../features/chams/chams.h"
#include "../../cs2/datatypes/cutlbuffer/cutlbuffer.h"
#include "../../cs2/datatypes/keyvalues/keyvalues.h"
#include "../../cs2/entity/C_Material/C_Material.h"
#include "../config/config.h"
#include "../interfaces/interfaces.h"
#include "../features/aim/aim.h"
void __fastcall H::hkFrameStageNotify(void* a1, int stage)
{
FrameStageNotify.GetOriginal()(a1, stage);
// frame_render_stage | 9
if (stage == 9 && oGetLocalPlayer(0)) {
Esp::cache();
Aimbot();
}
}
void* __fastcall H::hkLevelInit(void* pClientModeShared, const char* szNewMap) {
static void* g_pPVS = (void*)M::getAbsoluteAddress(M::patternScan("engine2", "48 8D 0D ? ? ? ? 33 D2 FF 50"), 0x3);
M::vfunc<void*, 6U, void>(g_pPVS, false);
return LevelInit.GetOriginal()(pClientModeShared, szNewMap);
}
void H::Hooks::init() {
oGetWeaponData = *reinterpret_cast<int*>(M::patternScan("client", ("48 8B 81 ? ? ? ? 85 D2 78 ? 48 83 FA ? 73 ? F3 0F 10 84 90 ? ? ? ? C3 F3 0F 10 80 ? ? ? ? C3 CC CC CC CC")) + 0x3);
ogGetBaseEntity = reinterpret_cast<decltype(ogGetBaseEntity)>(M::patternScan("client", ("81 FA ? ? ? ? 77 ? 8B C2 C1 F8 ? 83 F8 ? 77 ? 48 98 48 8B 4C C1 ? 48 85 C9 74 ? 8B C2 25 ? ? ? ? 48 6B C0 ? 48 03 C8 74 ? 8B 41 ? 25 ? ? ? ? 3B C2 75 ? 48 8B 01")));
oGetLocalPlayer = reinterpret_cast<decltype(oGetLocalPlayer)>(M::patternScan("client", ("48 83 EC 28 83 F9 FF 75 17 48 8B 0D ?? ?? ?? ?? 48 8D 54 24 30 48 8B 01 FF 90 ?? ?? ?? ?? 8B 08 48 63 C1 48 8D 0D ?? ?? ?? ?? 48 8B 0C")));
UpdateWallsObject.Add((void*)M::patternScan("scenesystem", ("48 89 5C 24 10 48 89 6C 24 18 56 57 41 54 41 56 41 57 48 83 EC 40")), &hkUpdateSceneObject);
FrameStageNotify.Add((void*)M::patternScan("client", ("48 89 5C 24 ? 56 48 83 EC 30 8B 05 ? ? ? ?")), &hkFrameStageNotify);
DrawArray.Add((void*)M::patternScan("scenesystem", ("48 8B C4 48 89 50 10 53 41 55 41 56 48 81 EC ? ? ? ? 4D 63 F1")), &chams::hook);
GetRenderFov.Add((void*)M::getAbsoluteAddress(M::patternScan("client", "E8 ? ? ? ? F3 0F 11 45 00 48 8B 5C 24 40"), 1), &hkGetRenderFov);
LevelInit.Add((void*)M::getAbsoluteAddress(M::patternScan("client", "E8 ? ? ? ? C6 83 ? ? ? ? ? C6 83"), 1), &hkLevelInit);
RenderFlashBangOverlay.Add((void*)M::patternScan("client", ("85 D2 0F 88 ? ? ? ? 55 56 41 55")), &hkRenderFlashbangOverlay);
MH_EnableHook(MH_ALL_HOOKS);
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "includeHooks.h"
#include "../../cs2/entity/C_AggregateSceneObject/C_AggregateSceneObject.h"
#include "../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
#include "../../cs2/datatypes/cutlbuffer/cutlbuffer.h"
#include "../../cs2/datatypes/keyvalues/keyvalues.h"
#include "../../cs2/entity/C_Material/C_Material.h"
// Forward declaration
class CMeshData;
class CEntityIdentity;
namespace H {
void* __fastcall hkUpdateSceneObject(C_AggregateSceneObject* object, void* unk);
void __fastcall hkFrameStageNotify(void* a1, int stage);
void* __fastcall hkLevelInit(void* pClientModeShared, const char* szNewMap);
void __fastcall hkChamsObject(void* pAnimatableSceneObjectDesc, void* pDx11, CMeshData* arrMeshDraw, int nDataCount, void* pSceneView, void* pSceneLayer, void* pUnk, void* pUnk2);
void __fastcall hkRenderFlashbangOverlay(void* a1, void* a2, void* a3, void* a4, void* a5);
inline float g_flActiveFov;
float hkGetRenderFov(void* rcx);
inline CInlineHookObj<decltype(&hkChamsObject)> DrawArray = { };
inline CInlineHookObj<decltype(&hkFrameStageNotify)> FrameStageNotify = { };
inline CInlineHookObj<decltype(&hkUpdateSceneObject)> UpdateWallsObject = { };
inline CInlineHookObj<decltype(&hkGetRenderFov)> GetRenderFov = { };
inline CInlineHookObj<decltype(&hkLevelInit)> LevelInit = { };
inline CInlineHookObj<decltype(&hkRenderFlashbangOverlay)> RenderFlashBangOverlay = { };
// inline hooks
inline int oGetWeaponData;
inline void* (__fastcall* ogGetBaseEntity)(void*, int);
inline C_CSPlayerPawn* (__fastcall* oGetLocalPlayer)(int);
class Hooks {
public:
void init();
};
}

View File

@ -0,0 +1,108 @@
#pragma once
#include "../../../external/kiero/minhook/include/MinHook.h"
#include <cstdint>
// @source: popular github minhook instance
template <typename T>
class CInlineHookObj
{
public:
/// setup hook and replace function
/// @returns: true if hook has been successfully created, false otherwise
bool Add(void* pFunction, void* pDetour)
{
if (pFunction == nullptr || pDetour == nullptr)
return false;
pBaseFn = pFunction;
pReplaceFn = pDetour;
if (const MH_STATUS status = MH_CreateHook(pBaseFn, pReplaceFn, &pOriginalFn); status != MH_OK)
{
return false;
}
if (!Replace())
return false;
return true;
}
/// patch memory to jump to our function instead of original
/// @returns: true if hook has been successfully applied, false otherwise
bool Replace()
{
// check is hook has been created
if (pBaseFn == nullptr)
return false;
// check that function isn't already hooked
if (bIsHooked)
return false;
if (const MH_STATUS status = MH_EnableHook(pBaseFn); status != MH_OK)
{
return false;
}
// switch hook state
bIsHooked = true;
return true;
}
/// restore original function call and cleanup hook data
/// @returns: true if hook has been successfully removed, false otherwise
bool Remove()
{
// restore it at first
if (!Restore())
return false;
if (const MH_STATUS status = MH_RemoveHook(pBaseFn); status != MH_OK)
{
return false;
}
return true;
}
/// restore patched memory to original function call
/// @returns: true if hook has been successfully restored, false otherwise
bool Restore()
{
// check that function is hooked
if (!bIsHooked)
return false;
if (const MH_STATUS status = MH_DisableHook(pBaseFn); status != MH_OK)
{
return false;
}
// switch hook state
bIsHooked = false;
return true;
}
/// @returns: original, unwrapped function that would be called without the hook
inline T GetOriginal()
{
return reinterpret_cast<T>(pOriginalFn);
}
/// @returns: true if hook is applied at the time, false otherwise
inline bool IsHooked() const
{
return bIsHooked;
}
private:
// current hook state
bool bIsHooked = false;
// function base handle
void* pBaseFn = nullptr;
// function that being replace the original call
void* pReplaceFn = nullptr;
// original function
void* pOriginalFn = nullptr;
};

View File

@ -0,0 +1,6 @@
#include "CGameEntitySystem.h"
#include "..\..\hooks\hooks.h"
void* CGameEntitySystem::GetEntityByIndex(int nIndex) {
return H::ogGetBaseEntity(this, nIndex);
}

View File

@ -0,0 +1,67 @@
#pragma once
#include <cstdint>
#include "../../../cs2/entity/handle.h"
#include "../../../templeware/utils/memory/memorycommon.h"
#include "../../../templeware/utils/math/vector/vector.h"
#include "..\..\..\..\source\templeware\utils\schema\schema.h"
#include "..\..\..\..\source\templeware\utils\memory\vfunc\vfunc.h"
#include "..\..\..\cs2\entity\C_BaseEntity\C_BaseEntity.h"
#include "..\..\..\cs2\entity\C_CSPlayerPawn\C_CSPlayerPawn.h"
#include "..\..\..\cs2\entity\CCSPlayerController\CCSPlayerController.h"
class CGameEntitySystem
{
public:
template <typename T = C_BaseEntity>
T* Get(int nIndex)
{
return reinterpret_cast<T*>(this->GetEntityByIndex(nIndex));
}
/// GetClientEntityFromHandle
template <typename T = C_BaseEntity>
T* Get(const CBaseHandle hHandle)
{
if (!hHandle.valid())
return nullptr;
return reinterpret_cast<T*>(this->GetEntityByIndex(hHandle.index()));
}
int GetHighestEntityIndex()
{
return *reinterpret_cast<int*>(reinterpret_cast<std::uintptr_t>(this) + 0x20F0);
}
C_CSPlayerPawn* get_entity(int index)
{
__int64 v2; // rcx
__int64 v3; // r8
__int64 result{}; // rax
if ((unsigned int)index <= 0x7FFE
&& (unsigned int)(index >> 9) <= 0x3F
&& (v2 = *(std::uintptr_t*)(std::uintptr_t(this) + 8 * (index >> 9) + 16)) != 0
&& (v3 = 120 * (index & 0x1FF), v3 + v2)
&& (*(std::uintptr_t*)(v3 + v2 + 16) & 0x7FFF) == index)
{
result = *(std::uintptr_t*)(v3 + v2);
}
return reinterpret_cast<C_CSPlayerPawn*>(result);
}
private:
void* GetEntityByIndex(int nIndex);
};
class IGameResourceService
{
public:
MEM_PAD(0x58);
CGameEntitySystem* Instance;
};

View File

@ -0,0 +1,34 @@
#pragma once
// used: callvfunc
#include "..\..\utils\memory\vfunc\vfunc.h"
#include <type_traits>
class IEngineClient
{
public:
int maxClients()
{
return M::vfunc<int, 34U>(this);
}
bool in_game()
{
return M::vfunc<bool, 35U>(this);
}
bool connected()
{
return M::vfunc<bool, 36U>(this);
}
int get_local_player() {
int nIndex = -1;
M::vfunc<void, 49U>(this, std::ref(nIndex), 0);
return nIndex + 1;
}
public:
inline bool valid() {
return connected() && in_game();
}
};

View File

@ -0,0 +1,36 @@
#include "interfaces.h"
#include "CGameEntitySystem/CGameEntitySystem.h"
// @used: I::Get<template>
#include "..\..\templeware\utils\memory\Interface\Interface.h"
bool I::Interfaces::init()
{
const HMODULE tier0_base = GetModuleHandleA("tier0.dll");
if (!tier0_base)
return false;
bool success = true;
// interfaces
EngineClient = I::Get<IEngineClient>(("engine2.dll"), "Source2EngineToClient00");
success &= (EngineClient != nullptr);
GameEntity = I::Get<IGameResourceService>(("engine2.dll"), "GameResourceServiceClientV00");
success &= (GameEntity != nullptr);
// exports
ConstructUtlBuffer = reinterpret_cast<decltype(ConstructUtlBuffer)>(GetProcAddress(tier0_base, "??0CUtlBuffer@@QEAA@HHH@Z"));
EnsureCapacityBuffer = reinterpret_cast<decltype(EnsureCapacityBuffer)>(GetProcAddress(tier0_base, "?EnsureCapacity@CUtlBuffer@@QEAAXH@Z"));
PutUtlString = reinterpret_cast<decltype(PutUtlString)>(GetProcAddress(tier0_base, "?PutString@CUtlBuffer@@QEAAXPEBD@Z"));
CreateMaterial = reinterpret_cast<decltype(CreateMaterial)>(M::FindPattern("materialsystem2.dll", "48 89 5C 24 ? 48 89 6C 24 ? 56 57 41 56 48 81 EC ? ? ? ? 48 8B 05"));
LoadKeyValues = reinterpret_cast<decltype(LoadKeyValues)>(GetProcAddress(tier0_base, "?LoadKV3@@YA_NPEAVKeyValues3@@PEAVCUtlString@@PEBDAEBUKV3ID_t@@2@Z"));
ConMsg = reinterpret_cast<decltype(ConMsg)>(GetProcAddress(tier0_base, "?ConMsg@@YAXPEBDZZ"));
ConColorMsg = reinterpret_cast<decltype(ConColorMsg)>(GetProcAddress(tier0_base, "?ConColorMsg@@YAXAEBVColor@@PEBDZZ"));
printf("Source2EngineToClient00: 0x%p\n", reinterpret_cast<void*>(EngineClient));
printf("GameResourceServiceClientV00: 0x%p\n", reinterpret_cast<void*>(GameEntity));
printf("CreateMaterial: 0x%p\n", reinterpret_cast<void*>(CreateMaterial));
// return status
return success;
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "IEngineClient/IEngineClient.h"
#include "CGameEntitySystem/CGameEntitySystem.h"
#include "..\..\cs2\entity\C_CSPlayerPawn\C_CSPlayerPawn.h"
#include "..\..\cs2\datatypes\cutlbuffer\cutlbuffer.h"
#include "..\..\cs2\datatypes\keyvalues\keyvalues.h"
#include "..\..\cs2\entity\C_Material\C_Material.h"
namespace I
{
inline void(__fastcall* EnsureCapacityBuffer)(CUtlBuffer*, int) = nullptr;
inline CUtlBuffer* (__fastcall* ConstructUtlBuffer)(CUtlBuffer*, int, int, int) = nullptr;
inline void(__fastcall* PutUtlString)(CUtlBuffer*, const char*);
inline std::int64_t(__fastcall* CreateMaterial)(void*, void*, const char*, void*, unsigned int, unsigned int);
inline bool(__fastcall* LoadKeyValues)(CKeyValues3*, void*, const char*, const KV3ID_t*, const char*);
// Logging functions
inline void(__fastcall* ConMsg)(const char*, ...);
inline void(__fastcall* ConColorMsg)(const Color&, const char*, ...);
inline IEngineClient* EngineClient = nullptr;
inline IGameResourceService* GameEntity = nullptr;
class Interfaces {
public:
bool init();
};
}

View File

@ -0,0 +1,99 @@
#include "keybinds.h"
#include <Windows.h>
#include <cstring> // For strcpy_s and sprintf_s
#include <cstdio> // For sprintf_s
#include "../../../external/imgui/imgui.h"
#include "../config/config.h"
Keybind::Keybind(bool& v, int k)
: var(v), key(k), isListening(false), skipFrame(false) {}
Keybinds::Keybinds() {
keybinds.emplace_back(Keybind(Config::aimbot, 0x12));
}
void Keybinds::pollInputs() {
for (Keybind& k : keybinds) {
if (k.key != 0) {
// Если кнопка удерживается
if (GetAsyncKeyState(k.key) & 0x8000) {
k.var = true;
} else {
k.var = false;
}
}
}
}
void Keybinds::menuButton(bool& var) {
for (auto& kb : keybinds) {
if (&kb.var != &var) continue;
char keyName[32] = "None";
if (kb.key != 0) {
switch (kb.key) {
case VK_INSERT: strcpy_s(keyName, "INSERT"); break;
case VK_DELETE: strcpy_s(keyName, "DELETE"); break;
case VK_HOME: strcpy_s(keyName, "HOME"); break;
case VK_END: strcpy_s(keyName, "END"); break;
case VK_PRIOR: strcpy_s(keyName, "PAGE UP"); break;
case VK_NEXT: strcpy_s(keyName, "PAGE DOWN"); break;
case VK_LBUTTON: strcpy_s(keyName, "MOUSE1"); break;
case VK_RBUTTON: strcpy_s(keyName, "MOUSE2"); break;
case VK_MBUTTON: strcpy_s(keyName, "MOUSE3"); break;
case VK_XBUTTON1: strcpy_s(keyName, "MOUSE4"); break;
case VK_XBUTTON2: strcpy_s(keyName, "MOUSE5"); break;
default:
if (kb.key >= 'A' && kb.key <= 'Z') {
sprintf_s(keyName, "%c", kb.key);
}
else if (kb.key >= '0' && kb.key <= '9') {
sprintf_s(keyName, "%c", kb.key);
}
else {
sprintf_s(keyName, "0x%X", kb.key);
}
break;
}
}
if (!kb.isListening) {
ImGui::PushID(&kb);
ImGui::Text("[%s]", keyName);
ImGui::SameLine();
bool clicked = ImGui::Button("Change##Bind");
ImGui::PopID();
if (clicked) {
kb.isListening = true;
kb.skipFrame = true;
}
}
else {
ImGui::Text("Press any key...");
ImGui::SameLine();
if (ImGui::Button("Cancel") || (GetAsyncKeyState(VK_ESCAPE) & 0x8000)) {
kb.isListening = false;
return;
}
if (!kb.skipFrame) {
for (int keyCode = 7; keyCode < 256; ++keyCode) {
if (GetAsyncKeyState(keyCode) & 0x8000) {
kb.key = keyCode;
kb.isListening = false;
return;
}
}
}
else {
kb.skipFrame = false;
}
}
}
}
Keybinds keybind;

View File

@ -0,0 +1,24 @@
#pragma once
#include <vector>
struct Keybind {
bool& var;
int key;
bool isListening;
bool skipFrame;
Keybind(bool& v, int k = 0);
};
class Keybinds {
public:
Keybinds();
void pollInputs();
void menuButton(bool& var);
private:
std::vector<Keybind> keybinds;
};
extern Keybinds keybind;

View File

@ -0,0 +1,82 @@
#include "hud.h"
#include "../../../external/imgui/imgui.h"
#include "../config/config.h"
#include "../hooks/hooks.h"
#include <ctime>
#include <string>
#include <sstream>
#include <DirectXMath.h>
std::string g_DebugString;
Hud::Hud() {
}
float CalculateFovRadius(float fovDegrees, float screenWidth, float screenHeight, float gameVerticalFOV) {
float aspectRatio = screenWidth / screenHeight;
float fovRadians = fovDegrees * (DirectX::XM_PI / 180.0f);
float screenRadius = std::tan(fovRadians / 2.0f) * (screenHeight / 2.0f) / std::tan(gameVerticalFOV * (DirectX::XM_PI / 180.0f) / 2.0f);
static float flScalingMultiplier = 2.5f;
return screenRadius * flScalingMultiplier;
}
void RenderFovCircle(ImDrawList* drawList, float fov, ImVec2 screenCenter, float screenWidth, float screenHeight, float thickness) {
float radius = CalculateFovRadius(fov, screenWidth, screenHeight, H::g_flActiveFov);
uint32_t color = ImGui::ColorConvertFloat4ToU32(Config::fovCircleColor);
drawList->AddCircle(screenCenter, radius, color, 100, thickness);
}
void Hud::render() {
// Time
std::time_t now = std::time(nullptr);
std::tm localTime;
localtime_s(&localTime, &now);
char timeBuffer[9];
std::strftime(timeBuffer, sizeof(timeBuffer), "%H:%M:%S", &localTime);
// FPS
float fps = ImGui::GetIO().Framerate;
std::ostringstream fpsStream;
fpsStream << static_cast<int>(fps) << " FPS";
// WaterMark
std::string watermarkText = "TempleWare | " + fpsStream.str() + " | " + timeBuffer;
ImVec2 textSize = ImGui::CalcTextSize(watermarkText.c_str());
float padding = 5.0f;
ImVec2 pos = ImVec2(10, 10);
ImVec2 rectSize = ImVec2(textSize.x + padding * 2, textSize.y + padding * 2);
ImU32 bgColor = IM_COL32(50, 50, 50, 200);
ImU32 borderColor = IM_COL32(153, 76, 204, 255);
ImU32 textColor = IM_COL32(255, 255, 255, 255);
ImDrawList* drawList = ImGui::GetBackgroundDrawList();
drawList->AddRectFilled(pos, ImVec2(pos.x + rectSize.x, pos.y + rectSize.y), bgColor);
float lineThickness = 2.0f;
drawList->AddLine(pos, ImVec2(pos.x, pos.y + rectSize.y), borderColor, lineThickness);
drawList->AddLine(ImVec2(pos.x + rectSize.x, pos.y), ImVec2(pos.x + rectSize.x, pos.y + rectSize.y), borderColor, lineThickness);
ImVec2 textPos = ImVec2(pos.x + padding, pos.y + padding);
drawList->AddText(textPos, textColor, watermarkText.c_str());
if (Config::fov_circle) {
ImVec2 Center = ImVec2(ImGui::GetIO().DisplaySize.x / 2.f, ImGui::GetIO().DisplaySize.y / 2.f);
RenderFovCircle(drawList, Config::aimbot_fov, Center, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y, 1.f);
}
// Debug overlay
if (!g_DebugString.empty()) {
ImVec2 debugPos = ImVec2(10, 40); // чуть ниже watermark
ImU32 debugColor = IM_COL32(255, 255, 0, 255); // жёлтый
ImGui::GetBackgroundDrawList()->AddText(debugPos, debugColor, g_DebugString.c_str());
}
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <string>
extern std::string g_DebugString;
class Hud {
public:
Hud();
void render();
};

View File

@ -0,0 +1,315 @@
#include "menu.h"
#include "../config/config.h"
#include <iostream>
#include <vector>
#include "../config/configmanager.h"
#include "../keybinds/keybinds.h"
#include "../utils/logging/log.h"
void ApplyImGuiTheme() {
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
ImVec4* colors = style.Colors;
ImVec4 primaryColor = ImVec4(0.44f, 0.23f, 0.78f, 1.0f);
ImVec4 outlineColor = ImVec4(0.54f, 0.33f, 0.88f, 0.7f);
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.11f, 0.13f, 1.0f);
colors[ImGuiCol_Border] = ImVec4(0.30f, 0.30f, 0.30f, 1.0f);
colors[ImGuiCol_FrameBg] = ImVec4(0.11f, 0.11f, 0.13f, 1.0f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.15f, 0.15f, 0.18f, 1.0f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.15f, 0.15f, 0.18f, 1.0f);
colors[ImGuiCol_TitleBg] = ImVec4(0.11f, 0.11f, 0.13f, 1.0f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.11f, 0.11f, 0.13f, 1.0f);
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.13f, 1.0f);
colors[ImGuiCol_Button] = primaryColor;
colors[ImGuiCol_ButtonHovered] = ImVec4(0.54f, 0.33f, 0.88f, 1.0f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.34f, 0.13f, 0.68f, 1.0f);
colors[ImGuiCol_CheckMark] = ImVec4(0.80f, 0.50f, 1.00f, 1.0f);
colors[ImGuiCol_SliderGrab] = primaryColor;
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.54f, 0.33f, 0.88f, 1.0f);
colors[ImGuiCol_Header] = primaryColor;
colors[ImGuiCol_HeaderHovered] = ImVec4(0.54f, 0.33f, 0.88f, 1.0f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.34f, 0.13f, 0.68f, 1.0f);
colors[ImGuiCol_Separator] = ImVec4(0.34f, 0.13f, 0.68f, 1.0f);
colors[ImGuiCol_SeparatorHovered] = primaryColor;
colors[ImGuiCol_SeparatorActive] = ImVec4(0.54f, 0.33f, 0.88f, 1.0f);
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_Tab] = ImVec4(0.17f, 0.17f, 0.21f, 1.0f);
colors[ImGuiCol_TabHovered] = ImVec4(0.44f, 0.23f, 0.78f, 0.8f);
colors[ImGuiCol_TabActive] = primaryColor;
colors[ImGuiCol_TabUnfocused] = ImVec4(0.17f, 0.17f, 0.21f, 1.0f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.34f, 0.13f, 0.68f, 1.0f);
colors[ImGuiCol_Border] = outlineColor;
colors[ImGuiCol_BorderShadow] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
style.WindowRounding = 0.0f;
style.FrameRounding = 0.0f;
style.ScrollbarRounding = 0.0f;
style.GrabRounding = 0.0f;
style.TabRounding = 0.0f;
style.ChildRounding = 0.0f;
style.PopupRounding = 0.0f;
style.ItemSpacing = ImVec2(8, 4);
style.FramePadding = ImVec2(4, 3);
style.WindowPadding = ImVec2(8, 8);
style.FrameBorderSize = 1.0f;
style.TabBorderSize = 1.0f;
style.WindowBorderSize = 1.0f;
style.PopupBorderSize = 1.0f;
style.ChildBorderSize = 1.0f;
style.GrabMinSize = 7.0f;
}
Menu::Menu() {
activeTab = 0;
showMenu = true;
}
void Menu::init(HWND& window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11RenderTargetView* mainRenderTargetView) {
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange;
ImGui_ImplWin32_Init(window);
ImGui_ImplDX11_Init(pDevice, pContext);
ApplyImGuiTheme();
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\arial.ttf", 16.0f);
std::cout << "initialized menu\n";
}
void Menu::render() {
keybind.pollInputs();
if (showMenu) {
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar;
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Once);
ImGui::SetNextWindowPos(ImVec2(50, 50), ImGuiCond_Once);
ImGui::Begin("TempleWare | Internal", nullptr, window_flags);
{
float windowWidth = ImGui::GetWindowWidth();
float rightTextWidth = ImGui::CalcTextSize("templecheats.xyz").x;
ImGui::Text("TempleWare - Internal");
ImGui::SameLine(windowWidth - rightTextWidth - 10);
ImGui::Text("templecheats.xyz");
}
ImGui::Separator();
const char* tabNames[] = { "Aim", "Visuals", "Misc", "Config" };
if (ImGui::BeginTabBar("MainTabBar", ImGuiTabBarFlags_NoTooltip)) {
for (int i = 0; i < 4; i++) {
if (ImGui::BeginTabItem(tabNames[i])) {
activeTab = i;
ImGui::EndTabItem();
}
}
ImGui::EndTabBar();
}
ImGui::BeginChild("ContentRegion", ImVec2(0, 0), false);
switch (activeTab) {
case 0:
{
ImGui::BeginChild("AimLeft", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f - 5, 0), true);
ImGui::Text("General");
ImGui::Separator();
ImGui::Checkbox("Enable##AimBot", &Config::aimbot);
ImGui::SameLine();
ImGui::Text("Key:");
ImGui::SameLine();
keybind.menuButton(Config::aimbot);
ImGui::Checkbox("Team Check", &Config::team_check);
ImGui::SliderFloat("FOV", &Config::aimbot_fov, 0.f, 90.f);
ImGui::Checkbox("Draw FOV Circle", &Config::fov_circle);
if (Config::fov_circle) {
ImGui::ColorEdit4("Circle Color##FovColor", (float*)&Config::fovCircleColor);
}
ImGui::Checkbox("Recoil Control", &Config::rcs);
ImGui::EndChild();
ImGui::SameLine();
ImGui::BeginChild("AimRight", ImVec2(0, 0), true);
ImGui::Text("TriggerBot");
ImGui::Separator();
ImGui::Text("No additional settings");
ImGui::EndChild();
}
break;
case 1:
{
ImGui::BeginChild("VisualsLeft", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f - 5, 0), true);
ImGui::Text("Player ESP");
ImGui::Separator();
ImGui::Checkbox("Box", &Config::esp);
ImGui::SliderFloat("Thickness", &Config::espThickness, 1.0f, 5.0f);
ImGui::Checkbox("Box Fill", &Config::espFill);
if (Config::espFill) {
ImGui::SliderFloat("Fill Opacity", &Config::espFillOpacity, 0.0f, 1.0f);
}
ImGui::ColorEdit4("ESP Color##BoxColor", (float*)&Config::espColor);
ImGui::Checkbox("Team Check", &Config::teamCheck);
ImGui::Checkbox("Health Bar", &Config::showHealth);
ImGui::Checkbox("Name Tags", &Config::showNameTags);
ImGui::Spacing();
ImGui::Text("World");
ImGui::Separator();
ImGui::Checkbox("Night Mode", &Config::Night);
if (Config::Night) {
ImGui::ColorEdit4("Night Color", (float*)&Config::NightColor);
}
ImGui::Checkbox("Custom FOV", &Config::fovEnabled);
if (Config::fovEnabled) {
ImGui::SliderFloat("FOV Value##FovSlider", &Config::fov, 20.0f, 160.0f, "%1.0f");
}
ImGui::EndChild();
ImGui::SameLine();
ImGui::BeginChild("VisualsRight", ImVec2(0, 0), true);
ImGui::Text("Chams");
ImGui::Separator();
ImGui::Checkbox("Chams##ChamsCheckbox", &Config::enemyChams);
const char* chamsMaterials[] = { "Flat", "Illuminate", "Glow" };
ImGui::Combo("Material", &Config::chamsMaterial, chamsMaterials, IM_ARRAYSIZE(chamsMaterials));
if (Config::enemyChams) {
ImGui::ColorEdit4("Chams Color##ChamsColor", (float*)&Config::colVisualChams);
}
ImGui::Checkbox("Chams-XQZ", &Config::enemyChamsInvisible);
if (Config::enemyChamsInvisible) {
ImGui::ColorEdit4("XQZ Color##ChamsXQZColor", (float*)&Config::colVisualChamsIgnoreZ);
}
ImGui::Spacing();
ImGui::Text("Hand Chams");
ImGui::Separator();
ImGui::Checkbox("Hand Chams", &Config::armChams);
if (Config::armChams) {
ImGui::ColorEdit4("Hand Color##HandChamsColor", (float*)&Config::colArmChams);
}
ImGui::Checkbox("Viewmodel Chams", &Config::viewmodelChams);
if (Config::viewmodelChams) {
ImGui::ColorEdit4("Viewmodel Color##ViewModelChamsColor", (float*)&Config::colViewmodelChams);
}
ImGui::Spacing();
ImGui::Text("Removals");
ImGui::Separator();
ImGui::Checkbox("Anti Flash", &Config::antiflash);
ImGui::EndChild();
}
break;
case 2:
{
ImGui::BeginChild("MiscLeft", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f - 5, 0), true);
ImGui::Text("Movement");
ImGui::Separator();
ImGui::Text("No additional settings");
ImGui::EndChild();
ImGui::SameLine();
ImGui::BeginChild("MiscRight", ImVec2(0, 0), true);
ImGui::Text("Other");
ImGui::Separator();
ImGui::Text("No additional settings");
ImGui::EndChild();
}
break;
case 3:
{
ImGui::BeginChild("ConfigLeft", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f - 5, 0), true);
ImGui::Text("General");
ImGui::Separator();
static char configName[128] = "";
static std::vector<std::string> configList = internal_config::ConfigManager::ListConfigs();
static int selectedConfigIndex = -1;
ImGui::InputText("Config Name", configName, IM_ARRAYSIZE(configName));
if (ImGui::Button("Refresh")) {
configList = internal_config::ConfigManager::ListConfigs();
}
ImGui::SameLine();
if (ImGui::Button("Load")) {
internal_config::ConfigManager::Load(configName);
}
ImGui::SameLine();
if (ImGui::Button("Save")) {
internal_config::ConfigManager::Save(configName);
configList = internal_config::ConfigManager::ListConfigs();
}
ImGui::SameLine();
if (ImGui::Button("Delete")) {
internal_config::ConfigManager::Remove(configName);
configList = internal_config::ConfigManager::ListConfigs();
}
ImGui::EndChild();
ImGui::SameLine();
ImGui::BeginChild("ConfigRight", ImVec2(0, 0), true);
ImGui::Text("Saved Configs");
ImGui::Separator();
for (int i = 0; i < static_cast<int>(configList.size()); i++) {
if (ImGui::Selectable(configList[i].c_str(), selectedConfigIndex == i)) {
selectedConfigIndex = i;
strncpy_s(configName, sizeof(configName), configList[i].c_str(), _TRUNCATE);
}
}
ImGui::EndChild();
}
break;
}
ImGui::EndChild();
ImGui::End();
}
}
void Menu::toggleMenu() {
showMenu = !showMenu;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <Windows.h>
#include <d3d11.h>
#include "../../../external/imgui/imgui.h"
#include "../../../external/imgui/imgui_impl_dx11.h"
#include "../../../external/imgui/imgui_impl_win32.h"
class Menu {
public:
Menu();
void init(HWND& window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11RenderTargetView* mainRenderTargetView);
void render();
void toggleMenu();
private:
bool showMenu;
int activeTab;
};

View File

@ -0,0 +1,13 @@
#pragma once
#include <cstddef>
namespace Offset {
constexpr std::ptrdiff_t dwLocalPlayerPawn = 0x188BF30;
namespace C_BasePlayerPawn {
constexpr std::ptrdiff_t m_vOldOrigin = 0x1324;
constexpr std::ptrdiff_t m_iHealth = 0x344;
constexpr std::ptrdiff_t m_iTeamNum = 0x3E3;
constexpr std::ptrdiff_t m_vecViewOffset = 0xCB0;
}
}

View File

@ -0,0 +1,83 @@
#include "../../../cs2/datatypes/schema/ISchemaClass/ISchemaClass.h"
#include "../players.h"
#include "playerHook.h"
#include <iostream>
/*
// @READ ME: This should be storing Handles and not address pointers
// it s hould store C_BaseEntity Handle
// which can later globally be used to grab its right instance
void onAddEntityHook(__int64 CGameEntitySystem, void* entityPointer, int entityHandle) {
if (!entityPointer || !CGameEntitySystem || !entityHandle) {
oOnAddEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
uintptr_t uEntityPointer = reinterpret_cast<uintptr_t>(entityPointer);
SchemaClassInfoData_t* entityInfo = nullptr;
GetSchemaClassInfo(uEntityPointer, &entityInfo);
if (entityInfo == nullptr) {
oOnAddEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
if (strcmp(entityInfo->szName, "C_CSPlayerPawn") == 0) {
Players::pawns.emplace_back(uEntityPointer);
std::cout << "Added pawn " << Players::pawns.size() << "\n";
oOnAddEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
if (strcmp(entityInfo->szName, "CCSPlayerController") == 0) {
Players::controllers.emplace_back(uEntityPointer);
oOnAddEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
oOnAddEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
void onRemoveEntityHook(__int64 CGameEntitySystem, void* entityPointer, int entityHandle) {
if (!entityPointer || !CGameEntitySystem || !entityHandle) {
oOnRemoveEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
uintptr_t uEntityPointer = reinterpret_cast<uintptr_t>(entityPointer);
SchemaClassInfoData_t* entityInfo = nullptr;
GetSchemaClassInfo(uEntityPointer, &entityInfo);
if (strcmp(entityInfo->szName, "C_CSPlayerPawn") == 0) {
for (auto it = Players::pawns.begin(); it != Players::pawns.end(); ++it) {
if (it->getAddress() == uEntityPointer) {
Players::pawns.erase(it);
std::cout << "Removed pawn " << Players::pawns.size();
break;
}
}
}
if (strcmp(entityInfo->szName, "CCSPlayerController") == 0) {
for (auto it = Players::controllers.begin(); it != Players::controllers.end(); ++it) {
if (it->getAddress() == uEntityPointer) {
Players::controllers.erase(it);
break;
}
}
}
oOnRemoveEntity(CGameEntitySystem, entityPointer, entityHandle);
return;
}
onAddEntity oOnAddEntity = nullptr;
onRemoveEntity oOnRemoveEntity = nullptr;*/

View File

@ -0,0 +1,21 @@
#pragma once
#include "../../hooks/includeHooks.h"
typedef void(__fastcall* onAddEntity)(__int64 CGameEntitySystem, void* entityPointer, int entityHandle);
extern onAddEntity oOnAddEntity;
// @Author: basmannetjeeee
// @IDA:
// Signature: 48 89 74 24 ? 57 48 83 EC ? 48 8B F9 41 8B C0 B9
// __int64 __fastcall sub_651290(__int64 a1, __int64 a2, int a3)
void onAddEntityHook(__int64 CGameEntitySystem, void* entityPointer, int entityHandle);
typedef void(__fastcall* onRemoveEntity)(__int64 CGameEntitySystem, void* entityPointer, int entityHandle);
extern onRemoveEntity oOnRemoveEntity;
// @Author: basmannetjeeee
// @IDA:
// Signature: 48 89 74 24 ? 57 48 83 EC ? 48 8B F9 41 8B C0 25
// __int64 __fastcall sub_651890(__int64 a1, _QWORD *a2, int a3)
void onRemoveEntityHook(__int64 CGameEntitySystem, void* entityPointer, int entityHandle);

View File

@ -0,0 +1,5 @@
#include "players.h"
#include "../offsets/offsets.h"
//@not used anymore
//std::vector<CCSPlayerController> Players::controllers;
//std::vector<C_CSPlayerPawn> Players::pawns;

View File

@ -0,0 +1,8 @@
#pragma once
#include "../../cs2/entity/CCSPlayerController/CCSPlayerController.h"
#include "../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
#include <cstdint>
#include <vector>
//@not used anymore

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
#pragma once
#include "../menu/menu.h"
#include "../features/visuals/visuals.h"
#include "../menu/hud.h"
class Renderer {
public:
Menu menu;
Esp::Visuals visuals;
Hud hud;
};

View File

@ -0,0 +1,48 @@
#include "templeware.h"
#include "utils/module/module.h"
#include <iostream>
#include <fstream>
#include <filesystem>
#include "config/configmanager.h"
void TempleWare::init(HWND& window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11RenderTargetView* mainRenderTargetView) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
auto printWithPrefix = [&](const char* message) {
std::cout << "[";
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::cout << "+";
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
std::cout << "] " << message << std::endl;
};
printWithPrefix("Initializing modules...");
modules.init();
printWithPrefix("Initializing menu...");
renderer.menu.init(window, pDevice, pContext, mainRenderTargetView);
printWithPrefix("Initializing schema...");
schema.init("client.dll", 0);
printWithPrefix("Initializing Interfaces...");
interfaces.init();
printWithPrefix("Initializing visuals...");
renderer.visuals.init();
printWithPrefix("Initializing materials...");
materials.init();
printWithPrefix("Initializing hooks...");
hooks.init();
printWithPrefix("Success...");
// --- Автозагрузка конфига 1.json ---
internal_config::ConfigManager::Load("1");
printWithPrefix("Loaded config: 1.json");
// --- конец автозагрузки ---
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "config/config.h"
#include "hooks/hooks.h"
#include "renderer/renderer.h"
#include "utils/schema/schema.h"
#include "interfaces/interfaces.h"
#include "features/chams/chams.h"
class TempleWare {
public:
void init(HWND& window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, ID3D11RenderTargetView* mainRenderTargetView);
Schema schema;
Renderer renderer;
H::Hooks hooks;
chams::Materials materials;
I::Interfaces interfaces;
};

View File

@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>
// FNV1a c++11 constexpr compile time hash functions, 32 and 64 bit
// str should be a null terminated string literal, value should be left out
// e.g hash_32_fnv1a_const("example")
// code license: public domain or equivalent
// post: https://notes.underscorediscovery.com/constexpr-fnv1a/
constexpr uint32_t val_32_const = 0x811c9dc5;
constexpr uint32_t prime_32_const = 0x1000193;
inline constexpr uint32_t hash_32_fnv1a_const(const char* const str, const uint32_t value = val_32_const) noexcept
{
return (str[0] == '\0') ? value : hash_32_fnv1a_const(&str[1], (value ^ uint32_t(str[0])) * prime_32_const);
}
// life do be like that
#define HASH hash_32_fnv1a_const

Some files were not shown because too many files have changed in this diff Show More