Reverse Engineering: Weather Wizard

Weather Wizard is a program written by Sandra & Antoine Becker which allows you to download real-world weather data, and exports it to Microsoft Flight Simulator situation files (.STN) and adventure files (.ADV). You can also create custom routines for WinPlanner (.WPA). Version 1.2 also supports METAR weather format. Published in 1996 under the name AirSoft, the original registration options from RegNet and CompuServe are unavailable. This leaves Weather Wizard as unregistered software that can no longer be registered.

16-bit DOS Debugging on 32-bit Windows

Bypassing registration requirements for software from the late 90s is nothing exceptionally challenging, however Weather Wizard is a 16-bit NE (New Executable) that was designed for Windows 3.1. Virtual machines under both VMWare and VirtualBox have been problematic for Windows 98 and earlier since upgrading my Intel 6700K to 12600K, presumably related to virtualization changes. Likely I will need hardware emulation alternatives such as DOSBox, PCem, or QEmu - which I did not explore but should in the future. Instead I opted for debugging on Windows XP which uses NTVDM (NT Virtual DOS Machine).

The NTVDM is essentially an official DOS emulator that was shipped with 32-bit versions of NT Windows to keep compatibility during the transition from MS-DOS. When you go to run an MS-DOS program, an NTVDM process is spawned with multiple threads - one being the translated program. The original program itself is not contained within the NTVDM process, meaning that the program is translated and then that's what is executed. Another article which demonstrates debugging an NTVDM program can be found here. What I needed to debug was the actual program and not the translated one, as making binary modifications would be on the original file and not the memory-translated (emulated?) one through NTVDM.

What I was able to do was instead debug the program with the Open Watcom 16-bit debugger. The debugger itself ends up getting emulated through NTVDM - but when it loads a program to debug, it remains as the original program. This is simply because the 16-bit debugger is loading and running the program, and the debugger is the one being emulated. I did notice as a side effect that when Open Watcom crashes the NTVDM which was seemingly often, I would have to restart my Windows XP VM.

Weather Wizard Debugging

For static analysis I decided to use Ghidra since IDA Free does not support 16-bit DOS files; at some point I may consider IDA Pro. In Ghidra the segments used were inconsistent with the segments that I saw when debugging through Open Watcom. This is likely related to either NTVDM, my lack of knowledge of memory segmentation, or Ghidra was incorrect. Either way, all I needed to do was note what the segments were in the debugger and what they were in Ghidra. Thankfully the segments didn't change during the dynamic analysis.

When attemping to register, it will fail with a generic unregistered message. This same MessageBox will appear if you try to use features of the program which require registartion such as Import Real Weather Data. Initially Ghidra did not report any references to the MessageBox function import because it failed to identify the function which used it during its (presumably) recursive descent. This meant I had to set a breakpoint on MessageBox (USER.DLL), then slowly walk back through the call stack until I reached a segment of memory back inside Weather Wizard (WINWX.EXE). Once I found where the program returned, I identified and created the function in Ghidra. The function it did return to had a lot of references to it, presumably because there are lots of registration checks for different features.

Since Weather Wizard is an Afx program, the call stack for this particular function which invokes the MessageBox is limited to a callback which was registered with the user control. This means I was able to find the function which gets invoked when a user presses the "OK" button on the registration dialog. This gives me the code path from when the user presses "OK" to when the dialog appears. Although now the functions were renamed, it was evident that there was a code path where the registration message was not displayed.

Now renamed to IsRegistered, when the function returns true the MessageBox does not appear. The IsRegistered function is referenced throughout the code, beyond clicking on registered-only features. For instance when you click "File", the "Register" menu option will be inactive (greyed out) if you are already registered. Initially I wanted to figure out the algorithm to create a key generator, however I decided the effort wasn't worth it and went with patching the IsRegistered function to take a code path which returns true. The patch is shown below which replaces a couple of checks on what appears to be a hash, with nops. To patch the binary I scanned an AOB (array of bytes) which represented the target instructions, then replaced them using HxD.

In case the screenshot above gets lost, replace file offset 0x26BDA - 0x26BF0 with 0x90 bytes (Version 1.2 only). A download link to the pre-patched program should exist under the Patchers section of my website.