Where does kernel32.dll GetVersionEx() get its information from?


  • Hello,

    Despite my protests, I've been tasked with installing an obsolete 10 year old application on Windows Server 2016. Unfortunately, the installer detects an incompatible Windows version and refuses to install the app. Since the customer absolutely needs to have the app AND Windows Server 2016, I need to somehow fool the installer into thinking that it's running on an older system.

    I do not have the source code for the app (3rd party), nor does it contain the list of supported OS versions in any of the plaintext config files. It most likely doesn't extract the info into %TEMP% either (I checked there and found nothing) - and if it does, it does not do it in a human-readable way.

    I know the app is old and written in Visual C++, so it's likely that it uses the GetVersionEx() function to obtain the version info. The installer log information it provides is also consistent with the output of this function.

    My first question is: where does that information come from, and whether it is feasible to spoof the version somehow. In case the answer is negative, I'd like to know what other ways of achieving the goal might there be.

    P.S. I tried compatibility mode - that didn't work.

    Thursday, December 6, 2018 12:32 PM


  • Even if you could find the value that a Windows API function returns, whether that value was embedded in a DLL or a Driver or the Registry, whether that value was hard set or calculated, you would never want to change that value for any reason.  The worst reason I can think of to make any system-wide change is for the sake of one single program.  I'm looking sidewise at my GFX card.

    If the installer is an EXE or an MSI, you should be able to open it like an Archive File with 7Zip.  To be clear:  You need 7Zip, not WinZip or Windows Zip File Support, you need the program called 7Zip.  With a lot of older programs you can just extract the program stuff from the installer and run it, and depending on how the installer was made you might find that the program inside runs just fine once you bypassed the installer's version test.  Then again, you might find that the program doesn't.

    If solution A doesn't work out (extract from installer with 7Zip and run the app):  The best, not because it's easiest (it is) but because it's a full solution with no room for doubt or error, is to run a virtual machine on your server with the needed OS installed.  I like xVM VirtualBox.  You can set it up to launch your new virt at host startup, but you have to manually shut it down before the server every single time and you would have to check both the server and the virt for any data corruption or other common problems that occur with a hard shutdown any time the box lost power.  It's a real PITA, but in your case that's awesome because a PITA means billable hours.

    If you're just really dedicated to hacking the problem out yourself, start over with Process Monitor from Microsoft's SysInternals, here. It takes a little learning time, but it's the handiest tool there is for troubleshooting and/or investigating software incompatibility issues. You'll need to launch your program and then look up its "image name" in the Task Manager, under the Processes tab, then set up a filter in Process Monitor that targets this image name only. The next time you launch the app while ProcMon runs, it will list out every single API call made from that app and it lists them in order.

    The reason I suggest that is that Windows API functions change and their output values change, but typically any given function will stay the same for a few versions at a time, so it's more than likely if the product doesn't tell you what version of Windows it wants it's failing for another reason.  That reason may be a function call that doesn't exist in the new version of Windows or it may be a return value in a struct that contains a lot more fields (or sometimes less fields) than the program expected.

    So once you get a good handle on whether you actually need to meddle with the program's API calls or not, then exactly which API calls you need to meddle with (no more and no less than the ones you absolutely need to), you should look into something called DLL Hijacking.  This is where you would create your own DLL (for example named kernel32.dll) and drop it right into the same directory as the program you want to capture API calls from.  You would rewrite the function(s) you need to rewrite and pass the rest through to the other, original DLL.

    It never hurts to try. In the worst-case scenario, you'll learn something.

    • Marked as answer by CZIntercity Thursday, December 6, 2018 7:34 PM
    Thursday, December 6, 2018 1:41 PM