向安装程序添加校验和,并在安装程序启动时对其进行验证。标准(也是推荐)的方法是使用代码签名证书对安装程序进行签名。必须的 https://security.stackexchange.com/q/222140/43677无论如何这些天。
验证签名的简单方法是使用 PowerShellGet-AuthenticodeSignature https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-authenticodesignature。为此,您需要 PowerShell 5.1。它与 Windows 10 Build 14393(2016 年 8 月)及更高版本捆绑在一起。以下代码使用它(并跳过对旧版本 Windows 的检查)。
function InitializeSetup(): Boolean;
var
WindowsVersion: TWindowsVersion;
S: string;
ResultCode: Integer;
begin
Result := True;
GetWindowsVersionEx(WindowsVersion);
Log(Format('Windows build %d', [WindowsVersion.Build]));
// TODO: Better would be to check PowerShell version
if WindowsVersion.Build < 14393 then
begin
Log('Old version of Windows, skipping certificate check');
end
else
begin
S := ExpandConstant('{srcexe}');
if (Pos('''', S) > 0) or (Pos('"', S) > 0) then
RaiseException('Possible code injection');
S := 'if ((Get-AuthenticodeSignature ''' + S + ''').Status -ne ''Valid'') ' +
'{ exit 1 }';
if ExecAsOriginalUser(
'powershell', '-ExecutionPolicy Bypass -command "' + S + '"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
(ResultCode = 0) then
begin
Log('Installer signature is valid');
end
else
begin
S := 'Installer signature is not valid. Are you sure you want to continue?';
Result := (MsgBox(S, mbError, MB_YESNO) = IDYES);
end;
end;
end;
如果您需要支持旧版本的Windows,则必须使用更复杂的方法,例如:
- 捆绑signtool https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool使用安装程序(不确定此处的许可证);
- Using X509Certificate class https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate.
See 如何检查文件是否有数字签名 https://stackoverflow.com/q/667017/850848.