mrkeyoor.com_
Fri 25 Sept 06:48 UTC
Dev Toolsevaluationupdated 25 Sept 2026

badnotes review

BadNotes is an Objective-C tweak that alters Goodnotes subscription checks inside a modified iOS app. It replaces the service's response with data that claims the user has Pro access, so its purpose is to bypass a paid entitlement rather than provide a new note-taking feature.

Verdict

Our 3-CPU, 8 GB sandbox did not run BadNotes because Objective-C is unsupported there and the repository has no Dockerfile. Do not use release 0.3 as a way to avoid paying for Goodnotes Pro: the code forges subscription data, server-side features still fail, and the main compatibility issue remains open. Its defensible use is limited to authorized iOS security research on a disposable device.

We ran it

Screenshot of badnotes (github.com/c22dev/badnotes)

Answers from our run

Did you run badnotes yourself?

No. Its code is Objective-C, and it carries no manifest our lab installs from, and no Dockerfile, so there was nothing standard to install, build or test. This review is written from the repository's own documentation.

Who should not use badnotes?

Goodnotes users seeking free Pro access: the code is explicitly designed to forge a paid entitlement, which puts the app and account outside normal supported use.

What are the alternatives to badnotes?

Joplin, Standard Notes, Logseq. Do not use release 0.

Setup1/5No end-to-end setup guide; current iPadOS crash reports remain
Docs2/5The hook is explained, but signing and installation are omitted
Community2/5148 stars, two open issues, and no released compatibility fix
Maturity1/5Release 0.3 still has an unresolved immediate-exit report

Who it’s for

iOS security researchers studying response tampering in an app they are authorized to test.
Objective-C developers who want a small, readable example of runtime method replacement on a disposable test device.
Reviewers documenting why client-side entitlement checks should not be trusted on their own.

Who it’s NOT for

Goodnotes users seeking free Pro access: the code is explicitly designed to forge a paid entitlement, which puts the app and account outside normal supported use.
Anyone who depends on Goodnotes AI or collaboration: the README says these server-side features do not work.
People expecting release 0.3 to work on current iPadOS sideloading setups: issue 1 remains open after reports of a blank screen and immediate exit.
New iOS users who need a supported installer: the README gives one compiler command, while issue 2 exists because a reader could not find a step-by-step path.
Teams that require a verified build or test result: our sandbox could not run this Objective-C project, and the repository has no Dockerfile.

Setup reality

Our 3-CPU, 8 GB sandbox did not run commit 9687b80 on 2026-09-23. Objective-C is not a supported ecosystem in the runner, and the repository has no Dockerfile, so we have no install, build, or test result to report.

The README shows one xcrun clang command that produces a dynamic library. Actual use also needs an Apple-compatible build and signing environment, a decrypted Goodnotes IPA, and an injection or sideloading path. The repository does not document that path from start to finish.

Release 0.3 is iOS-specific. An open issue reports blank-screen crashes tied by the owner to CloudKit entitlements, and the README says AI and collaboration remain unavailable because those features are handled by servers.

BadNotes 0.3 forges one subscription response

BadNotes changes what Goodnotes sees when the app checks a subscription. Its single Objective-C source file replaces NSURLSession's request method at runtime, watches for the /v1/subscribers/ path, and rewrites the returned JSON. The substituted data says the account owns a Pro product and gives that entitlement an expiry in 2099. This is a client-side bypass of a paid service, not an independent notes app or an extension API.

Release 0.3 goes beyond changing one JSON field. The code suppresses StoreKit receipt refresh and restore calls, changes two localized strings, removes cache validators from matching requests, and reports a successful JSON response to the app. Those choices make the intent easy to audit because the whole implementation fits in Tweak.m. They also mean the tweak reaches into networking, purchases, and interface text inside an app it does not control.

What happened when we ran it

Our 3-CPU, 8 GB sandbox did not run BadNotes at commit 9687b80 on September 23, 2026. The lab has no supported Objective-C ecosystem, and this repository has no Dockerfile that could provide one. We therefore have no successful install, build, or test to claim. That limitation matters here because a compiler command in a README does not establish that an injected iOS app opens, signs correctly, or survives a Goodnotes update.

The unprivileged sandbox also had no Apple device, iOS signing setup, or decrypted Goodnotes package. We did not substitute a different environment and call that equivalent. The useful result is the boundary itself: BadNotes cannot be evaluated through the project's documented command on our standard Debian runner. Any reliability judgment must therefore come from the source, release history, and reported device behavior rather than from a run we did not perform.

One compiler command does not produce an installable app

The README's build section contains one xcrun clang command for an arm64 dynamic library. It does not explain how to obtain or sign the host app, which iOS and Goodnotes versions match release 0.3, how to remove the tweak, or how to recover user data after a crash. That gap is visible in issue 2, where a reader asks for a tutorial and receives a community answer involving third-party sideloading rather than maintainer documentation.

A manual GitHub Actions workflow fills in part of the missing machinery. It accepts two URLs, downloads a decrypted IPA and a tweak, clones insert_dylib and ivinject, then publishes a modified IPA as a release asset. The workflow's default tweak URL still points to version 0.1 even though 0.3 is the latest tag. It also reads the tweak's MIME type without rejecting an unexpected result, so that step's name promises more validation than its shell commands perform.

Server-side Goodnotes features remain unavailable

BadNotes writes an AI quota of 525 into its replacement response, but the README plainly says server-side features such as AI and collaboration will not work. That is the right warning to believe. A local response patch can change what the interface thinks an account owns, while a remote service can still check authorization before doing work. Anyone choosing the tweak for those features is choosing the one part the author already excludes.

The open compatibility report is more basic. Issue 1 describes a white screen followed by an immediate exit on current iPadOS installation attempts. The owner attributed the failure to missing CloudKit entitlements and said on September 8 that a fix had been found but was not yet released. GitHub shows the latest push and release 0.3 on September 7, so the repository history does not contain that later promised update.

September activity has not produced the promised fix

GitHub listed 148 stars and 2 open issues and pull requests when we fetched the repository. The last push was September 7, 2026, the day release 0.3 appeared. Issue 1 was still receiving comments through September 20, which shows user interest, but activity around a problem is different from a shipped correction. The owner answered early in the thread, yet the release available to users still predates the claimed fix.

The project is also young. Its first commit landed on September 1, followed by three numbered releases within one week. Fast iteration can be useful during an experiment, but it leaves little compatibility history for a tweak that depends on private behavior inside another iOS app. With no result from our sandbox and no documented device matrix, a cautious reader should treat every Goodnotes update as an unverified target.

Three legitimate note apps avoid the entitlement bypass

Joplin is an offline-first Markdown notes app with iOS support and several sync choices. Standard Notes provides end-to-end encrypted notes across mobile and desktop clients. Logseq is aimed at linked, local knowledge management and includes mobile work. None is a drop-in replacement for Goodnotes handwriting, but each offers a supported path to open-source note-taking without injecting code into a commercial app or fabricating a purchase record.

BadNotes 0.3 is most defensible as a compact security example: it shows exactly why a paid entitlement should not depend on mutable client data. That lesson does not make the tweak a sensible daily tool. The published release still lacks the post-September 8 compatibility fix, the main issue still reports immediate exits, and the project's own README rules out the server features that might otherwise justify the risk.

Alternatives

ProjectWhat it isPick it when
Joplin gh↗A free, offline-first notes and to-do app with Markdown, mobile clients, and several sync choices.pick this instead when you want a legitimate iOS notes app whose core features are open source.
Standard NotesAn end-to-end encrypted notes app with cross-platform clients and a self-hosting route.pick this instead when encrypted sync and supported mobile apps matter more than Goodnotes compatibility.
Logseq gh↗A privacy-focused knowledge manager built around outlines, Markdown, tasks, and links.pick this instead when you want local knowledge management rather than a patched commercial app.

What people are saying

  1. [velocity-scout] c22dev/badnotes

Sources

  1. BadNotes repository
  2. BadNotes README
  3. BadNotes 0.3 source
  4. BadNotes release 0.3
  5. Current iPadOS compatibility issue
  6. BadNotes IPA build workflow

More dev tools reviews

container · awesome-neovim · zeron · cs2-dumper · hackingtool · react-native-continued-task · the whole board →