整个 Inno Setup 安装程序的完整性检查

2024-06-23

我们使用 Inno Setup 作为安装程序。最近有用户在安装过程中报告如下错误:

尝试复制文件时发生错误:源文件已损坏

这是由于安装文件确实已损坏。

理想情况下,安装 EXE 会在初始化时执行某种检查,以查看整个 EXE 是否有效。但显然它只是逐个文件地执行此操作。是否可以让 InnoSetup 来做到这一点?


我在 Inno Setup 文档中查找了“check”、“hash”等关键字,但没有看到任何内容 - 也许我错过了。

非常相似的问题(大约 10 年前 - 尽管专门询问 MD5):如何对 Inno Setup 安装程序实施 MD5 检查以获得“类似 NSIS 完整性检查”? https://stackoverflow.com/questions/12351506/how-to-implement-md5-check-into-inno-setup-installer-to-get-like-nsis-integrity。这个问题似乎表明这样的检查应该已经发生。因此,也许问题不在于安装 EXE 是否经过验证,而在于何时使用/向用户显示此信息。此外,接受的答案似乎相当手动,理想情况下我希望 Inno 自己做这件事。

类似的问题但有不同的错误消息:Inno Setup 出现“源文件已损坏:SHA-1 哈希不匹配”错误 https://stackoverflow.com/questions/14581083/source-file-corrupted-sha-1-hash-mismatch-error-from-inno-setup


向安装程序添加校验和,并在安装程序启动时对其进行验证。标准(也是推荐)的方法是使用代码签名证书对安装程序进行签名。必须的 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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

整个 Inno Setup 安装程序的完整性检查 的相关文章

随机推荐

  • Laravel 4:处理种子中的关系

    L4 的新种子功能中是否有一种简单的方法来管理多对多关系 一种方法是为数据透视表制作种子 但我需要做很多工作 对于此类事情的良好工作流程有什么想法吗 在最新版本的 Laravel 4 中 您可以在 DatabaseSeeder 类的 run
  • SublimeREPL 无法找到 R

    好吧 这让我发疯 我之前已经设置过 删除了 Sublime Text 现在我不记得正确的配置是什么 非常简单 我通过 SublimeREPL 运行 R 并且需要将 REPL 指向安装 R 的位置 我按照以下指示进行操作http sublim
  • 非成员运算符重载应该放在哪里?

    我想要超载operator lt lt 为了我的班级 我应该将这个重载定义添加到std命名空间 自从ostream operator lt lt 是的一部分std命名空间 或者我应该将其保留在全局命名空间中 简而言之 class MyCla
  • 为什么即使是非常简单的应用程序,MonoTouch 也会导致大量内存泄漏(根据 Instruments 的报告)?

    我正在使用 Instruments 运行一个非常基本的测试应用程序 它发现了很多内存泄漏 因为我知道 Apple 人员在将应用程序提交到 iTunes 时会检查内存泄漏 所以我想调查一下这个问题 我的环境 Mac OS X 10 6 6 上
  • svn 切换错误 - 不是同一个存储库

    我最近移动了 SVN 服务器 现在我正在尝试将工作副本从我的计算机重新定位到新服务器 但我得到了最奇怪的错误 我愿意 svn switch http 99 99 99 new svn company project trunk web 但我
  • 在标签上运行管道时如何获取分支名称?

    我从标签运行管道 比方说v1 0 0 在一个分支上 比方说staging 我的输出文件是用创建的 CI PROJECT NAME CI COMMIT REF NAME apk 结果是一个名为MyProject v1 0 0 apk 我希望在
  • 从 .gitlab-ci.yml 中的 JSON 中提取徽章 ID

    我有一个示例项目 https gitlab com mstein badge number example repo在 gitlab 中 我想获取最后一个徽章的 ID gitlab ci yml通过脚本 我了解所有徽章的概览作为 json
  • 如何避免 Google App Engine 标准环境中 Gorilla 会话的内存泄漏?

    我正在使用 Gorilla 在 Google App Engine 上启用会话变量 到目前为止 我只导入了 github com gorilla sessions 但 Gorilla 的页面显示 如果您不使用 gorilla mux 则需要
  • 将 Dynamo DB 流数据解组为 Json 格式

    我必须将DDB流消息转换为正常的json类型 为此我正在使用 unmarshalleddata aws DynamoDB Converter unmarshall result NewImage 其中 result NewImage 是 c
  • 如何在 Angular js 中创建动态工厂?

    在我的项目中 我必须在 Angular js 中创建动态工厂 其动态工厂名称如下 function createDynamicFactory modId return myModule factory modId existingServi
  • 从对象数组中删除重复项

    我有一堂课叫Customer它有几个字符串属性 例如 firstName lastName email etc 我从a读取客户信息csv创建类数组的文件 Customer customers 我需要删除具有相同电子邮件地址的重复客户 为每个
  • GUID 幕后花絮

    我想知道 GUID 的创建过程是怎样的 我的意思不是用什么来以特定语言创建 GUID SQL Server 中的 NewID C 中的 Guid NewGuid 我的意思是当你调用这些方法 函数时 它们会做什么来使图形用户界面 Also R
  • 如何在 Python 中打印异常?

    如何打印错误 异常except block try except print exception 对于 Python 2 6 及更高版本和 Python 3 x except Exception as e print e 对于 Python
  • 如何在 PHP 中解析 OFX(版本 1.0.2)文件?

    我有一个OFX http www ofx net 文件下载自Citibank https www citibank com co 该文件的 DTD 定义在http www ofx net DownloadPage Files ofx102s
  • 从 Laravel 中的命令调用控制器方法

    我有一个通过 Redis Pub Sub 监听的命令 收到发布后 我想调用控制器方法 以便可以更新数据库 但是 我无法找到任何关于如何从项目内部但在路由外部调用带有参数的控制器方法的解决方案 我见过的最接近的东西是这样的 return re
  • R Shiny Dashboard 在初始化时不会在 sidebarMenu 内加载渲染的 UI

    我正在尝试根据用户希望如何提供输入来生成动态的 UI 元素 为了简单起见 我使用闪亮的仪表板 但我遇到了侧边栏菜单的问题 以前 当我将静态 UI 元素直接放入 sidebarMenu 中时 没有任何问题 但是当尝试将动态 UI 元素放入 s
  • 什么是日历队列?

    我正在致力于构建一个离散事件模拟器 维基百科提到有几种通用优先级队列非常适合在 DES 中使用 具体来说 它提到日历队列是一个很好的结构 我找到了一份 pdf 1988 年的 其中提到了日历队列 但在大多数情况下我找不到关于它们的任何其他内
  • 如何在 python 套接字中使用浏览器作为客户端?

    我试图在互联网上搜索这个主题 但我没有找到一些答案 如果有人知道如何在 python 套接字中使用浏览器作为客户端 那就太好了 要将浏览器用作 python 服务器 套接字的客户端 您只需将其指向正确的端点即可 假设您在同一台计算机上运行浏
  • 当脚本执行暂停时,如何在 chrome devtools 中运行异步代码?

    await Promise resolve 1 在 chrome devtools chrome 版本 70 0 3538 77 中解析为 1当脚本执行未暂停时 Promise
  • 整个 Inno Setup 安装程序的完整性检查

    我们使用 Inno Setup 作为安装程序 最近有用户在安装过程中报告如下错误 尝试复制文件时发生错误 源文件已损坏 这是由于安装文件确实已损坏 理想情况下 安装 EXE 会在初始化时执行某种检查 以查看整个 EXE 是否有效 但显然它只