小计如何指定依赖dll的加载路径 (windows)

@vrqq  May 11, 2022

书接前文 回到之前说过的manifest文件

https://blog.vrqq.org/archives/779/

  • manifest文件能用link.exe写入,还可以后天修改(推荐后天mt.exe方式)
  • 微软建议 每个manifest仅和单个文件关联(当然也可以关联多个)
  • Please Know that before used, this is an undocumented feature.

给exe的manifest加参数 完整manifest如下

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="myprogram.quick.start"
                    version="20.20.20.20" processorArchitecture="x86" />
  <file name="ffmpeg.dll" loadFrom="C:\TheOtherPath\ffmpeg_other_name.dll"></file>
</assembly>

签名、验签、版本号、和dll依赖

dll依赖

  • 假设上文文件名为app2.manifest
  • 验证写的对不对 mt.exe -manifest app2.manifest -validate_manifest
  • 将app2.manifest挂入exe mt.exe -outputresource:"myapp.exe";#1 -manifest app2.manifest
  • 查看挂好的文件: VS打开文件夹,然后双击exe文件,右侧会出一个目录树,在RT_MANIFEST
  • 从exe导出manifest文件 mt.exe -inputresource:"myapp.exe";#1 -out:app2.manifest
  • 增量更新 mt.exe -updateresource:"myapp.exe";#1 -manifest patch3.manifest

版本号: 有两种

  • 一种是单个文件的 "version, author, ..." 在右键属性里
  • 另一种是manifest内规定的"version of file collection covered by manifest"

    • 常见情况是: 一个manifest内嵌在单个文件内,所以和前一种"version"产生了歧义
    • 一种不常见的情况: manifest内使用file指定了很多文件,这些文件都归属于当前manifest,见例子 https://blog.vrqq.org/archives/779/

数字签名
和https网站签名一样,使用 "证书crt" + "私钥key" 给dll/exe挂签名,证书的种类为 "OV Code Certificate" and "EV Code Certification",关键词 "Code Signing Certificate"

  • This type of certificate is different with SSL-certificate
  • 添加数字签名后,于文件属性可见 "Digital Signatures"
  • 输出数字签名详情: signtool verify /pa /v c:\Windows\system32\kernel32.dll
  • publicKeyToken 对于.Net程序 支持StrongName: sn -T YourAssembly.dll
  • publicKeyToken 对于普通程序: pktextract c:\workingdir\fable\check-same.cer
  • 工具 https://docs.microsoft.com/en-us/windows/win32/seccrypto/signtool

验签
很可惜,操作系统不支持用签名校验“程序包”完整性,但WindowsDefender可以

直觉上说 manifest可以包括"验证依赖是否完整",以及依赖的那些dll是不是系统dll

  • 操作系统保证了 C:\Windows\System32 这个目录不会乱搞 (关键词: 目录签名)
  • manifest文件中有一条assemblyIdentity.publicKeyToken,看起来可以验证依赖的程序集是不是原生的

写在最后
防破解、 防debug 和 防注入 在很多角度上是一回事,无非是再汇编代码里插桩,游戏厂商做不到,加壳厂商也做不到
用户组已经覆盖了正常使用,没有一个像模像样的container 否则快捷键、截屏、文件下载都没有了
也倡导软件开发者们:主动避免申请管理员权限,高权限代码主动开源。


添加新评论