Customizing an EXE Manifest File

Customizing an EXE Manifest File

When you build a project for a Windows target platform, RAD Studio automatically includes an application manifest file. You can use the default application manifest file as a base for your custom application manifest file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

Creating a Custom Application Manifest File

To do that, All you need is a Resources hacker/inspector program that allows you to change the manifest of an EXE file.

I personnaly use Angus Johnson’s Software for a long time because it’s just simple and cool to use.

Image1

Changing the Required Elevation Level

The default application manifest declares the required elevation level as asInvoker. That means that your application will have the same elevation level as its parent process. If you wish to elevate your application to the Windows Administrator privilege level, simply change the value of the level attribute in the requestedExecutionLevel tag from asInvoker to requireAdministrator.

You can add that to the TrustInfo, and the <security> tag where you will add both the Level and uiAccess to the Requested Execution Level:

1
2
3
4
5
6
7
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
  • uiAccess

    • false — The application does not need to drive input to the UI of another window on the desktop. Applications that are not providing accessibility should set this flag to false. Applications that are required to drive input to other windows on the desktop (on-screen keyboard, for example) should set this value to true.

    • true — The application is allowed to bypass UI protection levels to drive input to higher privilege windows on the desktop. This setting should only be used for UI Accessibility applications.

  • Level : Here you can find a table explaning the Level declared in application manifest and it’s behavior

Table

Note: The user will still need administrator privileges or credentials in order to run the application with the Administrator privilege level.

You can find more about it on Microsoft’s Docs website : /MANIFESTUAC (Embeds UAC information in manifest)

Changing the DPI Awareness

In order to create a DPI-aware application, you need to declare DPI awareness in the application manifest. For example, to declare that your application is per-monitor DPI-aware, add the following before the closing </assembly> tag:

1
2
3
4
5
6
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>

Testing the Administration Privileges

The following code snippet can serve as a quick test whether your application requires (and is properly granted) the Administrator level privileges. Declare the required elevation level of your application as requireAdministrator and execute the following procedure:

C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <System.Win.Registry.hpp>
#include <Winapi.Windows.hpp>

void __fastcall isAdmin(TObject *Sender){
TRegistry *reg;
bool openResult;
reg = new TRegistry(KEY_READ);
reg->RootKey = HKEY_LOCAL_MACHINE;
reg->Access = KEY_WRITE;
openResult = reg->OpenKey("Software\\MyCompanyName\\MyApplication\\" , true);
if (openResult != true){
MessageDlg("Unable to write to registry. Your application does NOT have Administrator level privileges.",
TMsgDlgType::mtError, mbOKCancel, 0);
}else{
MessageDlg("Write to registry permitted. Your application has Administrator level privileges.",
TMsgDlgType::mtInformation, mbOKCancel, 0);
}
reg->CloseKey();
reg->Free;
}
  • The application displays one of the following messages:

    • Unable to write to registry. Your application does NOT have Administrator level privileges.

    • Write to registry permitted. Your application has Administrator level privileges.

This test works because you need Administrator level privileges in order to write to the HKEY_LOCAL_MACHINE\Software part of the registry.
The snippet does not actually write anything to the registry, it just requests the write permission.

Make sure that you build your application and then execute it outside of the IDE, because the IDE will debug the application with Administrator level privileges by default (not respecting your application manifest).

© 2021 - Sofiane Hamlaooui - Making the world a better place 🌎