Simplify documentation and add repository development skill

This commit is contained in:
Ops Agent committed 2026-10-11 09:03:49 +02:00
1 parent 3d8cf46a63
commit 5aaa31dc1a
10 files changed
+473 -239

No files matched your search

+84 -17
View File
@@ -1,35 +1,102 @@
# Architecture
## Execution path
## Two ways to run the same code
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`.
`python -m whatsapp_suite` runs the editable source package. `python whatsapp.py` runs its generated portable distribution through the same CLI.
For a core live operation, Python uses Windows APIs through `ctypes`. It verifies the helper DLL, records application/WebView compatibility, installs a temporary `WH_GETMESSAGE` hook on the Desktop UI thread, and passes a bounded JavaScript request through shared memory. The native helper discovers function/vtable locations from relocation-free binary fingerprints and locates the existing WebView object using those dynamically resolved addresses 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.
The builder stores the maintained modules, fixtures and selected assets in a compressed archive. The launcher verifies its payload, imports Python modules from memory, and extracts only the native helper needed for a live operation into a hash-verified cache beside the bundle. A C++ compiler is needed to change native code, not to run the portable file.
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.
## Live JavaScript execution
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.
```mermaid
sequenceDiagram
participant CLI as Python CLI
participant DLL as Native helper
participant WV as Existing WhatsApp WebView
CLI->>CLI: Detect host and UI thread; verify helper
CLI->>DLL: Temporary Windows hook + shared request
DLL->>DLL: Discover and validate native layout
DLL->>WV: ExecuteScriptAsync
WV-->>DLL: JavaScript result
DLL-->>CLI: Shared result packet
CLI->>CLI: Release hook, mappings and handles
```
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.
Python calls Windows APIs through `ctypes`. A `WH_GETMESSAGE` hook loads the helper on WhatsApp's UI thread. A thread message wakes it; a shared mapping carries a bounded request and result.
## Boundaries
The helper scans the loaded WebView component for relocation-free code fingerprints and a matching vtable layout, then locates the existing object and validates its script-execution method. This avoids fixed module-relative function addresses. Compiler/object-field and interface ABI assumptions remain.
Live native operations were tested with Desktop build `2.2639.100.0`. Other versions are attempted with a warning. The helper resolves function and vtable addresses dynamically, but retains function fingerprints, an object field offset and the exact interface ABI derived from the tested WebView DLL. A changed layout may fail discovery or cause process instability; dynamic address discovery does not make all compiler/object layouts compatible. Updates require new evidence and validation to be considered tested. 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 hook is temporary. Normal exports and probes record cleanup of the hook, mapping, process handles and helper. Native failures are not evidence that a different layout is safe.
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.
## Read, search and send
## Security mechanism classification
| Operation | Data path | Boundary |
| --- | --- | --- |
| ZIP export | App database getter → app row decoder → paginated records → ZIP | Local rows; no atomic snapshot, phone sync or media download |
| Old-message read | Timestamp scan → five oldest rows → app decoder | Bounded scan; not limited to loaded chat models |
| Contact export | Local contact table → selected identity/name/business fields | May contain separate PN/LID records |
| Desktop search | Existing app message search → bounded metadata | Search scope comes from the app |
| Saved-export search | Python JSON/JSONL parsing and normalization | Does not need the app |
| Self-message | Resolve own identity → guarded send → stored readback | One fixed test message; no arbitrary-recipient CLI |
The observed implementation uses documented Windows hook loading and WebView script execution APIs. It does not demonstrate a memory-corruption exploit, privilege escalation or a cryptographic break. It obtains the running application's existing decrypted data through that application's internal getters under the current signed-in session.
Database text is decoded through WhatsApp's own JavaScript methods under the signed-in session. Failed row decodes remain explicit. Export publication refuses existing outputs and checks ZIP CRCs.
However, loading a helper into another process and locating internal objects by memory layout is reverse-engineered process instrumentation. WhatsApp does not expose the internal module calls used here as a documented external automation API. Calling documented OS/WebView APIs does not establish that this overall integration is supported or intended by WhatsApp, nor is this observation a complete security audit.
## Listener and delivery
References: [Microsoft SetWindowsHookExW](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw), [Microsoft WebView2 JavaScript execution](https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/javascript).
```mermaid
flowchart LR
M["Loaded message collection"] --> J["JS observer and decoded queue"]
J --> N["UI-thread native timer"]
N --> H["WinHTTP worker"]
H --> T["HTTPS target or loopback receiver"]
T --> A["HTTP 2xx"]
A --> Q["Remove acknowledged queue entries"]
R["Optional Windows minute task"] --> I["Restore after app restart"]
I --> J
```
## Autonomous webhook relay
The JavaScript producer observes message collection events, obtains stored rows through the app decoder, and queues bounded message events. It does not contain transport credentials. A UI-thread timer executes short queue scripts; a worker performs HTTP delivery outside that UI thread.
The explicit `webhook install` command registers JavaScript message collection observers and installs a separate resident helper. A UI-thread timer runs short queue-peek scripts; a WinHTTP worker posts bounded batches to the configured HTTPS endpoint or `127.0.0.1:port/whatsapp-webhook`, without proxies or redirects. HTTPS uses certificate validation and a token header. Queue entries are removed after HTTP 2xx. The built-in loopback receiver acknowledges after SQLite commit and deduplicates message IDs.
Direct HTTPS uses certificate validation and a token header. Loopback mode posts to a local receiver. Proxies and redirects are disabled. Native WinHTTP supplies the outbound transport; direct JavaScript localhost requests were blocked by WhatsApp's CSP during testing, and the implementation does not weaken CSP.
The installer exits and releases its temporary hooks. The webhook helper retains one module reference so native callbacks remain valid; stop cancels the timer and releases WebView references but leaves an idle DLL loaded until app exit. This is intentional and distinct from the short-lived test/export helpers' unload checks.
HTTP 2xx triggers queue acknowledgement. Failures leave records for retry. A consumer must deduplicate IDs; this is not exactly-once delivery. The built-in local receiver commits SQLite data before acknowledgement.
App process exit destroys both the injected JavaScript and resident relay. For direct HTTPS, `--auto-restore` registers a per-user Windows task that runs a short `webhook ensure` check every minute. It uses a DPAPI-protected token and does not keep Python or a local server running between checks. Alternatively, a loopback receiver started with `--restore-config` checks every five seconds. Saved configuration persists; injected process memory does not. See [webhook guide](WEBHOOKS.md) for limits.
The installer exits after setup. The native relay retains a module reference so timer/worker callbacks remain valid. Stop cancels observation/timers and releases WebView references; an idle DLL remains loaded until app exit.
## Restoration and configuration
WhatsApp process exit destroys the listener and native relay. Automatic restoration is a separate capability:
| Mode | Bootstrap | Lifetime |
| --- | --- | --- |
| Direct HTTPS with `--auto-restore` | Per-user Windows task invokes `webhook ensure` every minute | Short Python checks; no continuous local server |
| Loopback receiver with `--restore-config` | Receiver checks every five seconds | Receiver must remain running |
| Optional `watch` | Python restoration loop | Watcher remains running |
The task runs as the logged-in user with limited privileges. It stores paths to Python, the bundle and configuration; moving them breaks that registration. Direct restoration recovers a current-user DPAPI-protected token from the configuration. The bundle is portable, but that protected configuration is tied to the Windows user/machine.
Reinstallation reconciles qualifying loaded models since the saved start timestamp; it does not perform complete database catch-up. In-memory queues can be lost on exit, and messages in startup/polling gaps are not guaranteed to be delivered. See [the webhook guide](WEBHOOKS.md) for schema and limits.
## Source map
| Layer | Files |
| --- | --- |
| Command dispatch and tests | `cli.py`, `runner.py`, `tests/` |
| Shared resources/cache | `common.py` |
| Windows orchestration | `desktop.py`, `live.py`, `native_search.py` |
| Data operations | `history.py`, `zip_export.py`, `contacts_export.py`, `exports.py`, `self_message.py` |
| Listener orchestration | `webhook.py`, `assets/webhook_listener.js` |
| Native implementations | `native/math_probe.cpp`, `search_probe.cpp`, `webhook_probe.cpp`, `core_discovery.h` |
| Portable packaging | `build_whatsapp_bundle.py`, generated `whatsapp.py` |
All Python filenames above are under `whatsapp_suite/`. See [contributing](../CONTRIBUTING.md) for extension steps and hash updates.
## Compatibility and security boundaries
The tested Desktop build is `2.2639.100.0`. Other builds produce advisory metadata/warnings and are attempted, but dynamic address discovery does not imply compatibility with every future compiler/object layout. Changed layouts can fail or cause process instability.
The observed bridge uses documented Windows loading and WebView execution APIs. It does not demonstrate memory corruption, privilege escalation or broken encryption. The overall integration remains reverse-engineered process instrumentation: WhatsApp does not document these internal module calls as an external automation API. This is not a complete security audit.
Passwords/passkey private keys and media download are not implemented features. Core commands use no CDP or UI automation; optional research tools have separate transports. Hashes establish integrity, not publisher identity.
See [validation](VALIDATION.md) for evidence, [security](../SECURITY.md) for private-data handling, and [Microsoft's Windows hook](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw) and [WebView JavaScript](https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/javascript) documentation for the public APIs.