Skip to content
 
 

Repository files navigation

OpenSteamTool logo

OpenSteamTool

Open-Source Steam Unlock Tool

C++ 20+ CMake 3.20+ Windows only Ask DeepWiki

United States flag English  |  Spain flag Español  |  China flag 中文

Features

Core Unlocks & Manifest Management

  • Unlock unowned games and DLCs without limits
  • Auto-load depot decryption keys and PICS access tokens (addtoken) from Lua configs
  • Auto-download manifests via manifestdex (default), opensteamtool, steamrun, wudrm, or custom Lua endpoints
  • Lock manifest versions to prevent game updates
  • Recursive multi-level subdirectories in config/lua/ with automatic .manifest mirroring to Steam/depotcache/

Hot Reload

  • Watched .lua directories reload additions and modifications instantly without restarting Steam

Game Process Injection

  • Inject third-party DLLs into game processes via [[inject]] in opensteamtool.toml
  • Supports multiple DLL rules, command-line filtering, and AppID restrictions (see Third-party DLL injection rules)

Family Sharing Support

  • Automatically unlocks Family Sharing restrictions with zero configuration and no conflicts

Cloud Save Redirection (CloudRedirect)

  • Integrates CloudRedirect to enable cloud saves, playtime tracking, and achievement sync for OST-managed games (see [cloud] in Configuration)

Denuvo & SteamStub Compatibility

  • SteamStub: AppID spoofing via local ConfigStore tickets without game process injection
  • Explicit Tickets: Memory-only management via setAppTicket / setETicket in Lua; no disk .bin files generated
  • Account Switching Offline Auth: Auto-syncs credentials directly into <AppId>.lua (via setAppTicket) after running on a genuine account; switch to unowned accounts for offline play
  • Manifest Locking & Updates: Defaults to active setManifestid to lock versions for offline authorization. On authorized accounts, OST automatically permits official updates and syncs manifests (configurable via [manifest] lock_owned_games and auto_sync_on_update); pass -nodenuvo or set nodenuvo(appid) in Lua to bypass Denuvo handling entirely
  • Helper Flags:
    • -d+: Steam launch option on genuine accounts to auto-generate <AppId>.lua and lock manifests
    • -forcedenuvo: Force treat game as Denuvo-protected (or forcedenuvo(appid))

Extracting Tickets & Config with extract_tickets

Extracts AppTicket, ETicket, DLC lists, depot keys, manifests, and generates a ready-to-use <appid>.lua on accounts owning the game.

  • Download: GitHub Actions Tools Workflow or build locally via build.bat (build/tools/<Config>/extract_tickets.exe)
  • Usage:
    # Standard extraction (locally installed game)
    extract_tickets.exe 1361510
    
    # Force ETicket extraction for uninstalled game (restart Steam if button hangs)
    extract_tickets.exe 1361510 --force-eticket

Stats and Achievements

  • Enable stats and achievements for unowned games
  • Priority: Lua setStat(appid, "steamid") > stats API (https://stats.opensteamtool.com/{appid}) > default SteamID (76561198028121353)

Online Fix

  • Add -onlinefix to Steam launch options for 480 (Spacewar) multiplayer with automatic real AppID and save protection (one active game at a time)
  • Rare titles requiring 480 certificate match can use -onlinefix -p2pflip (use only if necessary due to compatibility risks)

Usage

Method 1: Portable Mode (Recommended)

No DLLs in the Steam directory; runs completely independently:

  1. Extract the release package (with ost-Injector.exe, OpenSteamTool.dll, etc.) to any standalone folder (e.g. D:\OpenSteamTool_Portable)
  2. Create config/lua/ and add your .lua unlock scripts; opensteamtool.toml can be placed directly in this portable folder
  3. Launch options:
    • Manual: Run ost-Injector.exe to detect or launch Steam and inject
    • Auto-start: Run CreateAutoInjectTask.bat (no administrator privileges required; uninstall via DeleteAutoInjectTask.bat)
    • CLI: Supports -watch / --watch / -daemon (background auto-injection watcher), -silent / --silent / -s (one-shot silent injection), and -help / --help / -h (command-line help)

Method 2: Standard Mode (DLL Hijacking)

  1. Copy dwmapi.dll, xinput1_4.dll, and OpenSteamTool.dll to the Steam root directory
  2. Create config/lua/ in the Steam root directory and place your Lua scripts there

Lua Configuration Example

addappid(1361510) -- unlock game
addappid(1361511, 0, "5954562e7f5260400040a818bc29b60b335bb690066ff767e20d145a3b6b4af0") -- unlock depot with key
addtoken(1361510, "2764735786934684318") -- add PICS access token

setManifestid(1361511, "5656605350306673283") -- pin depot manifest
setManifestid(1361511, "5656605350306673283", 12345678) -- pin depot manifest with size

setAppTicket(1361510, "0100000000000000...") -- memory AppTicket
setETicket(1361510, "0100000000000000...")   -- memory ETicket
setStat(1361510, "76561197960287930")        -- achievement source SteamID

addprocess(1361510, "CustomGame.exe")        -- map AppID for processes without SteamAppId env
seteticketurl("https://example.com/eticket") -- online ETicket minting endpoint (optional)

nodenuvo(1361510)    -- bypass Denuvo handling (same as -nodenuvo, alias: disallowdenuvo)
forcedenuvo(1361510) -- force treat as Denuvo (same as -forcedenuvo)

All function names are case-insensitive.


Configuration (optional)

Rename opensteamtool.example.toml (or localized templates opensteamtool.example_zh.toml / opensteamtool.example_es.toml) to opensteamtool.toml and place it in the portable directory or Steam root. Hot-reloaded on changes.

[log]
# Debug build only: trace, debug, info, warn, error
level = "info"
# Relative or absolute directory for debug logs (optional, Debug build only)
# dir = "opensteamtool"

[manifest]
# Upstream API: "manifestdex" (default), "opensteamtool", "steamrun", "wudrm"
url = "manifestdex"
timeout_resolve_ms = 5000
timeout_connect_ms = 5000
timeout_send_ms    = 10000
timeout_recv_ms    = 10000
# Allow official Steam updates for owned games/DLCs (default: false)
lock_owned_games = false
# Auto-sync Lua scripts and manifests in background after Steam completes updates (default: true)
auto_sync_on_update = true

[stats]
# Query stats API when setStat is absent
enable_api = true

[lua]
# Extra Lua directories to load (optional)
paths = []

[cloud]
# Steam Cloud redirection via CloudRedirect companion app
enabled = false
# library = "cloud_redirect.dll"

# Global DLL injection configuration (exclusion list)
[injects]
# AppIDs to strictly exclude from DLL injection (explicit config overrides built-in defaults; defaults protect ~20 competitive anti-cheat games)
# Note: Exclusion ONLY skips third-party DLL injection into game processes; game unlocking and DLC simulation are never affected!
exclude_appids = [
    730,      # Counter-Strike 2 (VAC)
    570,      # Dota 2 (VAC)
    1172470,  # Apex Legends (EAC)
    578080,   # PUBG: BATTLEGROUNDS (BattlEye)
    # See opensteamtool.example.toml for the full default list
]

# Individual library injection rules (array of tables, multiple allowed, commented out by default)
# [[inject]]
# path = "OnlineFix.dll"
# all_games = false
# when_cmdline = "-onlinefix"
# when_appids = [1361510]

[remote]
# Optional pattern metadata mirror (default GitHub with jsDelivr fallback)
# url_template = "https://your.server/{channel}/{component}/{sha256}.toml"

Global Injection Settings ([injects])

Key Explanation
exclude_appids List of AppIDs to strictly exclude from third-party DLL injection into game processes.
- Universal Protection: Strictly blocks DLL injection across rules unless explicitly overridden by a rule's when_appids whitelist;
- Explicit Override Principle: If explicitly configured (even with an empty list [] or a single game), strictly only these AppIDs are excluded (default list is not merged);
- Default Fallback Principle: If omitted entirely, automatically uses the built-in protection list (~20 competitive/anti-cheat titles including CS2, Dota 2, Apex, PUBG, etc.);
- Whitelist Priority: If an AppID is excluded here but explicitly specified in an [[inject]] rule's when_appids, the whitelist takes priority and the AppID will not be excluded for that rule.
Note: This exclusion strictly prevents DLL injection into game processes; game and DLC unlocking (addappid, manifests, tickets, etc.) are 100% active and unaffected!

Third-party DLL injection rules ([[inject]])

Key Explanation
path DLL to load. Bare file names resolve next to toml, DLL directory, or Steam root; absolute paths used as-is
all_games Optional. Defaults to false (strongly recommended).
- false: Only targets Lua-unlocked games. Important: If when_appids is omitted, ALL Lua-unlocked games will be injected upon launch! It is strongly recommended to specify when_appids (whitelist target AppIDs) or when_cmdline (e.g. "-onlinefix") to restrict injection;
- true: Global injection switch. Injects into all games (including genuine owned and free titles) launched via Steam, protected by [injects].exclude_appids above
when_cmdline Optional. Substring required in launch command line (e.g. "-onlinefix")
when_appids Optional. Whitelist mechanism targeting specific AppIDs (e.g. [1361510]). Takes priority over exclusion list: even if the target AppID is in the exclusion list, explicitly specifying it here ensures this rule injects into it

Manifest via Lua

If defined in config/lua/, these functions take priority over configured remote HTTP APIs:

  • fetch_manifest_code_ex(app_id, depot_id, gid) (Recommended): Extended variant receiving app_id, depot_id, and gid for app-aware API endpoints
  • fetch_manifest_code(gid): Base variant receiving manifest GID only

Built-in HTTP helper functions provided by the C++ runtime:

Function Signature Return Value
http_get http_get(url [, headers]) body, status_code
http_post http_post(url, body [, headers]) body, status_code

headers is an optional table: {["Key"]="Value", ...}


Debug logging

Debug builds write module logs under <Steam or Portable Dir>/opensteamtool/:

File Source Content
main.log General Init, config loading, Lua parsing
ipc.log LOG_IPC_* IPC commands, interface dispatch, spoofing
netpacket.log LOG_NETPACKET_* Network packet interception, eMsg dispatch
manifest.log LOG_MANIFEST_* Manifest downloads, depotcache mirroring
decryptionkey.log LOG_DECRYPTIONKEY_* Depot decryption key injection
keyvalue.log LOG_KEYVALUE_* KeyValues manifest patching
misc.log LOG_MISC_* Engine pointer capture, AppID mapping
achievement.log LOG_ACHIEVEMENT_* Stats and achievement handling
pics.log LOG_PICS_* PICS access token injection
package.log LOG_PACKAGE_* Package 0 licenses and dynamic revocation
onlinefix.log LOG_ONLINEFIX_* 480 online fix and AppID protection
richpresence.log LOG_RICHPRESENCE_* Rich Presence packet injection
steamui.log LOG_STEAMUI_* SteamUI state synchronization
inject.log LOG_INJECT_* Third-party DLL injection matching & results
pipe.log LOG_PIPE_* Pipe handshakes, Denuvo authorization
platform.log LOG_PLATFORM_* Platform helpers and remote injection

Build

Requirements

  • Windows 10/11
  • CMake 3.20+
  • Visual Studio 2022 with MSVC (x64 toolchain)

Quick build

build.bat

Output

  • Core Components (in build/Release/ or build/Debug/):
    • OpenSteamTool.dll, dwmapi.dll, xinput1_4.dll, ost-Injector.exe, and helper scripts
  • Standalone Tool (in build/tools/Release/ or build/tools/Debug/):
    • extract_tickets.exe (excluded from default release archive, explicitly built by build.bat)

Acknowledgments

Special thanks to upstream, contributors, and open-source projects:


Disclaimer

This project is provided for research and educational purposes only. You are responsible for complying with local laws, platform terms of service, and software licenses.

About

Open Source Steam Unlocker

Resources

Stars

102 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages