This text was written by Peter Szor, Data Fellows Ltd
Memorial is a very interesting Windows 95 virus. There has been a long
development in Windows virus writing so far [end of 1997]. However, the list
of Windows 95 infectors is still not long. Memorial shows new ideas by
being a “memory resident” Windows 95 virus. That is, it infects DOS-based
COM and EXE files as well as Win32 PE (Portable Executable) files,
respectively. The main format of the virus is a Windows 95 VxD (Virtual
The virus is not encrypted in DOS-based COM and EXE files, but rather infected PE
files are encrypted with an oligomorphic (semi-polymorphic) routine.
Moreover, the main virus body (the VxD image) is packed with a simple
algorithm. There is already one virus encrypted in PE files
(called Win95.Mad), but Memorial is certainly the first Windows 95 virus that shows oligomorphic capabilities. Thus, it makes the first step on the
way of Windows 95 polymorphism.
Memorial is also an effective retro-virus. It manipulates the Windows 95
registry to disable several well-known antivirus programs.
Fortunately, the virus has a few big bugs, which can slow down the spreading
a lot. However, Memorial.12413 has been reported to be “in the wild” in Sweden,
regardless of these problems.
Running an infected DOS COM file
Windows 95 virus writers started to understand the fact that people are
exchanging more DOS programs than Windows 95 applications. This becomes a
big problem from the virus point of view: it simply cannot spread too far
by infecting only Windows 95 programs. Memorial solves this problem by
infecting DOS executables also. The infected files function as
droppers of the main VxD module.
When an infected COM file with Memorial is executed, the virus drops a VxD
file to the root of the C: drive called C:CLINT.VXD. First it checks whether
Windows is currently running. If it is, the virus simply executes the DOS
host program. Otherwise, it makes its “Are you there” call, which is INT 2Fh
AX=0. If, upon returning from the call, the AX register is set to 4AB3h, the
virus assumes it is already active in memory, and returns control to the
host program. Then it creates the C:CLINT.VXD file with a hidden attribute,
and starts to write into it.
The writing routine appears as an anti-heuristic function. However, the
goal of this function is different. The main body of the virus is packed to
7508 bytes, and this function is supposed to unpack it. The algorithm is very
simple, but effective. VxD files are in LE (Linear Executable) format. The
structure of these files contains many zeros. This is why the packing of
these areas can be quite effective. Basically, the full VxD is packed to
7508 bytes, which grows to 12413 after unpacking. When the CLINT.VXD is
ready, Memorial copies a piece of code from itself into the Interrupt
Vector Table at 0:200, and hooks INT 2Fh (Multiplex Interrupt). This way the
virus does not have to worry about how to allocate memory, but it will be
incompatible with some applications.
The INT 2Fh handler answers the “Are you there call”, and waits for 1605h in
AX register to check the Windows Initialization Notification. This message
notifies DOS device drivers and TSRs that standard or 386 enhanced-mode
Windows is starting. Windows calls this function as it starts to allow DOS
device drivers and TSRs that monitor INT 2Fh the opportunity to prepare for
running in the Windows environment.
When this initial calls comes into the Memorial’s interrupt handler, the
virus opens C:CLINT.VXD to check for its existence. If the opening was
successful, Memorial initializes a Win386_Stratup_Info_Struc structure to
direct Windows to load the VxD. Any device driver or TSR can use a Windows
VxD to help support its operation in the Windows environment. To specify
the VxD name, the device driver or TSR sets the SIS_Virt_Dev_File_Ptr member
to the address of the virtual device’s filename. Thus, Memorial uses a
documented means of directing Windows to load C:CLINT.VXD. This is a more
elegant than modifying the SYSTEM.INI file’s device section, which is
more complicated and not so successful.
Running an infected DOS EXE file
When an infected EXE files is executed the same unpacking code takes
control from the entry point of the virus as in COM files. However this
function will write into C:CLINT.VXD endlessly because there is a major
bug in DOS EXE infection code. Memorial uses a wrong pointer and a bad
virus size parameter during EXE infection. It does not write the packed VxD
code (7508 bytes) into EXE files, but the unpacked 12413 bytes after the
unpacking code. Thus when unpacking, the dropper code extracts an already
unpacked VxD image.
Because the extractor code does not know about this possible problem it
writes megabytes of code into C:CLINT.VXD until it fills all the available
hard drive space, but even then the control will not come back to DOS. When
using Ctrl-C during this operation or restarting the machine, the huge
C:CLINT.VXD can be find but only if the /AH (display hidden files) option
of DIR command is used. Thus the virus in EXE files can be classified as
“Intended”. Fortunately, the detection and disinfection of these files
Running an infected PE file
When an infected PE file is executed the virus first decrypts itself,
because the main virus body is encrypted and packed. The decryptor is 46
bytes long and oligomorphic (see below).
As in case of COM infection the virus also drops the C:CLINT.VXD from PE
files. In case of DOS infections the dropper function takes 275 bytes
additional code at the entry point of the virus. In PE files this function
is in 32bit code and it is more complicated than the DOS version of it.
This is why this code is longer: 1360 bytes. This function also includes
Memorial’s activation routine and it is supposed to load the VxD, too.
First the virus calculates GetModuleHandleA function’s entry-point in
memory. It does this by using a real hack; it makes a search in internal
Windows 95 structures. This makes the PE infection a bit more easier later
on; the virus should not add any names to the Imported Names Table.
Memorial does not need a complicated patch function in its PE infection
code for this purpose.
Later on it calculates the entry point of GetProcAddress by using the same
trick. Then it uses GetModuleHanldeA to get the handle of KERNEL32 module.
By using this handle Memorial is able to call GetProcAddress to get and
save CreateFileA-, WriteFile-, ReadFile-, SetFilePointer-, CloseHandle-,
GetLocalTime-, LocalAlloc procedures addresses respectively. After this it
uses GetModuleHandleA again, to get USER32’s handle. Then it uses
GetProcAddress again to save the address of MessageBox procedure.
After this the virus calls GetLocalTime function to check the date: if it
is 10 April the virus activates and displays a message box by using the
Clinton Haines Memorial Virus by Quantum/VLAD and Qark/VLAD
Clinton Haines, also known as Harry McBungus, Terminator Z and Talon
died of a drug overdose on his 21st birthday, April the 10th, 1997.
During his time as a virus writer he wrote the No Frills family, X-Fungus,
Daemon and 1984 viruses. He was a good friend to VLAD and so we write
this virus in his honour. We hope it’s good enough to do him justice.
VLAD Remembers. Rest in Peace
Otherwise it checks if \.CLINT is already up and running. If it is, the
host program is executed. Otherwise it creates \.C:CLINT.VXD as normal
file (without using hidden attribute this time) with CreateFileA. If this
was successful Memorial allocates memory by calling LocalAlloc procedure.
This is because it has to unpack the packed virus body to a new location
before it is able to write the code into the file. Thus it unpacks the VxD
code (7508 bytes) to the buffer and writes 12413 bytes from it into
CLINT.VXD with WriteFile procedure. Then it closes the file with
CloseHandle. After this it executes the VxD by using CreateFileA procedure
with the specified name format for this purpose \.C:CLINT.VXD. Finally
it starts the host program.
The Initialization (IFS API hook)
When the CLINT.VXD file is executed, the virus waits for the following
Control Messages in its Control Message Handler: W32_DEVICEIOCONTROL,
INIT_COMPLETE, SYS_DYNAMIC_DEVICE_INIT and SYS_DYNAMIC_DEVICE_EXIT. In case
of W32_DEVICEIOCONTROL message the virus returns 0 since it does not want
to communicate with other Win32 applications. When SYS_DYNAMIC_DEVICE_EXIT
message arrives Memorial returns 1 to disallow the unload request. In case
of SYS_DYNAMIC_DEVICE_INIT and INIT_COMPLETE messages the virus executes
its Initialization procedure.
This procedure hooks the DOS IFS (Installable File System) API call first.
After this it deletes several keys from the Windows 95’s registry under
‘SystemCurrentControlSetServicesVxd’, where statically loaded VxD names
can be found; such as anti virus VxDs. First it deletes ‘VETMON95’ and
‘VETMACRO’ keys . Then it deletes ‘NAVAP’, ‘virusafe’, ‘WIMMUN32’ keys.
Then it opens ‘SOFTWAREMicrosoftWindowsCurrentVersionRun’ section and
deletes the following values from it: ‘NORTON AUTO-PROTECT’, ‘TBAV for
Windows 95’, ‘Anywhere Antivirus Validation’, ‘Vshwin32EXE’ and ‘ViruSafe’.
Then it goes to ‘SOFTWAREMcAfeeScreenScan’ and deletes
‘bEnableScreenScan’, ‘bScanAllFiles’, ‘bScanSubDirs’. Then deletes the
following keys under ‘SOFTWARECybecVET Antivirus for Win32’:
‘ActionsInfectedAction’, ‘ActionsSuspectAction’, ‘MemoryEnabled’,
‘ResidentFileCheck’, ‘ResidentInfectedAction’, ‘ResidentSuspectAction’,
‘ScanningScan All Files’, ‘ScanningScan Type’, ‘ScanningSkip Renamed’,
‘ScanningSubfolders’ and sets the ‘ScanningExtension List’ value to ‘bin,
dll, doc, drv, ovl, sys, dot’ removing ‘com, exe and possibly ‘scr’ from
this list. This way Memorial disables many Windows 95 antivirus programs.
Then the virus clears the attributes on C:CLINT.VXD. After this it opens
the file and gets and saves its size, and allocates enough memory for its
unpacked and packed copy. Then it reads itself from the file to the main
buffer. Memorial then closes the VxD file and deletes it.
After this it packs the VxD code into the second buffer. Finally it returns
from its initialization routine.
When Memorial intercepts a file open call, it first check the extension of
the file comparing it to ‘COM’ first. If the extension is ‘COM’, Memorial
gets and saves the attribute of the victim file and clears it. Thus the
read only attribute will not prevent the infection. Then it opens the
victim and reads 4 bytes from it. If the third byte (after the initial
jump) was ‘Z’ Memorial assumes the file is already infected. Then it checks
for ‘MZ’, ‘ZM’ markers to be sure that the victim’s structure is not COM.
Then it checks the victim size and does not infect it if smaller than 7168
or bigger than 51200 bytes. Then it reads the last 5 bytes of the program
and checks if they start with ‘SN’. If this is found the virus does not
infect the file. I do not see any other reason for this functionality
except to inoculate a certain PC (possible the virus writers own) by adding
this special marker to the end of COM files.
Then Memorial adds the DOS dropper code (275 bytes) to the end of the
victim together with the packed virus image (7508) bytes. Finally it
modifies the begging of the victim by changing the first 4 bytes to an
initial jump + a ‘Z’ marker and sets the attribute to the original one.
Thus the size of the virus is 7783 bytes in case of COM infection.
DOS EXE Infection
If the file started with ‘MZ’ or ‘ZM’ markers the virus checks the
extension by comparing it to ‘.EXE’ and ‘.SCR’. Then it calls
IFSMgr_Get_DOSTime to have a base number for its random number generator.
Since in PE files the virus needs a section name added to the PE header
area and it wants to be oligomorphic, it does not want to use a constant
section name. Thus it mutates the standard name from ‘CLINTON’ to some
‘garbage’ string first.
Basically it uses an 8 bit XOR for the encryption. During the encryption it
calculates a check byte and saves it as the last character of the section
name string. This additional byte will be used when checking existing PE
infections. Memorial mutates the section name during DOS EXE infections
only. This makes the mutation slow enough (slow oligomorphism).
When this one is ready Memorial opens the victim, reads it header and
checks for the ‘MZ, ‘ZM’ signature. Then it reads 4 bytes from 3Ch position
of the file. This double word holds a pointer to the Windows executables
header area. If this pointer is 0 the virus assumes that the file is a
normal DOS EXE file and tries to infect it as such. The it checks the
checksum field of the EXE header. If this one is 6666h the virus does not
infect the file, additionally if the IP field is 100h in the header the
virus wont infect either.
Then the virus increases the size of EXE files to the paragraph boundary
and add the VxD dropper code (275 bytes) to the end of the file. Then the
biggest bug in the virus comes: It writes the unpacked VxD to the end of
the file (12413 bytes). Thus the virus size is 12688 bytes in case of DOS
EXE victim files. Finally it modifies the executable’s header to point
which will point to the virus entry point.
When the EXE or SCR file had been assumed as Windows Executable, Memorial
checks for the PE signature first. Then it pays attention to the read only
attribute. Then it reads the last section from the Image Header structure
and calculates the check byte on the section name. If the checksum matches
Memorial does not infect. Otherwise it modifies the PE header by adding the
new virus section into it. Since Memorial is an oligomorphic virus it first
mutates a 46 bytes long decryptor (see: Oligomorphic engine) for the
beginning of its body. Then it encrypts the VxD dropper’s PE version which
is 1360 bytes long. The encryption is based an a 8 bit XOR. Then adds the
decryptor’s code + the VxD dropper code to the end of the victim (1406
bytes). Finally it encrypts the packed VxD image and adds it to the end of
the file (7508 bytes). Then it restores the attribute of the victim and
closes it. The PE infection is ready. Thus the size of the virus code is
46+1360+7508=8914 bytes. Note however that this might change because the
virus has to increase the file size up to a section alignment.
This engine is simple but effective. The basic decrypor consists of 11
different parts. The mutation engine modifies the order of these small
blocks by changing some of them with each other. Thus block 1 with 2, 8
with 9, 6 with 7 , 3 with 4, 5 with 4 and 10 with 0 can be replaced by each
others. This gives 2*2*2*2*6 all together 96 different cases. This makes
the detection of the virus difficult in PE files.
Memorial is a very complex virus. It shows that polymorphic Windows 95
viruses will appear in the near feature later on Polymorphic Mutation
Engines which can be used with Windows 95 viruses only. That means that its
time to implement new scanning engines for these new beasts.