Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/development/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,30 @@ npm run pack:preview
directory to use. Set `SOURCE_DATE_EPOCH` to normalize staged file timestamps.
The packager rejects archive content, game/save data, logs, dependencies, and
build intermediates.

## Re-anchor after a game executable update

Add the exact executable size and SHA-256 to `native/host/game_builds.json` as
`diagnostic`, regenerate the header, build, and install the diagnostic host.
With the game offline and a disposable dynasty selected, run:

```powershell
node scripts/board-verification/reanchor-build.cjs preflight --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
node scripts/board-verification/reanchor-build.cjs validate --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
```

Stop after preflight and inspect the printed source/backup paths and matching
hashes before allowing normal game UI actions. Capture two vanilla write traces
per operation, rank them, and confirm one full execute entry:

```powershell
node scripts/board-verification/reanchor-build.cjs capture-add-write --capture 1 --recruit-row 100 --team-row 22 --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
node scripts/board-verification/reanchor-build.cjs capture-add-write --capture 2 --recruit-row 101 --team-row 22 --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
node scripts/board-verification/reanchor-build.cjs analyze --stage rank --operation add --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
node scripts/board-verification/reanchor-build.cjs capture-add-execute --recruit-row 102 --team-row 22 --game-dir "F:\EA SPORTS College Football 27" --save "C:\path\to\disposable-dynasty"
```

Repeat the sequence with `remove`, then run `transition-check` with an
operation and valid recruit/team rows after leaving and re-entering Recruiting.
Final `analyze` writes the ignored, identity-bound `candidate.json`. The host
never loads that file; only explicit source promotion can enable writes.
13 changes: 9 additions & 4 deletions docs/lua-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ local base = cfb.module_base()
local byte = cfb.read_u8(base)
local matches = cfb.aob_scan("4D 5A ?? ??", 8)

-- Writes require the supported build, offline safety gates, an exact expected
-- Writes require a certified build, offline safety gates, an exact expected
-- byte, writable committed memory, and successful readback.
local changed = cfb.write_u8(address, expected, replacement)

Expand Down Expand Up @@ -90,7 +90,8 @@ API.

`cfb.call` accepts any committed executable address in the current process,
zero to eight integer or pointer arguments, and returns the function's 64-bit
integer result. It is enabled only for the supported offline game build. Calls
integer result. It is enabled only for an exact registry-matched, certified
offline game build. Calls
are serialized and execute synchronously on the host worker that evaluates the
Lua buffer; the primitive does not move work onto a game-owned UI thread.
Floating-point/vector arguments, structure returns, and alternate ABI shapes
Expand All @@ -108,8 +109,12 @@ count. Each hit includes the integer registers, up to 256 stack qwords, and up
to eight safely readable qwords at each of `rbx`, `rsi`, `rdi`, `rcx`, `rdx`,
`r8`, and `r9` in fields such as `rcx_memory`. An unreadable pointer produces
an empty or partial array. `cfb.unwatch()` restores saved debug-register state.
These functions are current-process research tools; always collect and disarm
before continuing normal play.
These functions, including hit collection and clearing, are enabled only for
an exact registry-matched diagnostic or certified build while no real
anticheat is present. They are current-process research tools; always collect
and disarm before continuing normal play. Diagnostic status grants no native-
call or write authority. A `.frtk` profile or its runtime evidence cannot grant
or elevate research, native-call, or write authority.

Supported callback names are `game_ready` and `tick`. The host runs `tick`
callbacks approximately every 100 ms. The event protocol coalesces observable
Expand Down
39 changes: 29 additions & 10 deletions docs/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ writes as `memoryWriteTransaction`, and structured event registration as
unverifiable rollback has permanently disabled writes for the current host
session.

`hello.supportedBuild` and `status.supportedBuild` are `true` only for an exact
registry-matched certified executable identity. Research watches use a separate
gate: they require an exact diagnostic or certified identity and no real
anticheat. Native calls and every write path require certification. These
existing `hello` and `status` result shapes gain no additional policy keys.

The FrTk families are advertised as `frtkProfileV1`, `frtkCatalogV1`,
`frtkRecordReadV1`, and `frtkFieldTransactionV1`. Public table selectors always
use `uniqueId`; logical names are display text and current-build table IDs stay
Expand All @@ -80,6 +86,10 @@ Discovery advances generation on every attempt and installs no partial catalog
when a required table is unresolved. Inspection returns sanitized identity,
capacity, authority, generation, and bounded evidence only.

A `.frtk` bundle and all evidence derived from it are data-validation inputs,
not runtime credentials. They cannot certify an executable or grant research,
native-call, or write authority.

Typed reads accept 1–64 record selectors. Each result has fixed keys
`uniqueId`, `row`, and `values`; `values` is an ordered array of fixed-shape
`{ field, value }` entries. A value is a number or a packed reference represented
Expand Down Expand Up @@ -274,10 +284,11 @@ eight values. The host uses the Windows x64 integer/pointer ABI and returns the
```

The target must be a committed executable address in the current process, and
the host must recognize the supported offline game build. Calls are serialized
and run synchronously on the named-pipe request worker; this command does not
schedule onto a game-owned UI thread. The primitive supports integer and
pointer arguments only—no floating-point/vector arguments, structures, or
the host must match a certified offline game-build identity. A diagnostic
identity can use research watches but cannot call native code. Calls are
serialized and run synchronously on the named-pipe request worker; this command
does not schedule onto a game-owned UI thread. The primitive supports integer
and pointer arguments only—no floating-point/vector arguments, structures, or
alternate calling conventions. `NATIVE_CALL_TARGET_INVALID` rejects a
non-executable target. `NATIVE_CALL_EXCEPTION` reports a structured-exception
code, but cannot roll back native side effects that occurred before the fault.
Expand All @@ -288,16 +299,24 @@ The SDK method is `client.nativeCall({ address, arguments })` and negotiates the
## Recruiting board mutations

`addBoard { recruitRow, teamRow }` and `removeBoard { recruitRow, teamRow }`
invoke the current supported build's verified full recruiting handlers. The
invoke the current certified build's verified full recruiting handlers. The
rows identify the requested Recruit record and the active Team record; no team
is hardcoded. Both commands require the `boardMutationV1` capability and must
is hardcoded. Both commands require a matched certified registry entry with a
board layout, require the `boardMutationV1` capability, and must
be called while the recruiting runtime is loaded, but they do not depend on a
specific recruiting screen or selected UI row.

The host freshly resolves the recruiting controller and both record wrappers,
validates compact membership and freelist state before the call, and verifies
the complete table postcondition afterward. A successful result uses status
`applied_verified`; an already-satisfied add or remove uses `unchanged`.
On the first board mutation in a game session, the host resolves the recruiting
controller, both record wrappers, and required tables in one snapshot pass. It
caches those addresses only while all object and table signatures continue to
validate. Later calls normally reuse that cache. The SDK allows up to 120
seconds for this first discovery when the client uses its default timeout;
an explicitly configured client timeout remains authoritative.

Every call validates compact membership and freelist state before invoking the
handler and verifies the complete table postcondition afterward. A successful
result uses status `applied_verified`; an already-satisfied add or remove uses
`unchanged`.

```json
{"protocol":1,"id":"board-1","command":"addBoard","params":{"recruitRow":3182,"teamRow":92}}
Expand Down
23 changes: 16 additions & 7 deletions docs/safety.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ provide, distribute, or document an anticheat bypass.

`cfb.write_u8` rejects a write unless all of these conditions hold:

1. The process is the exact supported CFB27 executable build.
1. The process is an exact registry-matched, certified CFB27 executable build.
2. No real EA anticheat or Javelin process is detected.
3. The address belongs to committed writable memory.
4. The current byte equals the caller's expected byte.
5. Readback equals the requested replacement byte.

An unsupported build may load the host for diagnostics, but writes stay
disabled. The native `writeTransaction` command preserves the exact-build and
anticheat gates, validates and compares every operation before writing, applies
and verifies in request order, and rolls attempted operations back in reverse
order after an apply or verification failure.
An exact registry-matched diagnostic build may load the host for research, but
writes and native calls stay disabled. An unknown build has neither research-
watch nor write authority. The native `writeTransaction` command preserves the
exact-build and anticheat gates, validates and compares every operation before
writing, applies and verifies in request order, and rolls attempted operations
back in reverse order after an apply or verification failure.

Transaction sequencing is not game-thread atomicity. The host does not suspend
the game or provide a stable snapshot; callers must establish a stable window
Expand All @@ -54,6 +55,14 @@ Unique-ID/row/field/value changes, reread live records, and use the existing
guarded engine. Non-`direct_verified` authority fails closed before planning;
rollback failure still disables raw, typed, and Lua writes for the session.

Research watches are allowed only when the running executable exactly matches
a diagnostic or certified registry identity and no real anticheat is present.
Writes, native calls, FrTk field transactions, live-class replacement, and
board mutations require a certified identity. A loaded `.frtk` profile,
discovered layout, runtime scan, or other evidence can validate data for the
matched build, but cannot create or elevate runtime authority.

`CFB27_SMOKE_ALLOW_WRITES=1` is a native test gate recognized only when the
hosting executable is exactly `cfb27_protocol_smoke.exe`. It does not enable
writes in the game, MMC, or any other executable.
writes in the game, MMC, or any other executable, and it does not grant
research-watch authority.
Loading
Loading