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
163
NOTES.md
163
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 |
|
||||||
|
|--------|------------|----------------------------------|
|
||||||
|
| 0x0000 | `void**` | Virtual Method Table |
|
||||||
|
| 0x0004 | `uint32_t` | Size of Entity Hashtable |
|
||||||
|
| 0x0008 | `void**` | Pointer to Entity Hashtable |
|
||||||
|
| 0x02B8 | `uint32_t` | Number of entity lists |
|
||||||
|
| 0x02BC | `void**` | Pointer to entity list Hashtable |
|
||||||
|
| 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` |
|
||||||
|
|
||||||
| Offset | Type | Description |
|
|
||||||
| ------ | -------- | --------------------------- |
|
|
||||||
| 0x0 | void** | Virtual Method Table |
|
|
||||||
| 0x4 | uint32_t | Size of Entity Hashtable |
|
|
||||||
| 0x8 | void** | Pointer to Entity Hashtable |
|
|
||||||
| 0x330 | float[3] | Time (why 3 times?) |
|
|
||||||
| 0x1c6c | float | Alarm level |
|
|
||||||
| 0x1C68 | float | Alarm Grow Level |
|
|
||||||
|
|
||||||
## 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,24 +54,29 @@ 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));
|
||||||
Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8);
|
Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8);
|
||||||
}
|
}
|
|
@ -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();
|
||||||
hook_d3d8();
|
sscanf(inj, "%d", &INJ_PID);
|
||||||
|
cout << INJ_PID << "," << PPID() << endl;
|
||||||
|
if (PPID() == INJ_PID) {
|
||||||
|
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…
Reference in New Issue