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…
	
	Add table
		Add a link
		
	
		Reference in a new issue