A native C++ launcher and injected plugin core for experimenting with the Old School RuneScape Windows client.
Kraken API Native is an early-stage C++ project for launching the native Old School RuneScape Windows client, injecting a DLL, and applying native patches and hooks from inside the client process.
This project is for educational plugin/API development only. It is not meant for botting, automation, account rule-breaking, malware, or bypass tooling. Use at your own risk. The developers are not responsible for consequences resulting from the use of this software.
Clone the project and build it with a Visual Studio x64 CMake toolchain:
git clone https://github.com/cbartram/kraken-api-native
cd kraken-api-native
cmake -S . -B cmake-build-debug -G "Visual Studio 17 2022" -A x64
cmake --build cmake-build-debug --target launcher --config DebugRun the launcher as administrator:
cmake-build-debug\launcher\Debug\launcher.exe
DLL injection generally requires administrator privileges.
The codebase has native injection targets plus a Java Swing UI shell:
kraken-ui
starts the RuneLite-style Swing shell
launches launcher.exe with a per-session named pipe
connects to plugin-core.dll over IPC
streams native logs into the bottom log pane
sends the first proof command: client.windowTitle.set
launcher.exe
starts the OSRS client
waits briefly for the client to become input-idle
passes KRAKEN_PIPE_NAME into the child process when requested
resolves plugin-core.dll from the build output
stages a per-run temporary DLL copy
injects the staged DLL with LoadLibraryW
waits for the client process to exit
plugin-core.dll
runs inside the OSRS client process
buffers logs and optionally forwards them over IPC
opens a debug console only when KRAKEN_DEBUG_CONSOLE=1
applies in-process patches
installs native hooks
kraken-ui-native.dll
optional JNI helper for finding and reparenting Win32 HWNDs
enables embedding the OSRS window inside the Swing GamePanel
launcherowns the OSRS process handle, primary thread handle, plugin DLL path resolution, staging path, and injection lifecycle.kraken-uiowns UI state, plugin-facing Java calls, launcher process orchestration, and log display.plugin-coreowns in-process patching, hook registration, command handling, and native log production after injection.- Hard-coded client RVAs live in
plugin-core/offsets.hppso client-version dependent addresses are easy to audit.
launcher.exewrites launch, staging, and injection status to its console.plugin-core.dllbuffers patch/hook diagnostics and forwards them to the UI named pipe once the Swing process connects.KRAKEN_DEBUG_CONSOLE=1opts into the old DLL-side console for native debugging.
- The launcher uses
WaitForInputIdlebefore injection instead of a fixed startup sleep. - The launcher stages
plugin-core.dllto a unique temp-file path before injection. This keeps the build output DLL from being locked by the running OSRS process. - The DLL does minimal work in
DllMain, then starts a worker thread for logging setup, IPC startup, patching, and hook installation.
.
├── CMakeLists.txt
├── launcher/
│ ├── CMakeLists.txt
│ ├── dll_injector.cpp
│ ├── dll_injector.hpp
│ ├── main.cpp
│ ├── plugin_stager.cpp
│ ├── plugin_stager.hpp
│ ├── process_launcher.cpp
│ ├── process_launcher.hpp
│ └── win32_handle.hpp
├── plugin-core/
├── CMakeLists.txt
├── dllmain.cpp
├── hooks.cpp
├── hooks.hpp
├── ipc_server.cpp
├── ipc_server.hpp
├── logger.cpp
├── logger.hpp
├── offsets.hpp
├── patcher.cpp
└── patcher.hpp
├── kraken-ui/
│ └── src/main/java/com/kraken/
└── ui-native/
├── CMakeLists.txt
└── ui_native.cpp
Use .hpp files for declarations: class names, function signatures, shared
types, constants, and small inline utilities.
Use .cpp files for implementation: function bodies, private helpers, global
state, Win32 calls, MinHook calls, and logic that should compile once.
This matters because #include copies header text into every .cpp file that
includes it. If a header defines normal functions or globals, adding a second
include site can create duplicate linker symbols. This repo keeps hook state
and patch logic in .cpp files for that reason.
- Windows 10/11
- Visual Studio 2022 or Build Tools 2022
- Desktop development with C++
- Windows 10 or Windows 11 SDK
- CMake 3.26+
- JDK 11+ for the Swing launcher UI
- Git
- CLion, Visual Studio, or another CMake-aware IDE
The native project uses C++20 and fetches
MinHook with CMake FetchContent.
The launcher currently uses a default client path in launcher/main.cpp:
constexpr wchar_t kDefaultClientPath[] =
L"C:\\Program Files (x86)\\Jagex Launcher\\Games\\Old School RuneScape\\Client\\osclient.exe";For manual testing, override it with:
launcher.exe --client "C:\path\to\osclient.exe"You can also override the plugin DLL path:
launcher.exe --plugin "C:\path\to\plugin-core.dll"From CLion:
- Open the repository.
- Configure the CMake profile with the Windows Visual Studio toolchain.
- Reload CMake.
- Build the
launchertarget. - Build the
kraken-ui-nativetarget. - Build the
kraken-ui-classestarget.
The UI is Java 11 source. The CMake kraken-ui-classes target uses javac
directly, so a Gradle installation that requires Java 17 is not on this UI
runtime path.
Building launcher also builds plugin-core. The launcher resolves
plugin-core.dll from either:
cmake-build-debug\launcher\Debug\plugin-core.dll
cmake-build-debug\plugin-core\Debug\plugin-core.dll
The second path is the normal CLion/Visual Studio CMake output after this backtrack.
For the native-only path, run launcher.exe as administrator.
Expected flow:
launcher.exestarts the OSRS native client.- The launcher waits for the client to become input-idle.
- The launcher copies
plugin-core.dllto a unique temp path. - The launcher injects the staged DLL with
LoadLibraryW. - The DLL applies patches and installs hooks.
- The launcher process waits until the client exits.
For the Swing launcher path, run the Java application as administrator:
cmake --build cmake-build-debug --target run-kraken-ui --config DebugExpected UI flow:
- The Swing UI starts
launcher.exewith a per-session named pipe. launcher.exepasses that pipe name toosclient.exethrough the child environment.plugin-core.dllcreates the pipe server after injection.- The Swing UI connects as the pipe client.
- Native logs stream into the bottom log pane.
- The
Set Titleaction calls JavaNativeClient.setWindowTitle(...), sendsclient.windowTitle.setover IPC, andplugin-core.dllchanges the OSRS window title from inside the injected process.
ProcessLauncherstarts the native client and resolves the launcher directory.DllInjectorwrites the DLL path into the target process and callsLoadLibraryWthrough a remote thread.PluginStagercopies the built DLL to a unique temp path before injection.UniqueHandleprovides RAII ownership for Win32HANDLEvalues.--pipepasses a UI-owned named pipe into the client environment forplugin-core.dllto connect back to after injection.
Patcherchanges memory protection, writes patch bytes, flushes the instruction cache, and restores protection.InstallLogHookinstalls the current native log hook through MinHook.Loggerowns thread-safe log buffering and forwards logs to a configured sink. SetKRAKEN_DEBUG_CONSOLE=1to opt into a debug console.IpcServerowns the named-pipe bridge from the injected DLL back to the Swing UI.offsets.hppcentralizes hard-coded RVAs.
kraken-uiowns the RuneLite-style shell, log pane, launcher process orchestration, and the thin Java-facing native API proof.ui-nativeoptionally exposes Win32 HWND helpers for embedding the OSRS window into the JavaGamePanel.
This is still a prototype foundation.
- RVAs are client-version dependent and must be verified after OSRS updates.
- The current log hook depends on a specific observed string layout.
- The plugin manager and config system are only UI groundwork right now.
- The first Java API proof is intentionally small:
NativeClient.setWindowTitle(...)sends one command to the injected DLL. Real game mutations should be queued and executed from a verified game-safe hook point. - There are no automated tests yet because the core behavior depends on a live Windows process and injected DLL lifecycle.
- Update or add code in the narrowest target that owns the behavior.
- Keep launcher-side process and injection logic in
launcher. - Keep injected patching and hooks in
plugin-core. - Keep headers as declarations unless code is intentionally header-only.
- Keep hard-coded offsets in
plugin-core/offsets.hpp. - Rebuild native targets from the CLion CMake profile.
- Rebuild the Swing UI with the
kraken-ui-classesCMake target. - Run
run-kraken-uior a Java Application config with the project root as the working directory and check the UI log pane.
- Confirm that
launcher.exewas run as administrator. - Confirm the OSRS client path is correct.
- Confirm
plugin-core.dllexists under the CMakeplugin-coreoutput directory for the same configuration. - Check the launcher console for injection errors.
- Set
KRAKEN_DEBUG_CONSOLE=1before launching if you need the old DLL-side debug console while diagnosing IPC startup.
New launcher runs inject a staged temp DLL instead of the build output DLL. If you still see a locked build-output DLL, close any OSRS process that was launched before the staging change and rebuild.
Update kDefaultClientPath in launcher/main.cpp, or run the launcher with
--client.
- The hard-coded RVAs may no longer match the installed client.
- The hook signature or target function may have changed.
- Disable the newest patch/hook and re-enable one piece at a time.
Install Visual Studio Build Tools 2022 and include:
- MSVC v143 compiler toolset
- Windows 10 or Windows 11 SDK
- CMake tools for Windows
- Desktop development with C++
Do not mix WSL/Linux CMake paths and Windows Visual Studio CMake paths in the
same cmake-build-debug directory. For this project, the binaries must be
Windows binaries because they inject into osclient.exe; use CLion's Windows
Visual Studio CMake profile or run Windows CMake with a Windows build path.
- C++20 - Native launcher and injected plugin core
- CMake - Build system
- Visual Studio Build Tools - Windows compiler/toolchain
- Win32 API - Process and memory integration
- MinHook - Native function hooking
This project is licensed under the GNU General Public License 3.0.