Prepare documented WhatsApp injector with portable Python bundle

This commit is contained in:
Ops Agent committed 2026-10-11 07:57:48 +02:00
commit d2b621bce7
49 files changed
+5737

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
# Architecture
## Execution path
The portable launcher verifies and decompresses its embedded payload, then imports the Python package directly from the in-memory ZIP. It uses the same CLI and modules as `python -m whatsapp_suite`.
For a core live operation, Python uses Windows APIs through `ctypes`. It verifies the helper DLL and supported application build, installs a temporary `WH_GETMESSAGE` hook on the Desktop UI thread, and passes a bounded JavaScript request through shared memory. The native helper locates the existing WebView object using build-specific signatures and calls its `ExecuteScriptAsync` interface. A thread message wakes the hook. Results return through the shared mapping; the hook, mapping and process handles are then released. Reports record cleanup outcomes.
This still uses native C++ DLLs. Python packages their bytes; it does not replace their implementation with pure Python. The C++ source is for maintenance and is unnecessary on a machine running the portable file. SHA-256 checks verify embedded asset integrity, not publisher identity or authenticity of a downloaded file.
Message export uses the app's own JavaScript database getter and row decoder. It paginates a bounded range, streams decoded records into a ZIP and writes a manifest. The scan is not an atomic database snapshot. Failed decodes remain visible and cause failure status. Final publication refuses existing output and verifies ZIP CRCs.
Contact export reads selected public fields from the local contact table. Sending is restricted to a fixed self-message test with recipient checks and persisted plaintext readback. No general-purpose arbitrary-recipient send CLI is provided.
## Boundaries
Live native operations support Desktop build `2.2639.100.0`. Updates may invalidate signatures and require new evidence and validation. Core bridge commands do not use CDP or UI automation; optional legacy commands have their own transports and dependencies. RAM readers only see loaded models. Exported message text does not include media file downloads. Password or passkey private-key extraction is not an implemented feature.
The repository includes only maintained source, synthetic fixtures and required runtime assets. Local profiles, extracted application code, credentials, messages, contacts and research dumps are excluded.
+179
View File
@@ -0,0 +1,179 @@
# WhatsApp test suite
## Portable single-file bundle
Copy **`whatsapp.py`** to another writable folder. That one Python file includes
all tools, both native helpers and the regression fixtures. No adjacent source
package, DLLs, C++ compiler or build script is needed to run it.
```powershell
python whatsapp.py --help
python whatsapp.py test
python whatsapp.py live --suite history-read
python whatsapp.py contacts-export --output contacts.json
python whatsapp.py export-zip --output messages.zip
python whatsapp.py send-self
```
The bundle compresses the original modules and resources together with LZMA.
It verifies its embedded payload and imports Python modules directly from memory.
Only a native helper needed for a live command is materialized in a hash-verified
cache beside the bundle. Keep the containing folder writable. Native helper
bytes, build checks, batch sizes and message read/send paths are unchanged.
Core WebView commands use the standard library. Python 3.11+, Windows x64,
64-bit Python and the supported WhatsApp build are still required for live
Desktop operations. Optional legacy CDP, Frida and QR tools retain the packages
listed below. Node.js remains optional for JavaScript fixture tests.
The development package below remains the editable source. Rebuild the generated
single-file distribution after changing it:
```powershell
python build_whatsapp_bundle.py
```
The build is deterministic and records size and SHA-256 in
`analysis/whatsapp-suite/bundle-build.json`. The build file is not needed on a
machine running the bundle.
The WhatsApp scripts are consolidated in `whatsapp_suite/`, with one CLI and
offline regression tests in `tests/`. Run commands from this workspace.
```powershell
python -m whatsapp_suite
python -m whatsapp_suite --help
python -m whatsapp_suite test --output analysis/whatsapp-suite/results.json
```
`python whatsapp_tests.py` is an equivalent entry point. The default run uses
fixtures and temporary files. It verifies saved-export parsing, Unicode search,
chat filtering, text redaction, history pagination/decryption contracts, fixed
probe responses, command dispatch, and bundled DLL hashes. Node.js runs the
JavaScript history fixtures; that test is reported as skipped if Node is absent.
Python 3.11 or newer is required.
To test an already running supported WhatsApp Desktop installation:
```powershell
python -m whatsapp_suite test --live
python -m whatsapp_suite test --capabilities
python -m whatsapp_suite live --suite math
python -m whatsapp_suite live --suite capabilities
python -m whatsapp_suite live --suite history-read --output analysis/whatsapp-suite/js-history-read.json
python -m whatsapp_suite export-zip --output exports/whatsapp-messages.zip
python -m whatsapp_suite contacts-export --output exports/contacts.json
python -m whatsapp_suite send-self
```
Live WebView probes require Windows x64, 64-bit Python, Desktop build
`2.2639.100.0`, and the verified WebView2 Core DLL. They use bundled native
helpers and check the build before installing a temporary hook. A missing or
unsupported app produces a failed live result. The JSON report includes cleanup
status. `--pid` selects a particular Desktop host.
## Tools
Every command supports `--help` for its options.
| Command | Purpose |
| --- | --- |
| `inventory` | List local Desktop storage files and sizes |
| `stats EXPORT` | Summarize a saved JSON or JSONL export |
| `search EXPORT QUERY` | Unicode-aware literal search of saved messages |
| `desktop-search QUERY` | Bounded native app search through WebView2; metadata output |
| `live --suite math\|capabilities\|all` | Fixed live WebView test suites |
| `live --suite message-json\|contacts` | Explicit fixed message search/contact sample; saves private data |
| `live --suite history-read` | Read the five oldest local message records through the JS database getter and decoder, without CDP |
| `webview-test` | Arithmetic check in a separate WebView2 host; may download its SDK |
| `analyze` | Storage analysis, optionally using an existing loopback CDP endpoint |
| `history-export` | Export local history through Desktop's own database decryption |
| `export-zip` | Export all local message rows to ZIP through JavaScript on WebView, without CDP or UI automation |
| `contacts-export` | Export all local contact rows to JSON through the app's JS database getter |
| `send-self` | Send one fixed test message to the signed-in account itself and verify stored plaintext |
| `ram-read` | Read loaded V8 message objects from process memory |
| `ram-search QUERY` | Search RAM models with verified collection membership |
| `native-search [QUERY]` | Experimental injected SQLite search, `--oldest --limit 5`, or `--export-index` |
| `qr-memory` | Recover candidate Desktop pairing QR payloads from RAM |
| `qr-window` | Save an already displayed Desktop linking QR |
| `pairing` | Start an isolated browser and request an official linking QR |
```powershell
python -m whatsapp_suite search export.jsonl "keyword" --redact-text
python -m whatsapp_suite desktop-search "keyword" --limit 10
python -m whatsapp_suite history-export --help
```
`history-read` uses the native WebView bridge to execute JavaScript in the running
app. It scans at most 100,000 local record timestamps in a read-only transaction,
then calls `WAWebSchemaMessage.getMessageTable().get` and
`WAWebDBMessageSerialization.messageFromDbRow` for the five oldest records.
It saves decoded body/caption text when present, including messages absent from
the loaded conversation models. System events and media-only records can have
no text. The live result includes page-state and native bridge cleanup status.
This command requires neither CDP nor optional Python packages.
`export-zip` uses the same native bridge and the app's JavaScript database getter
and decoder. It paginates all local rows up to the initial upper primary key,
streams them into `messages.jsonl`, and includes a `manifest.json` with row counts,
decoding errors, scope, and bridge cleanup status. Rows include message IDs,
chat IDs, timestamps, types, body and caption text; media files are not downloaded.
This is a live scan, not an atomic database snapshot. Row decoding failures are
preserved as error records and make the command return a failure status.
`--batch-size` controls bounded reads (default 100); `--redact-text` omits body and
caption text. Existing outputs are refused. Interrupted exports retain a
`.zip.partial` file and a `.zip.report.json` diagnostic report. A completed ZIP
is checked for CRC errors before publication.
`contacts-export` reads the local contact table rather than the five-contact
loaded-model sample. It exports selected identity, name, phone and business
fields. Local records can include separate PN/LID entries and contacts outside
the phone address book; this is not a deduplicated phone address-book export.
`send-self` resolves the signed-in account and checks both the selected chat and
outgoing message recipient before invoking the app's text-send action. It sends
one identifiable test message and reads it back through the message database
decoder, recording ACK and exact plaintext equality in a receipt. An existing
receipt is refused and sending is never retried automatically. Unlike the
offline test suite, this command actually sends a WhatsApp message.
The separate bulk `history-export` command requires an existing Desktop CDP endpoint. RAM tools only see
loaded objects and cannot retrieve all history. Pairing commands are separate
from the automated test run. The `runtime` module preserves the explicit
temporary CDP context manager for research scripts; entering that context
restarts Desktop and is never part of the default tests.
## Optional dependencies
The default suite, saved-export tools, and native WebView probes need only the
Python standard library (plus Node.js for the history fixture test).
| Tools | Additional Python packages |
| --- | --- |
| CDP analysis and history export | `websockets` |
| Injected SQLite search | `frida` |
| QR from RAM | `qrcode[pil]` |
| QR from Desktop window | `Pillow`, `zxing-cpp` |
| Isolated browser pairing | `websockets`, `qrcode[pil]`; installed Chrome |
Install all optional packages into a virtual environment with:
```powershell
python -m pip install -r requirements-whatsapp-optional.txt
```
## Layout and migration
- `whatsapp_suite/`: canonical tool implementations, common normalization,
storage paths, Desktop discovery, CLI, and test runner.
- `whatsapp_suite/assets/`: verified native DLLs and the native SQLite agent.
- `tests/`: synthetic Python regressions and the JavaScript history fixture.
- `analysis/whatsapp-suite/results.json`: latest automated test result.
The former `whatsapp_tool.py` commands now use `python -m whatsapp_suite`;
`whatsapp-search` is named `desktop-search`, and `whatsapp-test` is
`live --suite math`. The former `whatsapp_math.py` options are available under
`live`. Archived scripts have become package modules; the identical Desktop QR
RAM scripts have one implementation (`qr_memory`). Research helpers now import
these modules. Old script archive and portable script copies were removed.
The clean Git project excludes research reports, extracted application code and browser profiles. The surrounding original workspace retains those local files.
+17
View File
@@ -0,0 +1,17 @@
# Publish to tea.karlcom.de
This directory is the clean repository root. The surrounding research workspace is not the repository and must not be uploaded.
1. The configured repository is `https://tea.karlcom.de/karl/whatsapp_injector.git`.
2. Copy the SSH or HTTPS clone URL supplied by the server. Use your existing credential manager or SSH configuration; never embed tokens in the URL.
3. From this directory, inspect the tracked file list and configure the remote:
```powershell
git ls-files
git remote add origin https://tea.karlcom.de/karl/whatsapp_injector.git
git push -u origin main
```
The owner and remote URL were supplied by Karl. Repository visibility is controlled on the server. Never push the surrounding research workspace.
For a release, rebuild and test the bundle, then attach only `whatsapp.py` and a SHA-256 checksum to a server release. State the supported Desktop build and optional dependencies. Do not attach test exports or research reports. No server-specific CI workflow is included because runner availability and configuration have not been verified.
+17
View File
@@ -0,0 +1,17 @@
# Validation
Observed on 2026-10-11 in the original Windows development workspace. These observations describe that installation; they do not certify every command on every machine.
| Check | Result | Scope |
| --- | --- | --- |
| Portable offline regression suite | 30 tests passed, no failures/errors/skips | Isolated folder, Python `-I`, no adjacent source/assets |
| Portable contact export | Passed | 313 local contact rows |
| Portable old-message reading | Passed | 9,741 timestamp records scanned; five oldest records decoded |
| Portable native cleanup | Passed | Hook removed, handles released, helper unloaded |
| Deterministic build | Passed | Repeated build produced identical SHA-256 |
| Message ZIP export before bundling | Passed | 9,740 records, zero decode errors; plaintext verified |
| Self-message before bundling | Passed | One message sent; ACK 3 and exact persisted plaintext readback |
Every CLI help path is covered by regression tests. Synthetic fixtures cover parsing, normalization/search, export contracts, recipient guarding and helper cache integrity. Not every optional or live feature was rerun from the final bundle. Default tests do not send messages, link accounts or run live probes. JavaScript fixture checks can be skipped when Node.js is absent; inspect the report.
Run `python whatsapp.py test` for portable checks, or `python -m whatsapp_suite test` for source checks. Use `--help` before explicit live operations. Test reports and export artifacts are generated locally and ignored by Git. Do not commit live test output.
+8
View File
@@ -0,0 +1,8 @@
{
"note": "Runtime asset hashes; integrity only, not a publisher signature",
"sha256": {
"math_probe.dll": "136620d96f4745a4c41edfe1f4a9272ef25fc060ddace1c0eec1027bf252e02a",
"search_probe.dll": "911beb9f6bb52390cde8a75562ca1d6c46f4629f641426a5250286903de60895",
"sqlite_inject.js": "f31f31e170d30c0c845a3759db631d084b0bb096f1b654a9d9168a1078daed3f"
}
}