Cross-platform (Windows, Linux) game hack for Counter-Strike 2 with GUI and rendering based on game's Panorama UI. Compatible with the latest game update on Steam.
-
04 November 2025
- Improved smoothness of "Player Info in World" on moving players
-
30 October 2025
- Added Bomb Plant Alert feature
- Green color means the bomb will be planted before the end of the round if uninterrupted
- Red color means the bomb can not be planted before the end of the round
- Added Bomb Plant Alert feature
-
23 October 2025
- Hostage Outline Glow hue is now customizable
-
20 October 2025
- Added "No Scope Inaccuracy Visualization" feature
-
09 October 2025
- Added viewmodel fov modification
- C++ runtime library (CRT) is not used in release builds
- No heap memory allocations
- No static imports in release build on Windows
- No threads are created
- Exceptions are not used
- No external dependencies
Windows: Visual Studio 2022 with the Desktop development with C++ workload Linux: CMake 3.24 or newer, g++ 14 or newer or clang++ 18 or newer
& (& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1) Osiris.sln /p:Platform=x64 /p:Configuration=ReleaseThis locates MSBuild automatically (it is not on PATH in a regular PowerShell window) and builds the whole solution with the projects' default toolset (v143). Inside a Developer PowerShell / Developer Command Prompt for VS the plain command works too:
msbuild Osiris.sln /p:Platform=x64 /p:Configuration=ReleaseThe projects target the v143 toolset (Visual Studio 2022). If only a newer toolset is installed (e.g. v144/v145 from a newer Visual Studio), either add the matching component in the Visual Studio Installer ("MSVC v143 - VS 2022 C++ x64/x86 build tools") or override it per invocation:
... Osiris.sln /p:Platform=x64 /p:Configuration=Release /p:PlatformToolset=v144One build produces both artifacts (unified output directory x64\Release\, no scripts involved):
Osiris.dllInjector.exe— embeds the freshly builtOsiris.dllas an RCDATA resource (a one-lineEmbeddedDll.rcis generated during the build and rc.exe packs the bytes at link time). Double-click it and it injects.
Debug artifacts land in x64\Debug\, intermediate files in x64\obj\.
:: MSVC
cmake -S . -B build -A x64
cmake --build build --config Release --target Injector
:: ClangCL
cmake -S . -B build -A x64 -T ClangCL
cmake --build build --config Release --target Injector# MinGW-w64 (requires gcc/g++, windres, nasm and Ninja — e.g. from MSYS2)
cmake -S . -B build -G Ninja -D CMAKE_C_COMPILER=gcc -D CMAKE_CXX_COMPILER=g++
cmake --build build --target InjectorArtifacts are unified in build/x64/<config>/ (multi-config generators) or
build/x64/ (single-config generators). Assembly is picked per toolchain
(MASM Shellcode.asm for MSVC/ClangCL, NASM Shellcode.nasm for MinGW/LLVM);
resource compilation falls back to rc.exe / windres / llvm-rc automatically;
MinGW artifacts link the runtime statically and do not depend on extra DLLs
such as libstdc++/libwinpthread.
cmake -DCMAKE_BUILD_TYPE=Release -B build
cmake --build build -j $(nproc --all)The build produces libOsiris.so in build/Source/.
Double-click Injector.exe — the whole flow is automatic (no command-line
arguments are required or accepted; console output is diagnostic logging):
double-click
-> the executable embeds a requireAdministrator manifest, so a UAC prompt
appears without "Run as administrator"; if denied, it aborts and loads nothing
-> locate cs2.exe:
already running -> wait for client.dll, then inject immediately
not running -> launch CS2 via Steam (steam://rungameid/730)
wait for cs2.exe to appear (no timeout, 3 s refresh)
wait for client.dll (1-minute timeout per attempt,
any-key retry), then inject
-> inject the embedded Osiris.dll
-> keep the window open with the result (press any key to close)
Early-injection guard (no window-focus check): injection happens only once
client.dll is present in the process — at the "international / China region"
selection dialog engine2.dll is already loaded but client.dll is not, so that
phase is naturally excluded. If you get stuck at the region dialog the injector
polls client.dll every 3 seconds for up to 1 minute, then reports a timeout
(maximum wait: 1 minute) and offers an any-key retry; it injects automatically
once you pick a region and the real game starts.
| Variable | Effect |
|---|---|
INJECTOR_NO_ELEVATE=1 |
Skip the UAC elevation (automated testing; do not set for normal use) |
INJECTOR_TARGET_EXE=<name> |
Override the target process name (default cs2.exe, testing) |
INJECTOR_NO_LAUNCH=1 |
Do not launch via Steam when the target is missing; only wait |
INJECTOR_DRY_RUN=1 |
Run the whole flow but skip the actual injection |
- Parse the PE headers (validate x64 / PE32+) and
VirtualAllocExRWX memory inside the target sizedSizeOfImage(prefer the preferred base address, fall back to any address). - Rebuild the image section by section, VA-aligned, and write it into the target process.
- Apply
.relocrelocations (DIR64 / HIGHLOW) when the actual base differs from the preferred base. - Assemble the parameter block plus the position-independent payload
(
Shellcode.asm/Shellcode.nasm, PIC, no relocations) and write it into the target. CreateRemoteThreadruns the payload in the target:- resolves the import table inside the target via
ntdll!LdrLoadDll/LdrGetProcedureAddress(equivalent to LoadLibrary, guaranteeing correct addresses); - registers the exception directory (
RtlAddFunctionTable, x64 SEH); - invokes TLS callbacks;
- calls the entry point (
DllMain, DLL_PROCESS_ATTACH).
- resolves the import table inside the target via
- Read the payload return status, free the payload memory, keep the mapped image.
- Automatic elevation (UAC): when not running as administrator, the injector requests elevation through UAC and restarts itself. If elevation is denied it aborts without loading anything.
- No rights, no load: even when elevated, if
OpenProcesson the target is still denied (protected process etc.) the injector aborts without injecting. - Window persistence: after finishing, an interactive console stays on "Press any key to close..."; when output is redirected (CI) the wait is skipped automatically.
- Client wait timeout: if
client.dlldoes not appear within 60 seconds, the injector reports the timeout (maximum wait per attempt: 1 minute) and offers an any-key retry; without an interactive console (redirected output) it aborts instead of retrying. - Anti-cheat risk: CS2 ships with VAC and injection can be detected. For learning and personal testing only.
- If the mapped DLL entry point (DllMain) returns
FALSE, the injector reports failure and frees the image. - A payload timeout (60 seconds) is treated as failure, so a stuck DllMain cannot hang the injector.
Counter-Strike 2 blocks the LoadLibrary injection method, so the bundled Injector.exe manual-maps (reflective injection) the embedded Osiris.dll into the game — see the usage section above.
Third-party injectors Xenos and Extreme Injector are known to be detected by VAC.
You can simply run the following script in the directory containing libOsiris.so:
sudo gdb -batch-silent -p $(pidof cs2) -ex "call (void*)dlopen(\"$PWD/libOsiris.so\", 2)"
However, this injection method might be detected by VAC as gdb is visible under TracerPid in /proc/$(pidof cs2)/status for the duration of the injection.
After pushing or triggering the workflow manually, go to Actions → the run →
Artifacts and download Osiris-Release-MSVC-windows-2022 (no folder
nesting inside the zip):
Osiris.dllInjector.exe(embeds the matching Osiris.dll; ready to inject)
windows.yml has three jobs covering every toolchain: msbuild
(MSVC/ClangCL × Debug/Release), cmake (same matrix plus tests) and mingw
(MSYS2 + NASM + Ninja).
In a configuration file default.cfg inside %appdata%\OsirisCS2\configs directory on Windows and $HOME/OsirisCS2/configs on Linux.
On Windows the file is written atomically: a temporary default.cfg.new is
written first and then renamed over default.cfg; changes made in-game are
saved automatically.
| File | Description |
|---|---|
Injector.cpp |
Zero-argument entry point, automatic elevation, automatic injection, diagnostics |
ManualMapper.cpp/.h |
PE parsing, relocations, import resolution, payload assembly |
Shellcode.asm / Shellcode.nasm |
PIC payload executed inside the target (MASM for MSVC/ClangCL, NASM for MinGW/LLVM; identical semantics) |
Injector.ico / Injector.rc |
Executable icon |
resource.h |
Resource ID (IDR_EMBEDDED_DLL), kept in sync with the generator |
Injector.manifest |
requireAdministrator UAC manifest (embedded by the CMake/MinGW path; MSBuild uses linker flags) |
CMakeLists.txt |
Injector CMake target (toolchain-adaptive assembly/resources/manifest) |
make_embedded_rc.cmake |
Generates the one-line resource script (RCDATA pointing at Osiris.dll) for the CMake path |
EmbeddedDll.rc |
Generated: one-line RCDATA resource script (do not edit) |
make_icon.ps1 |
Icon generation script (rerun after changing the icon, then rebuild) |
dump_modules.ps1 |
Dumps the target process module list (development aid) |
Copyright (c) 2018-2025 Daniel Krupiński
This project is licensed under the MIT License - see the LICENSE file for details.
