Prepare documented WhatsApp injector with portable Python bundle
This commit is contained in:
commit
d2b621bce7
49 files changed
+5737
No files matched your search
@@ -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
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user