Reverse Engineering and Cracking Sublime Text 4 — DUMPS | Hardcore Engineering

[Skip to main content](#main)

[![<<HC&>|$ENG](/static/hc-eng-logo.svg)](/) 

[HOME](/) [SERVICES](/services) [ARTICLES](/articles) [DUMPS](/dumps) [APPS](/apps) [ABOUT](/about) 

CMD: 0 // CLK: 0 // KEY: 0 // 

take 2026-08-09 by Stephan Schielke / sc7a516f / [llm.md](/dumps/sublime-text-4-dev-patcher.md) 

# Reverse Engineering and Cracking Sublime Text 4

[#python](/dumps?tag=python) [#reverse-engineering](/dumps?tag=reverse-engineering) [#sublime-text](/dumps?tag=sublime-text) [#elf](/dumps?tag=elf) 

## [](#why-i-cracked-sublime-text-4)Why I cracked Sublime Text 4

Most devs know Sublime as a "free" text editor / IDE. Technically, Sublime Text can be *evaluated* for free but requires a license for continued use, which IMO is more than fair. However, I wanted to write an OSS Sublime Text 4 package (extension/plugin), and naturally wanted to use the latest version of the SDK to make it future-proof. With version 4205, after a decade, Sublime finally upgraded the Python plugin host to version 3.14. That is a huge jump, and it breaks a lot of contracts and interfaces between Sublime Text and packages. So, to properly test my new package, I had to install, run and test it against version 4205 — which is a `dev` version. Unbeknownst to me, ALL Sublime `dev` versions require a license to start and are not covered by the "evaluation" exception.

That left three choices:

*   Wait until version 4206 to get the new Python 3.14 SDK change
*   Write the plugin against soon-to-be-deprecated SDK functions
*   Buy a license to write an open-source package

I chose the fourth option: reverse-engineer the binary and write a crack and patcher, so I could test my package against the latest SDK.

## [](#cracking-sublime-text-4)Cracking Sublime Text 4

There are dozens of patchers for Sublime Text, but all of them are "dumb" and only ever provide a one-time solution for one specific Sublime binary. Given the massive internal core changes planned for Sublime Text 4205+, none of the existing patchers worked for such a recent (and `dev`) version. The previous reverse-engineering attempts of others did, however, offer some insight into how to approach the problem. Most binary patchers changed the return value of the "Enter your license" window so it would be accepted as valid.

I then had a look at the Executable and Linkable Format binary and extracted all raw string literals embedded in it, using [llvm-strings](https://llvm.org/docs/CommandGuide/llvm-strings.html) and [llvm-objdump](https://llvm.org/docs/CommandGuide/llvm-objdump.html), to find anything related to the license window. Next, [pyelftools](https://github.com/eliben/pyelftools) and [objdump](https://github.com/CyberGrandChallenge/binutils/raw/refs/heads/master/binutils/objdump.h) helped me identify the individual functions involved in the registration and license-check processes. Then I wrote a little helper using [strace](https://man7.org/linux/man-pages/man1/strace.1.html) to trace what happens when you start the software and enter a license.

Equipped with that information, I sent out an LLM agent to give me a visual representation of the program flow, the function signatures involved, and the expected return values. That is where most people stop: binary patching by hand, overwriting some hex values to change those "expected" values and trick the software into thinking it is registered.

![Sublime Text 4 About dialog showing Registered status on Build 4206 after patching](/static/images/dumps/Sublime%20Text%204206%20License%20Patcher.png)

Post-patch state — the About dialog reports "Registered to / Unlimited User License" on Dev Channel Build 4206. 

However, I noticed Sublime Text also tries to "phone home" for license checks, version update checks, and crash reports. So I decided to dig deeper and find ways to block those requests as well.

## [](#going-from-dumb-patcher-to-universal-crack)Going from dumb patcher to universal crack

I had already built a helper script to download any `main` or `dev` binary from scratch, so I could iterate over my hex changes always starting from a fresh binary. That raised the obvious question: why not patch ALL versions and make this future-proof (and history-proof)?

So I sent out an agent to locate signature patterns and caller fingerprints for the relevant patch sites structurally, instead of using hardcoded offsets. That makes the patcher build-agnostic across builds 4176 through 4206 (30+ builds, multiple architectures).

The patcher also supports optional hardening flags: `--hosts` (blocks phone-home), `--no-update` (silences the update popup), and `--no-crash` (prevents minidump upload). None of these touch the license patch itself; they are independent opt-ins.

## [](#how-to-use)How to use

```
uv run st4patch \
    --src 4206 \
    --out /tmp/sublime_text.patched \
    --hosts --no-update --no-crash
```

The pipeline:

1.  **Locate** — five patch sites resolved via byte signatures (not hardcoded offsets)
2.  **Patch** — NUL-padded, size-preserving rewrites at each site
3.  **Verify** — self-checks patched bytes against expected signatures
4.  **Report** — MD5 hash + per-site status printed to stdout

The locator uses [Capstone](https://github.com/capstone-engine/capstone) disassembly to fingerprint call-site prologues and resolve the valid-return convention per build. Below build 4176 the binary shape changes completely; above 4206 the approach should hold, but is untested.

## [](#links)Links

*   [GitHub repo](https://github.com/stephanschielke/sublime-text-4-dev-patcher) — source, research docs, and the full reverse-engineering record
*   [Sublime Text](https://www.sublimetext.com/) — buy a license if you use it
*   [Python 3.14 changelog](https://docs.python.org/3/whatsnew/changelog.html#python-3-14-5-final) — the plugin host that motivated this work

Source: [https://github.com/stephanschielke/sublime-text-4-dev-patcher](https://github.com/stephanschielke/sublime-text-4-dev-patcher) 

keyboard\_command\_key

/search for stuff Send a prompt to my LLMs /summarize a page Open a chat Use a /command Send a /dm to my phone Ask the /chat assistant Smash your head against the keyboard Hire me /search for stuff 

... 

CTRL+K