Question

I'm in the middle of writing my own version of the Windows Loader (albeit a very simple version) and thus far things have worked out fairly well. However, I've run into a little snag when it comes to recursively walking the Import table for the loaded module.

For most dependencies, things work out well and I can simply recursively load the module. However, for some dependencies, this just breaks the target process. Upon further investigation I realized that this is because of Windows Side-by-side assemblies. Essentially, the dependency in the loaded PE was a different SxS version of the module being used in the target process.

In one case, the DLL I was loading referenced msvcr90.dll, but the target process was using an earlier version of the runtime: msvcr71.dll.

Now, the windows loader can handle this fine, so there's obviously a "correct" way to do this. I've read up a bit on Activation Contexts, but they haven't really helped me grasp the issue.

Calling LoadLibrary itself doesn't resolve the dll to the correct version either

LoadLibraryW(L"msvcr90.dll");

Simply returns 0. Does anyone know

a) How to detect if an import is a SxS assembly

b) How to resolve the import into the correct SxS version for the process.

I'm really stumped on how to do this. I know most of the PE file format from research now, but I'm pretty sure the SxS is beyond the scope of PE structure.

If you need any more info, just comment. The executable doesn't have an external manifest, and its embedded manifest doesn't specify the runtime version. It does, however, contain a copy of msvcr71.dll in its working directory, if that helps anyone at all.

Cheers.

Was it helpful?

Solution

As a matter of fact, SxS dependencies are beyound the scope of the PE Structure! As you know, the Import Tables of PE enumerate the dependencies names but not their versions. When handling these tables of dependencies, the Loader also look at the Manifest of the PE dependent images. Should a Manifest documents one or more libraries (e.g msvcr90, advapi32,....) the loader looks in winsxs folder to find the dependency. Here an article that gives an overview of this assembly and how to collect these information in C++.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top