Deconstruct VncThumbnailViewer 1.4.2 and add self-contained build

The shipped VncThumbnailViewerWin1.4.2.exe is a native launcher stub with a
Java JAR appended. This commit adds:

- src/: full Java source recovered from the bundled .class files (CFR),
  plus src/summary.txt with decompiler caveats
- ANALYSIS.md: architecture, data flow, hosts-file format, and security notes
- build-app-image.ps1: reproducible jpackage build that repackages the
  original classes and bundles a slim jlinked runtime (java.base + java.desktop)
  into a self-contained native app-image (no Java required on the target)

The 74 MB app-image is shipped as a release asset rather than tracked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-01 10:42:42 -05:00
co-authored by Claude Opus 4.8
commit 41a52acef8
53 changed files with 9156 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
# VncThumbnailViewer 1.4.2 — Deconstruction
## What it is
A Windows executable (`VncThumbnailViewerWin1.4.2.exe`) that is really a **self-running
Java application**: a native launcher stub with a JAR (ZIP) appended to it. It is a
multi-host **VNC viewer** that shows many remote desktops as a live grid of thumbnails,
and lets you double-click one to open it full size ("solo"). It is derived from the
**TightVNC Java viewer** (2008 vintage), with a custom thumbnail/grid front-end bolted on.
- Built: 2008-05-19, `Created-By: 1.5.0_13 (Apple Computer)` — targets Java 1.5, AWT UI.
- `Main-Class: VncThumbnailViewer`
- Window title in code: **"DJC Thumbnail Viewer"**.
## How it was packaged
`file` reports *"Zip archive, with extra data prepended"*. The `.exe` is a launcher stub
followed by a standard JAR. Extracting the ZIP yields 52 entries: the app classes (default
package), plus the bundled `net.n3.nanoxml` XML library. No source shipped — only `.class`
bytecode, which was decompiled with CFR into [src/](src/).
## Component map (decompiled sources in `src/`)
### Thumbnail front-end (the custom part)
- **VncThumbnailViewer** — `main()` + top-level `Frame`. Parses CLI args
(`host/port/password/username/encpassword`, repeatable), builds a `GridLayout` whose row
count is `sqrt(n)+1`, rescales all canvases to fit their cell, and manages the "solo"
full-screen frame (double-click a thumbnail → `soloHost`). Also owns the File menu
(Add Host / Load / Save / Exit).
- **VncViewersList** (`extends Vector`) — collection of live viewers + host-list
persistence to/from **XML** via nanoxml. Handles per-connection security types and
optional encryption of saved credentials. `launchViewer(...)` constructs each `VncViewer`
in embedded (non-applet, view-only, auto-scaled) mode.
- **AddHostDialog** — modal add-host dialog; auth choice of none / Password /
*VNC Enc. Password* / MS-Logon. Contains `readEncPassword()`.
### VNC engine (inherited from TightVNC viewer)
- **VncViewer** — the viewer applet/app: connection setup, handshake, options.
- **RfbProto** (largest, ~1k LOC) — the RFB/VNC wire protocol: handshake, security
negotiation, framebuffer updates, encodings, session recording hooks.
- **VncCanvas** / **VncCanvas2** — draws the framebuffer, decodes encodings (Raw, CopyRect,
RRE, Hextile, ZRLE/Zlib, Tight), handles scaling and input.
- **OptionsFrame**, **ButtonPanel**, **AuthPanel**, **ClipboardFrame**, **ReloginPanel** — UI.
- **RecordingFrame** / **SessionRecorder** — record a session to an `.fbs` file.
- **InStream / MemInStream / ZlibInStream**, **CapabilityInfo / CapsContainer** — protocol
I/O and TightVNC capability negotiation.
- **DesCipher**, **DiffieHellman** — crypto (see below).
- **HTTPConnectSocket(Factory)**, **SocketFactory** — proxy/socket plumbing.
- **net.n3.nanoxml.\*** — third-party XML parser/writer for the hosts file.
## Data / control flow
1. `main()` (or the Add-Host dialog, or "Load list of hosts") produces `(host, port,
password, username, userdomain)` tuples.
2. `VncViewersList.launchViewer` spins up a `VncViewer` per host, embedded in the grid,
`viewOnly=true`, `autoScale=true`, `scalingFactor=10`.
3. Each `VncViewer`/`RfbProto` connects, authenticates, and streams framebuffer updates
into its `VncCanvas`, which is scaled down to fit its thumbnail cell.
4. Double-click → `soloHost` moves that canvas to a full-screen frame and re-enables input.
## Hosts file (persistence) format
XML `<Manifest Version="1.4" Encrypted="0|1">` containing `<Connection>` elements with
`Host, Port, SecType, Password, Username`. `SecType`: `1`=none, `2`=VncAuth,
`-6`=MS-Logon; several TightVNC sec-types (5/6/16-19) are recognized but rejected as
"incomplete". If `Encrypted="1"`, the credential fields are DES-encrypted under a
user-supplied passphrase (`HostsFilePasswordDialog`).
## Security notes (this is a 2008 codebase — expect weak crypto)
- **"VNC Enc. Password"** (`AddHostDialog.readEncPassword`) is the classic VNC password
obfuscation, **not real security**: it DES-*decrypts* the 16-hex-char stored value with
the well-known fixed key `{0x17,0x52,0x6B,0x06,0x23,0x4E,0x58,0x07}`. Anyone with this
key (it's public and right here in the binary) can recover the plaintext password. This
is the same fixed key TightVNC/RealVNC use for `.vnc` files.
- Encrypted hosts files use single **DES** (56-bit, broken) keyed off the user passphrase —
weak by modern standards.
- VncAuth itself is DES challenge-response, inherently weak.
- Passwords are held in plaintext `String`s in memory and passed on the command line
(visible in process listings). Treat any stored credentials as effectively public.
## To rebuild / run from source
Needs a JDK 1.51.8 (uses removed AWT calls like `Component.enable(...)`, `Dialog.show()`
— will warn/fail on modern JDKs without `--release 8`-style tweaks). Roughly:
```
javac -d out src/*.java src/net/n3/nanoxml/*.java
java -cp out VncThumbnailViewer host <ip> port 5900
```
Or just run the original: `java -cp VncThumbnailViewerWin1.4.2.exe VncThumbnailViewer` (the
exe is a valid JAR despite the prepended stub, though the stub also lets Windows run it
directly).
```
```