High-fidelity browser runtime for Python, powered by V8 (import as iv8_rs)
Project description
iv8-rs
High-fidelity browser-like JS runtime for Python (V8 + Rust + PyO3).
Built for Web JS reverse engineering, controlled re-execution, anti-bot / fingerprint host simulation, and ChaosVM-class instrumentation / analysis.
Current: milestone continuum through v0.8.102 · package 0.8.12 (D-151 dual-track) — CHANGELOG
PyPI: ming_iv8_rs · import: import iv8_rs · package track: 0.8.12 (D-151; not the same number as continuum tags v0.8.10x)
中文版:README.zh-CN.md · API contracts:docs/api/ · Coverage audit:docs/api/COVERAGE.md
Origin: why iv8-rs exists
We first met iv8 (the PyPI iv8 0.1.x line): V8 inside Python, environment-driven browser surface — a shape that fits Web reverse work. We wanted the same product category, dug one layer deeper:
- Sturdier host surface — not only “can eval”, but brand checks, getters, Workers, Intl, DOM collections under high-signal probes;
- Reproducible runs — offline ResourceBundle, deterministic seeds, logical clocks for CI and dual-engine compare;
- Execution + observation together — run the script in a host while
instrument_source/ CDP / unified traces open ChaosVM / TDC-style paths. A bit “left foot on right foot”, but the intent is real: runtime host + analysis plane on one stack.
Product intuition borrows from iv8 (Python-friendly, injectable environment, offline-first). The kernel choice is Rust + PyO3 + large codegen/native browser surface for performance, type boundaries, and long-term maintenance.
No need to dunk on peers. This repo and PyPI iv8 0.1.x are related lineage / dual-engine oracle. The product name here is iv8-rs — not “replace X”, but “same spark, deeper dig”.
Design philosophy: two branches, one loop
iv8-rs is not “only a browser stub” and not “only a decompiler”. The core bet is a dual-branch product:
| Branch | Name | Question it answers |
|---|---|---|
| A | Runtime host | Can this script run under a controlled, browser-like host? |
| B | Runtime analysis | Can we observe, structure, and reason about what that run did? |
They are meant to feed each other: a better host produces cleaner traces and fewer Illegal-invocation lies; better analysis points back at missing host surface, wrong brands, or incomplete network. Informally: left foot on right foot — host fidelity and analysis depth climb together, not as two disconnected tools.
What ships today is a strong Branch A plus a usable Branch B spine (instrumentation, unified trace, entry plane, diagnostics). Deeper IR / SSA / full decompile pipelines are an explicit desired state on Branch B — not vaporware branding, not “everything unfinished,” but a north-star map of where analysis is going while Branch A remains the production weight.
Branch A — runtime environment (host)
The script must believe it lives in something like a page: same-thread V8 isolate, large browser surface, offline-first I/O, deterministic knobs for CI.
| Layer | Includes (illustrative, not exhaustive) |
|---|---|
| Kernel | V8 isolate, stack/thread affinity, ICU/Intl + timezone redetect, logical vs system time, seeds |
| Browser surface | Window / Navigator / Screen / Location / DOM parse & query, events, collections, Workers |
| Media & crypto | Canvas, WebGL params, Audio paths, SubtleCrypto |
| Network | ResourceBundle → optional Python handler → error (no silent open crawl) |
| Identity | Profiles, flat environment overrides, storage, cookies/headers helpers |
| Anti-detect building blocks | wrap/hook natives, chrome object, toString / brand hygiene (fidelity, not “pass all detectors”) |
| Product honesty | Explicit non-goals: not full Chromium, not layout luxury, not one-click bypass |
Branch A is what makes controlled re-execution possible: same inputs, same seeds, offline chunks, dual-engine compare.
Branch B — runtime analysis (observe & structure)
Once the host can run the payload, Branch B turns the run into evidence: traces, diffs, entry plans, diagnostic reports — and, as the desired state deepens, richer intermediate forms.
| Layer | Today (shipping spine) | Desired state (north star, not a claim of full completion) |
|---|---|---|
| Instrumentation | instrument_source / ChaosVM path A, global instrument_chaosvm, env Proxies |
Broader VM families, lower false Illegal-invocation, optional expose_handlers policies |
| Trace plane | Unified D/R/C/W lines, VM trace, trace_diff, recording / profiler / coverage |
Stable schemas, streaming, multi-run corpora as first-class |
| Debugger / CDP | DevTools attach, breakpoints, step, Debugger helpers |
Deeper scope/object UX, CI-friendly programmatic sessions |
| Entry / bundlers | prepare_entry / run_with_entry / multi-entry plans; caller-owned chunks |
Richer bundler graphs without silent network fetch |
| Structure & reasoning | CFG / taint / pattern / crypto detectors, report models, environment plane (diagnostic) | IR / SSA-style views, opcode/handler IR, string-array & deobf reports as a coherent pipeline, cross-version VM diff as default workflow |
| Formats & adapters | Schema-versioned reports, corpus manifests | More intermediate formats, dual-oracle packs, export for external RE tools |
Branch B must stay honest: default environment toolchain is report-only; analysis is not a “site bypass kit.” Deeper IR/SSA language in the table is design intent — pieces exist or are scaffolded; the full pipeline remains the climb, not a checkbox of “already done.”
How A and B reinforce each other
+------------------+
| JS under test |
+--------+---------+
|
+--------v---------+
| Branch A: host | run / freeze / offline / brand
+--------+---------+
| traces, events, gaps
+--------v---------+
| Branch B: analyze | instrument, CFG, plan, report
+--------+---------+
| missing surface, wrong values, entry fixes
+-----> back into Branch A (profiles, shims, network)
- A → B: Without a faithful host, traces are noise and Illegal invocation masks real logic.
- B → A: Diffs and probes show which getters, plugins, or network edges still lie.
- Loop: Each milestone should either harden the host, deepen observation, or tighten the contract between them.
That is the product thesis: one Python process, two complementary branches, not a pile of unrelated scripts.
Why this technical path
| Approach | Common gap |
|---|---|
| Pure Node / pure Python | Thin browser surface; instanceof, getters, workers, Intl often wrong |
| Full CDP browser only | Heavy, hard to instrument VMs offline, non-deterministic for CI |
| Thin stubs | Fail brand checks, canvas/WebGL/crypto fingerprints, DOM collections |
iv8-rs embeds V8 with a large native browser surface, offline ResourceBundle networking, deterministic seeds, ChaosVM / instrument_source path A, multi-bundler entry plane, and a diagnostic environment toolchain — one Python process, same-thread isolate, honest bounds (not full Chrome).
Capabilities
Organized by domain, not version waterfall. Version deltas live in CHANGELOG. Contracts: docs/api/.
Runtime host
JSContextfactory withenvironment/profile/ defaults merge; context manager;close/ dispose- Same-thread isolate affinity; 128MB Python thread stack at import (mixin-scale templates)
time_modelogical|system;random_seed/crypto_seed/time_freezeconfig:timezone,locale,storage_path; TZ → processTZ+ V8 Redetect (ICU 77 data)- Dual-track versioning: milestone tags vs package number (docs/api/versioning.md)
Browser surface & DOM
- Window / Navigator / Screen / Location / History / Performance / document APIs (codegen + native)
- html5ever parse, ego-tree, CSS Level 4 selectors, EventTarget 3-phase dispatch
page_load/page_load_with_headers; NodeList iterable;getElementsByTagName('*')- Collections / plugins / HTMLAll / Options structure; Worker + WorkerNavigator paths
- Profile-driven identity (Chrome-line default profile; flat dot-path environment)
Crypto / Canvas / WebGL / Audio
- SubtleCrypto: AES-GCM/CBC/CTR, RSA-OAEP/PSS, ECDSA/ECDH, HMAC, HKDF, PBKDF2, X25519/AES-KW paths
- Canvas 2D (tiny-skia + deterministic noise / fixed fingerprint modes)
- WebGL parameter surface + environment UNMASKED_* / call log hooks
- AudioContext / OfflineAudio completion paths; font metrics from profile where wired
Network & event loop
- 3-layer network: ResourceBundle → Python
set_network_handler→ error (no silent open-web crawl) add_resourceoffline bodies; XHR / fetch / WebSocket lifecycle surfaces- Logical vs system timers; advance / sleep / tick / drain patterns (see GUIDE)
- Cookie / Headers / storage persist-load helpers on context
Anti-detection primitives
- wrapNative / hookNative /
window.chrome/ MarkAsUndetectable paths - Function toString / toStringTag / prototype brand hygiene (ongoing fidelity work)
- High-signal Illegal invocation fixes on brand-sensitive APIs
- Not a “pass every detector” product guarantee — host fidelity + explicit bounds
Instrumentation & observability
- Module
instrument_source(ChaosVM path A, closure-scoped handlers, e.g. TDC) - Instance
instrument_chaosvmfor global handler tables only - Unified / VM traces;
trace_diff; trace points; recording / profiler / coverage - CDP Inspector:
with_devtools, breakpoints, step, scope, programmatic API Debuggerclass:trace_api,watch_property,eval_traced, snapshots
Entry / multi-bundler
prepare_entry/run_with_entry/plan_multi_entry- Webpack / Parcel / Browserify / Vite-adjacent bridges; chunk supply is caller-owned
- Corpus runner CLI helpers for offline multi-case runs
Environment toolchain (diagnostic plane)
- Probe / gap / candidate / pressure / MAPE-K-style reports
- Report-only / no automatic apply / no silent profile write by default
- Not a one-click site bypass kit; sample adapters are separate and non-API
Workers
- Dedicated isolate + OS thread + structured clone (方案 A)
- WorkerNavigator / import static+dynamic paths; residual gaps in residual ledgers
Non-goals / honest bounds
| Not claimed | Reality |
|---|---|
| Full Chromium / Blink | Large IDL + intentional stubs; parity is continuous work |
| Auto-fetch all bundler chunks | Offline-first; you supply chunk text |
| Silent live network product | ResourceBundle-first |
| Environment toolchain auto-fixes hosts | Diagnostic reports only unless you authorize mutation elsewhere |
Identity with PyPI package iv8 0.1.x |
Related lineage / dual-engine oracle; this product is iv8-rs |
| Full layout engine / deep fingerprint luxury | Deferred (v0.9+ / residual) |
Global bounds: docs/api/overview.md.
Install
Requires Python 3.13+. ICU 77 data ships as icudtl.dat (override with IV8_ICUDTL_PATH).
Prebuilt wheels (PyPI / GitHub Release)
When published, install from PyPI:
pip install ming_iv8_rs
python -c "import iv8_rs; c=iv8_rs.JSContext(); print(c.eval('1+1')); c.close()"
Supported wheel platforms (package track 0.8.12):
| Platform | Wheel tag (typical) | Notes |
|---|---|---|
| Windows x86_64 | win_amd64 |
Primary desktop |
| Linux x86_64 | manylinux_2_34_x86_64 |
Prebuilt V8 150+ (cdylib TLS-safe) |
| macOS Apple Silicon | macosx_*_arm64 |
arm64 only |
Not shipped in 0.8.12: macOS Intel (x86_64), Linux aarch64. Build from source if needed.
GitHub Release tag for binaries (when cut): pkg-0.8.12 (package release; not continuum milestone v0.8.12).
Build from source
Requires Rust toolchain (see rust-version in workspace) in addition to Python 3.13+.
git clone https://github.com/lgnorant-lu/ming_iv8_rs
cd ming_iv8_rs
# Local development (fast iteration)
uv run maturin develop --target-dir target-maturin --strip --profile dev
# Distribution build (LTO, slow)
uv run maturin develop --release
Stack: create JSContext after import iv8_rs (module sets threading.stack_size(128MB)). Full-kernel Rust tests: RUST_MIN_STACK=134217728.
Optional: cargo/maturin --target-dir on a fast local cache path to avoid IDE contention on target/.
Quick start
import iv8_rs
with iv8_rs.JSContext() as ctx:
print(ctx.eval("navigator.userAgent"))
# Profile + overrides (environment wins over profile)
ctx = iv8_rs.JSContext(
profile="default",
environment={
"timezone": "Asia/Shanghai",
"navigator.userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
"screen.width": 1920,
"screen.height": 1080,
},
time_mode="system",
config={"timezone": "Asia/Shanghai"},
)
print(ctx.eval("Intl.DateTimeFormat().resolvedOptions().timeZone"))
ctx.close()
# Offline resource + eval
ctx = iv8_rs.JSContext()
ctx.add_resource("https://example.com/app.js", "window.__ok = 1", status=200)
ctx.page_load("<html><body></body></html>", base_url="https://example.com/")
# ChaosVM / TDC-style: prefer instrument_source, then eval patched source
# patched, info = iv8_rs.instrument_source(source)
# ctx.eval(patched)
ctx.close()
Full method surface: docs/api/runtime/jscontext.md.
Instrumentation: docs/api/instrumentation/.
Documentation map
| Doc | Role |
|---|---|
| docs/api/ | Stable API contracts (layered; public-oriented) |
| docs/GUIDE.public.md | Public tutorial cut (§1–16); full GUIDE is private-oriented |
| CHANGELOG.md | Per-version deltas |
| docs/quality-harness/ | Quality gate definitions |
| docs/conventions/ | Naming / testing / docs / docstring standards |
| CONTRIBUTING.md | Commit / scope conventions |
| docs/PROGRESS.md | Internal progress (private-oriented) |
Do not treat acceptance/roadmap trees as public product API.
Architecture (bird's-eye)
Python (iv8_rs)
│ PyO3
▼
iv8-py ──► iv8-core (V8 isolate, DOM, crypto, canvas, network, inspector)
│
├── iv8-undetect (wrap/hook/chrome primitives)
├── iv8-surface / codegen (IDL templates)
└── iv8-profile (profile matrix helpers)
iv8-rs/
├── crates/ # Rust workspace (core, py, undetect, surface, …)
├── python/iv8_rs/ # Package surface, profiles, analysis, toolchain
├── tests/ # Python integration
└── docs/ # GUIDE, api/, quality-harness, roadmap (mixed public/private)
Development
# Rust
cargo test --workspace
cargo test -p iv8-core --lib
cargo clippy --workspace --all-targets -- -D warnings
# Python release-style gate
uv run python -m pytest tests -q
See CONTRIBUTING.md and in-repo agent notes for commit format, stack size, and non-authorization rules (no public push / package bump without explicit request).
Acknowledgments
- iv8 — major inspiration and dual-engine reference lineage for Python↔V8 hosting
- Upstream: V8, PyO3, maturin, html5ever, and the wider ecosystem
Disclaimer and terms of use (read carefully)
This software is provided for research, education, interoperability testing, debugging, and legitimate software engineering only.
No warranty. The software is provided AS IS, without warranty of any kind, express or implied, including but not limited to merchantability, fitness for a particular purpose, non-infringement, accuracy of browser emulation, or undetectability. See the Apache License 2.0.
You are solely responsible for how you use this software and for compliance with all applicable laws, regulations, website/service terms of use, and third- party rights in your jurisdiction.
Prohibited / out of scope (non-exhaustive):
- Unauthorized access, fraud, credential stuffing, account takeover
- Bypassing security, anti-bot, CAPTCHA, or access controls without permission
- Targeting production systems or users in ways that violate law or terms of service
- Distributing malware, phishing kits, or “one-click site bypass” packs built on this engine
- Misrepresenting this project as a full Chromium browser or as guaranteed anti-detect
Not a bypass product. Environment tooling is diagnostic / report-oriented by design. Sample-specific reverse notes and site overlays are not product API and are not provided as attack recipes.
Fingerprint / anti-bot. Any anti-detection primitives are host-fidelity building blocks, not a promise to pass every detector or to evade any named vendor.
Dual-engine / lineage. Mentions of related packages (e.g. PyPI iv8 0.1.x)
are for technical comparison only. This product is iv8-rs / ming_iv8_rs.
Export and dual-repo. Public trees are path-filtered views of a private development history. Commit messages may still reflect development narrative; do not treat the public git log as a complete private process record.
Indemnity. To the maximum extent permitted by law, authors and contributors shall not be liable for any claim, damages, or other liability arising from use or inability to use the software, including legal costs arising from your misuse.
By cloning, installing, or using this software, you acknowledge this disclaimer.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ming_iv8_rs-0.8.12-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: ming_iv8_rs-0.8.12-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 38.0 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ada45f7fb77b72e4465421f0e4b3ff531a931e31af41267bfdcb0fb989e8b5e
|
|
| MD5 |
b3a3f2c1f696bb90cdd66f5b7699a5ea
|
|
| BLAKE2b-256 |
aa234c2a20eeb1139b57879d191860b4a951e80ebf352147f28e8195af805ff9
|
Provenance
The following attestation bundles were made for ming_iv8_rs-0.8.12-cp313-cp313-win_amd64.whl:
Publisher:
build-wheels.yml on lgnorant-lu/ming_iv8_rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ming_iv8_rs-0.8.12-cp313-cp313-win_amd64.whl -
Subject digest:
4ada45f7fb77b72e4465421f0e4b3ff531a931e31af41267bfdcb0fb989e8b5e - Sigstore transparency entry: 2190519731
- Sigstore integration time:
-
Permalink:
lgnorant-lu/ming_iv8_rs@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lgnorant-lu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-wheels.yml@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ming_iv8_rs-0.8.12-cp313-cp313-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: ming_iv8_rs-0.8.12-cp313-cp313-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 41.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99e877440ebb4b87a3fdf7328932b57660a3b891bb76ee4e05ef3517843c89da
|
|
| MD5 |
d6a91823a636d7ad1dcdca62b5930d45
|
|
| BLAKE2b-256 |
f25c6f8ba8a8ad74374e60608a6f22fe41760dcb5ea4730142820bc87c7c183f
|
Provenance
The following attestation bundles were made for ming_iv8_rs-0.8.12-cp313-cp313-manylinux_2_34_x86_64.whl:
Publisher:
build-wheels.yml on lgnorant-lu/ming_iv8_rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ming_iv8_rs-0.8.12-cp313-cp313-manylinux_2_34_x86_64.whl -
Subject digest:
99e877440ebb4b87a3fdf7328932b57660a3b891bb76ee4e05ef3517843c89da - Sigstore transparency entry: 2190519705
- Sigstore integration time:
-
Permalink:
lgnorant-lu/ming_iv8_rs@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lgnorant-lu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-wheels.yml@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ming_iv8_rs-0.8.12-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: ming_iv8_rs-0.8.12-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 35.7 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3032a46b0f024e989f270a5e868972f502668a341af7322544f20335b71a787c
|
|
| MD5 |
91f752bc40bf3b3ab118425bcecc2410
|
|
| BLAKE2b-256 |
d1f243cb47ef960d6e9c77fadae5f40108a59b96dc38848f02dd9948dd3e9484
|
Provenance
The following attestation bundles were made for ming_iv8_rs-0.8.12-cp313-cp313-macosx_11_0_arm64.whl:
Publisher:
build-wheels.yml on lgnorant-lu/ming_iv8_rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ming_iv8_rs-0.8.12-cp313-cp313-macosx_11_0_arm64.whl -
Subject digest:
3032a46b0f024e989f270a5e868972f502668a341af7322544f20335b71a787c - Sigstore transparency entry: 2190519713
- Sigstore integration time:
-
Permalink:
lgnorant-lu/ming_iv8_rs@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Branch / Tag:
refs/heads/main - Owner: https://github.com/lgnorant-lu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-wheels.yml@75c5e55ba6b693d935be494fc79f46bcd81902ca -
Trigger Event:
workflow_dispatch
-
Statement type: