In this article I like to spend a few words on a concept introduced with Windows XP: Manifest files. These files are used beside an executable to tell various things about the context the program will run in. I think the most common usage of manifests is to enable visual styles in an application. But if we look closer on that we can see that it actually is not like manifests directly enable the visual styles, no, the manifest actually only tells the operating system that our application depends on a so called 'assembly'. Don't be scared, it has nothing to do with assembler, ill explain later what to understand under assemblies and what dependency means.
So we have learned one important aspect of manifests:
- They can declare dependencies to assemblies.
- It searches in the global cache.
- It searches for the first resource inside the executable which has the type RT_MANIFEST (24 on my system)
- If nothing is found inside the exe it searches inside the folder if it finds a file named EXENAME.exe.manifest.
Well, i think its time now to have a view on an example manifest. If you create a new project in Visual Studio a manifest is automatically generated when you build your application. It can be found inside the Debug (or Release) folder of your project (not solution) and is called 'ProjectName.exe.intermediate.manifest'. It has the intermediate inside it because thats the part that gets automatically added but you can modify that inside the project settings and thus its not the final version but only an intermediate one.
I named my Project ManifestExample so the manifest is called ManifestExample.exe.intermediate.manifest and the contents are:
<assembly manifestversion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <trustinfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedprivileges> <requestedexecutionlevel level="asInvoker" uiaccess="false"> </requestedexecutionlevel> </security> </trustinfo> </assembly>
First thing we see is that manifests are written using the XML syntax. That makes it pretty straightforward to understand and we can focus on the actual elements. What this manifest does is that it defines some security related properties of the application. To be more clear: It declares which access rights the user has to have this application will run in. That is controlled using the 'level' attribute inside the requestedexecutionlevel tag. There are 3 values valid for the level attribute:
- asInvoker -> The application will run with the same privileges as the calling user
- highestAvailable -> The application will run with the highest privileges the current user can reach
- requireAdministrator -> The application must be run in administrator mode (on Vista and Win7 a window will pop up asking the user to allow the application to run as administrator if thats enabled)
The uiaccess attribute is a bit more complex. Imagine you are writing an application that simulates a keyboard on the monitor where the user can make input. Now it may be necessary to bypass regular input control mechanics to work properly. To be able to do that the uiaccess attribute must be set to true.
In addition setting uiaccess to true requires some additional security options! The application first has to be signed by Authenticode and second it has to be in protected folder (for example system32 or program files).
Second thing we learned about manifests:
- Manifests define security aspects of an application.
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level='asInvoker' uiAccess='false' /> </requestedPrivileges> </security> </trustInfo> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' /> </dependentAssembly> </dependency> </assembly>
The new tags we see are dependency, dependentAssembly, assemblyIndentity. The dependency tag lists a dependency for application the dependentAssembly tag hosts a dependency to an assembly and the assemblyIndentity tag finally specifies the assembly our application is depending from. There we find several possible attributes that identify the assembly. Actually only two of them are required the rest is optional and is used to distinguish it from other assemblies that may have the same attributes.
Explanation:
- type - Optional - Only valid value is win32
- name - Required - The name of the assembly
- version - Required - The version of the assembly to load
- processorArchitectur - Optional - May be clear. Valid values are (ia64, amd64, x86, msil)
- publicKeyToken - Optional - The strong name of the assembly
- language - Optional - The language ID of the assembly
Now its time to talk about how the system finds an assembly. This is actually pretty simple. The system does the same as it does when you launch an application. In the above code it will search a manifest which denotes an assembly witch defines an assemblyIdentity that matches the requested one. In our case it searches the following way:
- It searches the Microsoft.Windows.Common-Controls.dll inside global search paths and inside the current executables path. If it finds that dll it searches a manifest resource inside that dll that is called "Microsoft.Windows.Common-Controls.manifest" and compares it.
- If that didnt succeed the system searches in the same paths for a file called Microsoft.Windows.Common-Controls.manifest and parses it
- If that failed it searches for the folder "Microsoft.Windows.Common-Controls" inside all global search paths and the current executable path and does the same search as above again
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="Win32" name="MyNiceAssembly" version="1.0.0.0" /> </assembly>
We learn:
- Manifests can be used to give any component (DLL, exe, ...) a name with which it can be identified
Thanks
Yanick
I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers
AntwortenLöschenwindows server 2019 essentials key