Lots of changes (expand to read more)
- Update NOTES with new findings - Add Cutter link to README - Add ASMJIT, ASMTK and Zydis to CMake - Make DX8 setting cofigurable via ScrapHacks REPL - Add scaffolding for build hook trampolines using asmjit - Add on the fly assembling of code to REPL - Clean up command structure - Add memory RWX to REPL - Add stack dumping to REPL - Add Gamevar dumping to REPL - Add hook check to overlay commands (don't work if DX8 not hooked) - Allow nested command definitions for cleaner REPL - AllocConsole() as early as possible - shuffle some code around for cleanup - Add GameVar, PakEntry and HashIndex structures
This commit is contained in:
parent
48bf3773c9
commit
7e044f0114
20 changed files with 1607 additions and 760 deletions
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
@ -6,5 +6,9 @@
|
|||
"markdown",
|
||||
"latex",
|
||||
"plaintext"
|
||||
]
|
||||
],
|
||||
"files.associations": {
|
||||
"xstring": "cpp",
|
||||
"iterator": "cpp"
|
||||
}
|
||||
}
|
210
NOTES.md
210
NOTES.md
|
@ -1,4 +1,5 @@
|
|||
# Infos
|
||||
|
||||
- Engine: ScrapEngine
|
||||
- Ingame Scripting Language: Python 1.5.2
|
||||
|
||||
|
@ -9,7 +10,8 @@
|
|||
|
||||
# Functions identified:
|
||||
|
||||
## Ingame-Console (Ctrl+\^ or right click on titlebar and select "switch console") (Handler@0x402190):
|
||||
## Ingame-Console (Ctrl+\^ or right click on titlebar and select "switch console") (Handler@`0x402190`):
|
||||
|
||||
* `<Command>`: Try to evaluate Command as Python expression
|
||||
* `:<Var>`: Get Game Engine Global Variable
|
||||
* `:<Var> <Val>`: Set Game Engine Global Variable
|
||||
|
@ -18,7 +20,8 @@
|
|||
* `/<command>`: Run Command defined in `QuickConsole.py`: `import quickconsole;quickconsole.%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`
|
||||
* `arbol` (Patch Scrap.exe@offset 0x314bc9 replace 0x20 with 0x00 (or just type `arbol ` with a space at the end))
|
||||
|
@ -30,36 +33,114 @@
|
|||
* `capullo`
|
||||
|
||||
## Python Stuff
|
||||
- Modules List @ 0x79C698 (Module Name as `char*` followed by Pointer to Init Function)
|
||||
- InitPyMod @ 0x5A8FB0
|
||||
- PyExec @ 0x5A8390
|
||||
|
||||
- `0x79C698`: Modules List (Module Name as `char*` followed by Pointer to Init Function)
|
||||
- `0x5A8FB0`: InitPyMod
|
||||
- `0x5A8390`: PyExec
|
||||
|
||||
## Other interesting Memory Addresses
|
||||
|
||||
- `0x852914`: D3D8-Device pointer
|
||||
- `0x7FCC00`: number of opened `.packed` files
|
||||
- `0x84cb64`: pointer to console command handler
|
||||
- `0x7fac84`: pointer to C++ callback list structure
|
||||
- `0x80b2cc`: pointer to ActionClassList (???)
|
||||
- `0x807a20`: pointer to SScorer (ingame GUI/Menu/Text system) structure (???)
|
||||
- `0x80a398`: pointer to SoundSystem (???)
|
||||
- `0x8b18f0`: pointer to Models Data (can be dumped using scenegraph debugging console)
|
||||
- `0x8b18f4`: pointer to Scenes Data (can be dumped using scenegraph debugging console)
|
||||
- `0x8b18f8`: pointer to active Models Data (can be dumped using scenegraph debugging console)
|
||||
|
||||
## Hash-function used in Hash-Tables
|
||||
|
||||
```c
|
||||
unsigned long hash(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;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Other Functions:
|
||||
|
||||
- FindEntity @ 0x404a50
|
||||
- HashTable hashfunc @ 0x404bb0
|
||||
- Register C Callback @ 0x404460
|
||||
- Load Game @ 0x417470
|
||||
- File opening functions @ 0x5e3800 and 0x419950
|
||||
- Scrap_Debug_Init @ 0x403370
|
||||
- Scrap_Init @ 0x401770
|
||||
- Scrap_InitPy @ 0x4026d0
|
||||
- Scrap_OpenPak @ 0x41ab50
|
||||
- PyExec @ 0x5a8390
|
||||
- Setup_Game_Var @ 0x414570
|
||||
- Throw_Assertion @ 0x5fbc50
|
||||
- m3d.ini loader @ 0x5f7000
|
||||
- SM3 Scene Loader @ 0x650f80 (?)
|
||||
- M3D Model Loader @ 0x6665a0 (??)
|
||||
- World_Constructor @ 0x479b20 (???)
|
||||
- World_Init @ 0x479b40
|
||||
- World_DeInit @ 0x402510
|
||||
- Make_World @ 0x479870
|
||||
- RenderFrame(?) @ 0x602a70
|
||||
Check `r2_analyze.py` for full list
|
||||
|
||||
# Data Structures
|
||||
## File Index struct @ `0x7fcbec`
|
||||
|
||||
D3D8-Device @ `0x852914`
|
||||
```cpp
|
||||
|
||||
struct FileEntry {
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
uint32_t unk; // seems to always be 0xBADFOO1
|
||||
unsigned char* path;
|
||||
FileEntry* next; // next entry in hashtable chain
|
||||
}
|
||||
|
||||
struct FileIDX {
|
||||
uint32_t size;
|
||||
FileEntry** entries;
|
||||
};
|
||||
```
|
||||
|
||||
## Packed Index struct (array @ `0x7fc1b0`)
|
||||
```cpp
|
||||
struct PackedIDX {
|
||||
void** VMT;
|
||||
unsigned char* filename;
|
||||
uint32_t locked; // not sure
|
||||
void* data;
|
||||
uint32_t seek;
|
||||
}
|
||||
```
|
||||
|
||||
## C(++)-Callbacks @ `0x7fac84`
|
||||
|
||||
Structure:
|
||||
|
||||
```cpp
|
||||
struct CPP_Callback {
|
||||
const char* name;
|
||||
void* func;
|
||||
CPP_Callback* left;
|
||||
CPP_Callback* right;
|
||||
}
|
||||
```
|
||||
|
||||
## Game engine Variables Pointer @ `0x7FBE4C`
|
||||
|
||||
Structure:
|
||||
|
||||
```cpp
|
||||
struct GameVar {
|
||||
GameVar* next;
|
||||
const char* name;
|
||||
const char* desc;
|
||||
uint8_t subtype;
|
||||
uint8_t type;
|
||||
uint16_t unk;
|
||||
void* value;
|
||||
void* def_value;
|
||||
}
|
||||
```
|
||||
|
||||
Types
|
||||
|
||||
| Value | Type |
|
||||
| ------ | ----------------------- |
|
||||
| `0x10` | const char* |
|
||||
| `0x20` | int32_t |
|
||||
| `0x30` | User Control Definition |
|
||||
| `0x40` | float |
|
||||
| `0x60` | Callback function |
|
||||
|
||||
## Game World/State Pointer @ `0x7fe944`
|
||||
|
||||
|
@ -70,6 +151,10 @@ Points to World struct
|
|||
| 0x0000 | `void**` | Virtual Method Table |
|
||||
| 0x0004 | `uint32_t` | Size of Entity Hashtable |
|
||||
| 0x0008 | `void**` | Pointer to Entity Hashtable |
|
||||
| 0x0288 | `pyEntity*` | UsrEntity[0] |
|
||||
| 0x028C | `pyEntity*` | UsrEntity[1] |
|
||||
| 0x0290 | `pyEntity*` | UsrEntity[2] |
|
||||
| 0x0294 | `pyEntity*` | UsrEntity[3] |
|
||||
| 0x02B8 | `uint32_t` | Number of entity lists |
|
||||
| 0x02BC | `void**` | Pointer to entity list Hashtable |
|
||||
| 0x0330 | `float[3]` | Time (why 3 times?) |
|
||||
|
@ -91,18 +176,19 @@ Points to World struct
|
|||
| 0x2238 | `???` | Used in `World_Init` |
|
||||
| 0x2254 | `float` | Used in `World_Init` |
|
||||
|
||||
|
||||
## Entity Hash Table
|
||||
|
||||
Hash-function used: [PJW](https://en.wikipedia.org/wiki/PJW_hash_function) (Same parameters as the example implementation)
|
||||
|
||||
Entry format:
|
||||
|
||||
| Offset | Type | Description |
|
||||
| ------ | ------------- | ------------------------------ |
|
||||
| 0x0 | `void*` | Pointer to data |
|
||||
| 0x4 | `const char*` | key as `char*` |
|
||||
| 0x8 | `void*` | Pointer to next entry in chain |
|
||||
```cpp
|
||||
struct HT_Entry {
|
||||
void* data;
|
||||
const char* key;
|
||||
HT_Entry* next;
|
||||
}
|
||||
```
|
||||
|
||||
Data format:
|
||||
|
||||
|
@ -113,10 +199,19 @@ Data format:
|
|||
| 0x14 | `void*` | pointer to self (why?) |
|
||||
| 0x28 | `float[3]` | Position in Game World |
|
||||
|
||||
## EntityList Hash Table
|
||||
|
||||
Attributes:
|
||||
- `Near`
|
||||
- `First`
|
||||
- `Num`
|
||||
- `OnDeath`
|
||||
- `OnDamage`
|
||||
|
||||
# File Formats
|
||||
|
||||
## .packed File Format:
|
||||
|
||||
```
|
||||
Header:
|
||||
"BFPK\0\0\0\0"
|
||||
|
@ -128,35 +223,44 @@ Header:
|
|||
Int32ul: offset in file
|
||||
```
|
||||
|
||||
# Virtual Method Tables:
|
||||
|
||||
check `r2_analyze.py` for full list
|
||||
|
||||
## Loading Custom Content (not really working)
|
||||
|
||||
1. Create a folder `mods`
|
||||
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 inside `Data.packed`
|
||||
|
||||
* `m3d.ini`: Rendering Engine Configuration
|
||||
* `scripts/`: Game Engine Scripts
|
||||
|
||||
|
||||
# How to enable External Console:
|
||||
1. exctract `Data.packed`
|
||||
|
||||
1. Right click on the title bar (in windowed mode) and click "Switch Console"
|
||||
2. or Use a custom Content Pack (**untested!**)
|
||||
|
||||
# How to enable Scenegraph debugging console
|
||||
|
||||
1. extract `Data.packed`
|
||||
2. in m3d.ini uncomment (remove `;`) `ConsolaWnd` (GUI Console) and/or `ConsolaTxt` (Text Console) and set the value to `SI`
|
||||
3. repack `Data.packed`
|
||||
|
||||
or right click on the title bar (in windowed mode) and click "Switch Console"
|
||||
|
||||
or Use a custom Content Pack (**untested!**)
|
||||
|
||||
# Misc. Interesting things
|
||||
- sys.path contains "./lib" so you can load your own Python Modules
|
||||
|
||||
- `sys.path` contains "./lib" so you can import your own Python Modules
|
||||
- Games crashes when starting a multiplayer server and feeding it random UDP data
|
||||
|
||||
# Code Snippets
|
||||
|
||||
## [Kaitai Struct](http://kaitai.io/) Parser for .packed files
|
||||
|
||||
```yaml
|
||||
meta:
|
||||
id: packed
|
||||
|
@ -170,9 +274,9 @@ seq:
|
|||
- id: magic
|
||||
contents: BFPK
|
||||
doc: File Magic
|
||||
- id: magic2
|
||||
- id: version
|
||||
contents: [0,0,0,0]
|
||||
doc: Second File Magic
|
||||
doc: File Version
|
||||
- id: num_files
|
||||
type: u4
|
||||
doc: Number of files
|
||||
|
@ -180,7 +284,7 @@ seq:
|
|||
type: file_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_files
|
||||
doc: Directory entry for each file
|
||||
doc: Entry for each file
|
||||
types:
|
||||
file_entry:
|
||||
seq:
|
||||
|
@ -203,19 +307,9 @@ types:
|
|||
size: size
|
||||
```
|
||||
|
||||
## Hashfunction used in Entity Hash-Table
|
||||
# TODO:
|
||||
|
||||
```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;
|
||||
}
|
||||
```
|
||||
- Figure out how C++ Callbacks work
|
||||
- Figure out SM3 (Models), CM3 (Animations) file formats
|
||||
- Figure out rest of World structure
|
||||
- Figure out rest of Entity structure
|
|
@ -29,4 +29,4 @@ WIP Memory hacking library
|
|||
- [Reclass.NET](https://github.com/ReClassNET/ReClass.NET)
|
||||
- [HxD](https://mh-nexus.de/en/hxd/)
|
||||
- [Kaitai Struct](http://kaitai.io/)
|
||||
- [Radare2](https://www.radare.org/)
|
||||
- [Radare2](https://www.radare.org/) + [Cutter](https://cutter.re/)
|
25
ScrapHacks/.vscode/c_cpp_properties.json
vendored
Normal file
25
ScrapHacks/.vscode/c_cpp_properties.json
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${vcpkgRoot}/x64-windows/include",
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.22.27905/include"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.18362.0",
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.22.27905/bin/Hostx64/x64/cl.exe",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "msvc-x86",
|
||||
"configurationProvider": "vector-of-bool.cmake-tools",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -6,88 +6,123 @@ project(ScrapHacks
|
|||
DESCRIPTION "Scrapland memory hacking library"
|
||||
LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
message(STATUS "Fetching Scrapland installation folder")
|
||||
get_filename_component(SCRAPLAND_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\MercurySteam Entertainment\\Scrapland;DIRECTORY]" ABSOLUTE CACHE)
|
||||
|
||||
if(NOT IS_ABSOLUTE "${SCRAPLAND_DIR}" OR NOT EXISTS "${SCRAPLAND_DIR}")
|
||||
message(FATAL_ERROR "Scrapland installation folder not found!")
|
||||
endif()
|
||||
|
||||
message(STATUS "Checking Scrap.exe hash")
|
||||
file(SHA1 "${SCRAPLAND_DIR}/Bin/Scrap.exe" SCRAP_EXE_HASH)
|
||||
|
||||
if(NOT ${SCRAP_EXE_HASH} STREQUAL "d2dde960e8eca69d60c2e39a439088b75f0c89fa")
|
||||
message(FATAL_ERROR "Scrap.exe hash miss match!")
|
||||
endif()
|
||||
|
||||
set(FETCHCONTENT_QUIET 0)
|
||||
set(CMAKE_BUILD_TYPE "RelMinSize")
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}")
|
||||
set(ASMJIT_EMBED true)
|
||||
set(ASMTK_EMBED true)
|
||||
set(ZYDIS_BUILD_TOOLS false)
|
||||
set(ZYDIS_BUILD_EXAMPLES false)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
# ensure we use minimal "windows.h" lib without the crazy min max macros
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"")
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"")
|
||||
# disable SAFESEH - to avoid "LNK2026: module unsafe"
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"SAFESEH:NO\"")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO /ignore:4217")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO /ignore:4217")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO /ignore:4217")
|
||||
endif(MSVC)
|
||||
endif(WIN32)
|
||||
|
||||
include(ExternalProject)
|
||||
include(FetchContent)
|
||||
|
||||
ExternalProject_Add(
|
||||
FetchContent_Declare(
|
||||
DirectX
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
URL
|
||||
https://archive.org/download/DirectX.8.0a.SDK_includes_libs_only/DirectX.8.0a.SDK.zip
|
||||
URL_HASH SHA1=39f168336d0df92ff14d62d5e3aef1b9e3191312)
|
||||
|
||||
FetchContent_MakeAvailable(DirectX)
|
||||
|
||||
ExternalProject_Get_Property(DirectX SOURCE_DIR)
|
||||
include_directories(AFTER ${SOURCE_DIR}/8.0/include/)
|
||||
link_directories(AFTER ${SOURCE_DIR}/8.0/lib/)
|
||||
FetchContent_Declare(
|
||||
ASM_JIT
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
GIT_REPOSITORY git@github.com:asmjit/asmjit.git
|
||||
GIT_SHALLOW true
|
||||
GIT_PROGRESS true
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(ASM_JIT)
|
||||
|
||||
FetchContent_Declare(
|
||||
ASM_TK
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
GIT_REPOSITORY git@github.com:asmjit/asmtk.git
|
||||
GIT_SHALLOW true
|
||||
GIT_PROGRESS true
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(ASM_TK)
|
||||
|
||||
set(ASMJIT_DIR ${asm_jit_SOURCE_DIR})
|
||||
|
||||
include(${asm_tk_SOURCE_DIR}/CMakeLists.txt)
|
||||
|
||||
|
||||
FetchContent_Declare(
|
||||
Zydis
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
GIT_REPOSITORY git@github.com:zyantific/zydis.git
|
||||
GIT_SHALLOW true
|
||||
GIT_PROGRESS true
|
||||
)
|
||||
|
||||
# FetchContent_MakeAvailable(Zydis)
|
||||
|
||||
include_directories(AFTER ${directx_SOURCE_DIR}/8.0/include/ ${ASMTK_INCLUDE_DIRS} ${ASMJIT_INCLUDE_DIRS})
|
||||
link_directories(AFTER ${directx_SOURCE_DIR}/8.0/lib/)
|
||||
|
||||
find_package(Python3 3.6 REQUIRED COMPONENTS Interpreter)
|
||||
|
||||
add_custom_target(
|
||||
MAKE_D3D8_VMT ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/src/make_D3D8_VMT.py ${CMAKE_CURRENT_SOURCE_DIR}/src/D3D8_VMT.hpp ${SOURCE_DIR}/8.0/include/d3d8.h
|
||||
DEPENDS DirectX
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/D3D8_VMT.hpp
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/utils/make_D3D8_VMT.py ${CMAKE_CURRENT_SOURCE_DIR}/src/D3D8_VMT.hpp ${directx_SOURCE_DIR}/8.0/include/d3d8.h
|
||||
COMMENT "Generating D3D8_VMT.hpp from d3d8.h"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# ExternalProject_Add(
|
||||
# Python152
|
||||
# PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
# CONFIGURE_COMMAND ""
|
||||
# BUILD_COMMAND ""
|
||||
# INSTALL_COMMAND ""
|
||||
# URL
|
||||
# https://www.python.org/ftp/python/src/py152.tgz
|
||||
# URL_HASH SHA1=2d648d07b1aa1aab32a3a24851c33715141779b9
|
||||
# )
|
||||
# ExternalProject_Get_Property(Python152 SOURCE_DIR)
|
||||
# include_directories(AFTER ${SOURCE_DIR}/Include/)
|
||||
|
||||
|
||||
# ExternalProject_Add(
|
||||
# Python152_Bin
|
||||
# PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
# CONFIGURE_COMMAND ""
|
||||
# BUILD_COMMAND ""
|
||||
# INSTALL_COMMAND ""
|
||||
# URL
|
||||
# https://www.python.org/ftp/python/win32/py152.exe
|
||||
# URL_HASH SHA1=dfaf2dcc3704fb1bbc339db4f33ff94bd61c74c6
|
||||
# )
|
||||
# ExternalProject_Get_Property(Python152 SOURCE_DIR)
|
||||
# link_directories(AFTER ${SOURCE_DIR}/)
|
||||
add_custom_target(D3D8_VMT ALL
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/D3D8_VMT.hpp")
|
||||
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
add_compile_definitions(POINTER_64=__ptr64)
|
||||
add_library(ScrapHack SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/dllmain.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ScrapHack.cpp
|
||||
)
|
||||
${ASMTK_SRC}
|
||||
${ASMJIT_SRC}
|
||||
)
|
||||
|
||||
set_target_properties(ScrapHack PROPERTIES SUFFIX ".pyd")
|
||||
add_dependencies(ScrapHack DirectX)
|
||||
add_dependencies(ScrapHack MAKE_D3D8_VMT)
|
||||
add_dependencies(MAKE_D3D8_VMT DirectX)
|
||||
add_dependencies(ScrapHack D3D8_VMT)
|
||||
# add_dependencies(ScrapHack Python152)
|
||||
# add_dependencies(ScrapHack Python152_Bin)
|
||||
target_link_libraries(ScrapHack
|
||||
d3d8
|
||||
d3dx8
|
||||
dxerr8
|
||||
gdiplus
|
||||
# PYTHON15
|
||||
# Zydis
|
||||
legacy_stdio_definitions)
|
||||
|
||||
install(TARGETS ScrapHack RUNTIME DESTINATION ${SCRAPLAND_DIR}/lib)
|
||||
target_compile_features(ScrapHack PUBLIC cxx_std_11)
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
## Features
|
||||
|
||||
- read and write memory
|
||||
- change DirectX state
|
||||
- Draw DirectX overlay (still need to make a useful overlay)
|
||||
- Dump various data structures to the console
|
||||
- Assemble and execute code on the fly
|
||||
- Can be controlled via keyboard shortcuts (TODO: allow defining own shortcuts for commands)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Visual Studio 2017/2019 (others might work)
|
||||
|
@ -13,16 +22,13 @@ cmake -G"NMake Makefiles" -B build
|
|||
cmake --build build --target install
|
||||
```
|
||||
|
||||
this will generate `ScrapHack.pyd` in `./build`
|
||||
This will find the Games's installation folder, verify that the version you have is compatible with ScrapHacks and drop the compiled `.pyd` file into the correct folder to be imported
|
||||
|
||||
## Usage
|
||||
## Getting started
|
||||
|
||||
- create a `lib` folder next to `Scrapland.exe`
|
||||
- copy `ScrapHack.pyd` into said folder
|
||||
- open the ingame console (Ctrl+^)
|
||||
- type `import ScrapHack`
|
||||
- type `$help`
|
||||
- Done!
|
||||
|
||||
## Notes
|
||||
|
||||
|
|
10
ScrapHacks/build.bat
Normal file
10
ScrapHacks/build.bat
Normal file
|
@ -0,0 +1,10 @@
|
|||
@echo off
|
||||
setlocal
|
||||
if "%VSINSTALLDIR%"=="" (
|
||||
for /f "usebackq tokens=*" %%i in (`vswhere -latest -find **\vcvarsall.bat`) do (
|
||||
call "%%i" x86
|
||||
)
|
||||
)
|
||||
if not exist build cmake -G"NMake Makefiles" -B build
|
||||
cmake --build build --target install
|
||||
endlocal
|
|
@ -1,33 +1,55 @@
|
|||
#pragma once
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <d3d8.h>
|
||||
#include <d3dx8.h>
|
||||
#include <dxerr8.h>
|
||||
|
||||
|
||||
#include "D3D8_VMT.hpp"
|
||||
#include "Hook.hpp"
|
||||
#include "Scrapland.hpp"
|
||||
#include "Structures.hpp"
|
||||
#include "Util.hpp"
|
||||
|
||||
|
||||
uintmax_t frame = 0;
|
||||
bool hooked=false;
|
||||
bool hooked = false;
|
||||
bool overlay = false;
|
||||
LPD3DXFONT m_pFont;
|
||||
HFONT hFont;
|
||||
HBRUSH hBrush;
|
||||
D3DCOLOR color = D3DCOLOR_ARGB(255, 255, 0, 0);
|
||||
D3DCOLOR color = D3DCOLOR_XRGB(255, 0, 0);
|
||||
RECT Rect = {0, 0, 0, 0};
|
||||
D3DRECT panel;
|
||||
|
||||
D3DFILLMODE fillmode = D3DFILLMODE::D3DFILL_SOLID;
|
||||
boolean use_z;
|
||||
|
||||
size_t size_ht(HashTable<EntityList> *ht);
|
||||
size_t size_ht(HashTable<Entity> *ht);
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
#define DX_Check(call) (_DX_Check(call,TOSTRING(call),__LINE__,__FILE__))
|
||||
|
||||
HRESULT _DX_Check(HRESULT res,char* call,size_t line, char* file) {
|
||||
if (res!=D3D_OK) {
|
||||
return DXTraceA(file,line,res,call,true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
LPDIRECT3DDEVICE8
|
||||
Render(LPDIRECT3DDEVICE8 dev) {
|
||||
if (!overlay) {
|
||||
return dev;
|
||||
}
|
||||
IDirect3DSurface8* surf;
|
||||
char text[4096];
|
||||
int32_t money = 0;
|
||||
size_t num_ents = 0;
|
||||
|
@ -37,30 +59,42 @@ Render(LPDIRECT3DDEVICE8 dev) {
|
|||
num_ents = size_ht(ptr<HashTable<Entity>>(P_WORLD, O_ENTS));
|
||||
num_ent_lst = size_ht(ptr<HashTable<EntityList>>(P_WORLD, O_ENTLISTS));
|
||||
}
|
||||
snprintf(text, 4096,
|
||||
R"(ScrapHack v0.1
|
||||
Frame: [%lld]
|
||||
Money: [%d]
|
||||
Entities: [%ld]
|
||||
Entity Lists: [%ld])",
|
||||
++frame, money, num_ents, num_ent_lst);
|
||||
snprintf(text, 4096,"ScrapHack v0.1\nFrame: [%lld]\nMoney: [%d]\nEntities: [%ld]\nEntity Lists: [%ld]",++frame, money, num_ents, num_ent_lst);
|
||||
if (m_pFont == nullptr) {
|
||||
D3DXCreateFont(dev, hFont, &m_pFont);
|
||||
hFont = nullptr;
|
||||
}
|
||||
m_pFont->Begin();
|
||||
m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0);
|
||||
D3DRECT rec = {Rect.left,Rect.top,Rect.right,Rect.bottom};
|
||||
// dev->Clear(1,NULL,D3DCLEAR_TARGET,D3DCOLOR_ARGB(10,255,255,255),0,0);
|
||||
m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color);
|
||||
m_pFont->End();
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
LPDIRECT3DDEVICE8
|
||||
BeforeRender(LPDIRECT3DDEVICE8 dev) {
|
||||
return dev;
|
||||
}
|
||||
|
||||
HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) {
|
||||
typedef decltype(&H_EndScene) t_func;
|
||||
shared_ptr<Hook> hook = Hook::get(H_EndScene);
|
||||
return hook->func<t_func>(Render(dev));
|
||||
}
|
||||
|
||||
|
||||
HRESULT WINAPI H_BeginScene(LPDIRECT3DDEVICE8 dev) {
|
||||
typedef decltype(&H_BeginScene) t_func;
|
||||
shared_ptr<Hook> hook = Hook::get(H_BeginScene);
|
||||
HRESULT ret=hook->func<t_func>(dev);
|
||||
BeforeRender(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
HRESULT WINAPI H_SetLight(LPDIRECT3DDEVICE8 dev, DWORD index,
|
||||
D3DLIGHT8 *light) {
|
||||
typedef decltype(&H_SetLight) t_func;
|
||||
|
@ -87,13 +121,13 @@ HRESULT WINAPI H_DrawIndexedPrimitive(LPDIRECT3DDEVICE8 dev,
|
|||
typedef decltype(&H_DrawIndexedPrimitive) t_func;
|
||||
DWORD AMBIENT;
|
||||
shared_ptr<Hook> hook = Hook::get(H_DrawIndexedPrimitive);
|
||||
dev->GetRenderState(D3DRS_AMBIENT, &AMBIENT);
|
||||
dev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255, 255, 255));
|
||||
dev->SetRenderState(D3DRS_FILLMODE, D3DFILLMODE::D3DFILL_SOLID);
|
||||
dev->SetRenderState(D3DRS_ZENABLE, 0);
|
||||
// dev->GetRenderState(D3DRS_AMBIENT, &AMBIENT);
|
||||
// dev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255, 255, 255));
|
||||
dev->SetRenderState(D3DRS_FILLMODE, fillmode);
|
||||
dev->SetRenderState(D3DRS_ZENABLE, use_z);
|
||||
auto ret = hook->func<t_func>(dev, Type, minIndex, NumVertices, startIndex,
|
||||
primCount);
|
||||
dev->SetRenderState(D3DRS_AMBIENT, AMBIENT);
|
||||
// dev->SetRenderState(D3DRS_AMBIENT, AMBIENT);
|
||||
dev->SetRenderState(D3DRS_ZENABLE, 1);
|
||||
return ret;
|
||||
}
|
||||
|
@ -107,6 +141,7 @@ void unhook_d3d8() {
|
|||
m_pFont = nullptr;
|
||||
}
|
||||
Hook::drop(H_EndScene);
|
||||
Hook::drop(H_BeginScene);
|
||||
Hook::drop(H_DrawIndexedPrimitive);
|
||||
Hook::drop(H_SetLight);
|
||||
hooked=false;
|
||||
|
@ -116,9 +151,6 @@ void hook_d3d8() {
|
|||
if (hooked) {
|
||||
return;
|
||||
}
|
||||
hFont = CreateFontA(15, 0, 0, 0, FW_EXTRABOLD, 0, 0, 0, ANSI_CHARSET, 0, 0,
|
||||
0, 0, "Lucida Console");
|
||||
hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0));
|
||||
void *dev = nullptr;
|
||||
while (true) {
|
||||
dev = ptr<void>(P_D3DDEV);
|
||||
|
@ -127,7 +159,11 @@ void hook_d3d8() {
|
|||
}
|
||||
Sleep(100);
|
||||
};
|
||||
hFont = CreateFontA(15, 0, 0, 0, FW_EXTRABOLD, 0, 0, 0, ANSI_CHARSET, 0, 0,
|
||||
0, 0, "Lucida Console");
|
||||
hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0));
|
||||
Hook::addr(GetVTable(dev)[VMT_IDirect3DDevice8::m_EndScene], H_EndScene);
|
||||
Hook::addr(GetVTable(dev)[VMT_IDirect3DDevice8::m_BeginScene], H_BeginScene);
|
||||
Hook::addr(GetVTable(dev)[VMT_IDirect3DDevice8::m_DrawIndexedPrimitive],
|
||||
H_DrawIndexedPrimitive);
|
||||
Hook::addr(GetVTable(dev)[VMT_IDirect3DDevice8::m_SetLight], H_SetLight);
|
||||
|
|
|
@ -1,274 +1,274 @@
|
|||
namespace VMT_IDirect3D8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_RegisterSoftwareDevice = 3;
|
||||
const size_t m_GetAdapterCount = 4;
|
||||
const size_t m_GetAdapterIdentifier = 5;
|
||||
const size_t m_GetAdapterModeCount = 6;
|
||||
const size_t m_EnumAdapterModes = 7;
|
||||
const size_t m_GetAdapterDisplayMode = 8;
|
||||
const size_t m_CheckDeviceType = 9;
|
||||
const size_t m_CheckDeviceFormat = 10;
|
||||
const size_t m_CheckDeviceMultiSampleType = 11;
|
||||
const size_t m_CheckDepthStencilMatch = 12;
|
||||
const size_t m_GetDeviceCaps = 13;
|
||||
const size_t m_GetAdapterMonitor = 14;
|
||||
const size_t m_CreateDevice = 15;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_RegisterSoftwareDevice = 3;
|
||||
const size_t m_GetAdapterCount = 4;
|
||||
const size_t m_GetAdapterIdentifier = 5;
|
||||
const size_t m_GetAdapterModeCount = 6;
|
||||
const size_t m_EnumAdapterModes = 7;
|
||||
const size_t m_GetAdapterDisplayMode = 8;
|
||||
const size_t m_CheckDeviceType = 9;
|
||||
const size_t m_CheckDeviceFormat = 10;
|
||||
const size_t m_CheckDeviceMultiSampleType = 11;
|
||||
const size_t m_CheckDepthStencilMatch = 12;
|
||||
const size_t m_GetDeviceCaps = 13;
|
||||
const size_t m_GetAdapterMonitor = 14;
|
||||
const size_t m_CreateDevice = 15;
|
||||
}
|
||||
namespace VMT_IDirect3DBaseTexture8_IDirect3DResource8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
}
|
||||
namespace VMT_IDirect3DCubeTexture8_IDirect3DBaseTexture8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetCubeMapSurface = 15;
|
||||
const size_t m_LockRect = 16;
|
||||
const size_t m_UnlockRect = 17;
|
||||
const size_t m_AddDirtyRect = 18;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetCubeMapSurface = 15;
|
||||
const size_t m_LockRect = 16;
|
||||
const size_t m_UnlockRect = 17;
|
||||
const size_t m_AddDirtyRect = 18;
|
||||
}
|
||||
namespace VMT_IDirect3DDevice8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_TestCooperativeLevel = 3;
|
||||
const size_t m_GetAvailableTextureMem = 4;
|
||||
const size_t m_ResourceManagerDiscardBytes = 5;
|
||||
const size_t m_GetDirect3D = 6;
|
||||
const size_t m_GetDeviceCaps = 7;
|
||||
const size_t m_GetDisplayMode = 8;
|
||||
const size_t m_GetCreationParameters = 9;
|
||||
const size_t m_SetCursorProperties = 10;
|
||||
const size_t m_SetCursorPosition = 11;
|
||||
const size_t m_ShowCursor = 12;
|
||||
const size_t m_CreateAdditionalSwapChain = 13;
|
||||
const size_t m_Reset = 14;
|
||||
const size_t m_Present = 15;
|
||||
const size_t m_GetBackBuffer = 16;
|
||||
const size_t m_GetRasterStatus = 17;
|
||||
const size_t m_SetGammaRamp = 18;
|
||||
const size_t m_GetGammaRamp = 19;
|
||||
const size_t m_CreateTexture = 20;
|
||||
const size_t m_CreateVolumeTexture = 21;
|
||||
const size_t m_CreateCubeTexture = 22;
|
||||
const size_t m_CreateVertexBuffer = 23;
|
||||
const size_t m_CreateIndexBuffer = 24;
|
||||
const size_t m_CreateRenderTarget = 25;
|
||||
const size_t m_CreateDepthStencilSurface = 26;
|
||||
const size_t m_CreateImageSurface = 27;
|
||||
const size_t m_CopyRects = 28;
|
||||
const size_t m_UpdateTexture = 29;
|
||||
const size_t m_GetFrontBuffer = 30;
|
||||
const size_t m_SetRenderTarget = 31;
|
||||
const size_t m_GetRenderTarget = 32;
|
||||
const size_t m_GetDepthStencilSurface = 33;
|
||||
const size_t m_BeginScene = 34;
|
||||
const size_t m_EndScene = 35;
|
||||
const size_t m_Clear = 36;
|
||||
const size_t m_SetTransform = 37;
|
||||
const size_t m_GetTransform = 38;
|
||||
const size_t m_MultiplyTransform = 39;
|
||||
const size_t m_SetViewport = 40;
|
||||
const size_t m_GetViewport = 41;
|
||||
const size_t m_SetMaterial = 42;
|
||||
const size_t m_GetMaterial = 43;
|
||||
const size_t m_SetLight = 44;
|
||||
const size_t m_GetLight = 45;
|
||||
const size_t m_LightEnable = 46;
|
||||
const size_t m_GetLightEnable = 47;
|
||||
const size_t m_SetClipPlane = 48;
|
||||
const size_t m_GetClipPlane = 49;
|
||||
const size_t m_SetRenderState = 50;
|
||||
const size_t m_GetRenderState = 51;
|
||||
const size_t m_BeginStateBlock = 52;
|
||||
const size_t m_EndStateBlock = 53;
|
||||
const size_t m_ApplyStateBlock = 54;
|
||||
const size_t m_CaptureStateBlock = 55;
|
||||
const size_t m_DeleteStateBlock = 56;
|
||||
const size_t m_CreateStateBlock = 57;
|
||||
const size_t m_SetClipStatus = 58;
|
||||
const size_t m_GetClipStatus = 59;
|
||||
const size_t m_GetTexture = 60;
|
||||
const size_t m_SetTexture = 61;
|
||||
const size_t m_GetTextureStageState = 62;
|
||||
const size_t m_SetTextureStageState = 63;
|
||||
const size_t m_ValidateDevice = 64;
|
||||
const size_t m_GetInfo = 65;
|
||||
const size_t m_SetPaletteEntries = 66;
|
||||
const size_t m_GetPaletteEntries = 67;
|
||||
const size_t m_SetCurrentTexturePalette = 68;
|
||||
const size_t m_GetCurrentTexturePalette = 69;
|
||||
const size_t m_DrawPrimitive = 70;
|
||||
const size_t m_DrawIndexedPrimitive = 71;
|
||||
const size_t m_DrawPrimitiveUP = 72;
|
||||
const size_t m_DrawIndexedPrimitiveUP = 73;
|
||||
const size_t m_ProcessVertices = 74;
|
||||
const size_t m_CreateVertexShader = 75;
|
||||
const size_t m_SetVertexShader = 76;
|
||||
const size_t m_GetVertexShader = 77;
|
||||
const size_t m_DeleteVertexShader = 78;
|
||||
const size_t m_SetVertexShaderConstant = 79;
|
||||
const size_t m_GetVertexShaderConstant = 80;
|
||||
const size_t m_GetVertexShaderDeclaration = 81;
|
||||
const size_t m_GetVertexShaderFunction = 82;
|
||||
const size_t m_SetStreamSource = 83;
|
||||
const size_t m_GetStreamSource = 84;
|
||||
const size_t m_SetIndices = 85;
|
||||
const size_t m_GetIndices = 86;
|
||||
const size_t m_CreatePixelShader = 87;
|
||||
const size_t m_SetPixelShader = 88;
|
||||
const size_t m_GetPixelShader = 89;
|
||||
const size_t m_DeletePixelShader = 90;
|
||||
const size_t m_SetPixelShaderConstant = 91;
|
||||
const size_t m_GetPixelShaderConstant = 92;
|
||||
const size_t m_GetPixelShaderFunction = 93;
|
||||
const size_t m_DrawRectPatch = 94;
|
||||
const size_t m_DrawTriPatch = 95;
|
||||
const size_t m_DeletePatch = 96;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_TestCooperativeLevel = 3;
|
||||
const size_t m_GetAvailableTextureMem = 4;
|
||||
const size_t m_ResourceManagerDiscardBytes = 5;
|
||||
const size_t m_GetDirect3D = 6;
|
||||
const size_t m_GetDeviceCaps = 7;
|
||||
const size_t m_GetDisplayMode = 8;
|
||||
const size_t m_GetCreationParameters = 9;
|
||||
const size_t m_SetCursorProperties = 10;
|
||||
const size_t m_SetCursorPosition = 11;
|
||||
const size_t m_ShowCursor = 12;
|
||||
const size_t m_CreateAdditionalSwapChain = 13;
|
||||
const size_t m_Reset = 14;
|
||||
const size_t m_Present = 15;
|
||||
const size_t m_GetBackBuffer = 16;
|
||||
const size_t m_GetRasterStatus = 17;
|
||||
const size_t m_SetGammaRamp = 18;
|
||||
const size_t m_GetGammaRamp = 19;
|
||||
const size_t m_CreateTexture = 20;
|
||||
const size_t m_CreateVolumeTexture = 21;
|
||||
const size_t m_CreateCubeTexture = 22;
|
||||
const size_t m_CreateVertexBuffer = 23;
|
||||
const size_t m_CreateIndexBuffer = 24;
|
||||
const size_t m_CreateRenderTarget = 25;
|
||||
const size_t m_CreateDepthStencilSurface = 26;
|
||||
const size_t m_CreateImageSurface = 27;
|
||||
const size_t m_CopyRects = 28;
|
||||
const size_t m_UpdateTexture = 29;
|
||||
const size_t m_GetFrontBuffer = 30;
|
||||
const size_t m_SetRenderTarget = 31;
|
||||
const size_t m_GetRenderTarget = 32;
|
||||
const size_t m_GetDepthStencilSurface = 33;
|
||||
const size_t m_BeginScene = 34;
|
||||
const size_t m_EndScene = 35;
|
||||
const size_t m_Clear = 36;
|
||||
const size_t m_SetTransform = 37;
|
||||
const size_t m_GetTransform = 38;
|
||||
const size_t m_MultiplyTransform = 39;
|
||||
const size_t m_SetViewport = 40;
|
||||
const size_t m_GetViewport = 41;
|
||||
const size_t m_SetMaterial = 42;
|
||||
const size_t m_GetMaterial = 43;
|
||||
const size_t m_SetLight = 44;
|
||||
const size_t m_GetLight = 45;
|
||||
const size_t m_LightEnable = 46;
|
||||
const size_t m_GetLightEnable = 47;
|
||||
const size_t m_SetClipPlane = 48;
|
||||
const size_t m_GetClipPlane = 49;
|
||||
const size_t m_SetRenderState = 50;
|
||||
const size_t m_GetRenderState = 51;
|
||||
const size_t m_BeginStateBlock = 52;
|
||||
const size_t m_EndStateBlock = 53;
|
||||
const size_t m_ApplyStateBlock = 54;
|
||||
const size_t m_CaptureStateBlock = 55;
|
||||
const size_t m_DeleteStateBlock = 56;
|
||||
const size_t m_CreateStateBlock = 57;
|
||||
const size_t m_SetClipStatus = 58;
|
||||
const size_t m_GetClipStatus = 59;
|
||||
const size_t m_GetTexture = 60;
|
||||
const size_t m_SetTexture = 61;
|
||||
const size_t m_GetTextureStageState = 62;
|
||||
const size_t m_SetTextureStageState = 63;
|
||||
const size_t m_ValidateDevice = 64;
|
||||
const size_t m_GetInfo = 65;
|
||||
const size_t m_SetPaletteEntries = 66;
|
||||
const size_t m_GetPaletteEntries = 67;
|
||||
const size_t m_SetCurrentTexturePalette = 68;
|
||||
const size_t m_GetCurrentTexturePalette = 69;
|
||||
const size_t m_DrawPrimitive = 70;
|
||||
const size_t m_DrawIndexedPrimitive = 71;
|
||||
const size_t m_DrawPrimitiveUP = 72;
|
||||
const size_t m_DrawIndexedPrimitiveUP = 73;
|
||||
const size_t m_ProcessVertices = 74;
|
||||
const size_t m_CreateVertexShader = 75;
|
||||
const size_t m_SetVertexShader = 76;
|
||||
const size_t m_GetVertexShader = 77;
|
||||
const size_t m_DeleteVertexShader = 78;
|
||||
const size_t m_SetVertexShaderConstant = 79;
|
||||
const size_t m_GetVertexShaderConstant = 80;
|
||||
const size_t m_GetVertexShaderDeclaration = 81;
|
||||
const size_t m_GetVertexShaderFunction = 82;
|
||||
const size_t m_SetStreamSource = 83;
|
||||
const size_t m_GetStreamSource = 84;
|
||||
const size_t m_SetIndices = 85;
|
||||
const size_t m_GetIndices = 86;
|
||||
const size_t m_CreatePixelShader = 87;
|
||||
const size_t m_SetPixelShader = 88;
|
||||
const size_t m_GetPixelShader = 89;
|
||||
const size_t m_DeletePixelShader = 90;
|
||||
const size_t m_SetPixelShaderConstant = 91;
|
||||
const size_t m_GetPixelShaderConstant = 92;
|
||||
const size_t m_GetPixelShaderFunction = 93;
|
||||
const size_t m_DrawRectPatch = 94;
|
||||
const size_t m_DrawTriPatch = 95;
|
||||
const size_t m_DeletePatch = 96;
|
||||
}
|
||||
namespace VMT_IDirect3DIndexBuffer8_IDirect3DResource8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_Lock = 11;
|
||||
const size_t m_Unlock = 12;
|
||||
const size_t m_GetDesc = 13;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_Lock = 11;
|
||||
const size_t m_Unlock = 12;
|
||||
const size_t m_GetDesc = 13;
|
||||
}
|
||||
namespace VMT_IDirect3DResource8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
}
|
||||
namespace VMT_IDirect3DSurface8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_GetContainer = 7;
|
||||
const size_t m_GetDesc = 8;
|
||||
const size_t m_LockRect = 9;
|
||||
const size_t m_UnlockRect = 10;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_GetContainer = 7;
|
||||
const size_t m_GetDesc = 8;
|
||||
const size_t m_LockRect = 9;
|
||||
const size_t m_UnlockRect = 10;
|
||||
}
|
||||
namespace VMT_IDirect3DSwapChain8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_Present = 3;
|
||||
const size_t m_GetBackBuffer = 4;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_Present = 3;
|
||||
const size_t m_GetBackBuffer = 4;
|
||||
}
|
||||
namespace VMT_IDirect3DTexture8_IDirect3DBaseTexture8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetSurfaceLevel = 15;
|
||||
const size_t m_LockRect = 16;
|
||||
const size_t m_UnlockRect = 17;
|
||||
const size_t m_AddDirtyRect = 18;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetSurfaceLevel = 15;
|
||||
const size_t m_LockRect = 16;
|
||||
const size_t m_UnlockRect = 17;
|
||||
const size_t m_AddDirtyRect = 18;
|
||||
}
|
||||
namespace VMT_IDirect3DVertexBuffer8_IDirect3DResource8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_Lock = 11;
|
||||
const size_t m_Unlock = 12;
|
||||
const size_t m_GetDesc = 13;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_Lock = 11;
|
||||
const size_t m_Unlock = 12;
|
||||
const size_t m_GetDesc = 13;
|
||||
}
|
||||
namespace VMT_IDirect3DVolume8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_GetContainer = 7;
|
||||
const size_t m_GetDesc = 8;
|
||||
const size_t m_LockBox = 9;
|
||||
const size_t m_UnlockBox = 10;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_GetContainer = 7;
|
||||
const size_t m_GetDesc = 8;
|
||||
const size_t m_LockBox = 9;
|
||||
const size_t m_UnlockBox = 10;
|
||||
}
|
||||
namespace VMT_IDirect3DVolumeTexture8_IDirect3DBaseTexture8 {
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetVolumeLevel = 15;
|
||||
const size_t m_LockBox = 16;
|
||||
const size_t m_UnlockBox = 17;
|
||||
const size_t m_AddDirtyBox = 18;
|
||||
const size_t m_QueryInterface = 0;
|
||||
const size_t m_AddRef = 1;
|
||||
const size_t m_Release = 2;
|
||||
const size_t m_GetDevice = 3;
|
||||
const size_t m_SetPrivateData = 4;
|
||||
const size_t m_GetPrivateData = 5;
|
||||
const size_t m_FreePrivateData = 6;
|
||||
const size_t m_SetPriority = 7;
|
||||
const size_t m_GetPriority = 8;
|
||||
const size_t m_PreLoad = 9;
|
||||
const size_t m_GetType = 10;
|
||||
const size_t m_SetLOD = 11;
|
||||
const size_t m_GetLOD = 12;
|
||||
const size_t m_GetLevelCount = 13;
|
||||
const size_t m_GetLevelDesc = 14;
|
||||
const size_t m_GetVolumeLevel = 15;
|
||||
const size_t m_LockBox = 16;
|
||||
const size_t m_UnlockBox = 17;
|
||||
const size_t m_AddDirtyBox = 18;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,29 @@
|
|||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <asmjit/asmjit.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
vector<uint8_t> make_trampoline(uintptr_t orig,uintptr_t hook) {
|
||||
using namespace asmjit;
|
||||
JitRuntime rt;
|
||||
CodeHolder code;
|
||||
CodeInfo ci=rt.codeInfo();
|
||||
code.init(ci);
|
||||
x86::Assembler a(&code);
|
||||
a.jmp(hook);
|
||||
a.ret();
|
||||
code.flatten();
|
||||
code.resolveUnresolvedLinks();
|
||||
code.relocateToBase(orig);
|
||||
size_t code_size=code.sectionById(0)->buffer().size();
|
||||
code.copyFlattenedData((void*)orig, code_size, CodeHolder::kCopyWithPadding);
|
||||
}
|
||||
*/
|
||||
|
||||
class Hook {
|
||||
private:
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
@ -19,6 +39,7 @@ class Hook {
|
|||
|
||||
public:
|
||||
Hook(void *func, void *detour) {
|
||||
// TODO: build jmp_bytes using asmjit
|
||||
uintptr_t dest = reinterpret_cast<uintptr_t>(detour);
|
||||
uintptr_t src = reinterpret_cast<uintptr_t>(func);
|
||||
this->orig = func;
|
||||
|
@ -83,7 +104,7 @@ class Hook {
|
|||
}
|
||||
|
||||
void disable() {
|
||||
if (enabled) {
|
||||
if (this->enabled) {
|
||||
// cout << "Disabling: [" << this->orig << " <- " << this->detour <<
|
||||
// "]"
|
||||
// << endl;
|
||||
|
@ -91,7 +112,7 @@ class Hook {
|
|||
PAGE_EXECUTE_READWRITE, NULL);
|
||||
memcpy(this->orig, this->orig_bytes, 1 + 4 + 1);
|
||||
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL);
|
||||
enabled = false;
|
||||
this->enabled = false;
|
||||
}
|
||||
}
|
||||
void enable() {
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#define ASMJIT_EMBED
|
||||
#define ASMTK_EMBED
|
||||
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <asmtk/asmtk.h>
|
||||
#include "Scrapland.hpp"
|
||||
#include "Util.hpp"
|
||||
|
||||
|
@ -13,15 +19,196 @@ void DllUnload();
|
|||
void unhook_d3d8();
|
||||
void hook_d3d8();
|
||||
|
||||
typedef void(_cdecl *t_cmd_func)(vector<string>);
|
||||
struct Command;
|
||||
|
||||
struct t_cmd {
|
||||
typedef void(_cdecl *t_cmd_func)(Command*,vector<string>);
|
||||
|
||||
size_t assemble(vector<string> assembly,uint64_t base) {
|
||||
using namespace asmjit;
|
||||
using namespace asmtk;
|
||||
|
||||
char err_msg[1024];
|
||||
Error err;
|
||||
|
||||
CodeInfo ci(ArchInfo::kIdX86);
|
||||
ci.setBaseAddress(base);
|
||||
CodeHolder code;
|
||||
code.init(ci);
|
||||
x86::Assembler a(&code);
|
||||
AsmParser p(&a);
|
||||
|
||||
for (string line:assembly) {
|
||||
if (err = p.parse((line+"\n").c_str())) {
|
||||
snprintf(err_msg,1024,"PARSE ERROR: [%s] %08x (%s)\n",line.c_str(), err, DebugUtils::errorAsString(err));
|
||||
scrap_log(ERR_COLOR,err_msg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (err=code.flatten()) {
|
||||
snprintf(err_msg,1024,"FLATTEN ERROR: %08x (%s)\n", err, DebugUtils::errorAsString(err));
|
||||
scrap_log(ERR_COLOR,err_msg);
|
||||
return 0;
|
||||
}
|
||||
if (err=code.resolveUnresolvedLinks()) {
|
||||
snprintf(err_msg,1024,"RESOLVE ERROR: %08x (%s)\n", err, DebugUtils::errorAsString(err));
|
||||
scrap_log(ERR_COLOR,err_msg);
|
||||
return 0;
|
||||
}
|
||||
CodeBuffer& buffer = code.sectionById(0)->buffer();
|
||||
|
||||
if (base==0) {
|
||||
return buffer.size();
|
||||
}
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
if (VirtualQuery((void*)base, &mbi, sizeof(mbi)) == 0) {
|
||||
scrap_log(ERR_COLOR, "ERROR: ");
|
||||
scrap_log(ERR_COLOR, GetLastErrorAsString());
|
||||
scrap_log(ERR_COLOR, "\n");
|
||||