Skip to content

robin-scharf/gapbf

Repository files navigation

GAPBF

Pipeline status on GitLab CI

GAPBF is a Linux-first Python CLI for brute-forcing Android pattern locks through TWRP recovery using a graph-based path generator.

It is intended for legitimate device recovery scenarios where you control the device, can boot into TWRP, and want to constrain the search space using partial knowledge of the original unlock pattern.

Current Status

  • Typer-based CLI with Rich output
  • SQLite-backed run history and attempt persistence
  • Resume-aware status reporting
  • Geometric path generation with Android-style blocker rules plus optional user-defined distance pruning
  • Tested with pytest and packaged via uv

Constraints

  • Linux-focused workflow
  • Requires adb access to a device already booted into TWRP
  • TWRP enforces an effective per-attempt delay; this project does not bypass that limit
  • Large search spaces are still expensive, so partial pattern knowledge matters
  • 6x6 pattern support is still based on an assumed mapping and should be treated as experimental

How It Works

GAPBF generates valid pattern paths for Android-style grids and evaluates them through one or more handlers:

  • a: send attempts to TWRP via adb shell twrp decrypt ...
  • p: print generated paths for inspection/debugging
  • t: compare generated paths against a configured test path

Run and attempt metadata is stored in SQLite so interrupted sessions can be inspected later with the CLI.

Requirements

  • Linux
  • Python 3.11 or newer
  • uv
  • adb
  • A device with pattern lock support and TWRP recovery available

Installation

git clone git@github.com:robin-scharf/gapbf.git
cd gapbf
uv sync --dev
cp config.example.yaml config.yaml
uv run pre-commit install
uv run pre-commit install --hook-type pre-push

This repo uses pre-commit as the Python equivalent of Husky:

  • pre-commit runs ruff check and mypy before each commit
  • pre-push runs the full pytest suite before each push

Run the hooks across the whole repository at any time with:

uv run pre-commit run --all-files
uv run pre-commit run --hook-stage pre-push --all-files

Quick Start

Inspect the available commands:

uv run gapbf --help

Check that the device is visible to ADB/TWRP:

adb devices
uv run gapbf check-device

Review current configuration and resume state:

uv run gapbf status

Launch the local web UI:

uv run gapbf web
uv run gapbf web --config config.yaml --host 127.0.0.1 --port 8000

Run the brute-force process:

uv run gapbf run -m a

Use combined modes when needed:

uv run gapbf run -m ap
uv run gapbf run -m t

Review stored run history:

uv run gapbf history
uv run gapbf history --limit 10

Legacy-compatible invocation is still supported:

uv run gapbf -m ap

Configuration

This repository ships a template config at config.example.yaml.

Create your local runtime config with:

cp config.example.yaml config.yaml

config.yaml is intentionally gitignored so device-specific settings, path constraints, and local runtime values stay out of commits.

Runtime configuration is loaded from config.yaml by default.

Important fields include:

  • grid_size
  • path_min_length
  • path_max_length
  • path_max_node_distance
  • path_prefix
  • path_suffix
  • excluded_nodes
  • attempt_delay
  • adb_timeout
  • db_path
  • stdout_normal
  • stdout_success
  • stdout_error

path_max_node_distance is a user-defined search limiter, not part of the underlying blocker legality check. It caps how far a single move may travel in grid coordinates.

  • 1 keeps moves to direct neighbors
  • grid_size - 1 allows the full theoretical move range for the selected grid
  • intermediate values intentionally prune longer jumps to reduce the search space

By default, GAPBF now uses the theoretical maximum for the selected grid, so a 3x3 config defaults to 2, a 4x4 config to 3, and so on up to 5 for 6x6.

The web UI exposes the same configuration surface with grid-aware limits and live validation. Prefix and suffix segments can be drawn directly on the board, excluded nodes can be toggled visually, and run progress plus attempt logs stream back into the browser while a search is active.

Constrain the pattern space as aggressively as possible. Prefixes, suffixes, excluded nodes, and realistic path lengths have a much larger effect on runtime than implementation-level optimizations because TWRP remains the throughput bottleneck.

Grid Mappings

GAPBF supports 3x3, 4x4, 5x5, and 6x6 pattern grids. Availability of non-3x3 grids depends on the device, ROM, and recovery implementation you are working with, so treat the larger layouts as environment-dependent rather than assuming every Android build exposes the same settings UI.

Example 3x3 grid:

[
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

Example 4x4 grid:

[
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, :, ;, <],
    [=, >, ?, @]
]

Example 5x5 grid:

[
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, :],
    [;, <, =, >, ?],
    [@, A, B, C, D],
    [E, F, G, H, I]
]

Current 6x6 assumption:

[
    [1, 2, 3, 4, 5, 6],
    [7, 8, 9, :, ;, <],
    [=, >, ?, @, A, B],
    [C, D, E, F, G, H],
    [I, J, K, L, M, N],
    [O, P, Q, R, S, T]
]

Development

Run tests:

uv run python -m pytest

Run the same quality gates used by the Git hooks:

uv run ruff check .
uv run mypy src
uv run pytest

The project is packaged from src/gapbf and exposes the gapbf console script via pyproject.toml.

Roadmap

See NEXT_STEPS.md for follow-up work, known gaps, and suggested improvements before broader public distribution.

License

This project is released under the GNU GPL-3.0 license. See LICENSE for details.

About

Graph-based Android lock pattern brute forcer based on timvisee/apbf.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors