Grand Theft Auto 2 Wild Demo
Exact artifacts
- Original distribution:
gta2demo.exe, 12,972,175 bytes, SHA-256f8fc0a9653932f008a03e56ea892fb31dbeb98d228cc4df61b910bcb35d08d21. - Installed
gta2.exe: 2,893,824 bytes, SHA-25697ad743b6ec9ea1be95282053c3127084acd764a7f37a3e57e2268af52d02ae3. - Installed
mss32.dll: SHA-2560974b244354a5d13e0711db15430c05f7949dc279b63897146f304d1401153fc.
The installed program tree has 73 payload files. InstallShield also writes
uninst.isu, making 74 files beneath C:\Program Files\GTA2 DEMO after a
complete run.
Authentic installer chain
gta2demo.exe is a PackageForTheWeb self-extractor. Its LZ32 calls unpack 92
split data*.cab volumes and the rest of Disk1 under
C:\WINDOWS\TEMP\pftw3~tmp\Disk1. It then calls:
CreateProcessA(NULL, "\"C:\WINDOWS\TEMP\pftw3~tmp\Disk1\Setup.exe\" /SMS", ...)
The emitted 73,728-byte Setup.exe has SHA-256
5656e87da0641c9dcfcd0ee8949ce72b3fa6a7d0e8b1fd985a16f6bd6c34ce52.
It expands the InstallShield engine and invokes
C:\WINDOWS\TEMP\_ISTMP1.DIR\_INS5576._MP with WinExec. That engine has
SHA-256
a8657371f03e2e66db951c3dcd3aeb42c576894908ca2eb1b3806aa0404cb083.
Wine Assembly currently emulates one Win32 process and does not execute either
child-process request. test/test-gta2-demo-installer.js therefore resumes the
two files emitted by the preceding authentic stage as separate emulator runs.
It does not use Unshield. The engine receives the command line generated by
Setup's _INS0432.INI, its actual wizard pages are clicked, its cabinet copy
runs, and acceptance requires this final text:
The GTA2 Installer has finished installing GTA2 on your computer.
The GTA2 Installer can now launch GTA2.
Unshield was used once while diagnosing a split-volume boundary issue and to compare file layouts. That extraction is neither the prepared collection path nor installer acceptance.
Compatibility findings
- The self-extractor needs ordinary-stream
LZCopyplusLZOpenFileAsupport for write/create flags. - The wizard's DirectX check creates CLSID DirectMusic
{636B9F10-0C7D-11D1-95B2-0020AFDC7421}as an availability probe. d3ddll.dllsleeps for 500 ms fromDllMain. Returning to the caller at that cooperative yield abandoned its live initializer stack; the loader must resume bounded Sleep yields before restoring the outer registers.- GTA2 queries IID_IDirectDraw4
{9C59509A-39BD-11D1-8C4A-00C04FD930C5}and calls slot 27,GetDeviceIdentifier. Aliasing it to the old 24-slot IDirectDraw2 table dispatched into the next interface and corrupted ESP. IDirectDraw4 and IDirectDraw7 now have 28- and 30-slot extension vtables. - The game queries
IDirectDrawGammaControland snapshots/sets its gamma ramp. mss32.dllmust be preloaded;d3ddll.dllanddmavideo.dllare discovered dynamically from the mounted installed tree.
Gameplay reproduction
node test/run.js --app=gta2_demo --no-build \
--max-batches=4500 --batch-size=1000 \
'--input=3000:di-keydown:13,3100:di-keyup:13' \
--quiet-api --quiet-blocks --dx-slot=7 --png=/tmp/gta2.png
Slot 7 is the primary gameplay surface. The generic screenshot heuristic can otherwise select a cached front-end surface because this title creates many DirectDraw surfaces. The captured 640x480 frame contains the player in the Wild Demo playfield, the health-heart HUD, and the opening tutorial message.
Shared lazy synchronization A/B (2026-09-29)
The hardware browser benchmark reached gameplay
with two live guest workers throughout measurement. Lazy OFF / ON measured
29.86 / 29.79 FPS and about one readback per frame in both modes. ON leaves
one armed Lock untouched per frame, but presentation still needs its readback
and GPU backend fence calls increase from one to two. A later call-stack trace
confirmed only one guest fence request per frame: the other backend call is
inside queued-flip replay. Publication adds its own wait, measured separately.
The helper recorded no lazy
surface touches, so this is coexistence coverage, not a real-game test of
foreign-thread pixel access. This initially remained opt-in; the subsequent
shared-WebGL default rollout provides ?no-lazy-sync and the live Lazy sync
debug checkbox as opt-outs. The retained-GDI-pointer limitation still applies.