forked from ReScrap/ScrapHacks
		
	Update NOTES and README
Fix DX8 hooking bug in ScrapHacks, deinitialize everything properly by hooking `Scrap.Exit`
This commit is contained in:
		
							parent
							
								
									3a9ab54240
								
							
						
					
					
						commit
						4b6f9c520f
					
				
					 10 changed files with 279 additions and 92 deletions
				
			
		
							
								
								
									
										157
									
								
								NOTES.md
									
										
									
									
									
								
							
							
						
						
									
										157
									
								
								NOTES.md
									
										
									
									
									
								
							|  | @ -9,14 +9,14 @@ | ||||||
| * `:<Var>`: Get Game Engine Global Variable | * `:<Var>`: Get Game Engine Global Variable | ||||||
| * `:<Var> <Val>`: Set Game Engine Global Variable | * `:<Var> <Val>`: Set Game Engine Global Variable | ||||||
| * `?`: Show all Global Variable | * `?`: Show all Global Variable | ||||||
| * `?<String>`: Show all Global Variable matching <String> | * `?<String>`: Show all Global Variable matching `<String>` | ||||||
| * `/<command>`: Run Command defined in QuickConsole.py(c) 'import quickconsole;quickconsole.%s()' | * `/<command>`: Run Command defined in `QuickConsole.py`: `import quickconsole;quickconsole.%s()` | ||||||
| * `/<command> <arg>,<arg>`: Run function in QuickConsole.py(c) with argument(s) 'import quickconsole;quickconsole.%s(%s)' | * `/<command> <arg>,<arg>`: Run function in `QuickConsole.py` with argument(s) `import quickconsole;quickconsole.%s(%s)` | ||||||
| 
 | 
 | ||||||
| ## External Console (Scenegraph Debugging?) (Handler@0x5f9520): | ## External Console (Scenegraph Debugging?) (Handler@0x5f9520): | ||||||
| * `listar luces` | * `listar luces` | ||||||
| * `listar` | * `listar` | ||||||
| * `arbol` (Patch Scrap.exe@offset 0x314bc9 replace 0x20 with 0x00 (or just type `arbol ` with the space at the end)) | * `arbol` (Patch Scrap.exe@offset 0x314bc9 replace 0x20 with 0x00 (or just type `arbol ` with a space at the end)) | ||||||
| * `mem` | * `mem` | ||||||
| * `ver uniones` | * `ver uniones` | ||||||
| * Easter Eggs: | * Easter Eggs: | ||||||
|  | @ -29,7 +29,7 @@ | ||||||
| - InitPyMod @ 0x5A8FB0 | - InitPyMod @ 0x5A8FB0 | ||||||
| - PyExec @ 0x5A8390 | - PyExec @ 0x5A8390 | ||||||
| 
 | 
 | ||||||
| # Other Functions: | ## Other Functions: | ||||||
| 
 | 
 | ||||||
| - FindEntity @ 0x404a50 | - FindEntity @ 0x404a50 | ||||||
| - HashTable hashfunc @ 0x404bb0 | - HashTable hashfunc @ 0x404bb0 | ||||||
|  | @ -47,46 +47,74 @@ | ||||||
| - SM3 Scene Loader @ 0x650f80 (?) | - SM3 Scene Loader @ 0x650f80 (?) | ||||||
| - M3D Model Loader @ 0x6665a0 (??) | - M3D Model Loader @ 0x6665a0 (??) | ||||||
| - World_Init @ 0x479b20 (???) | - World_Init @ 0x479b20 (???) | ||||||
|  | - World_DeInit @ 0x402510 | ||||||
| 
 | 
 | ||||||
| # Data Structures | # Data Structures | ||||||
| 
 | 
 | ||||||
| ## Game World/State Pointer @ 0x7fe944 | ## Game World/State Pointer @ `0x7fe944` | ||||||
| 
 | 
 | ||||||
| Points to GameState struct | Points to World struct | ||||||
| 
 | 
 | ||||||
| | Offset | Type       | Description                      | | | Offset | Type       | Description                      | | ||||||
| | ------ | -------- | --------------------------- | | |--------|------------|----------------------------------| | ||||||
| | 0x0    | void**   | Virtual Method Table        | | | 0x0000 | `void**`   | Virtual Method Table             | | ||||||
| | 0x4    | uint32_t | Size of Entity Hashtable    | | | 0x0004 | `uint32_t` | Size of Entity Hashtable         | | ||||||
| | 0x8    | void**   | Pointer to Entity Hashtable | | | 0x0008 | `void**`   | Pointer to Entity Hashtable      | | ||||||
| | 0x330  | float[3] | Time (why 3 times?)         | | | 0x02B8 | `uint32_t` | Number of entity lists           | | ||||||
| | 0x1c6c | float    | Alarm level                 | | | 0x02BC | `void**`   | Pointer to entity list Hashtable | | ||||||
| | 0x1C68 | float    | Alarm Grow Level            | | | 0x0330 | `float[3]` | Time (why 3 times?)              | | ||||||
|  | | 0x1C6C | `float`    | Alarm level                      | | ||||||
|  | | 0x1C68 | `float`    | Alarm Grow Level                 | | ||||||
|  | | 0x2158 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2170 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2180 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2188 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x218C | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2190 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2198 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x219C | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x21A0 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x21B4 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x21C8 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2204 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2230 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2238 | `???`      | Used in `World_Init`             | | ||||||
|  | | 0x2254 | `???`      | Used in `World_Init`             | | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| ## Entity Hash Table | ## Entity Hash Table | ||||||
| 
 | 
 | ||||||
| Hashfunction used: [PJW](https://en.wikipedia.org/wiki/PJW_hash_function) (Same parameters as the example implementation) | Hash-function used: [PJW](https://en.wikipedia.org/wiki/PJW_hash_function) (Same parameters as the example implementation) | ||||||
| 
 | 
 | ||||||
| Entry format: | Entry format: | ||||||
| 
 | 
 | ||||||
| | Offset | Type          | Description                    | | | Offset | Type          | Description                    | | ||||||
| | ------ | ----------- | ------------------------------ | | |--------|---------------|--------------------------------| | ||||||
| | 0x0    | void*       | Pointer to data                | | | 0x0    | `void*`       | Pointer to data                | | ||||||
| | 0x4    | const char* | key as string                  | | | 0x4    | `const char*` | key as `char*`                 | | ||||||
| | 0x8    | void*       | Pointer to next entry in chain | | | 0x8    | `void*`       | Pointer to next entry in chain | | ||||||
| 
 | 
 | ||||||
| Data format: | Data format: | ||||||
| 
 | 
 | ||||||
| | Offset | Type          | Description              | | | Offset | Type          | Description              | | ||||||
| | ------ | ----------- | -------------------- | | |--------|---------------|--------------------------| | ||||||
| | 0x0    | void**      | Virtual Method Table | | | 0x0    | `void**`      | Virtual Method Table (?) | | ||||||
| | 0x4    | const char* | name as string       | | | 0x4    | `const char*` | name as string           | | ||||||
| | 0x14   | void*       | pointer to self      | | | 0x14   | `void*`       | pointer to self (why?)   | | ||||||
| | 0x28   | float[3]    | Position             | | | 0x28   | `float[3]`    | Position in Game World   | | ||||||
|  | 
 | ||||||
|  | ## Game Window Object (?) Pointer @ `0x7fa380` | ||||||
|  | 
 | ||||||
|  | | Offset | Type          | Description          | | ||||||
|  | |--------|---------------|----------------------| | ||||||
|  | | 0x0000 | `void**`      | Virtual Method Table | | ||||||
|  | | 0x0004 | `const char*` | Some Model Name (?)  | | ||||||
|  | | 0x0008 | `void*`       | Pointer to something | | ||||||
|  | | 0x000C | `void*`       | Ditto                | | ||||||
| 
 | 
 | ||||||
| # File Formats | # File Formats | ||||||
| 
 | 
 | ||||||
| ## *.packed File Format: | ## .packed File Format: | ||||||
| ``` | ``` | ||||||
| Header: | Header: | ||||||
|     "BFPK\0\0\0\0" |     "BFPK\0\0\0\0" | ||||||
|  | @ -98,19 +126,24 @@ Header: | ||||||
|         Int32ul: offset in file |         Int32ul: offset in file | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ## Loading Custom Content (not really working) | ## Loading Custom Content (not really working) | ||||||
| 1. Create a folder `mods` | 1. Create a folder `mods` | ||||||
| 2. Drop a `*.packed` file into it | 2. Drop a `*.packed` file into it | ||||||
|  | 3. Change `Scrap.cfg` as follows | ||||||
|  |    1. Add `ModPathName = mods` | ||||||
|  |    2. Add `ModFileName = <filename>` | ||||||
| 
 | 
 | ||||||
| ## Interesting file: | ## Interesting file: | ||||||
| * m3d.ini: Rendering Engine Configuration | * `m3d.ini`: Rendering Engine Configuration | ||||||
| * scripts/: Game Engine Scripts | * `scripts/`: Game Engine Scripts | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # How to enable External Console: | # How to enable External Console: | ||||||
| 1. exctract `Data.packed` | 1. exctract `Data.packed` | ||||||
| 2. in m3d.ini uncomment (remove `;`) "ConsolaWnd" (GUI Console) or "ConsolaTxt" (Text Console) and set the value to "SI" | 2. in m3d.ini uncomment (remove `;`) `ConsolaWnd` (GUI Console) and/or `ConsolaTxt` (Text Console) and set the value to `SI` | ||||||
| 3. repack "Data.packed" | 3. repack `Data.packed` | ||||||
| 
 | 
 | ||||||
| or right click on the title bar (in windowed mode) and click "Switch Console" | or right click on the title bar (in windowed mode) and click "Switch Console" | ||||||
| 
 | 
 | ||||||
|  | @ -118,3 +151,69 @@ or Use a custom Content Pack (**untested!**) | ||||||
| 
 | 
 | ||||||
| # Misc. Interesting things | # Misc. Interesting things | ||||||
| - sys.path contains "./lib" so you can load your own Python Modules | - sys.path contains "./lib" so you can load your own Python Modules | ||||||
|  | 
 | ||||||
|  | # Code Snippets | ||||||
|  | 
 | ||||||
|  | ## [Kaitai Struct](http://kaitai.io/) Parser for .packed files | ||||||
|  | ```yaml | ||||||
|  | meta: | ||||||
|  |   id: packed | ||||||
|  |   application: Scrapland | ||||||
|  |   file-extension: packed | ||||||
|  |   endian: le | ||||||
|  |   xref: http://wiki.xentax.com/index.php/Scrapland_PACKED | ||||||
|  |   license: MIT | ||||||
|  |   encoding: UTF-8 | ||||||
|  | seq: | ||||||
|  |   - id: magic | ||||||
|  |     contents: BFPK | ||||||
|  |     doc: File Magic | ||||||
|  |   - id: magic2 | ||||||
|  |     contents: [0,0,0,0] | ||||||
|  |     doc: Second File Magic | ||||||
|  |   - id: num_files | ||||||
|  |     type: u4 | ||||||
|  |     doc: Number of files | ||||||
|  |   - id: files | ||||||
|  |     type: file_entry | ||||||
|  |     repeat: expr | ||||||
|  |     repeat-expr: num_files | ||||||
|  |     doc: Directory entry for each file | ||||||
|  | types: | ||||||
|  |   file_entry: | ||||||
|  |     seq: | ||||||
|  |       - id: path_len | ||||||
|  |         type: u4 | ||||||
|  |         doc: Length of file path | ||||||
|  |       - id: path | ||||||
|  |         type: str | ||||||
|  |         size: path_len | ||||||
|  |         doc: File path | ||||||
|  |       - id: size | ||||||
|  |         type: u4 | ||||||
|  |         doc: File size | ||||||
|  |       - id: offset | ||||||
|  |         type: u4 | ||||||
|  |         doc: Absoulte File offset | ||||||
|  |     instances: | ||||||
|  |       data: | ||||||
|  |         pos: offset | ||||||
|  |         size: size | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Hashfunction used in Entity Hash-Table | ||||||
|  | 
 | ||||||
|  | ```c | ||||||
|  | unsigned long ElfHash(const unsigned char *s) | ||||||
|  | { | ||||||
|  |     unsigned long h = 0, high; | ||||||
|  |     while ( *s ) | ||||||
|  |     { | ||||||
|  |         h = ( h << 4 ) + *s++; | ||||||
|  |         if ( high = h & 0xF0000000 ) | ||||||
|  |             h ^= high >> 24; | ||||||
|  |         h &= ~high; | ||||||
|  |     } | ||||||
|  |     return h; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | @ -24,6 +24,7 @@ WIP Memory hacking library | ||||||
| # Tools used: | # Tools used: | ||||||
| 
 | 
 | ||||||
| - [Python 3](https://python.org/) + [Construct](https://construct.readthedocs.io/en/latest/) | - [Python 3](https://python.org/) + [Construct](https://construct.readthedocs.io/en/latest/) | ||||||
| - [IDA](https://www.hex-rays.com/products/ida/index.shtml) and [x32dbg](https://x64dbg.com/#start) | - [IDA](https://www.hex-rays.com/products/ida/index.shtml) and [x32dbg](https://x64dbg.com/) | ||||||
| - [Reclass.NET](https://github.com/ReClassNET/ReClass.NET) | - [Reclass.NET](https://github.com/ReClassNET/ReClass.NET) | ||||||
| - [HxD](https://mh-nexus.de/en/hxd/) | - [HxD](https://mh-nexus.de/en/hxd/) | ||||||
|  | - [Kaitai Struct](http://kaitai.io/) | ||||||
|  | @ -226,6 +226,10 @@ int main(int argc, char *argv[]) | ||||||
| 	HANDLE hProc = INVALID_HANDLE_VALUE; | 	HANDLE hProc = INVALID_HANDLE_VALUE; | ||||||
| 	HANDLE hThread = INVALID_HANDLE_VALUE; | 	HANDLE hThread = INVALID_HANDLE_VALUE; | ||||||
| 	DWORD PID = 0; | 	DWORD PID = 0; | ||||||
|  | 	char s_PID[MAX_PATH]; | ||||||
|  | 	snprintf(s_PID, MAX_PATH, "%d", GetCurrentProcessId()); | ||||||
|  | 	SetEnvironmentVariable("Inj_PID", s_PID); | ||||||
|  | 	cout << "[*] Injector PID: " << GetCurrentProcessId() << endl; | ||||||
| 	if ((argc>1)&&fexists(argv[1])) { | 	if ((argc>1)&&fexists(argv[1])) { | ||||||
| 		cout << "[*] Spawning process for \"" << argv[1] << "\"" << endl; | 		cout << "[*] Spawning process for \"" << argv[1] << "\"" << endl; | ||||||
| 		vector<HANDLE> handles = spawn(argv[1]); | 		vector<HANDLE> handles = spawn(argv[1]); | ||||||
|  | @ -254,6 +258,7 @@ int main(int argc, char *argv[]) | ||||||
| 	if (hThread != INVALID_HANDLE_VALUE) { | 	if (hThread != INVALID_HANDLE_VALUE) { | ||||||
| 		while (ResumeThread(hThread)); | 		while (ResumeThread(hThread)); | ||||||
| 	} | 	} | ||||||
|  | 	SetEnvironmentVariable("Inj_PID", NULL); | ||||||
| 	cout << "[*] Done!" << endl; | 	cout << "[*] Done!" << endl; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
|     <ProjectGuid>{7C91C225-D95C-4B7A-9251-0CE358BAF556}</ProjectGuid> |     <ProjectGuid>{7C91C225-D95C-4B7A-9251-0CE358BAF556}</ProjectGuid> | ||||||
|     <Keyword>Win32Proj</Keyword> |     <Keyword>Win32Proj</Keyword> | ||||||
|     <RootNamespace>Injector</RootNamespace> |     <RootNamespace>Injector</RootNamespace> | ||||||
|     <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> |     <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||||
|  |  | ||||||
|  | @ -9,60 +9,44 @@ bool overlay = false; | ||||||
| LPD3DXFONT m_pFont; | LPD3DXFONT m_pFont; | ||||||
| HFONT hFont; | HFONT hFont; | ||||||
| HBRUSH hBrush; | HBRUSH hBrush; | ||||||
| D3DCOLOR color = D3DCOLOR_XRGB(255, 0, 0); | D3DCOLOR color = D3DCOLOR_ARGB(255,255, 0, 0); | ||||||
| RECT Rect = { 0,0,0,0 }; | RECT Rect = { 0,0,0,0 }; | ||||||
| D3DRECT panel; | D3DRECT panel; | ||||||
| 
 | 
 | ||||||
| void Render(LPDIRECT3DDEVICE8 dev) { | LPDIRECT3DDEVICE8 Render(LPDIRECT3DDEVICE8 dev) { | ||||||
| 	if (!overlay) { | 	if (!overlay) { | ||||||
| 		return; | 		return dev; | ||||||
| 	} | 	} | ||||||
| 	char text[MAX_PATH]; | 	char text[1024]; | ||||||
| 	snprintf(text, MAX_PATH, "Frame: [%lld]\nTest", ++frame); | 	snprintf(text, 1024, "ScrapHack v0.1\nFrame: [%lld]", ++frame); | ||||||
| 	if (m_pFont == nullptr) { | 	if (m_pFont == nullptr) { | ||||||
| 		D3DXCreateFont(dev, hFont, &m_pFont); | 		D3DXCreateFont(dev, hFont, &m_pFont); | ||||||
| 		CloseHandle(hFont); | 		CloseHandle(hFont); | ||||||
| 	} | 	} | ||||||
| 	m_pFont->Begin(); | 	m_pFont->Begin(); | ||||||
| 	m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); | 	m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); | ||||||
| 	 |  | ||||||
| 	dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(25, 0, 0, 0),0.5,0); |  | ||||||
| 	 |  | ||||||
| 	m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); | 	m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); | ||||||
| 	m_pFont->End(); | 	m_pFont->End(); | ||||||
|  | 	return dev; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) { | HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) { | ||||||
| 	typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8); | 	typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8); | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_EndScene); | 	shared_ptr<Hook> hook = Hook::get(H_EndScene); | ||||||
| 	_asm push esi; | 	return hook->func<t_func>(Render(dev)); | ||||||
| 	_asm pushad; |  | ||||||
| 	Render(dev); |  | ||||||
| 	hook->disable(); |  | ||||||
| 	HRESULT ret = hook->func<t_func>()(dev); |  | ||||||
| 	hook->enable(); |  | ||||||
| 	_asm popad; |  | ||||||
| 	_asm pop esi; |  | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT WINAPI H_CreateDevice(void* pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, | HRESULT WINAPI H_CreateDevice(void* pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, | ||||||
| 	unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, | 	unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, | ||||||
| 	LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) { | 	LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) { | ||||||
| 	_asm push esi; |  | ||||||
| 	_asm pushad; |  | ||||||
| 	typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*); | 	typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*); | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_CreateDevice); | 	shared_ptr<Hook> hook = Hook::get(H_CreateDevice); | ||||||
| 	hook->disable(); | 	HRESULT ret = hook->func<t_func>(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); | ||||||
| 	HRESULT ret = hook->func<t_func>()(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); |  | ||||||
| 	cout << "CreateDevice -> " << ret << endl; | 	cout << "CreateDevice -> " << ret << endl; | ||||||
| 	void* EndScene = reinterpret_cast<void*>(GetVTable(ppReturnedDeviceInterface[0])[35]); | 	void* EndScene = reinterpret_cast<void*>(GetVTable(ppReturnedDeviceInterface[0])[35]); | ||||||
| 	cout << "EndScene @ " << EndScene << endl; // EndScene
 | 	cout << "EndScene @ " << EndScene << endl; // EndScene
 | ||||||
| 	Hook::addr(EndScene, H_EndScene); | 	Hook::addr(EndScene, H_EndScene); | ||||||
| 	Hook::drop(H_CreateDevice); | 	Hook::drop(H_CreateDevice); | ||||||
| 	_asm popad; |  | ||||||
| 	_asm pop esi; |  | ||||||
| 
 |  | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -70,22 +54,27 @@ LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) { | ||||||
| 	typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int); | 	typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int); | ||||||
| 	shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8); | 	shared_ptr<Hook> hook = Hook::get(H_Direct3DCreate8); | ||||||
| 	 | 	 | ||||||
| 	_asm push esi; | 	LPDIRECT3D8 ret = hook->func<t_func>(SDKVersion); | ||||||
| 	_asm pushad; |  | ||||||
| 
 |  | ||||||
| 	hook->disable(); |  | ||||||
| 	LPDIRECT3D8 ret = hook->func<t_func>()(SDKVersion); |  | ||||||
| 	cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; | 	cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; | ||||||
| 	void *CreateDevice = reinterpret_cast<void*>(GetVTable(ret)[15]); | 	void *CreateDevice = reinterpret_cast<void*>(GetVTable(ret)[15]); | ||||||
|  | 	void *Release = reinterpret_cast<void*>(GetVTable(ret)[2]); | ||||||
| 	cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice
 | 	cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice
 | ||||||
| 	Hook::addr(CreateDevice, H_CreateDevice); | 	Hook::addr(CreateDevice, H_CreateDevice); | ||||||
| 	Hook::drop(H_Direct3DCreate8); | 	Hook::drop(H_Direct3DCreate8); | ||||||
| 	_asm popad; |  | ||||||
| 	_asm pop esi; |  | ||||||
| 	 | 	 | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void unhook_d3d8() { | ||||||
|  | 	if (hFont != INVALID_HANDLE_VALUE) { | ||||||
|  | 		CloseHandle(hFont); | ||||||
|  | 	} | ||||||
|  | 	if (m_pFont != nullptr) { | ||||||
|  | 		m_pFont->Release(); | ||||||
|  | 	} | ||||||
|  | 	Hook::drop(H_EndScene); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void hook_d3d8() { | void hook_d3d8() { | ||||||
| 	hFont = CreateFont(20, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); | 	hFont = CreateFont(20, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); | ||||||
| 	hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0)); | 	hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0)); | ||||||
|  |  | ||||||
|  | @ -99,9 +99,16 @@ public: | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	template<typename T> | 	void* get_orig() { | ||||||
| 	T func() { | 		return this->orig; | ||||||
| 		return reinterpret_cast<T>(this->orig); | 	} | ||||||
|  | 
 | ||||||
|  | 	template<typename F,typename ...Args> | ||||||
|  | 	decltype(auto) func(Args... args) { | ||||||
|  | 		disable(); | ||||||
|  | 		auto ret=reinterpret_cast<F>(this->orig)(args...); | ||||||
|  | 		enable(); | ||||||
|  | 		return ret; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,15 +31,18 @@ bool initialized = false; | ||||||
| bool running = true; | bool running = true; | ||||||
| HMODULE mod = 0; | HMODULE mod = 0; | ||||||
| 
 | 
 | ||||||
| void dump_ht(HashTable* ht) { | void DllUnload(HMODULE); | ||||||
|  | void hook_exit(); | ||||||
|  | 
 | ||||||
|  | size_t dump_ht(HashTable<EntityList>* ht) { | ||||||
| 	size_t cnt = 0; | 	size_t cnt = 0; | ||||||
| 	for (size_t i = 0; i < ht->size; ++i) { | 	for (size_t i = 0; i < ht->size; ++i) { | ||||||
| 		HashTableEntry* ent = ht->chains[i]; | 		HashTableEntry<EntityList>* ent = ht->chains[i]; | ||||||
| 		if (ent != NULL) { | 		if (ent) { | ||||||
| 			cout << i << ": "; | 			cout << i << ": "; | ||||||
| 			while (ent != NULL) { | 			while (ent) { | ||||||
| 				++cnt; | 				++cnt; | ||||||
| 				cout << ent->name; | 				cout << "[ " << ent->name << ": " << ent->data << "]"; | ||||||
| 				if (ent->next) { | 				if (ent->next) { | ||||||
| 					cout << " -> "; | 					cout << " -> "; | ||||||
| 				}; | 				}; | ||||||
|  | @ -48,13 +51,35 @@ void dump_ht(HashTable* ht) { | ||||||
| 			cout << endl; | 			cout << endl; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	cout << cnt << " Entities" << endl; | 	cout << cnt << " Entries" << endl; | ||||||
| 	return; | 	return cnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | size_t dump_ht(HashTable<Entity>* ht) { | ||||||
|  | 	size_t cnt = 0; | ||||||
|  | 	for (size_t i = 0; i < ht->size; ++i) { | ||||||
|  | 		HashTableEntry<Entity>* ent = ht->chains[i]; | ||||||
|  | 		if (ent) { | ||||||
|  | 			cout << i << ": "; | ||||||
|  | 			while (ent) { | ||||||
|  | 				++cnt; | ||||||
|  | 				cout << "[ " << ent->name << ": " << ent->data<<"]"; | ||||||
|  | 				if (ent->next) { | ||||||
|  | 					cout << " -> "; | ||||||
|  | 				}; | ||||||
|  | 				ent = ent->next; | ||||||
|  | 			} | ||||||
|  | 			cout << endl; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	cout << cnt << " Entries" << endl; | ||||||
|  | 	return cnt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MainLoop(HMODULE mod) | void MainLoop(HMODULE mod) | ||||||
| { | { | ||||||
| 	Sleep(100); | 	Sleep(100); | ||||||
|  | 	hook_exit(); | ||||||
| 	cout << "[*] Starting main Loop" << endl; | 	cout << "[*] Starting main Loop" << endl; | ||||||
| 	cout << endl; | 	cout << endl; | ||||||
| 	cout << "[F3 ] Unload ScrapHacks" << endl; | 	cout << "[F3 ] Unload ScrapHacks" << endl; | ||||||
|  | @ -107,8 +132,10 @@ void MainLoop(HMODULE mod) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (key_down_norepeat(VK_F9)) { | 		if (key_down_norepeat(VK_F9)) { | ||||||
| 			HashTable *ht = ptr<HashTable>(P_WORLD,O_HASHTABLE); | 			cout << "Entities:" << endl; | ||||||
| 			dump_ht(ht); | 			dump_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS)); | ||||||
|  | 			cout << "Entity Lists:" << endl; | ||||||
|  | 			dump_ht(ptr<HashTable<EntityList>>(P_WORLD, O_ENTLISTS)); | ||||||
| 		} | 		} | ||||||
| 		if (key_down_norepeat(VK_F10)) | 		if (key_down_norepeat(VK_F10)) | ||||||
| 		{ | 		{ | ||||||
|  | @ -140,9 +167,7 @@ int hooked_console(const char* cmd) { | ||||||
| 		handle_command(++cmd); | 		handle_command(++cmd); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	hook->disable(); | 	int ret= hook->func<t_func>(cmd); | ||||||
| 	int ret= hook->func<t_func>()(cmd); |  | ||||||
| 	hook->enable(); |  | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -150,14 +175,62 @@ void hook_console() { | ||||||
| 	Hook::addr(reinterpret_cast<void*>(P_CON_HANDLER) , hooked_console); | 	Hook::addr(reinterpret_cast<void*>(P_CON_HANDLER) , hooked_console); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void H_Exit(){ | ||||||
|  | 	typedef void(_cdecl *t_func)(void); | ||||||
|  | 	shared_ptr<Hook> hook = Hook::get(H_Exit); | ||||||
|  | 	DllUnload(mod); | ||||||
|  | 	hook->disable(); | ||||||
|  | 	HWND hMainWindow = ptr<HWND>(0x7FA830, 0x7c)[0]; | ||||||
|  | 	SendMessage(hMainWindow, WM_CLOSE, 0, 0); | ||||||
|  | 	return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void hook_exit() { | ||||||
|  | 	//void* p_exit = ptr<void*>(0x7fa830,0x0, 0x20);
 | ||||||
|  | 	Hook::addr(reinterpret_cast<void*>(0x4010c0), H_Exit); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DWORD PPID() { | ||||||
|  | 	DWORD PID = GetCurrentProcessId(); | ||||||
|  | 	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | ||||||
|  | 	PROCESSENTRY32 procentry; | ||||||
|  | 	if (hSnapShot == INVALID_HANDLE_VALUE) { | ||||||
|  | 		cout << GetLastErrorAsString() << endl; | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 	if (Process32First(hSnapShot, &procentry)) { | ||||||
|  | 		do { | ||||||
|  | 			if (procentry.th32ProcessID == PID) { | ||||||
|  | 				CloseHandle(hSnapShot); | ||||||
|  | 				return procentry.th32ParentProcessID; | ||||||
|  | 			} | ||||||
|  | 			procentry.dwSize = sizeof(PROCESSENTRY32); | ||||||
|  | 		} while (Process32Next(hSnapShot, &procentry)); | ||||||
|  | 	} | ||||||
|  | 	CloseHandle(hSnapShot); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void DllPreInit(HMODULE _mod) { | void DllPreInit(HMODULE _mod) { | ||||||
| 	char mfn[1024]; | 	char mfn[1024]; | ||||||
|  | 	char inj[MAX_PATH]; | ||||||
|  | 	DWORD INJ_PID=0; | ||||||
| 	InitConsole(); | 	InitConsole(); | ||||||
| 	GetModuleFileName(0, mfn, 1024); | 	GetModuleFileName(0, mfn, 1024); | ||||||
| 	Py = get_modules(P_PY_MODS); | 	Py = get_modules(P_PY_MODS); | ||||||
| 	cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << endl; | 	cout << "[+] ScrapHacks v0.1 Loaded in " << mfn << " (PID: " << std::hex << GetCurrentProcessId() <<std::dec << ")" << endl; | ||||||
|  | 	GetEnvironmentVariable("Inj_PID", inj, MAX_PATH); | ||||||
|  | 	SetEnvironmentVariable("Inj_PID", NULL); | ||||||
| 	hook_console(); | 	hook_console(); | ||||||
|  | 	sscanf(inj, "%d", &INJ_PID); | ||||||
|  | 	cout << INJ_PID << "," << PPID() << endl; | ||||||
|  | 	if (PPID() == INJ_PID) { | ||||||
| 		hook_d3d8(); | 		hook_d3d8(); | ||||||
|  | 		overlay = true; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		cout << "[-] No launched by Injector, not hooking DX8" << endl; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void DllInit(HMODULE _mod) | void DllInit(HMODULE _mod) | ||||||
|  | @ -182,10 +255,11 @@ void DllInit(HMODULE _mod) | ||||||
| 
 | 
 | ||||||
| void DllUnload(HMODULE _mod) { | void DllUnload(HMODULE _mod) { | ||||||
| 	SetConsoleCtrlHandler(NULL, false); | 	SetConsoleCtrlHandler(NULL, false); | ||||||
|  | 	unhook_d3d8(); | ||||||
| 	Hook::clear(); | 	Hook::clear(); | ||||||
| 	scrap_log(0xff0000, "ScrapHacks unloaded!\n"); | 	scrap_log(0xff0000, "ScrapHacks unloaded!\n"); | ||||||
| 	cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl; | 	cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl; | ||||||
| 	FreeConsole(); | 	FreeConsole(); | ||||||
| 	PostQuitMessage(0); | 	DestroyWindow(GetConsoleWindow()); | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
|     <ProjectGuid>{72CB1B9E-50C7-4010-BEAD-82FACF87A87A}</ProjectGuid> |     <ProjectGuid>{72CB1B9E-50C7-4010-BEAD-82FACF87A87A}</ProjectGuid> | ||||||
|     <Keyword>Win32Proj</Keyword> |     <Keyword>Win32Proj</Keyword> | ||||||
|     <RootNamespace>ScrapHack</RootNamespace> |     <RootNamespace>ScrapHack</RootNamespace> | ||||||
|     <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> |     <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||||
|  |  | ||||||
|  | @ -4,7 +4,8 @@ | ||||||
| #define O_MONEY 0x2090 | #define O_MONEY 0x2090 | ||||||
| #define O_ALARM 0x1C6C | #define O_ALARM 0x1C6C | ||||||
| #define O_ALARM_GROW 0x1C68 | #define O_ALARM_GROW 0x1C68 | ||||||
| #define O_HASHTABLE 0x4 | #define O_ENTS 0x4 | ||||||
|  | #define O_ENTLISTS 0x2b8 | ||||||
| 
 | 
 | ||||||
| //POINTERS
 | //POINTERS
 | ||||||
| #define P_WORLD 0x7FE944 | #define P_WORLD 0x7FE944 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #pragma once | #pragma once | ||||||
|  | template<typename T> | ||||||
| struct HashTableEntry; | struct HashTableEntry; | ||||||
| struct Vector3 { | struct Vector3 { | ||||||
| 	float x; | 	float x; | ||||||
|  | @ -34,17 +35,27 @@ struct Module | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct Entity { | struct Entity { | ||||||
| 	void* VMT; | 	void* vmt; | ||||||
| 
 | 	const char* name; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct EntityList { | ||||||
|  | 	const char* name; | ||||||
|  | 	void* unk_1; | ||||||
|  | 	void* unk_2; | ||||||
|  | 	const char* mod; | ||||||
|  | 	const char* func; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
| struct HashTable { | struct HashTable { | ||||||
| 	uint32_t size; | 	uint32_t size; | ||||||
| 	HashTableEntry** chains; | 	HashTableEntry<T>** chains; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | template<typename T> | ||||||
| struct HashTableEntry { | struct HashTableEntry { | ||||||
| 	Entity* data; | 	T* data; | ||||||
| 	const char* name; | 	const char* name; | ||||||
| 	HashTableEntry* next; | 	HashTableEntry* next; | ||||||
| }; | }; | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue