diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..da425ea --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/imgui"] + path = ext/imgui + url = https://github.com/iWanheda/imgui.git diff --git a/based.vcxproj b/based.vcxproj index c9c9aad..10b27b5 100644 --- a/based.vcxproj +++ b/based.vcxproj @@ -74,11 +74,15 @@ true $(SolutionDir)build\ $(SolutionDir)build\intermediates\ + $(DXSDK_DIR)Include;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(DXSDK_DIR)Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) false $(SolutionDir)build\ $(SolutionDir)build\intermediates\ + $(DXSDK_DIR)Include;$(VC_IncludePath);$(WindowsSDK_IncludePath); + $(DXSDK_DIR)Lib\x86;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86) true @@ -147,6 +151,13 @@ + + + + + + + @@ -156,10 +167,19 @@ + + + + + + + + + @@ -172,9 +192,11 @@ + + @@ -197,4 +219,4 @@ - \ No newline at end of file + diff --git a/based.vcxproj.filters b/based.vcxproj.filters index faf5daf..474ce67 100644 --- a/based.vcxproj.filters +++ b/based.vcxproj.filters @@ -48,6 +48,30 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + @@ -149,5 +173,35 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/ext/imgui b/ext/imgui new file mode 160000 index 0000000..71bba2a --- /dev/null +++ b/ext/imgui @@ -0,0 +1 @@ +Subproject commit 71bba2ab1e7840bd0e3b9d57214275fea7f1b84c diff --git a/src/core/hooks.cpp b/src/core/hooks.cpp index a830e9a..514412d 100644 --- a/src/core/hooks.cpp +++ b/src/core/hooks.cpp @@ -2,9 +2,13 @@ // include minhook for epic hookage #include "../../ext/minhook/minhook.h" +#include "../gui/cmenu.hpp" #include +// Instance our menu class, perhaps we could use smart pointers? +static CMenu menu; + void hooks::Setup() noexcept { MH_Initialize(); @@ -23,6 +27,20 @@ void hooks::Setup() noexcept reinterpret_cast(&CreateMoveOriginal) ); + // EndScene hook + MH_CreateHook( + memory::Get(interfaces::device, 42), + &EndScene, + reinterpret_cast(&EndSceneOriginal) + ); + + // Reset hook + MH_CreateHook( + memory::Get(interfaces::device, 16), + &Reset, + reinterpret_cast(&ResetOriginal) + ); + MH_EnableHook(MH_ALL_HOOKS); } @@ -70,3 +88,77 @@ bool __stdcall hooks::CreateMove(float frameTime, CUserCmd* cmd) noexcept return false; } + +LONG __stdcall hooks::EndScene(IDirect3DDevice9* device) noexcept +{ + static const auto retAddr = _ReturnAddress(); + const auto result = EndSceneOriginal(device, device); + + if (_ReturnAddress() == retAddr) + return result; + + // This prevents OBS from capturing our ESP/Menu, of course cazz you will not want to have this XD + // You can change this in main.cpp or just click F12 and go to definition +#if CAZZ_BIG_MAN == FALSE + static std::uintptr_t gameOverlayRetAddr = 0; + + if (!gameOverlayRetAddr) + { + MEMORY_BASIC_INFORMATION memInfo; + VirtualQuery(_ReturnAddress(), &memInfo, sizeof(MEMORY_BASIC_INFORMATION)); + + char fileName[MAX_PATH]; + GetModuleFileNameA(reinterpret_cast(memInfo.AllocationBase), fileName, MAX_PATH); + + if (strstr(fileName, "gameoverlay")) + gameOverlayRetAddr = reinterpret_cast(_ReturnAddress()); + } + + if (gameOverlayRetAddr != reinterpret_cast(_ReturnAddress())) + return result; +#endif + + menu.Setup(device); + + ImGui_ImplDX9_NewFrame(); + ImGui_ImplWin32_NewFrame(); + + ImGui::NewFrame(); + + // Exercise: Get Input class and disable game input when the menu is open :D + menu.Render(); + + ImGui::EndFrame(); + + ImGui::Render(); + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + + return result; +} + +HRESULT __stdcall hooks::Reset(IDirect3DDevice9* device, D3DPRESENT_PARAMETERS* params) noexcept +{ + ImGui_ImplDX9_InvalidateDeviceObjects(); + const auto result = ResetOriginal(device, device, params); + ImGui_ImplDX9_CreateDeviceObjects(); + + return result; +} + +WNDPROC oldWindow = reinterpret_cast( + SetWindowLongPtr(FindWindowA("Valve001", nullptr), GWL_WNDPROC, reinterpret_cast(hooks::WndProcess)) +); + +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler( + HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +LRESULT __stdcall hooks::WndProcess(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (GetAsyncKeyState(GUI_KEY) & 1) + menu.Press(); + + if (menu.IsOpen() && ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) + return 1L; + + return CallWindowProc(oldWindow, hWnd, uMsg, wParam, lParam); +} \ No newline at end of file diff --git a/src/core/hooks.h b/src/core/hooks.h index ba4f361..d32255a 100644 --- a/src/core/hooks.h +++ b/src/core/hooks.h @@ -1,6 +1,12 @@ #pragma once #include "interfaces.h" +#include + +#include "../../ext/imgui/imgui.h" +#include "../../ext/imgui/imgui_impl_win32.h" +#include "../../ext/imgui/imgui_impl_dx9.h" + namespace hooks { // call once to emplace all hooks @@ -18,4 +24,17 @@ namespace hooks using CreateMoveFn = bool(__thiscall*)(IClientModeShared*, float, CUserCmd*) noexcept; inline CreateMoveFn CreateMoveOriginal = nullptr; bool __stdcall CreateMove(float frameTime, CUserCmd* cmd) noexcept; + + // EndScene hook for our imgay menu + using EndSceneFn = long(__thiscall*)(void*, IDirect3DDevice9*) noexcept; + inline EndSceneFn EndSceneOriginal = nullptr; + long __stdcall EndScene(IDirect3DDevice9*) noexcept; + + // Reset hook + using ResetFn = HRESULT(__thiscall*)(void*, IDirect3DDevice9*, D3DPRESENT_PARAMETERS*) noexcept; + inline ResetFn ResetOriginal = nullptr; + HRESULT __stdcall Reset(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*) noexcept; + + // WndProc hook + static LRESULT __stdcall WndProcess(HWND, UINT, WPARAM, LPARAM); } diff --git a/src/core/interfaces.cpp b/src/core/interfaces.cpp index bd297c4..663301d 100644 --- a/src/core/interfaces.cpp +++ b/src/core/interfaces.cpp @@ -16,6 +16,7 @@ void interfaces::Setup() noexcept studioRender = Capture("studiorender.dll", "VStudioRender026"); engine = Capture("engine.dll", "VEngineClient014"); modelInfo = Capture("engine.dll", "VModelInfoClient004"); + device = **reinterpret_cast(memory::PatternScan("shaderapidx9.dll", "A1 ? ? ? ? 50 8B 08 FF 51 0C") + 0x1); // get the exported KeyValuesSystem function if (const HINSTANCE handle = GetModuleHandle("vstdlib.dll")) diff --git a/src/core/interfaces.h b/src/core/interfaces.h index c37a51d..7aeaafd 100644 --- a/src/core/interfaces.h +++ b/src/core/interfaces.h @@ -13,6 +13,10 @@ #include "../valve/ivengineclient.h" #include "../valve/ivmodelinfo.h" +#include "../../ext/imgui/imgui.h" +#include "../../ext/imgui/imgui_impl_dx9.h" +#include "../../ext/imgui/imgui_impl_win32.h" + // learn more about interfaces -> https://www.youtube.com/watch?v=C0wGdwnaArA namespace interfaces { @@ -34,6 +38,7 @@ namespace interfaces inline IStudioRender* studioRender = nullptr; inline IVEngineClient* engine = nullptr; inline IVModelInfo* modelInfo = nullptr; + inline IDirect3DDevice9* device = nullptr; // other inline void* keyValuesSystem = nullptr; diff --git a/src/gui/cmenu.cpp b/src/gui/cmenu.cpp new file mode 100644 index 0000000..ee607eb --- /dev/null +++ b/src/gui/cmenu.cpp @@ -0,0 +1,46 @@ +#include "cmenu.hpp" + +void CMenu::Setup(IDirect3DDevice9* device) noexcept +{ + if (!dxSetup) + { + ImGui::CreateContext(); + + ImGui_ImplWin32_Init(FindWindowA("Valve001", nullptr)); + ImGui_ImplDX9_Init(device); + + // Here you can initialize + // textures, fonts, etc... + + dxSetup = true; + } +} + +void CMenu::Render() noexcept +{ + // If the menu isn't open + if (!IsOpen()) return; + + ImGui::SetNextWindowSize(ImVec2(370.f, 420.f)); + ImGui::Begin("based", &guiOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize); + { + // I would make this const but I can't cuz reference :') + static bool cazzAwesome = true; + // This one I'll let you choose + static float cazzDSize = 2; + + ImGui::Checkbox("cazz is fucking awesome", &cazzAwesome); + ImGui::SliderFloat("cazz's d size", &cazzDSize, 2, 45); + } + ImGui::End(); +} + +void CMenu::Press() noexcept +{ + guiOpen = !guiOpen; +} + +bool CMenu::IsOpen() noexcept +{ + return guiOpen; +} \ No newline at end of file diff --git a/src/gui/cmenu.hpp b/src/gui/cmenu.hpp new file mode 100644 index 0000000..7c013b5 --- /dev/null +++ b/src/gui/cmenu.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "../../ext/imgui/imgui.h" +#include "../../ext/imgui/imgui_impl_win32.h" +#include "../../ext/imgui/imgui_impl_dx9.h" + +#include +#include + +inline constexpr std::uint8_t GUI_KEY = VK_INSERT; + +class CMenu +{ +public: + void Setup(IDirect3DDevice9*) noexcept; + void Render() noexcept; + void Press() noexcept; + bool IsOpen() noexcept; + +private: + bool guiOpen = false, + dxSetup = false; +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a10d484..84858a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,8 @@ // expose our cheat to main.cpp #include "core/hooks.h" +#define CAZZ_BIG_MAN FALSE + // setup our cheat & unload it when exit key is pressed DWORD WINAPI Setup(LPVOID lpParam) {