#define OSHGUI_COMPILE_STATIC
#include "../../OSHGui.hpp"
#include "../../Drawing/RendererDX9.hpp"
#include "../../Input/Windows.hpp"
using namespace OSHGui;
//---------------------------------------------------------------------------
DWORD FindPattern(const HMODULE module, const BYTE *pattern, LPCTSTR mask);
void* DetourFunction(BYTE *source, const BYTE *destination, const int length);
typedef HRESULT (WINAPI *oEndScene)(LPDIRECT3DDEVICE9 pDevice);
oEndScene pEndScene = nullptr;
//---------------------------------------------------------------------------
//global vars
//---------------------------------------------------------------------------
Input::Windows input;
Drawing::RendererDX9 *renderer;
HHOOK messageHookHandle;
//---------------------------------------------------------------------------
LRESULT CALLBACK KeyboardHook(int code, WPARAM wParam, LPARAM lParam)
{
if (lParam & 0x80000000 || lParam & 0x40000000)
{
return CallNextHookEx(messageHookHandle, code, wParam, lParam);
}
if (code == HC_ACTION)
{
if(input.ProcessMessage((LPMSG)lParam))
{
return true;
}
}
return CallNextHookEx(messageHookHandle, code, wParam, lParam);
}
//---------------------------------------------------------------------------
HRESULT WINAPI hook_EndScene(LPDIRECT3DDEVICE9 pDevice)
{
Application *app = Application::Instance();
static bool initGui = true;
if (initGui)
{
initGui = false;
renderer = new Drawing::RendererDX9(pDevice);
app->Create(renderer);
messageHookHandle = SetWindowsHookExW(WH_GETMESSAGE, KeyboardHook, 0, GetCurrentThreadId());
app->Run(std::shared_ptr<Form>(new Form()));
app->Enable();
}
renderer->Begin();
app->Render();
renderer->End();
return pEndScene(pDevice);
}
//---------------------------------------------------------------------------
bool WINAPI DllMain(HMODULE hDll, DWORD dwReason, PVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hDll);
HMODULE d3d9 = NULL;
for (; !(d3d9 = GetModuleHandle("d3d9.dll")); Sleep(100));
DWORD device = FindPattern(d3d9, (BYTE*)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx") + 2;
DWORD *VTable = NULL;
memcpy(&VTable, (void*)device, 4);
pEndScene = (oEndScene)DetourFunction((BYTE*)VTable[42], (BYTE*)hook_EndScene, 5);
}
return true;
}
//---------------------------------------------------------------------------
//Utils
//---------------------------------------------------------------------------
bool DataCompare(const BYTE *data, const BYTE *pattern, LPCTSTR mask)
{
for (; *mask; ++mask, ++data, ++pattern)
{
if (*mask == 'x' && *data != *pattern)
{
return false;
}
}
return *mask == 0;
}
//---------------------------------------------------------------------------
DWORD FindPattern(const HMODULE module, const BYTE *pattern, LPCTSTR mask)
{
if (module == NULL || module == INVALID_HANDLE_VALUE)
{
throw Misc::ArgumentNullException("module");
}
PIMAGE_DOS_HEADER dosHeader =(PIMAGE_DOS_HEADER)module;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
throw Misc::Exception("e_magic != IMAGE_DOS_SIGNATURE");
}
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + (DWORD)dosHeader->e_lfanew);
if (NTHead->Signature != IMAGE_NT_SIGNATURE)
{
throw Misc::Exception("Signature != IMAGE_NT_SIGNATURE");
}
DWORD address = (DWORD)module + NTHead->OptionalHeader.BaseOfCode;
DWORD size = NTHead->OptionalHeader.SizeOfCode;
for (DWORD i = NULL; i < size; i++)
{
if (DataCompare((BYTE*)(address + i), pattern, mask))
{
return address + i;
}
}
return NULL;
}
//---------------------------------------------------------------------------
void* DetourFunction(BYTE *source, const BYTE *destination, const int length)
{
BYTE *trampolin = (BYTE*)malloc(5 + length);
DWORD dwback;
VirtualProtect(trampolin, length + 5, PAGE_EXECUTE_READWRITE, &dwback);
VirtualProtect(source, length, PAGE_EXECUTE_READWRITE, &dwback);
memcpy(trampolin, source, length);
trampolin += length;
trampolin[0] = 0xE9;
*(DWORD*)(trampolin + 1) = (DWORD)(source + length - trampolin) - 5;
source[0] = 0xE9;
*(DWORD*)(source + 1) = (DWORD)(destination - source) - 5;
for (int i = 5; i < length; i++)
{
source[i] = 0x90;
}
return trampolin - length;
}
//---------------------------------------------------------------------------