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

Commit

Permalink
Bugfixes
Browse files Browse the repository at this point in the history
Fixed bug with mouse input (for now mouse input is working)
Fixed few bugs with D3D init logic

TODO:
 * Implement D3D::Release hook
 * Implement debug menu

Resolves #7
  • Loading branch information
DronCode committed Feb 5, 2020
1 parent eb7af01 commit 08f2586
Show file tree
Hide file tree
Showing 11 changed files with 365 additions and 23 deletions.
5 changes: 4 additions & 1 deletion HM3CoreKill/HM3CoreKill/ck/HM3DebugConsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ class HM3DebugConsole
assert(false); \
}

#define HM3_UNUSED(something) (void)something;
#define HM3_UNUSED(something) (void)something;

#define HM3_PAUSE __asm { int 3 }
#define HM3_PAUSE_UI() MessageBox(nullptr, "Pause", "Paused", MB_OK);
11 changes: 6 additions & 5 deletions HM3CoreKill/HM3CoreKill/ck/HM3Direct3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ 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 WINAPI Direct3DDevice_OnBeginScene(IDirect3DDevice9* device)
HRESULT __stdcall Direct3DDevice_OnBeginScene(IDirect3DDevice9* device)
{
HRESULT result = originalBeginSceneFunc(device);

Expand All @@ -23,14 +24,14 @@ namespace ck
return result;
}

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

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

Expand All @@ -40,7 +41,7 @@ namespace ck
return instance;
}

void HM3Direct3D::setupHooks(IDirect3DDevice9* device)
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));
Expand All @@ -54,7 +55,7 @@ namespace ck

void HM3Direct3D::initialize(IDirect3DDevice9* device)
{
setupHooks(device);
setupHooksDirectX9Hooks(device);
if (onD3DReady)
onD3DReady(device);
}
Expand Down
2 changes: 1 addition & 1 deletion HM3CoreKill/HM3CoreKill/ck/HM3Direct3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ namespace ck

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

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

Expand Down
29 changes: 25 additions & 4 deletions HM3CoreKill/HM3CoreKill/ck/HM3Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void HM3Game::fixEnableCheats()
void HM3Game::setupD3DDeviceCreationHook()
{
HM3Function::hookFunction<void(__stdcall*)(DWORD), 10>(
HM3_PROCESS_NAME,
HM3_PROCESS_NAME,
HM3Offsets::ZDirect3DDevice_ConstructorFunc,
(DWORD)ZDirect3DDevice_OnDeviceReady,
// pre
Expand All @@ -163,9 +163,27 @@ void HM3Game::setupD3DDeviceCreationHook()
});
HM3_DEBUG("[Setup ZDirect3DDevice hook]\n");

ck::HM3Direct3D::getInstance().onD3DReady = std::bind(&HM3Game::onD3DInitialized, this, std::placeholders::_1);
ck::HM3Direct3D::getInstance().onBeginScene = std::bind(&HM3Game::onD3DBeginScene, this, std::placeholders::_1);
ck::HM3Direct3D::getInstance().onEndScene = std::bind(&HM3Game::onD3DEndScene, this, std::placeholders::_1);
const DWORD addr = 0x0045007C;

HM3Function::hookFunction<void(__stdcall*)(DWORD), 5>(
HM3_PROCESS_NAME,
addr,
(DWORD)OnZMouseWintelCreated,
// pre
{
x86_pushad,
x86_pushfd,
x86_push_eax
},
// post
{
x86_popfd,
x86_popad
});

ck::HM3Direct3D::getInstance().onD3DReady = std::bind(&HM3Game::onD3DInitialized, this, std::placeholders::_1);
ck::HM3Direct3D::getInstance().onBeginScene = std::bind(&HM3Game::onD3DBeginScene, this, std::placeholders::_1);
ck::HM3Direct3D::getInstance().onEndScene = std::bind(&HM3Game::onD3DEndScene, this, std::placeholders::_1);
}

bool __stdcall Stub(DWORD ecx, bool someFlag)
Expand Down Expand Up @@ -212,6 +230,9 @@ void HM3Game::setupInputWatcher()
{
HM3Function::overrideInstruction(HM3_PROCESS_NAME, HM3Offsets::ZHM3RegisterWindowClassExA_Func, { x86_nop, x86_nop, x86_nop, x86_nop, x86_nop, x86_nop });
HM3Function::hookFunction<bool(__stdcall*)(const WNDCLASSEXA*), 6>(HM3_PROCESS_NAME, HM3Offsets::ZHM3RegisterWindowClassExA_Func, (DWORD)RegisterClassExA_Hooked, {}, {});

HM3Function::overrideInstruction(HM3_PROCESS_NAME, 0x00453EC6, { x86_nop, x86_nop, x86_nop, x86_nop, x86_nop, x86_nop });
HM3Function::hookFunction<HWND(__stdcall*)(DWORD dwExStyle, LPCSTR, LPCSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID), 6>(HM3_PROCESS_NAME, 0x00453EC6, (DWORD)CreateWindowExA_Hooked, {}, {});
}

void HM3Game::setupDoesPlayerAcceptDamage()
Expand Down
70 changes: 60 additions & 10 deletions HM3CoreKill/HM3CoreKill/ck/HM3Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <sdk/ZGameDataFactory.h>
#include <ck/HM3InGameTools.h>

#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <windowsx.h>
#include <d3d9.h>

Expand All @@ -22,17 +24,10 @@ LRESULT WINAPI Glacier_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
if (ck::HM3InGameTools::getInstance().processEvent(hWnd, msg, wParam, lParam))
return true;

const bool glacierResult = glacierWndProc(hWnd, msg, wParam, lParam);
if (msg == WM_ACTIVATE)
return 0;

if (
msg == WM_LBUTTONUP || msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK ||
msg == WM_RBUTTONUP || msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK ||
msg == WM_MBUTTONUP || msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK ||
msg == WM_MOUSEMOVE || msg == WM_MOUSEACTIVATE || msg == WM_MOUSEWHEEL
)
{
HM3_DEBUG("MOUSE EVENT\n");
}
const bool glacierResult = glacierWndProc(hWnd, msg, wParam, lParam);

return glacierResult; //if glacier returns false we must ignore that event
}
Expand All @@ -44,6 +39,24 @@ ATOM __stdcall RegisterClassExA_Hooked(WNDCLASSEXA* wndClass)
return RegisterClassExA(wndClass);
}

HWND __stdcall CreateWindowExA_Hooked(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam)
{
HWND result = CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
return result;
}

int __stdcall ZHM3Player_DoesPlayerAcceptAnyDamage(void* pThis)
{
HM3_DEBUG("ZHM3Player_DoesPlayerAcceptAnyDamage| ZHitman3 vftable instance at 0x%X", pThis);
Expand Down Expand Up @@ -79,4 +92,41 @@ void __stdcall ZDirect3DDevice_OnDeviceReady(ioi::hm3::ZDirect3DDevice* device)

ck::HM3Direct3D::getInstance().initialize(device->m_d3dDevice);
HM3_DEBUG(" D3D9 Hooked\n");
}

/// --------------------------------------------------------------------------------
#include <sdk/ZMouseWintel.h>
#include <sdk/ZSysInputWintel.h>

DWORD originalMember = 0x0;

DWORD __stdcall ZMouseWintel_OnUpdate()
{
DWORD result = false;
ioi::hm3::ZSysInputWintel* input = ioi::hm3::getGlacierInterface<ioi::hm3::ZSysInputWintel>(ioi::hm3::WintelInput);
ioi::hm3::ZMouseWintel* mouse = input->m_mouseDevice;

__asm {
mov ecx, mouse
call [originalMember]
mov result, eax
}

{
ck::HM3InGameTools& instance = ck::HM3InGameTools::getInstance();

instance.setMouseButtonState(0, mouse->m_leftButton);
instance.setMouseButtonState(1, mouse->m_rightButton);
instance.setMouseWheelState(mouse->m_wheel);
}

__asm mov ecx, mouse
return result;
}

void __stdcall OnZMouseWintelCreated(DWORD device)
{
HM3_DEBUG("ZMouseWintel created at 0x%.8X\n", device);

originalMember = HM3Function::hookVFTable(device, 26, (DWORD)ZMouseWintel_OnUpdate, true);
}
18 changes: 17 additions & 1 deletion HM3CoreKill/HM3CoreKill/ck/HM3Hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@

ATOM __stdcall RegisterClassExA_Hooked(WNDCLASSEXA* wndClass);

HWND __stdcall CreateWindowExA_Hooked(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);

/***
Bugs:
***/
Expand All @@ -20,4 +34,6 @@ void __stdcall ZGEOM_Ctor_CALLBACK(DWORD ptr);

void __stdcall ZPlayer_Constructor(DWORD instance);

void __stdcall ZDirect3DDevice_OnDeviceReady(ioi::hm3::ZDirect3DDevice* device);
void __stdcall ZDirect3DDevice_OnDeviceReady(ioi::hm3::ZDirect3DDevice* device);

void __stdcall OnZMouseWintelCreated(DWORD device);
21 changes: 20 additions & 1 deletion HM3CoreKill/HM3CoreKill/ck/HM3InGameTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,15 @@ namespace ck
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
}

bool HM3InGameTools::processEvent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
bool result = ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam);

if (msg == WM_KEYUP && static_cast<uint32_t>(wParam) == VK_F3)
{
toggleVisibility();
}

return result;
}
Expand All @@ -85,4 +87,21 @@ namespace ck
{
m_isVisible = !m_isVisible;
}

bool HM3InGameTools::isVisible() const
{
return m_isVisible;
}

void HM3InGameTools::setMouseButtonState(int button, bool state)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseDown[button] = state;
}

void HM3InGameTools::setMouseWheelState(int value)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheel += static_cast<float>(value) / static_cast<float>(WHEEL_DELTA);
}
}
3 changes: 3 additions & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3InGameTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace ck
void draw();
bool processEvent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void toggleVisibility();
bool isVisible() const;
void setMouseButtonState(int button, bool state);
void setMouseWheelState(int value);
};

}
51 changes: 51 additions & 0 deletions HM3CoreKill/HM3CoreKill/sdk/CIngameMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include <cstdint>
#include <sdk/MathCommon.h>

#define DECLARE_UNKNOWN_TYPE_PTR(name) using name = std::uintptr_t;

namespace ioi { namespace hm3 {

DECLARE_UNKNOWN_TYPE_PTR(ZWINDOW);
DECLARE_UNKNOWN_TYPE_PTR(ZActionMapTree);

class CMapIconDraw;

class CIngameMap
{
public:
char pad_0000[36]; //0x0000
ZWINDOW* m_UIWindow; //0x0024 [ZWINDOW]
char pad_0028[144]; //0x0028
ZActionMapTree* m_actionsTree; //0x00B8 [ZActionMapTree]
char pad_00BC[276]; //0x00BC
CMapIconDraw* m_iconDraw; //0x01D0
char pad_01D4[180]; //0x01D4
Vector2 m_mapOffset; //0x0288
char pad_0290[12]; //0x0290
bool m_isInDragProcess; //0x029C
char pad_029D[11]; //0x029D
bool m_isShowing; //0x02A8
char pad_02A9[3]; //0x02A9
int32_t m_currentPage; //0x02AC
char pad_02B0[32]; //0x02B0
}; //Size: 0x02D0

class CMapIconDraw
{
public:
char pad_0000[16]; //0x0000
int8_t N00000981; //0x0010
char pad_0011[3]; //0x0011
int8_t N00000982; //0x0014
char pad_0015[3]; //0x0015
int8_t N00000983; //0x0018
char pad_0019[3]; //0x0019
Vector3 m_position; //0x001C
char pad_0028[480]; //0x0028
}; //Size: 0x0208

}}

#undef DECLARE_UNKNOWN_TYPE_PTR
Loading

0 comments on commit 08f2586

Please sign in to comment.