Authenticode signature verification for plugins via the OnValidateModule hook.
SignedPluginsApp.exe
| DCC_UsePackage = rtl;fmx;FMXPluginFramework
|
+-- TBPLLoader.Create(BinPath)
+-- FLoader.OnValidateModule := ValidateModule <- set hook
+-- FLoader.LoadAll(plugins.json)
| |
| +-- SignedPlugin.bpl -> ValidateModule -> VerifyAuthenticode -> OK -> load
| +-- UnsignedOptional.bpl -> ValidateModule -> VerifyAuthenticode -> FAIL -> skip (optional)
| +-- UnsignedRequired.bpl -> ValidateModule -> VerifyAuthenticode -> FAIL -> Exception (required)
|
+-- Application.Run
- OnValidateModule hook: Callback is called BEFORE each
LoadPackage - TSecurityValidator.VerifyAuthenticode: Windows WinVerifyTrust API for signature verification
- Required vs Optional:
plugins.jsoncontrols whether a validation failure stops the app or skips the plugin - Three plugin variants: Signed, unsigned-optional, unsigned-required
| File | Purpose |
|---|---|
SignedPluginsApp.dpr |
Host app with ValidateModule callback |
SignedPlugins.groupproj |
Build: Framework -> 3 Plugins -> App |
plugins.json |
Plugin list with required flag |
../DemoPlugins/SignedPlugin/ |
Simulates a signed plugin |
../DemoPlugins/UnsignedOptional/ |
Unsigned, required: false |
../DemoPlugins/UnsignedRequired/ |
Unsigned, required: true |
- Framework is statically linked (
DCC_UsePackage) OnValidateModuleis set beforeLoadAllis called- For each BPL the loader calls the hook -- on
false:- Optional: Plugin is skipped, app continues
- Required: Exception is raised, app shows error message
TSecurityValidator.VerifyAuthenticodeuses the Windows WinVerifyTrust API
{
"plugins": [
{ "name": "SignedPlugin", "file": "SignedPlugin", "required": false },
{ "name": "UnsignedOptional", "file": "UnsignedOptional", "required": false },
{ "name": "UnsignedRequired", "file": "UnsignedRequired", "required": true }
]
}- Framework is loaded BEFORE the app: Since
FMXPluginFrameworkis inDCC_UsePackage, the OS loader loads the framework BPL before the EXE even starts. A tampered framework would not be detected. - Only plugin BPLs are checked: The EXE and the framework itself are not validated.
The Authenticode check can be extended with hash-based checks using Plugin.Manifest (from Helpers/). TManifestValidator verifies SHA256 hashes against plugins.json and can be used directly as an OnValidateModule callback.
For pre-load validation of all BPLs, see SecureBootstrap.