Type File virus
Creators Qark, Quantum
Date Discovered 1995.04
Place of Origin Australia
Source Language Assembly
Platform MS Windows
File Type(s) .exe
Infection Length 1,422 bytes

Winsurfer is a memory-resident MS Windows 16-bit infector of NE (NewEXE - Win16 executables). Winsurfer was written by both Qark and Quantum of VLAD and appeared in Issue 4 of VLAD magazine in April 1995.

Table of Contents


Although a Win16 virus, Winsurfer used a mix of INT 21h (MS-DOS API), INT 2Fh (MS-DOS Multiplex) and INT 31h (DPMI - DOS Protected Mode Interface calls). INT 2Fh is called only once to determine if DPMI/INT 31h is present. INT 21h is called for file I/O such as open/read/lseek/write/close. INT 31h is used to change segment protection and to hook INT 21h globally The INT 21h handler serves two purposes: to provide the viruses residency check and to find NE files to infect. 'NE' files are infected on INT 21h/AX=4B00h - Execute. Under all infections Winsurfer calls INT 2Fh to check if DPMI is present, INT 31h to make its code segment writeable and INT 21h to check if the virus is already resident in memory.

When run from a regular NE executable Winsurfer attempts a direct-action infection of the Win16 shell (usually Program Manger). This executable is targeted because it can be relied on as being resident at all times for the virus to stay resident. The shell is located in three steps: First the 'windir' environment variable is found. The virus locates this in the environment segment given by the PSP (Program Segment Prefix) of the host at offset 2Ch. Next the virus attempts to open an read 'system.ini' in the Windows directory. Finally the virus attempts to locate the shell by searching system.ini for the 'shell=' key.

When run from the windows shell the virus goes resident in memory: The virus needs to take no special action to allocate memory as it stays loaded with the windows shell. INT 31h is used to retrieve the current real mode INT 21h vector and then set it to the Winsurfer's own INT 21h handler.

Winsurfer introduces the 'VLAD' method of infecting NE executables. This method basically worked by moving the NE header back 8 bytes making space to add an extra 8 byte entry to the 'Segment Table'. The virus is appended to the end of the file and the extra Segment Table entry points to this appended code. Winsurfer first checks the MZ header of the file: Is the 'MZ' marker there? Is the 'Offset of First Relocation Item' (MZ header offset +18h) 40h or more? (This is a sign of a NE). Is the pointer to the NE header at offset +3Ch of the MZ header exactly 400h? The victim is deemed to be a NewEXE file, but no test of the NE header is performed before infection starts. This could lead to corruption of other types of executables such as PE, LE, LX etc. The first immediately reduces the pointer to the NE header at absolute offset +3Ch and the MZ header SP field by 8.

Next, the Winsurfer infector reads 512 of the NE header from hard coded absolute offset of +400h. The virus reads the Segment table offset (NE +22h) and adjust several values of the NE header by 8 if they occur after the start of this table. Values adjusted are: offset to 'Entry Table' (NE +04h), offset to 'Relocation Table' (NE +24h), offset to 'Resident Names Table (NE +26h), offset to 'Module Reference Table' (NE +28h) and offset to 'Imported Names Table' (NE +2Ah). Winsurfer reads then increments the 'Segment Count' field (NE +1Ch) making the assumption there are less than 256 segments.

Winsurfer saves the original CS:IP combination for use in its single relocation item and then sets CS:IP entry point in the NE header to future segment index and offset of the appended virus. Winsurfer uses the 'Segment Count' and 'Segment Table Offset' (NE +22h) to calculate the end of the new Segment Table and move all of the NE header before this location back 8 bytes in 512 byte chunks. Winsurfer uses the 'File Alignment Shift' value (NE +32h) to calculate the new position of the appended virus and creates a new Segment Table entry to contain the appended virus code.

The new Segment Table entry has physical and memory size set to the size of the virus, file offset pointing to appended virus code and adjusted by File Alignment Shift value and Segment Attributes: 'NonMovable+Relocations'. Winsurfer then writes the new Segment Table back to the NE header on disk. Winsurfer appends the virus to the end of the file at the position previously calculated and then appends a single relocation item for the virus segment after that. Their location item is of type '3' (PTR) and flags value 'additive'. Infection of the NewEXE victim is then complete. Additionally the source code mentions some situation in which the NE infection may fail.


Winsurfer appeared in the 4th issue of VLAD magazine in April of 1995. According to the source code the Interrupt Service Routine (ISR) was written by Quantum with the infection code written by Qark.


Original research by JPanic aka @JPanicVX

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License