Open Source Steam Unlocker
opensteamtool / steamrun / wudrm upstream APIs (default is opensteamtool), or a custom Lua endpoint (see Manifest via Lua)..lua files in any watched directory automatically triggers a reload. No restart, no offline/online toggle needed.[inject] in opensteamtool.toml.enabled, library_x64, and library_x86; the injected library must match the target process architecture.library_x64 and library_x86 may be absolute paths, or relative paths resolved from the Steam root directory.addappid in Lua. All accounts in the Steam Family that participate in sharing must use OpenSteamTool for this to work.AppTicket. OpenSteamTool can reuse Steam's local ConfigStore ticket and forge the requested AppId through a SteamDRMP off-by-four ticket parsing vulnerability, without injecting into the game process.AppTicket and ETicket through the platform credential store.setAppTicket(appid, "hex") and setETicket(appid, "hex") in Lua config to write these values to the platform credential store automatically.88500005; refresh the ticket data before retrying.setAppTicket and existing cached AppTicket credential values. If no explicit AppTicket is available, OpenSteamTool falls back to the forged local ConfigStore ticket path.SteamID first; if missing, parse from explicit AppTicket. On Windows, the credential store backend currently uses HKCU\Software\Valve\Steam\Apps\<AppId>. The Linux backend is not implemented yet.extract_ticketsThe extract_tickets tool dumps the AppTicket and ETicket hex strings you need for setAppTicket / setETicket. Run it on a machine where Steam is running and logged into an account that owns the target game.
build/tools/Release/extract_tickets.exe.extract_tickets.exe 1361510
steamclient64.dll, and writes everything into an <appid>/ folder next to the executable:appticket.bin — raw app ownership ticket (binary)eticket.bin — raw encrypted app ticket (binary)tickets.txt — plain-text summary with the hex strings:appid:1361510
appticket(184 bytes):14000000...
eticket(143 bytes):...
A ticket that could not be obtained is reported as appticket:null / eticket:null.
tickets.txt into your Lua config:setAppTicket(1361510, "14000000...")
setETicket(1361510, "...")
Note: Tickets are only valid when extracted from an account that genuinely owns the game.
setStat(appid, "steamid") to configure which SteamID's achievement data to pull.setStat is configured for an app, OpenSteamTool queries https://stats.opensteamtool.com/{appid} when [stats] enable_api = true (default).setStat > stats API when enabled and valid > hardcoded preset SteamID 76561198028121353.-onlinefix to the Steam launch parameters to enable 480-based online play in games that use lobby matchmaking. The current limitation is that only one such game can run at a time.To revert, simply remove -onlinefix from the launch parameters — online play returns to normal on the next launch.build.bat from the project root to build the project.dwmapi.dll, xinput1_4.dll and OpenSteamTool.dll to the Steam root directory.C:\steam\config\lua) and place Lua scripts there. The DLL will automatically load and execute them.…
All function names are case-insensitive. setAppTicket, setappticket, SetAppticket, SETAPPTICKET etc. are all equivalent. The same applies to every registered function (addAppId, AddToken, SETManifestid, etc.).
Rename opensteamtool.example.toml to opensteamtool.toml and place it in the Steam root directory (next to steam.exe).
If no config file is found, built-in defaults are used — no auto-creation.
The file is watched while Steam is running; valid changes are hot-reloaded without restarting Steam.
…
Two manifest code functions are supported:
fetch_manifest_code(gid)Basic function that receives only the manifest GID.
fetch_manifest_code_ex(app_id, depot_id, gid) (recommended)Extended function that receives app_id, depot_id, and gid. Allows constructing API endpoints that require app identification.
The C++ runtime provides two Lua helpers:
Function Signature Returnshttp_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", ...}.
OpenSteamTool no longer ships byte-pattern signatures inside the DLL. Instead, on each launch it computes the SHA-256 of steamclient64.dll and steamui.dll on disk and looks up a matching pattern file from the upstream tracker at OpenSteam001/steam-monitor (pattern branch).
Lookup order (every launch):
https://raw.githubusercontent.com/OpenSteam001/steam-monitor/pattern/.... Canonical source.raw.githubusercontent.com is blocked but jsDelivr is reachable (e.g. mainland China).<Steam>\opensteamtool\pattern\<subdir>\<sha256>.toml. Used only when remote is unreachable. The cache is overwritten after every successful remote fetch.Remote is consulted on every launch so users automatically pick up upstream re-publications (e.g. the bot adding a new signature, or fixing an existing one) without having to clear any cache.
If a step returns HTTP 404 the mirror loop stops immediately — all mirrors serve the same content, so a 404 means the upstream bot has not yet published a TOML for this Steam build. The code then falls back to the local cache if one exists; otherwise a one-shot popup appears with the unmatched DLL name, its SHA-256, the expected cache path, and the upstream URL. Only the hooks tied to that DLL are disabled — the rest of OpenSteamTool keeps working.
You can also drop a pattern TOML into the cache directory manually if you know the layout for a given build; the file name must be <sha256>.toml. The cache fallback will pick it up the next time remote is unreachable.
A short outbound HTTPS request is performed at every launch (one per DLL:
steamclient64.dll,steamui.dll). The downloaded bodies are tiny (~10 KB each) and the work runs on a worker thread, so it never blocks Steam's loader.
For most users, the built-in GitHub -> jsDelivr fallback is enough. To use a private mirror or intranet server, configure a full URL template. A custom mirror replaces the built-in remote sources; local cache fallback remains available.
The template must include {channel}, {component}, and {sha256}. Channels currently used are pattern and ipc.
[remote]
url_template = "https://your.server/{channel}/{component}/{sha256}.toml"
# url_template = "https://fast.jsdelivr.net/gh/OpenSteam001/steam-monitor@{channel}/{component}/{sha256}.toml"
Debug builds write per-module log files under <Steam>/opensteamtool/:
main.log
General
Init, config loading, Lua parsing, utilities
ipc.log
LOG_IPC_*
IPC commands, InterfaceCall dispatch, spoofing
netpacket.log
LOG_NETPACKET_*
Network packet send/recv, eMsg dispatch
manifest.log
LOG_MANIFEST_*
Manifest download, fetch_manifest_code, manifest binding
decryptionkey.log
LOG_DECRYPTIONKEY_*
Depot decryption key injection
keyvalue.log
LOG_KEYVALUE_*
KeyValues patching (manifest binding)
misc.log
LOG_MISC_*
Engine pointer capture, AppId hints
achievement.log
LOG_ACHIEVEMENT_*
UserStats requests/responses, steamid spoofing
pics.log
LOG_PICS_*
PICS access token injection
package.log
LOG_PACKAGE_*
Package injection, FileWatcher events
onlinefix.log
LOG_ONLINEFIX_*
Online fix (480 AppId spoofing)
richpresence.log
LOG_RICHPRESENCE_*
Rich Presence packet construction and injection
steamui.log
LOG_STEAMUI_*
SteamUI hook diagnostics
pipe.log
LOG_PIPE_*
Pipe handshakes, process inspection, Denuvo authorization, library injection
platform.log
LOG_PLATFORM_*
Platform helper diagnostics, including remote-process operations
The log level is controlled by [log] level in opensteamtool.toml.
raw.githubusercontent.com on first launch after a Steam update (see Steam version compatibility). Cached afterwards.build.bat
build/Debug/OpenSteamTool.dll, build/Debug/dwmapi.dll, build/Debug/xinput1_4.dllbuild/Release/OpenSteamTool.dll, build/Release/dwmapi.dll, build/Release/xinput1_4.dllThis project is provided for research and educational purposes only. You are responsible for complying with local laws, platform terms of service, and software licenses.
No open issues yet, or sync has not completed.