THIS PROJECT IS A REA (Reverse Engineering Anything) CAPABILITY DEMONSTRATION ONLY.
- It exists to show what REA (Reverse Engineering Anything) can do, not to crack Guitar Pro 8.
- NO working licence bypass is implemented or shared. Only the trial-day display counter of a local, re-signed copy is patched for observation. The actual licence chain is left intact — in fact this repo documents that it still fails at
tryGetLicence(). - It is not fully implemented (intentionally) and will never be distributed as a usable crack. Do not ask.
- Reverse-engineering and modifying software may be illegal in your jurisdiction and violates the vendor's terms. Run this only on software you legally own, on your own machine, for learning.
- It is provided AS-IS, with NO warranty of any kind. Authors accept NO liability for anything you do with it.
- USE AT YOUR OWN RISK. You alone are responsible.
Demonstrates abilities of REA (Reverse Engineering Anything) In this project we are injecting a value into Guitar Pro 8's trial-day counter. Guitar Pro 8's Welcome dialog is read straight out of one function, and that the value can therefore be injected from outside the process.
| Layer | Tool |
|---|---|
| Static analysis | REA → Ghidra 12.1.4 (arm64 thin slice) |
| Runtime injection | Frida 17 (Interceptor.replace) |
| Orchestration | Rust 2021 CLI, no async runtime |
| Target | Qt5 C++ Mach-O, not stripped, no DWARF |
Symbols resolve by mangled-name substring at run time, so there is no address table and no dependence on ASLR or app version.
REA/Ghidra traced the number to a single function,
gp::base::LicenceModel::demoDaysLeft() const, whose whole body is:
return isSystemTimeFraud() ? 0 : abs(_initialDemoPeriodDaysLeft());demoDaysCount() is hardcoded mov w0, #0x7, so the trial is 7 days. The
Welcome dialog drives off updateDaysLeftLabel(int), whose argument is the
rendered number — that is the evidence the tool reports.
gpdays N replaces demoDaysLeft with movz w0, #N ; ret.
Two things worth knowing:
- The dialog clamps. The progress bar's maximum is the real trial length,
so a value above it never reaches the label (
N=8renders as 7).--extend Mraises that cap viademoDaysCount. --observereports the real value without patching anything.
cargo build --release --manifest-path rust/Cargo.toml
target/release/gpdays 3 # inject 3 days -> [7, 3] PASS
target/release/gpdays 999 --extend 1000 # above the real cap PASS
target/release/gpdays --observe # real value, nothing patched
target/release/gpdays --observe --chain # + full licence validation chain
target/release/gpdays --setup # (re)create and re-sign the working copyBy default the app stays up with the hooks attached so you can click through
the Welcome dialog; Ctrl-C detaches and leaves it running. --kill reports
and terminates instead. -v streams hook events.
Exit code is 0 only when the UI sink actually received the requested value.
The shipped app is hardened runtime without get-task-allow, so
task_for_pid is refused and nothing can attach. The tool works on a copy that
is re-signed ad-hoc with get-task-allow and without hardened runtime.
/Applications is never modified. artifacts/ holds the 280 MB copy and is
gitignored.
target/release/gpdays --observe --chain reports, on this machine:
tryGetLicence() == 0— the only failing link. No licence is installed, which is correct behaviour, not a bug.isSystemTimeFraud() == 0— the clock-rollback theory is ruled out, even though that function sits directly on the days-left path.isLicenceValid/isLicenceBlacklistednever run; the chain short-circuits attryGetLicence().
Full write-up, including the corrections and the failed approaches, is in NOTES.md.
