Thursday, 17 January 2019

Getting set up

Virus writing starts with a development environment. Here's how I set up a Windows 95 VM and my development tools. If this is your first visit to VeXation you might want to read the "Welcome" post introducing the project.

Before going too far I think its valuable to get into a 1995 mindset: Coolio's Gangster's Paradise is the #1 single. Quebec narrowly remains a province of Canada. A pog collection was still cool. Netscape only recently released SSL and faces challenge from a brand new web browser called Internet Explorer. A top of the line home PC was something like a 486 with a 1 GB harddrive and a whopping 8mb of RAM.

Pretty wild! With the right mindset established let's take this new Windows 95 thing for a spin.

Get hype, we're installing Windows 95

Software Choices

I'm writing this on Linux and will be using VirtualBox for virtualization. There are some eccentric new ways to run Windows95 as an Electron app but VirtualBox is the devil I know. In theory most of this setup could be adapted to macOS or modern Windows but you'll have to try that on your own. Luckily for me most of the hard work involved in setting up Windows 95 with VirtualBox was covered by Socket3's blog post on the subject. Rather than duplicate that effort I will defer to that post for the basic setup instructions and only point out areas of difference. 

Windows 95 Version
There are a number of versions of Windows 95 available. To make things simple I chose to use the same one as Socket3: Windows 95 OSR 2.1. Later on I'll want to test code on a few versions to make sure differences in patch level don't break things.

I don't know if its true but I get the impression the prevailing choice for writing ASM malware in the 90s was Microsoft Macro Assembler (almost always referred to as MASM). To spice things up a little bit I decided it would be fun to try using Borland Turbo Assembler (almost always referred to as TASM). I ended up choosing Borland Turbo Assembler 5.0. It was easy to install and supported 32bit Win32 development. TASM has fairly extensive MASM compatibility so this turned out to be an OK decision. If all else fails its fun to say "Borland" out loud (I recommend you try it).

Are you ready to pinch individual MOV instructions? I sure am!

Text Editor
This part was a real struggle. I tried a few random "Programmer's Text Editors" that I could remember (Notepad++, UltraEdit, etc) but couldn't get any of them to install on a fresh Windows 95 OSR 2.1 system. This was probably because I was using newer versions meant for Win98+ but it was tedious digging up old installers to try. Ultimately I ended up choosing an ancient freeware program called the Programmer's File Editor (PFE). Compared to a modern IDE it is somewhat feature bare but it sure is... "authentic". Using Programmer's File Editor does provide important features missing from notepad.exe like line numbers and being able to open files > 64KB. Best of all PFE is probably Y2K safe.

The brushed steel effect is how you know we're going to be working close to the metal.

Installing Windows 95 OSR 2.1

To install Win95 in VirtualBox I followed Socket3's blog post on the subject.  If you're following along you'll want to download the following:
  1. Windows 95 OSR 2.1 OEM CDROM ISO.
  2. Windows 95 Bootdisk floppy disk image
  3. SciTech Display Doctor 7.0 Beta
You will also need a valid Win95 "Certificate of Authenticity" serial number. These are all over the internet but I'll save you a Google and share the one I used (if you're a cop stop reading this): 24796-OEM-0014736-66386

I chose to use some virtual machine settings that aren't true to the period to make life a little more bearable. I created a VM with a Pentium processor, 64mb of RAM and a 2GB disk. Don't forget to disable VT-x/AMD-V and Nested Paging in the CPU settings.

Using a floppy disk image to bootstrap CDROM drivers to be able to run the Win95 installer CD is certainly nostalgic. In the VM the overall install time is quite fast compared to 1995 when it would often take most of an hour.


Socket3's instructions worked as described except for a few minor things I had to adapt:
  1. The CDROM drive did not default to drive R:\ - instead it was drive D:\ like I would have expected. I replaced any references to R:\ with D:\. I also skipped editing autoexec.bat to rename the CDROM drive.
  2. Despite it being drive D:\ I did have to follow the described process of copying *.cab files from the CDROM to the harddrive before starting the installation process or trouble would ensue.
  3. The process of copying CDROM files to drive C:\ in Socket3's post is described before the fdisk and format process that prepares drive C:\. I had to reverse this order and prepare the drive before copying to it. Remember to restart the VM after partitioning and formatting.
I'm having Fun™ already

Getting the somewhat sketchy SciTech Display Doctor driver installed and configured is a little fiddly but the improved screen resolution is worth it. I had to drag around the SciTech application interface a bit before I could see the "Apply" button I needed to click to change the Display and Graphics Drivers to follow Socket3's instructions.

Following the network setup instructions was important to me because I knew I would want to copy files to the VM from my host machine (installers, goat files, etc). If you want to do the same make sure not to forget to reinstall "Client for Microsoft Networks" after you install the TCP/IP protocol because it will be removed when you first remove NetBEUI and IPX/SPX.  I put the VM on a network that did not have a DHCP server and so I also had to configure the system IP Address, Gateway, and DNS Configuration manually. Get used to restarting your VM because Literally Everything requires rebooting in Windows 95: installing a new driver, changing the screen resolution, changing the system IP address, you name it.

One important thing to point out is that Socket3's approach to VM networking bridges the VM to your host machine's network adapter which means you may effectively be putting a Windows 95 machine on the big scary Internet unless you're careful. I gave up on using VirtualBox NAT so ultimately I "airgap" the VM by strategically connecting/disconnecting the network adapter virtual cable when I want to send/receive files. The irony of getting a virus while trying to develop a virus would be too much for me to bear.

File Sharing

There are no VirtualBox guest additions for Windows95 which means I couldn't use conventional means to share files between the host and the guest. I tried mounting the VM's FAT32 disk image directly into Linux using various tricks but found it unreliable and annoying because the guest had to be shut down first. Out of the box Win95 OSR 2.1 has IE 4.0 so browsing the web to download tools is a nightmare. Barely any sites will work and you're almost guaranteed to be more hacked than Marriott. The best solution I could find without getting lost in yak shaving was to enable Windows file sharing in the VM. I use a Linux samba client from my host machine to interact with the VM shared folder.

File sharing isn't enabled out of the box so after configuring TCP/IP and connecting the virtual cable again (plz don't hack me) I enabled and configured it. To do so yourself:
  1. Right click Network Neighbourhood and choose properties
  2. Click the ugly button labelled "File and Print Sharing"
  3. Click "I want to be able to give others access to my files"
  4. Click OK
  5. Insert the Windows 95 install CDROM again if you've removed it
  6. Click Yes to restart your computer (of course you have to restart your computer for this)
  7. Create a folder in your C:\ drive called "portal"
  8. Right click the folder and choose properties
  9. Click the "Sharing" tab
  10. Configure a share name and access type for the folder
I found it easiest to access the shared folder on the VM from my host using a command line SMB client called, unsurprisingly, "smbclient". To download a TAR archive of some files in the portal directory is as easy as running:
smbclient //VMNAME/PORTAL "" -N -Tc backup.$(date +%Y-%m-%d-%s).tar <files>
To poke around in an interactive mode is even easier:
smbclient //VMNAME/PORTAL ""
The smbclient man page has plenty more information. Remember to disconnect the virtual network cable when you're done. Also note that "VMNAME" is a placeholder for the name I chose to identify the computer in Windows file sharing settings, not the VirtualBox VM name.

Enabling file and print sharing
Enabling file and print sharing pt2
Configuring a file share

Installing Borland Turbo Assembler 5.0

Overall this was a straight-forward process. To begin I had to download the three floppy disk images for the Borland Turbo Assembler 5.0 installer. You can find these on Win32World as a 7z archive. If you're following along you'll need a way to unzip 7z files to get at the individual disk images you can mount as virtual floppy disks for the VM using VirtualBox.

After mounting disk01.img to the virtual floppy drive I was able to begin the installation. One way to do this is to:
  1. Open My Computer
  2. Double click the A:\ drive
  3. Double click the "Install" icon
  4. Hit enter as required to proceed
  5. Leave all the defaults and choose Start Installation
  6. Mount disk #2 and disk #3 when prompted
  7. When TSM_RDME.TXT is displayed the installation is complete. Hit ESC to exit. Don't forget to eject the floppy disk before you reboot the VM or the next boot-up will try to boot from the Borland floppy and fail.

Next I had to add the TASM tools to the %PATH% environment variable so I can use the tools easily from a command prompt without a fully qualified path. For Win95 this means editing the Autoexec.bat script. One way to do so:
  1. Open My Computer
  2. Open the C:\ drive
  3. Right click "Autoexec" and choose "Edit"
  4. The file will probably be empty since this is a fresh installation. I added the following line without the surrounding quotes:
  5. Save the file and exit
  6. Reboot (of course)
I was able to verify that I had a working installation and gain some basic familiarity with the tools by building one of the Win32 sample applications that comes with TASM. To do this:

  1. Open a command prompt (My favourite way is to hold the windows key, hit "r", enter "command" and then hit enter)
  2. Change to the "wap32" example directory by running "cd C:\TASM\EXAMPLES\WAP32"
  3. Build the sample application by running "make". If you get the error "Bad command or file name" you should double check your %PATH% was setup correctly. It's expected to see two warning messages about heap and stack reserve size (Shout out to the Borland dev that shipped example code that builds with warnings...).
  4. Run the built application by running "wap32" in the console
  5. You should see an ugly win32 application window appear
  6. You can try debugging the application by running "td32 wap32". Because we built the sample application without debug symbols the debugger will warn us about this fact and only show disassembled machine code
  7. You can try debugging *with* symbols by running "make -B -DDEBUG". The -B forces a rebuild even though the sourcecode hasn't changed. -DDEBUG passes a "DEBUG" argument to the Makefile so it can change the assembler and linker command line flags
  8. After rebuilding with debug symbols you can run "td32 wap32" again and it should not warn about missing debug symbols anymore and instead show you a source code listing. Much nicer!
Building wap32 example without debug symbols.
wap32 in all its glory.

Debugging wap32 without debug symbols
Debugging wap32 with debug symbols

Wrapping Up

Cool! A real development environment. If you followed along I recommend that you create a snapshot of the VM state at this point so no matter how screwed up things get you can always return to a fresh setup. It would also be useful to duplicate these setup instructions to make a few more Windows 95 VMs that you can use to test your virus down the road without infecting your development machine.

A full development environment in action
Bonus fact: If you've read Fabien Sanglard's excellent Game Engine Black Book: Wolfenstein 3D you might noticed the td32 debugger interface looks just like the one shown in Chapter 3. John Carmack and id software used Borland Turbo C++ for the development of Wolf 3D and it came bundled with Borland Turbo Debugger (though we've installed a newer version).

At this point I spent most of my time reading the Borland Turbo Assembler 5.0 manual and browsing through the WAP32 source code. It was a pretty good starting example for win32 programming in x86 assembly. Once I had a grasp of WAP32 I dipped my toes into some of Iczelion's tutorials. These are mostly MASM based but work with TASM with minimal fuss. Compared to 2019's version of development tutorials and medium dot com think-pieces I found these older "community style" tutorials very endearing if not always crystal clear.

You might have been surprised to see the "make" command show up in a Win95 dev environment. I admit I was. Initially I assumed it would be something similar to GNU Make and I definitely set myself up for disappointment. Instead it's some kind of proprietary Borland flavour of Make that is missing a lot of what I associate with GNU Make. It takes some getting used to, especially when paired with the lousy command.exe shell Win95 offers. Overall its still nicer (to me anyway) than writing BAT files.

Coming up

With the dev env ready I can move on to more interesting topics. Next time I'd like to talk about the theory behind PE infectors and some challenges that we'll face compared to standard application development.

I would love to hear feedback about this project, especially if you were someone writing assembly code in this era. Feel free to drop me a line on twitter (@cpu) or by email (

Until next time,