Skip to content
This repository has been archived by the owner on Sep 12, 2021. It is now read-only.

Render, DirectX hooks, ImGui debugger, new input hook #5

Merged
merged 6 commits into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added GitHub/index_preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 24 additions & 2 deletions HM3CoreKill/HM3CoreKill/HM3CoreKill.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetExt>.dll</TargetExt>
<OutDir>Z:\Reverse\Games</OutDir>
<IncludePath>utils/zydis/include;.;$(IncludePath)</IncludePath>
<IncludePath>third_party/ImGUI/examples;third_party/ImGUI;third_party;utils/zydis/include;.;$(IncludePath)</IncludePath>
<LibraryPath>utils/zydis/lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
Expand Down Expand Up @@ -135,16 +135,17 @@
<ClInclude Include="ck\HM3ActionFactory.h" />
<ClInclude Include="ck\HM3CrashHandler.h" />
<ClInclude Include="ck\HM3DebugConsole.h" />
<ClInclude Include="ck\HM3Direct3D.h" />
<ClInclude Include="ck\HM3Function.h" />
<ClInclude Include="ck\HM3Game.h" />
<ClInclude Include="ck\HM3Hooks.h" />
<ClInclude Include="ck\HM3InGameTools.h" />
<ClInclude Include="ck\HM3MemoryProvider.h" />
<ClInclude Include="ck\HM3Offsets.h" />
<ClInclude Include="ck\HM3Player.h" />
<ClInclude Include="ck\HM3ProcessCache.h" />
<ClInclude Include="ck\HM3ScopedProtection.h" />
<ClInclude Include="ck\HM3Types.h" />
<ClInclude Include="ck\HM3VFTableHook.h" />
<ClInclude Include="mp\MP.h" />
<ClInclude Include="sdk\actions\ZLnkAction.h" />
<ClInclude Include="sdk\CTelePortList.h" />
Expand All @@ -155,7 +156,9 @@
<ClInclude Include="sdk\InterfacesProvider.h" />
<ClInclude Include="sdk\ResourceCollection.h" />
<ClInclude Include="sdk\scripting\ZScriptC.h" />
<ClInclude Include="sdk\ZDirect3DDevice.h" />
<ClInclude Include="sdk\ZEngineDatabase.h" />
<ClInclude Include="sdk\ZEntityLocator.h" />
<ClInclude Include="sdk\ZEventBuffer.h" />
<ClInclude Include="sdk\ZGameFunctions.h" />
<ClInclude Include="sdk\ZGeomBuffer.h" />
Expand All @@ -169,12 +172,23 @@
<ClInclude Include="sdk\ZHM3Hitman3.h" />
<ClInclude Include="sdk\ZHM3LevelControl.h" />
<ClInclude Include="sdk\ZHM3MenuElements.h" />
<ClInclude Include="sdk\ZKeyboardWintel.h" />
<ClInclude Include="sdk\ZMouseWintel.h" />
<ClInclude Include="sdk\ZOSD.h" />
<ClInclude Include="sdk\ZRenderWintelD3D.h" />
<ClInclude Include="sdk\ZSTD.h" />
<ClInclude Include="sdk\ZSysFile.h" />
<ClInclude Include="sdk\ZSysInputWintel.h" />
<ClInclude Include="sdk\ZSysInterfaceWintel.h" />
<ClInclude Include="sdk\ZSysMem.h" />
<ClInclude Include="third_party\ImGUI\examples\imgui_impl_dx9.h" />
<ClInclude Include="third_party\ImGUI\examples\imgui_impl_win32.h" />
<ClInclude Include="third_party\ImGUI\imconfig.h" />
<ClInclude Include="third_party\ImGUI\imgui.h" />
<ClInclude Include="third_party\ImGUI\imgui_internal.h" />
<ClInclude Include="third_party\ImGUI\imstb_rectpack.h" />
<ClInclude Include="third_party\ImGUI\imstb_textedit.h" />
<ClInclude Include="third_party\ImGUI\imstb_truetype.h" />
<ClInclude Include="utils\X86Arch.h" />
<ClInclude Include="utils\X86Backend.h" />
<ClInclude Include="utils\X86MemAccessEngine.h" />
Expand All @@ -186,13 +200,21 @@
<ClCompile Include="ck\HM3ActionFactory.cpp" />
<ClCompile Include="ck\HM3CrashHandler.cpp" />
<ClCompile Include="ck\HM3DebugConsole.cpp" />
<ClCompile Include="ck\HM3Direct3D.cpp" />
<ClCompile Include="ck\HM3Game.cpp" />
<ClCompile Include="ck\HM3Hooks.cpp" />
<ClCompile Include="ck\HM3InGameTools.cpp" />
<ClCompile Include="ck\HM3MemoryProvider.cpp" />
<ClCompile Include="ck\HM3Player.cpp" />
<ClCompile Include="ck\HM3ProcessCache.cpp" />
<ClCompile Include="DllEntry.cpp" />
<ClCompile Include="sdk\ZEngineDatabase.cpp" />
<ClCompile Include="third_party\ImGUI\examples\imgui_impl_dx9.cpp" />
<ClCompile Include="third_party\ImGUI\examples\imgui_impl_win32.cpp" />
<ClCompile Include="third_party\ImGUI\imgui.cpp" />
<ClCompile Include="third_party\ImGUI\imgui_demo.cpp" />
<ClCompile Include="third_party\ImGUI\imgui_draw.cpp" />
<ClCompile Include="third_party\ImGUI\imgui_widgets.cpp" />
<ClCompile Include="utils\X86Backend.cpp" />
<ClCompile Include="utils\X86MemAccessEngine.cpp" />
<ClCompile Include="utils\X86MemTools.cpp" />
Expand Down
78 changes: 75 additions & 3 deletions HM3CoreKill/HM3CoreKill/HM3CoreKill.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
<Filter Include="utils">
<UniqueIdentifier>{3b43f60a-4677-4ed3-90de-5b6611177644}</UniqueIdentifier>
</Filter>
<Filter Include="third_party">
<UniqueIdentifier>{3a6aab74-be8f-455c-8711-46c74989c178}</UniqueIdentifier>
</Filter>
<Filter Include="third_party\ImGUI">
<UniqueIdentifier>{511e04c8-c4e2-4298-91e9-44c1d3e1d269}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ck\HM3DebugConsole.h">
Expand Down Expand Up @@ -60,9 +66,6 @@
<ClInclude Include="ck\HM3ScopedProtection.h">
<Filter>ck</Filter>
</ClInclude>
<ClInclude Include="ck\HM3VFTableHook.h">
<Filter>ck</Filter>
</ClInclude>
<ClInclude Include="sdk\ZHM3Hitman3.h">
<Filter>sdk</Filter>
</ClInclude>
Expand Down Expand Up @@ -171,6 +174,51 @@
<ClInclude Include="sdk\ZHM3LevelControl.h">
<Filter>sdk</Filter>
</ClInclude>
<ClInclude Include="sdk\ZEntityLocator.h">
<Filter>sdk</Filter>
</ClInclude>
<ClInclude Include="sdk\ZDirect3DDevice.h">
<Filter>sdk</Filter>
</ClInclude>
<ClInclude Include="ck\HM3Direct3D.h">
<Filter>ck</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\examples\imgui_impl_dx9.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\examples\imgui_impl_win32.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imconfig.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imgui.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imgui_internal.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imstb_rectpack.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imstb_textedit.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="third_party\ImGUI\imstb_truetype.h">
<Filter>third_party\ImGUI</Filter>
</ClInclude>
<ClInclude Include="ck\HM3InGameTools.h">
<Filter>ck</Filter>
</ClInclude>
<ClInclude Include="sdk\ZSysInputWintel.h">
<Filter>sdk</Filter>
</ClInclude>
<ClInclude Include="sdk\ZKeyboardWintel.h">
<Filter>sdk</Filter>
</ClInclude>
<ClInclude Include="sdk\ZMouseWintel.h">
<Filter>sdk</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ck\HM3DebugConsole.cpp">
Expand Down Expand Up @@ -213,5 +261,29 @@
<ClCompile Include="utils\X86Backend.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="ck\HM3Direct3D.cpp">
<Filter>ck</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\examples\imgui_impl_dx9.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\examples\imgui_impl_win32.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\imgui.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\imgui_demo.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\imgui_draw.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="third_party\ImGUI\imgui_widgets.cpp">
<Filter>third_party\ImGUI</Filter>
</ClCompile>
<ClCompile Include="ck\HM3InGameTools.cpp">
<Filter>ck</Filter>
</ClCompile>
</ItemGroup>
</Project>
9 changes: 7 additions & 2 deletions HM3CoreKill/HM3CoreKill/ck/HM3DebugConsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ class HM3DebugConsole
HM3_DEBUG("\n");

#define HM3_ASSERT(condition, message) \
if ((!condition)) { \
if (!(condition)) { \
HM3_DEBUG("%s\n", message); \
assert(false); \
}
}

#define HM3_UNUSED(something) (void)something;

#define HM3_PAUSE __asm { int 3 }
#define HM3_PAUSE_UI() MessageBox(nullptr, "Pause", "Paused", MB_OK);
62 changes: 62 additions & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3Direct3D.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <ck/HM3Direct3D.h>
#include <ck/HM3Function.h>

namespace ck
{
static constexpr const int BeginSceneIndex = 41;
static constexpr const int EndSceneIndex = 42;
static constexpr const int GetDeviceStateIndex = 9;

typedef HRESULT(__stdcall* D3DBeginScene_t)(IDirect3DDevice9*);
typedef HRESULT(__stdcall* D3DEndScene_t)(IDirect3DDevice9*);

D3DBeginScene_t originalBeginSceneFunc;
D3DEndScene_t originalEndSceneFunc;

HRESULT __stdcall Direct3DDevice_OnBeginScene(IDirect3DDevice9* device)
{
HRESULT result = originalBeginSceneFunc(device);

auto callback = HM3Direct3D::getInstance().onBeginScene;
if (callback)
callback(device);

return result;
}

HRESULT __stdcall Direct3DDevice_OnEndScene(IDirect3DDevice9* device)
{
auto callback = HM3Direct3D::getInstance().onEndScene;
if (callback)
callback(device);

auto result = originalEndSceneFunc(device);
HM3Direct3D::getInstance().setupHooksDirectX9Hooks(device); /// D3D can reset their own vftable. We must protect us from M$. They usually do that after EndScene.
return result;
}

HM3Direct3D& HM3Direct3D::getInstance()
{
static HM3Direct3D instance;
return instance;
}

void HM3Direct3D::setupHooksDirectX9Hooks(IDirect3DDevice9* device)
{
auto beginScenePtr = reinterpret_cast<D3DBeginScene_t>(HM3Function::hookVFTable((DWORD)device, BeginSceneIndex, (DWORD)Direct3DDevice_OnBeginScene, false));
auto endScenePtr = reinterpret_cast<D3DEndScene_t>(HM3Function::hookVFTable((DWORD)device, EndSceneIndex, (DWORD)Direct3DDevice_OnEndScene, false));

if ((DWORD)beginScenePtr != (DWORD)&Direct3DDevice_OnBeginScene)
originalBeginSceneFunc = (D3DBeginScene_t)beginScenePtr;

if ((DWORD)endScenePtr != (DWORD)&Direct3DDevice_OnEndScene)
originalEndSceneFunc = (D3DBeginScene_t)endScenePtr;
}

void HM3Direct3D::initialize(IDirect3DDevice9* device)
{
setupHooksDirectX9Hooks(device);
if (onD3DReady)
onD3DReady(device);
}
}
23 changes: 23 additions & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3Direct3D.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <functional>
#include <d3d9.h>

namespace ck
{

class HM3Direct3D
{
public:
static HM3Direct3D& getInstance();
void initialize(IDirect3DDevice9* device);
void setupHooksDirectX9Hooks(IDirect3DDevice9* device);

using CommonCallback = std::function<void(IDirect3DDevice9*)>;

CommonCallback onD3DReady;
CommonCallback onBeginScene;
CommonCallback onEndScene;
};

}
76 changes: 72 additions & 4 deletions HM3CoreKill/HM3CoreKill/ck/HM3Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
*/

namespace vtable_hook {
int vtablehook_unprotect(void* region) {
static int vtablehook_unprotect(void* region) {
#ifdef WIN32
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((LPCVOID)region, &mbi, sizeof(mbi));
Expand All @@ -61,7 +61,7 @@ namespace vtable_hook {
#endif
}

void vtablehook_protect(void* region, int protection) {
static void vtablehook_protect(void* region, int protection) {
#ifdef WIN32
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery((LPCVOID)region, &mbi, sizeof(mbi));
Expand Down Expand Up @@ -328,7 +328,7 @@ class HM3Function
HM3_ASSERT(writtenBytes == chunkSize, "Count of written to new place bytes must be equal to count of required bytes");
}

static void hookVFTable(DWORD instance, DWORD index, DWORD newAddr)
static DWORD hookVFTable(DWORD instance, DWORD index, DWORD newAddr, bool doLog = true)
{
std::intptr_t vftable_ptr = *reinterpret_cast<std::intptr_t*>(instance);
std::intptr_t entity = vftable_ptr + sizeof(std::intptr_t) * index;
Expand All @@ -338,7 +338,75 @@ class HM3Function
*reinterpret_cast<std::intptr_t*>(entity) = static_cast<std::intptr_t>(newAddr);
vtable_hook::vtablehook_protect((void*)entity, original_protection);

HM3_DEBUG(" Override function #%.3d of instance 0x%.8X replace member at 0x%.8X by 0x%.8X\n", index, instance, entity, newAddr);
if (doLog)
HM3_DEBUG(" Override function #%.3d of instance 0x%.8X replace member at 0x%.8X by 0x%.8X\n", index, instance, original_func, newAddr);

return static_cast<DWORD>(original_func);
}

static DWORD hookIAT(const std::string& process, const char* functionName, DWORD to)
{
ProcessHandleCacheController::ProcessCacheRow cacheRow = ProcessHandleCacheController::getProcessHandle(process);
HANDLE pHandle = cacheRow.handle;
HM3_ASSERT(pHandle != 0, "Unable to locate required process!");

/*
Credits : Game Hacking: Developing Autonomous Bots for Online Games
*/

const DWORD DOSMagic = 0x5A4D;
const DWORD OptionalHeaderMagicBytes = 0x10B;

DWORD baseAddr = reinterpret_cast<DWORD>(cacheRow.handle);

auto dosHeader = (IMAGE_DOS_HEADER*)(baseAddr);
if (dosHeader->e_magic != DOSMagic)
{
HM3_DEBUG(" Failed to hook IAT method \"%s\". Bad DOS header magic bytes.\n", functionName);
return 0;
}

auto optHeader = (IMAGE_OPTIONAL_HEADER*)(baseAddr + dosHeader->e_lfanew + 24);
if (optHeader->Magic != OptionalHeaderMagicBytes)
{
HM3_DEBUG(" Failed to hook IAT method \"%s\". Bad optional header magic bytes.\n", functionName);
return 0;
}

auto IAT = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (IAT.Size == 0 || IAT.VirtualAddress == 0)
{
HM3_DEBUG(" Failed to hook IAT method \"%s\". Bad IAT table size.\n", functionName);
return 0;
}

auto impDesc = (IMAGE_IMPORT_DESCRIPTOR*)(baseAddr + IAT.VirtualAddress);

while (impDesc->FirstThunk)
{
auto thunkData = (IMAGE_THUNK_DATA*)(baseAddr + impDesc->OriginalFirstThunk);

int n = 0;

while (thunkData->u1.Function)
{
char* importFuncName = (char*)(baseAddr + (DWORD)thunkData->u1.AddressOfData + 2);

if (strcmp(importFuncName, functionName) == 0)
{
auto vfTable = (DWORD*)(baseAddr + impDesc->FirstThunk);
DWORD original = vfTable[n];
int originalProtection = vtable_hook::vtablehook_unprotect(&vfTable[n]);
vfTable[n] = to;
vtable_hook::vtablehook_protect(&vfTable[n], originalProtection);
HM3_DEBUG(" Hook IAT method \"%s\" 0x%.8X -> 0x%.8X DONE\n", functionName, original, to);
return original;
}
}
}

HM3_DEBUG(" Failed to hook IAT method \"%s\". Function not found in IAT table of process %s\n", functionName, process);
return 0;
}

static void swapInstructions(const std::string& process, DWORD first, DWORD second, const DWORD count)
Expand Down
Loading