• Stars
    star
    275
  • Rank 145,435 (Top 3 %)
  • Language
    Python
  • Created over 3 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A single .exe binary which runs DOOM on DOS 6, Windows 95 and Windows 10 (and probably everything in between).

A single .exe binary which runs DOOM on DOS 6, Windows 95 and Windows 10 (and probably everything in between).

Quickstart

Run DOOM.EXE on your OS of choice, making sure that a suitable .WAD file is present. DOOM1.WAD, in this repo, is the shareware demo.

Introduction

DOS and Windows .exe files both start with a common header (the DOS "MZ" header), which might suggest that you can run programs for one OS on the other one. However, this is complicated by a few facts: DOS support was dropped in Windows a long time ago (DOS binaries don't load on Windows 10, for example), and DOS programs use a completely different execution environment.

This repo builds a single .exe file with a "polyglot" MZ header which allows it to load one program (the original DOOM) when running inside DOS, and a different program (a custom static build of Chocolate DOOM) when running on Windows.

The DOS binary

The DOS binary, DOOMD.EXE, is exactly the original DOOM for DOS, derived from the shareware version that was widely distributed. DOOMDUPX.EXE is the same binary, but packed with UPX to make it smaller.

The Windows binary

The Windows binary, DOOMW.EXE, is a custom build of Chocolate DOOM, a source port of DOOM which hews very closely to the original. Chocolate DOOM is based on libSDL 1.2; this custom build integrates it statically rather than linking to libSDL dynamically. This binary is stripped. DOOMWUPX.EXE is the same binary, but packed with UPX to make it smaller.

Build instructions

  1. apt install mingw-w64 build-essential on an Ubuntu 18.04 machine.
  2. Download and unpack the source code for Chocolate DOOM 2.2.1, SDL 1.2.15, SDL_mixer 1.2.7, and SDL_net 1.2.8.
  3. cd SDL-1.2.15; ./configure --enable-shared --enable-static --disable-directx --host=i686-w64-mingw32; make; sudo make install
  4. cd SDL_mixer-1.2.7; ./configure --enable-shared --enable-static --host=i686-w64-mingw32; make; sudo make install
  5. sudo mv /usr/local/lib/libSDL_mixer.* /usr/local/cross-tools/i386-mingw32/lib/; sudo mv /usr/local/include/SDL/SDL_mixer.h /usr/local/cross-tools/i386-mingw32/include/SDL/ (I could probably also have just set prefix correctly)
  6. Apply this patch to SDL_net to eliminate the dependency on iphlpapi.dll:
diff -ur a/SDL_net-1.2.8/SDLnet.c SDL_net-1.2.8/SDLnet.c
--- a/SDL_net-1.2.8/SDLnet.c	2012-01-15 16:20:10.000000000 +0000
+++ b/SDL_net-1.2.8/SDLnet.c	2020-11-13 18:49:24.602850922 +0000
@@ -212,6 +212,7 @@
 		return 0;
     }
 
+#if 0
     if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == ERROR_BUFFER_OVERFLOW) {
         pAdapterInfo = (IP_ADAPTER_INFO *) SDL_realloc(pAdapterInfo, ulOutBufLen);
         if (pAdapterInfo == NULL) {
@@ -219,6 +220,9 @@
         }
 		dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
     }
+#else
+    return 0;
+#endif
 
     if (dwRetVal == NO_ERROR) {
         for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
  1. cd SDL_net-1.2.8; ./configure --enable-shared --enable-static --host=i686-w64-mingw32; make; sudo make install
  2. sudo rm /usr/local/cross-tools/i386-mingw32/lib/*.dll.a. This eliminates the dynamic libraries to force static linking of SDL.
  3. cd chocolate-doom-2.2.1; ./configure --host=i686-w64-mingw32 --build=i386-linux LIBS="-lgdi32 -lwinmm -lwsock32"; make
  4. i686-w64-mingw32-strip src/chocolate-doom.exe

Voila, a statically built version of Chocolate DOOM which runs on everything from Windows 95 to Windows 10 (might need msvcrt.dll on old versions of Windows 95).

The merged binary

smash.py merges the two binaries together to produce the merged binary DOOM.EXE. What it basically does is extend the size of the DOS header to make room for a PE header, appends the entire Windows binary to the DOS binary, then inserts the PE header into the slack space and rewrites the section offsets appropriately. On DOS, the next_offset in the header is ignored: DOS/4GW uses the executable size in the second and third WORDs of the DOS header to find the next binary to load. On Windows, the entire DOS header is ignored except for the next_offset, which points to the PE header and thus loads the Windows binary.

DOOMUPX.EXE, similarly, is generated by merging together the two UPX'd binaries DOOMDUPX.EXE and DOOMWUPX.EXE. It's quite a bit smaller, but on the use of UPX (plus the unusual file structure) seems to cause a lot of virus scanners to flag it as suspicious. It's the original version that was posted to Twitter.

Acknowledgements

Thanks @angealbertini (angea) for this neat challenge!

More Repositories

1

2048-ai

AI for the 2048 game
Python
1,062
star
2

sha1collider

Build two PDFs that have different content but identical SHA1 sums.
Python
409
star
3

iOS-SOCKS-Server

iOS HTTP/SOCKS proxy server for fake-tethering
Python
243
star
4

eqgrp-free-file

Free sampling of files from the purported Equation Group hack.
Python
176
star
5

pwn-stuff

Miscellaneous utilities and such that I use for pwning. Open sourced since people might find these useful. Be warned: nothing is stable.
Python
123
star
6

ffsend

Python client for Firefox Send
Python
120
star
7

ntfsrecover

NTFS data-recovery program written in Python
Python
115
star
8

Il2CppVersions

Build scripts & historical header files for every available minor version of Unity's Il2Cpp project
C
102
star
9

ghidra-rickroll

Get rickrolled, right in your favourite NSA reverse engineering tool
C
77
star
10

socks5-ios

SOCKS server for iOS. Handy for defeating tethering speed limits, among other uses.
Objective-C
71
star
11

threes-ai

AI for the game Threes!
Python
55
star
12

direct-handtracking

DIRECT - Depth IR Enhanced Contact Tracking
C++
30
star
13

iOS-Torrent-Client

A torrent client for iOS which runs on play.js - without sideloading or jailbreaking!
JavaScript
29
star
14

fixedint

Fixed-width integers for Python
Python
26
star
15

doublethink

Doublethink challenge from DEF CON 2018
Python
23
star
16

ofxWin8Touch

Windows 8 touch driver for OpenFrameworks using WM_POINTER events
C++
21
star
17

openFrameworks-AndroidStudio

OpenFrameworks modifications to work with Android Studio
19
star
18

sstic-2021

Files for my solution to the SSTIC 2021 challenge
C
15
star
19

firefox-charset-extension

Override Character Encoding extension for Firefox
JavaScript
10
star
20

sublime-replace-with-python

"Replace with Python" for Sublime Text 2
Python
9
star
21

Insta360-X3-Firmware-Tools

Tools for unpacking and repacking firmware images for the Insta360 X3
Python
6
star
22

bgrep

Binary grep with support for sophisticated regexes and grep(1)-like usage
Python
6
star
23

steam-phishing-analysis

Analysis and dissection of a Steam login phishing site.
HTML
6
star
24

sstv-encoder

SSTV encoder for Terebeep challenge at PlaidCTF 2017
Python
5
star
25

pogo-iv-reader

Screenshot-reading IV calculator for Pokemon GO
Python
4
star
26

net-nrbf

Utilities to dump and process .NET binary-serialized data streams.
Python
4
star
27

android_remote_control

Control an Android phone's touchscreen via ADB.
Python
3
star
28

hexacon-2022

Files for my solution to the Hexacon 2022 challenge
Python
3
star
29

pandt

HCI P&T projects
C
3
star
30

libm3

Library for reading and writing Blizzard .m3 model files.
C++
3
star
31

sstic-2023

My writeup for the SSTIC 2023 challenge (https://www.sstic.org/2023/challenge/)
Python
3
star
32

ghidra-skeleton-language

Skeleton language module for Ghidra
Java
2
star
33

sarah2-attack

Cryptanalysis of the Sarah2 pen-and-paper cipher
Python
2
star
34

weka-android

Weka for Android.
Java
1
star
35

ofxGestureCam

OpenFrameworks addon for the Creative Gesture Cam
C
1
star