diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5f3544 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/ +injector/build-*/ +__pycache__/ +*.pyc +decrypted files/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7763200 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,102 @@ +cmake_minimum_required(VERSION 3.20) +project(slinky LANGUAGES C CXX) + +# clang-cl + lld-link without a Windows SDK: CMake still wants a manifest tool for the DLL link step. LLVM ships +# llvm-mt, which takes the same arguments as mt.exe; without it the build fails after all objects are compiled. +if(WIN32 AND NOT CMAKE_MT) + find_program(SLINKY_MT NAMES llvm-mt) + if(SLINKY_MT) + set(CMAKE_MT "${SLINKY_MT}") + endif() +endif() + +# The client as one shared library that is loaded into the Minecraft JVM. +# engine src/engine the client's own engine (JNI, JVMTI, GUI, module manager, ...), start-up in protected/ +# logic src/logic the module logic (one function per original routine) +# src/logic/*/*.h module descriptors' callbacks (GUI, setting registration, status); each one is compiled +# on its own (they declare the settings as opaque blobs, the logic .cpp as typed values) +# data src/data .rdata/.data of the original image (strings, tables, module descriptors), generated +# platform src/platform everything that depends on the operating system, NanoVG, GL loader, C runtime bindings +if(NOT WIN32) + message(FATAL_ERROR "Only the Windows build exists so far. Cross-compile with\n" + " cmake -S . -B build/cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-windows-clang-cl.cmake\n" + "(a Linux platform layer is planned: JVMTI agent, GLFW/X11 input, dlopen)") +endif() + +set(CMAKE_CXX_FLAGS "" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS "" CACHE STRING "" FORCE) + +# ---- sources ---- +file(GLOB_RECURSE ENGINE_SRC CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/src/engine/*.cpp) +file(GLOB_RECURSE LOGIC_SRC CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/src/logic/*.cpp) +file(GLOB_RECURSE MODULE_SRC CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/src/logic/*.h) +set_source_files_properties(${MODULE_SRC} PROPERTIES LANGUAGE CXX COMPILE_OPTIONS /TP) +file(GLOB PLATFORM_SRC CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/*.cpp ${CMAKE_SOURCE_DIR}/src/platform/win/*.cpp) +# stack probe for large frames (clang-cl would take it from the C runtime library) +set(CHKSTK_OBJ ${CMAKE_BINARY_DIR}/chkstk.obj) +# NanoVG core (+ fontstash, stb_truetype, stb_image) and its GL3 backend +set(NANOVG_SRC ${CMAKE_SOURCE_DIR}/third_party/nanovg/src/nanovg.c ${CMAKE_SOURCE_DIR}/src/platform/nanovg_impl.c) + +# ---- the original's data, assembled (GNU syntax) ---- +find_program(SLINKY_CLANG clang REQUIRED) +set(DATA_OBJ) +foreach(part rdata data iat) + set(obj ${CMAKE_BINARY_DIR}/data_${part}.obj) + add_custom_command(OUTPUT ${obj} + COMMAND ${SLINKY_CLANG} --target=x86_64-pc-windows-msvc -c ${CMAKE_SOURCE_DIR}/src/data/${part}.s -o ${obj} + DEPENDS ${CMAKE_SOURCE_DIR}/src/data/${part}.s VERBATIM) + list(APPEND DATA_OBJ ${obj}) +endforeach() + +add_custom_command(OUTPUT ${CHKSTK_OBJ} + COMMAND ${SLINKY_CLANG} --target=x86_64-pc-windows-msvc -c ${CMAKE_SOURCE_DIR}/src/platform/win/chkstk.s -o ${CHKSTK_OBJ} + DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/win/chkstk.s VERBATIM) +list(APPEND DATA_OBJ ${CHKSTK_OBJ}) + +# ---- import libraries from the .def files (no Windows SDK needed) ---- +find_program(SLINKY_DLLTOOL NAMES llvm-dlltool REQUIRED) +set(IMPORT_LIBS) +foreach(dll kernel32 user32 shell32 ucrtbase) + set(lib ${CMAKE_BINARY_DIR}/imports/${dll}.lib) + add_custom_command(OUTPUT ${lib} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/imports + COMMAND ${SLINKY_DLLTOOL} -m i386:x86-64 -d ${CMAKE_SOURCE_DIR}/cmake/imports/${dll}.def -l ${lib} + DEPENDS ${CMAKE_SOURCE_DIR}/cmake/imports/${dll}.def VERBATIM) + list(APPEND IMPORT_LIBS ${lib}) +endforeach() + +add_custom_target(slinky_imports DEPENDS ${IMPORT_LIBS}) +add_library(slinky SHARED ${ENGINE_SRC} ${LOGIC_SRC} ${MODULE_SRC} ${PLATFORM_SRC} ${NANOVG_SRC} ${DATA_OBJ}) +add_dependencies(slinky slinky_imports) +target_link_libraries(slinky PRIVATE ${IMPORT_LIBS}) +set_target_properties(slinky PROPERTIES PREFIX "" LINKER_LANGUAGE CXX) +set_source_files_properties(${DATA_OBJ} PROPERTIES EXTERNAL_OBJECT TRUE GENERATED TRUE) + +# The code generation is the one the sources were verified against (tools/asmdiff.py CFLAGS): same optimiser +# settings, frame pointers, no stack cookies, no COMDAT per function, the old compiler's inc/dec and nop choices. +target_compile_options(slinky PRIVATE + -O2 -GS- /Gy- + "SHELL:-Xclang -mframe-pointer=all" + "SHELL:-Xclang -target-feature -Xclang +slow-incdec" + "SHELL:-Xclang -target-feature -Xclang -fast-11bytenop" + "SHELL:-Xclang -target-feature -Xclang -fast-15bytenop" + -w) +target_include_directories(slinky PRIVATE include third_party/nanovg/src third_party/gl) +# the bundled C libraries (NanoVG, stb) get a minimal libc declaration set instead of the Windows SDK's headers +set_source_files_properties(${NANOVG_SRC} PROPERTIES COMPILE_OPTIONS "-I${CMAKE_SOURCE_DIR}/third_party/minicrt/include") +# glcorearb.h would include (not available in the cross build) just to define APIENTRY +target_compile_definitions(slinky PRIVATE APIENTRY=) + +# some files need extra flags (`// cflags: ...` in their first lines): the compiler version that built the +# original lowered a few constructs differently +foreach(f ${ENGINE_SRC} ${LOGIC_SRC} ${MODULE_SRC}) + file(STRINGS ${f} line LIMIT_COUNT 1 REGEX "^// cflags:") + if(line) + string(REGEX REPLACE "^// cflags:[ ]*" "" extra "${line}") + separate_arguments(extra_list NATIVE_COMMAND "${extra}") + set_source_files_properties(${f} PROPERTIES COMPILE_OPTIONS "${extra_list}") + endif() +endforeach() + +# Reached from the DLL's own entry point; no C runtime start-up code is linked (the UCRT in the process is used) +target_link_options(slinky PRIVATE /NODEFAULTLIB /ENTRY:DllMain /SUBSYSTEM:WINDOWS /OPT:NOREF /OPT:NOICF /ERRORLIMIT:0 /MAP) diff --git a/README.md b/README.md index 93bc1f2..0142ac1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,130 @@ -# slinky +

+ Open Slinky Banner +
+ Open Slinky +
+ by Skid Solutions +
+ credits to cat; +

-slinky fully decompiled and readable \ No newline at end of file +--- + +

+ https://discord.gg/AEwatvnvSf +

+ +

+ java hooks + unload + symbol recovery + readable names +

+ +--- + +

+ build proof +

+ +--- + +## About + +Open Slinky is a readable C++ reconstruction of the Slinky client for Minecraft +1.8.9. The client is injected into the game process as a native DLL; it hooks the +game at the Java bytecode level through JVMTI, dispatches events to the module +system, and renders its interface through NanoVG. + +This edition is cleaned up for development: + +- address-based file and function names have been replaced with descriptive + ones; the original symbols are recorded in `docs/symbol-map.json` (functions) + and `docs/global-symbol-map.json` (`data_` / `rdata_` globals and + the `*_part` event handlers), and inferred names are listed in + `docs/renames.md`; +- assembly used only for byte-exact code generation has been removed; the + remaining `asm` tokens are symbol aliases, not instructions; +- the client's data tables remain in `src/data` because the code links against + them (fonts, strings, module descriptors). + +--- + +## How to build + +### Prerequisites + +- **LLVM** — clang-cl, lld-link, llvm-rc and llvm-mt on `PATH` +- **CMake** 3.20 or newer +- **Ninja** +- **Windows x64** +- **Java Development Kit 8** — runtime for Minecraft 1.8.9; not required to + compile the DLL + +### 1. Configure + +```powershell +cmake -S . -B build -G Ninja ` + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-windows-clang-cl.cmake +``` + +If Ninja is not on `PATH`, add +`-DCMAKE_MAKE_PROGRAM=C:/path/to/ninja.exe`. + +### 2. Build + +```powershell +cmake --build build +``` + +Output: + +- `build/slinky.dll` + +### Running + +Inject `slinky.dll` into the running Minecraft 1.8.9 process with +`LoadLibrary`. Start-up runs on its own thread; the client interface is opened +with its GUI key. The last interface tab unloads the client: it saves the +settings, removes the Java hooks and frees the library. + +--- + +## Project layout + +``` +src/engine/ hooks, JNI/JVMTI, GUI, module manager, math, shared services +src/logic/ per-module behaviour (.cpp) and its descriptor callbacks / settings page (.h) +src/platform/ Windows layer, GL loader, NanoVG integration +src/data/ data tables (fonts, strings, descriptors) - required to link +include/slinky/ public headers +docs/ design notes and the symbol map +third_party/ NanoVG and GL headers +``` + +## Notes + +- Start-up, teardown, the window hook and the unload thread were virtualised in + the original image and are reconstructed in `src/engine/protected/`. +- `docs/symbol-map.json` maps every original `fn_`, `logic_`, + `cb_`, `reg_` and `aux_` symbol to its readable name. +- Settings and profiles are stored in `~/.slinky` (`settings`, `profiles/`). +- `src/data/*.s` and `src/platform/win/chkstk.s` are data/compiler-support + sections, not client code, this is 1 to 1 logic but may have some issues that we didnt find. + +## Credits + +- Original client: Slinky +- Reconstruction: Claude (VMProtect devirtualization), DeepSeek (decryption), + GLM and Claude (symbol recovery) + +## Legal & disclaimers + +- **Affiliation:** This is an independent development. It is **NOT AN OFFICIAL + SLINKY PRODUCT**, is not approved by or associated with the original authors, + and is not affiliated with Mojang or Zelix Pty Ltd. +- **Assets & code:** No un-obfuscated original source code is distributed + directly within this repository. The `src/data` tables are the client's own + data required for linking; all third-party assets and code belong to their + respective owners. +- **Purpose:** research and preservation. Use at your own risk. diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..cb2638e --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# Compile every module and verify it against the original slinky2 image. +# Original image path: tools/paths.py (override with SLINKY_ORIG=...). +set -e +cd "$(dirname "$0")" +python3 tools/verify.py +python3 tools/verify_logic.py +python3 tools/verify_engine.py --quiet +for f in src/engine/protected/*.cpp; do + clang-cl --target=x86_64-pc-windows-msvc -O2 -Iinclude -c "$f" -o "build/obj/protected_$(basename "$f" .cpp).obj" +done +echo "protected (readable, compile-checked): $(ls src/engine/protected/*.cpp | wc -l) files" +for f in src/engine/lib/*.cpp; do + clang-cl --target=x86_64-pc-windows-msvc -O2 -Iinclude -c "$f" -o "build/obj/lib_$(basename "$f" .cpp).obj" +done +echo "lib (translated from the listing, compile-checked): $(ls src/engine/lib/*.cpp | wc -l) files" +echo "full DLL: cmake -S . -B build/cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-windows-clang-cl.cmake && cmake --build build/cmake" +python3 tools/verify_modules.py +python3 tools/report_modules.py