Added D3D8 EndScene hooking (which currently crashes the game after some time)
This commit is contained in:
parent
7cf3ab8580
commit
efba0894c4
9 changed files with 193 additions and 37 deletions
4
ScrapHacks/.gitignore
vendored
4
ScrapHacks/.gitignore
vendored
|
@ -258,4 +258,6 @@ paket-files/
|
|||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyc
|
||||
|
||||
ScrapHack/dx8/
|
11
ScrapHacks/.vscode/settings.json
vendored
Normal file
11
ScrapHacks/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"spellright.language": [
|
||||
"de",
|
||||
"en"
|
||||
],
|
||||
"spellright.documentTypes": [
|
||||
"markdown",
|
||||
"latex",
|
||||
"plaintext"
|
||||
]
|
||||
}
|
|
@ -2,9 +2,14 @@
|
|||
|
||||
## Usage
|
||||
|
||||
0. Build Project
|
||||
1. Run Injector `.\Injector.exe`
|
||||
2. Run Game
|
||||
0. Download `DirectX.8.0a.SDK.zip` from [here](https://archive.org/download/DirectX.8.0a.SDK_includes_libs_only)
|
||||
1. Extract `DirectX.SDK/8.0/include` and `DirectX.SDK/8.0/lib` to `ScrapHacks/ScrapHack/dx8/include` and `ScrapHacks/ScrapHack/dx8/lib`
|
||||
2. Add include and library dirs to project
|
||||
3. Build Project
|
||||
4. Run Injector `.\Injector.exe <Path to Scrap.exe>`
|
||||
5. Wait for game to crash
|
||||
6. Comment out `hook_d3d8()` call in `ScrapHack.cpp:DllPreInit()`
|
||||
7. Rebuild and run Injector again
|
||||
|
||||
```
|
||||
[F3 ] Unload ScrapHacks
|
||||
|
|
76
ScrapHacks/ScrapHack/D3D8_Hook.h
Normal file
76
ScrapHacks/ScrapHack/D3D8_Hook.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
uintmax_t frame = 0;
|
||||
DWORD* GetVTable(void* addr) {
|
||||
return (DWORD*)(*(DWORD*)addr);
|
||||
}
|
||||
|
||||
void Render(LPDIRECT3DDEVICE8 dev) {
|
||||
char text[MAX_PATH];
|
||||
LPD3DXFONT m_pFont;
|
||||
HFONT hFont;
|
||||
RECT Rect={0,0,0,0};
|
||||
D3DCOLOR color = D3DCOLOR_XRGB(255, 0, 0);
|
||||
hFont = CreateFont(50, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana");
|
||||
D3DXCreateFont(dev, hFont, &m_pFont);
|
||||
snprintf(text, MAX_PATH, "Frame: %d", ++frame);
|
||||
if (m_pFont) {
|
||||
m_pFont->Begin();
|
||||
m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0);
|
||||
m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color);
|
||||
m_pFont->End();
|
||||
m_pFont->Release();
|
||||
m_pFont = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) {
|
||||
typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8);
|
||||
shared_ptr<Hook> hook = Hook::get(H_EndScene);
|
||||
t_func func = reinterpret_cast<t_func>(hook->func());
|
||||
Render(dev);
|
||||
hook->disable();
|
||||
HRESULT ret = func(dev);
|
||||
hook->enable();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
HRESULT WINAPI H_CreateDevice(void* pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow,
|
||||
unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
|
||||
LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) {
|
||||
typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*);
|
||||
shared_ptr<Hook> hook = Hook::get(H_CreateDevice);
|
||||
t_func func = reinterpret_cast<t_func>(hook->func());
|
||||
hook->disable();
|
||||
HRESULT ret = func(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
|
||||
cout << "Ret:" << ret << endl;
|
||||
DWORD *vtable = GetVTable(ppReturnedDeviceInterface[0]);
|
||||
cout << "Dev VTable @ " << vtable << endl;
|
||||
cout << "Dev VTable[35]: " << (void*)(vtable[35]) << endl; // EndScene
|
||||
Hook::addr((void*)vtable[35], H_EndScene);
|
||||
Hook::drop(H_CreateDevice);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) {
|
||||
typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int);
|
||||
shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8);
|
||||
t_func func = reinterpret_cast<t_func>(hook->func());
|
||||
hook->disable();
|
||||
D3DPRESENT_PARAMETERS D3D_Present_Param = { 0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,D3DSWAPEFFECT_DISCARD,0,1,0,D3DFMT_UNKNOWN,0,0,0 };
|
||||
LPDIRECT3D8 ret = func(SDKVersion);
|
||||
cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl;
|
||||
DWORD *vtable = GetVTable(ret);
|
||||
cout << "ID3D8 VTable @ " << vtable << endl;
|
||||
cout << "ID3D8 VTable[15]: " << (void*)(vtable[15]) << endl; // CreateDevice
|
||||
Hook::addr((void*)vtable[15], reinterpret_cast<void*>(H_CreateDevice));
|
||||
Hook::drop(H_Direct3DCreate8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hook_d3d8() {
|
||||
Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8);
|
||||
}
|
|
@ -2,18 +2,19 @@
|
|||
#include <functional>
|
||||
class Hook;
|
||||
|
||||
map<uintptr_t, shared_ptr<Hook>> hooks;
|
||||
|
||||
class Hook {
|
||||
class Hook
|
||||
{
|
||||
private:
|
||||
DWORD protect;
|
||||
void* orig;
|
||||
void* detour;
|
||||
bool enabled;
|
||||
uint8_t orig_bytes[6];
|
||||
uint8_t jmp_bytes[6];
|
||||
static map<uintptr_t, shared_ptr<Hook>> hooks;
|
||||
|
||||
public:
|
||||
Hook(void* func, void* detour) {
|
||||
cout << "Hooking: " << func << " -> " << detour << endl;
|
||||
uintptr_t dest = reinterpret_cast<uintptr_t>(detour);
|
||||
uintptr_t src = reinterpret_cast<uintptr_t>(func);
|
||||
this->orig = func;
|
||||
|
@ -26,25 +27,77 @@ public:
|
|||
this->jmp_bytes[5] = 0xC3; // ret
|
||||
VirtualProtect(func, 16, PAGE_EXECUTE_READWRITE, &(this->protect));
|
||||
memcpy(this->orig_bytes, this->orig, 1 + 4 + 1);
|
||||
memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1);
|
||||
hooks[src]=shared_ptr<Hook>(this);
|
||||
}
|
||||
|
||||
~Hook() {
|
||||
cout << "Unhooking: " << this->detour << " -> " << this->orig << endl;
|
||||
uintptr_t src = reinterpret_cast<uintptr_t>(this->orig);
|
||||
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
|
||||
VirtualProtect(func, 16, this->protect, NULL);
|
||||
this->enabled = false;
|
||||
}
|
||||
|
||||
~Hook() {
|
||||
this->disable();
|
||||
}
|
||||
|
||||
static void addr(void* addr, void* detour) {
|
||||
cout << "Hooking: [" << addr << " -> " << detour <<"]" << endl;
|
||||
uintptr_t key = reinterpret_cast<uintptr_t>(detour);
|
||||
hooks[key] = make_shared<Hook>(addr,detour);
|
||||
hooks[key]->enable();
|
||||
}
|
||||
|
||||
static void module(const char* mod, const char* func, void* detour) {
|
||||
cout << "Hooking: [" << mod<<"]."<<func << " -> " << detour << endl;
|
||||
void* addr = GetProcAddress(GetModuleHandle(mod), func);
|
||||
if (addr != NULL) {
|
||||
Hook::addr(addr, detour);
|
||||
}
|
||||
else {
|
||||
cerr << "[" << mod << "]." << func << " not found!" << endl;
|
||||
};
|
||||
}
|
||||
|
||||
static shared_ptr<Hook> get(void* func) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(func);
|
||||
return Hook::get(addr);
|
||||
}
|
||||
|
||||
static shared_ptr<Hook> get(uintptr_t addr) {
|
||||
return hooks.at(addr);
|
||||
}
|
||||
|
||||
static size_t drop(void* func) {
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(func);
|
||||
return Hook::drop(addr);
|
||||
}
|
||||
|
||||
static size_t drop(uintptr_t addr) {
|
||||
return hooks.erase(addr);
|
||||
}
|
||||
|
||||
static void clear() {
|
||||
return hooks.clear();
|
||||
}
|
||||
|
||||
|
||||
void disable() {
|
||||
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
|
||||
if (enabled) {
|
||||
//cout << "Disabling: [" << this->orig << " <- " << this->detour << "]" << endl;
|
||||
VirtualProtect(this->orig, 16, PAGE_EXECUTE_READWRITE, NULL);
|
||||
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
|
||||
VirtualProtect(this->orig, 16, this->protect, NULL);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
void enable() {
|
||||
memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1);
|
||||
if (!enabled) {
|
||||
//cout << "Enabling: [" << this->orig << " -> " << this->detour << "]" << endl;
|
||||
VirtualProtect(this->orig, 16, PAGE_EXECUTE_READWRITE, NULL);
|
||||
memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1);
|
||||
VirtualProtect(this->orig, 16, this->protect, NULL);
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void* func() {
|
||||
return this->orig;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
map<uintptr_t, shared_ptr<Hook>> Hook::hooks;
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#include <functional>
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#pragma comment(lib, "d3d8.lib")
|
||||
#pragma comment(lib, "d3dx8.lib")
|
||||
#pragma comment(lib, "legacy_stdio_definitions.lib")
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "Scrapland.h"
|
||||
|
@ -17,8 +22,7 @@ using namespace std;
|
|||
#include "Structures.h"
|
||||
#include "Py_Utils.h"
|
||||
#include "Hook.h"
|
||||
|
||||
#define SIZE 6
|
||||
#include "D3D8_Hook.h"
|
||||
|
||||
HMODULE hD3D8Dll = 0;
|
||||
|
||||
|
@ -32,6 +36,7 @@ void MainLoop(HMODULE mod)
|
|||
cout << "[*] Starting main Loop" << endl;
|
||||
cout << endl;
|
||||
cout << "[F3 ] Unload ScrapHacks" << endl;
|
||||
cout << "[F6 ] Show Alarm status" << endl;
|
||||
cout << "[F7 ] Set Money to 0x7fffffff" << endl;
|
||||
cout << "[F8 ] Dump python modules" << endl;
|
||||
cout << "[F10] Enable python tracing" << endl;
|
||||
|
@ -50,17 +55,13 @@ void MainLoop(HMODULE mod)
|
|||
}
|
||||
if (key_down_norepeat(VK_F6))
|
||||
{
|
||||
/*
|
||||
int32_t* alarm = reinterpret_cast<int32_t*>(ptr(WORLD, { 0x1C6C }));
|
||||
int16_t* alarm = reinterpret_cast<int16_t*>(ptr(WORLD, { 0x1C6C }));
|
||||
*/
|
||||
|
||||
float* alarm = ptr<float>(P_WORLD, O_ALARM);
|
||||
float* alarm_grow = ptr<float>(P_WORLD, O_ALARM_GROW);
|
||||
cout << "Alarm: " << alarm[0] << " + " << alarm_grow[0] << endl;
|
||||
}
|
||||
if (key_down_norepeat(VK_F7))
|
||||
{
|
||||
/*==========================
|
||||
mov ecx, [7FE944h]
|
||||
mov edx, [ecx + 2090h]
|
||||
==========================*/
|
||||
int32_t *money = ptr<int32_t>(P_WORLD,O_MONEY);
|
||||
*money = 0x7fffffff;
|
||||
}
|
||||
|
@ -80,7 +81,7 @@ void MainLoop(HMODULE mod)
|
|||
}
|
||||
}
|
||||
SetConsoleCtrlHandler(NULL, false);
|
||||
hooks.clear();
|
||||
Hook::clear();
|
||||
scrap_log(0xff0000, "ScrapHacks unloaded!\n");
|
||||
cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl;
|
||||
FreeConsole();
|
||||
|
@ -103,9 +104,9 @@ void handle_command(const char* cmd) {
|
|||
return;
|
||||
}
|
||||
|
||||
int my_console(const char* cmd) {
|
||||
int hooked_console(const char* cmd) {
|
||||
typedef int(_cdecl *t_func)(const char*);
|
||||
shared_ptr<Hook> hook = hooks[P_CON_HANDLER];
|
||||
shared_ptr<Hook> hook = Hook::get(hooked_console);
|
||||
t_func func= reinterpret_cast<t_func>(hook->func());
|
||||
if (cmd[0] == '$') {
|
||||
handle_command(++cmd);
|
||||
|
@ -118,7 +119,7 @@ int my_console(const char* cmd) {
|
|||
}
|
||||
|
||||
void hook_console() {
|
||||
new Hook(reinterpret_cast<void*>(P_CON_HANDLER) , my_console);
|
||||
Hook::addr(reinterpret_cast<void*>(P_CON_HANDLER) , hooked_console);
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,10 +128,9 @@ void DllPreInit(HMODULE _mod) {
|
|||
InitConsole();
|
||||
GetModuleFileName(0, mfn, 1024);
|
||||
Py = get_modules(P_PY_MODS);
|
||||
hD3D8Dll = GetModuleHandle("d3d8.dll");
|
||||
cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << endl;
|
||||
cout << "[*] D3D8 DLL @0x" << hD3D8Dll << endl;
|
||||
hook_console();
|
||||
hook_d3d8();
|
||||
}
|
||||
|
||||
void DllInit(HMODULE _mod)
|
||||
|
|
|
@ -72,14 +72,16 @@
|
|||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)dx8\include;$(SolutionDir)include</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)dx8\lib;$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)dx8\include;$(SolutionDir)include</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)dx8\lib;$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -129,6 +131,7 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -150,6 +153,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="D3D8_Hook.h" />
|
||||
<ClInclude Include="Hook.h" />
|
||||
<ClInclude Include="Py_Utils.h" />
|
||||
<ClInclude Include="Structures.h" />
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
<ClInclude Include="Hook.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="D3D8_Hook.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
//OFFSETS
|
||||
#define O_MONEY 0x2090
|
||||
#define O_ALARM 0x1C6C
|
||||
#define O_ALARM_GROW 0x1C68
|
||||
|
||||
//POINTERS
|
||||
#define P_WORLD 0x7FE944
|
||||
|
|
Loading…
Reference in a new issue