Simplify documentation and add repository development skill
This commit is contained in:
1 parent
3d8cf46a63
commit
5aaa31dc1a
10 files changed
+473
-239
No files matched your search
+84
-17
@@ -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.
|
||||
Reference in new issue
Block a user