Tuesday, 3 July 2018

MSIX PSF - Promise of a New World for Migrants (apps)

At MS Build 2018 (on 8th May), MSIX was launched with a promise of the new world (Win10) for the old legacy apps. I was one of the few partners who got a first-hand session from MSIX developers at a 2-day summit in Redmond before Build conference. At Build, the Windows team disclosed details of MSIX components including the Package Support Framework (PSF).

In this blog, we will take a closer look at what was revealed during the session at Build 2018 and do a technical dissection to see what this might lead to in future. I'll be interpreting PSF based on my experience of working with a similar software. So, few things might seem to be as if I am reading between the lines. As PSF isn't released yet, this write-up will touch base on basic concepts only. Once it gets released, I'll post subsequent blogs getting into details.

First, a disclaimer; although my day to day job involves working on similar tech at Cloudhouse and I work very closely with Microsoft's MSIX team; blogs published here don't reflect the opinion of Microsoft or my employer. I've launched this website as a community initiative to share my views and spread the word about MSIX PSF. Hence I'll be penning down my knowledge and experience on fixing legacy apps without violating my NDA. 

Now let's discuss the "What.. Why.. and How" Stuff.


PSF is a framework to facilitate fixing of app compatibility issues without changing the application's source code. This framework will be responsible for injecting DLLs (called "Fix-ups") into the application at runtime. The code in these Fix-up DLLs gets triggered whenever application issues a relevant API call. You can imagine it as a layer positioned in the OS stack in between the application and the operating system. To summarize, it is a mechanism which uses API Hooking to re-route the API calls made by an application before they hit the OS. It is based on Microsoft's Detours technology (which is a huge topic in itself). Will keep it for my next blog in the Training section. 

WHY now?

Why did Microsoft come up with this kind of solution now?

Legacy apps have been an issue for ages! Officially revealed figure by Microsoft says that there are 16 million legacy apps which can't move to latest platforms. That's no surprise to me. At Cloudhouse, we deal with hundreds of apps blocked on XP from every industry (including top organizations in healthcare, finance or government sector). 

These apps wouldn't have become legacy if their code was actively under development/maintenance phase. But unfortunately, many of these apps don't even have a source code maintained for it. They have just been deployed in production and forgotten! It's a pain for IT Pros to run these apps on old unsupported Operating Systems (like XP) in a highly restrictive and secure environment to avoid vulnerabilities getting exploited.

So, to me, the answer to "why now" is "because it had to be done someday". They just can't be left behind and the sooner you migrate it, the better. Also, recent malware attacks targeted many big organizations; so its high time!

HOW will PSF fix it?

Let's first take a quick look at how this stuff will work. As I said, I'll be interpreting Stefan's session based on my experience.

Fig 1

Fig 2

Fig 2 shows the components involved in Package Support Framework. It consists of 3 mandatory components viz Launcher.exe, Config JSON, and RuntimeManager.dll.

Notes from Session:
Launcher.exe is the entry point to apply the PSF functionality for your app. This is responsible for reading the configuration (from Config JSON) file to see which FixUps are to be applied. It then injecting the Fixups (example Fixup1.dll, Fixup2.dll) along with RuntimeManager.dll into the app. RuntimeManager.dll is a wrapper around detours which provides the functionality of API hooking and redirections for custom fixups.

My Interpretation: Normally, when you run your app (without PSF), you just execute App.exe. But if you want to apply the fixups then Launcher.exe will first be invoked. Build session didn't disclose how this will be invoked. But I am guessing that Launcher.exe will have a provision to take arguments with App.exe being mandatory arg and others being optional. It will also have a provision to accept args required by the App.exe (which will be passed to the App.exe when it gets launched). Once Launcher.exe is invoked, it reads the config and invokes your actual App.exe. It also injects Fixups.dll and RuntimeManager.dll into the app.

[Correction: On discussing this with Tim Mangan, he pointed out that AppX shortcuts don't allow command line arguments (today). Hence he is guessing that launcher.exe might read app's arguments from the configuration JSON file (and maybe AppxManifest). I agree with him.]

The code in Fixup.dll will be the implementation of the API's new functionality. For example, if you want to change a path in CreateFileW API (as Stefan showed in the demo) then the Fixup.dll's code will have some code to modify the path before calling the original CreateFileW function. This code will, in turn, use the APIs provided by Detours library to perform the actual hooking task. This is facilitated by the RuntimeManager.dll (which is a wrapper around Detours for API hooking). That's the reason Launcher.exe will have to inject RuntimeManager.dll into the app, otherwise, the code inside Fixup.dll won't be able to replace CreateFileW functionality for this app.

Fig 3

Fig 3 shows each of these files in Explorer view. Looking at the size of RuntimeManager.dll (4KB), it doesn't seem to have a lot of stuff in it. So, it looks like a bunch of small wrapper functions to call actual Detours APIs internally. But as this was just for the demo, MS might release a full-blown RuntimeManager when they launch the PSF product.

Fig 4

Fig 4 shows a sample AppManifest.xml. For those who worked on AppX or AppV (version 5 and above) will be familiar with this. It is used to change entry point to the application. During the session, Stefan showed an incorrect config by mistake. It should have been Launcher.exe instead of LegacyApp.exe.

Fig 5

Fig 5 shows the code in the config file. It's self-explanatory and simple to maintain. It just tells Launcher.exe to inject a specific DLL (Fixup.dll) into the app (LegacyAppWithIssues.exe) along with some other parameters like what will be the working directory to be set while invoking the app.

Fig 6
Fig 6 demonstrates the actual code in Fixup.dll. This shows how CreateFileW API'sbehaviorr will be changed on the fly. When an app calls CreateFileW, instead of going to actual CreateFileW, the detours library (RuntimeManager.dll in this case) will redirect the call to the CreateFileWImpl which is implemented in this Fixup.dll. This code will modify the path before calling the actual Windows API (CreateFileW). So, in effect, this mechanism is putting our custom API between App and the OS code.

Fig 7

This is an interesting thing. It will be very useful to have commonly used fixups baked into the product. Most of the simple scenarios will be reusable. There is no point reinventing the wheel for every single app. I am planning to contribute commonly used fixups on this site on Fixups page; which in turn points to a git repo (https://github.com/PS83/MSIX-Fixups). Microsoft might also maintain their own repo, but in case I find a useful scenario then I'll keep it here (for the community to use). I would welcome anyone who wants to contribute to the community using this repo. Please contact me if you want to be added as a contributor (would really appreciate).

Fig 8
Finally, Fig8 shows the whole end to end workflow for MSIX. As you can notice PSF will be a part of the testing phase where if an app fails, then packaging expert or IT Pro can add fixups on the fly to fix the incompatible code. I think this was the missing piece of the puzzle in the old world including AppV.

That's all for now. Hope this gets you to a quick start on MSIX PSF. As promised, I'll write some more articles to cover basics of Detours. I am eagerly waiting for the PSF to be released (hopefully we will see an initial version soon).

As I said, I am working very closely with the MSIX development team on Cloudhouse's support for PSF. We are incorporating our years of experience in fixing legacy apps into MSIX containers. I'll be blogging more on that when the time is right. Once PSF is in the market, we can start developing fixups to migrate old legacy apps to the shiny new MSIX world.

Stay tuned!

Priya Saxena.

No comments:

Post a Comment