之前曾经写过一篇个人经历,是关于VC2005分发包版本不一致而引起应用程序无法正常启动的(http://www.cnblogs.com/mixiyou/archive/2009/10/02/1575311.html)。这篇文章里只是介绍了个人在开发过程中遇到的一个非常极品的问题,但是没有给出更多详细的信息和解决方法。今日偶然看到一篇牛人写的文章,顺手翻译下来,总算了了长久以来的心愿。

原文地址:http://dumian.spaces.live.com/blog/cns!B67A33A47F9F9C48!459.entry

/// 原文

VC redistributable security update -KB971090 mitigation problem

Problem

After installing KB971090 for Visual C++ 2005 SP1, the version of ATL/MFC/CRT referenced in the generated manifests is changed from 8.0.50727.762 to 8.0.50727.4053

The above change forces the application developer to rebuild all components to reference the 4053 version of the versions of ATL/MFC/CRT in the manifest, as well as making it necessary to ship a new vcredist_x86.exe and/or MSM files containing the new 4053 versions of ATL/MFC/CRT.

Solution

Instead of uninstalling the KB971090 update, we can force the build to use the 8.0.50727.762 version instead of the default which is 8.0.50727.4053. Microsoft provides a mechanism to specify the assembly version number to use in the manifests.

Steps to take to allow your applications to reference 8.0.50727.762 instead of 8.0.50727.4053

1) Create a file named targetsxs.h with the following content and put it in a common location

#ifndef __midl
#define _SXS_ASSEMBLY_VERSION "8.0.50727.762"
#define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

#ifdef __cplusplus
extern "C" {
#endif
__declspec(selectany) int _forceCRTManifest;
__declspec(selectany) int _forceMFCManifest;
__declspec(selectany) int _forceAtlDllManifest;
__declspec(selectany) int _forceCRTManifestRTM;
__declspec(selectany) int _forceMFCManifestRTM;
__declspec(selectany) int _forceAtlDllManifestRTM;
#ifdef __cplusplus
}
#endif
#endif

2) The above file needs to be included in every project you wish to build.

Accomplish this in one of two ways. The first method involves the changing of source code. The second involves changing of project settings.

choose A or B which ever one is more appropriate for your situation:

A) #include "targetsxs.h" near the top of every one of your stdafx.h files
(using the path you saved the targetsxs.h)

B) Use the force include (/FI) compile option to make sure that the above file is included in every file built. To accomplish that, add the following command line to your compiler options

/FIc:\path\targetsxs.h

(where c:\path is the location of the targetsxs.h you created in step 1)

There are two methods to accomplish that: either directly in your project or through a compiler environment variable:

Method i)

Add the above to the command line section of the C/C++ project properties.

Method ii)

Create an environment variable named CL with the above-mentioned /FI statement

Method (ii) is more convenient to use when you have dozens of projects that you do not wish to make changes to, but may conflict with other work you do on your machine.

3) For every MFC DLL project in your solution add the following line to the bottom of the stdafx.cpp file

#include "..\src\mfc\dllmodul.cpp"

Step three is only necessary if you have any MFC DLL projects (this step is necessary due to a bug in the handling of the assembly versions in MFC DLLs – the bug is that a reference to the latest version of the DLLs will always be included regardless of what is set in step 1)

4) Do a rebuild all of all the projects in your solution

5) Inspect manifest files (by doing a find in files for *.intermediate.manifest) to ensure that 4053 no longer appears in any of the manifests.

6) Run your app on a machine that has no 4053 components installed to WinSxS to make sure runs properly.

IMPORTANT NOTE: if you have ATL controls that are affected by this security problem please ensure you have followed the directions to modify your controls to take advantage of the security updates. A simple recompile may not be enough. For more info please see the video at:

http://channel9.msdn.com/posts/Charles/Out-of-Band-Inside-the-ATL-Security-Update/

Q&A

Does referencing 762 instead of 4053 make your application less secure?

No. Microsoft provides WinSxS policy redirection, so any application referencing 762 will end up loading the 4053 versions (if they’re installed). The ATL security update redistributable has been released as an update on Windows Update, so the 4053 version of ATL will be in place, and will be used even though your app still references the 762 version of ATL.

*Important note: you should still ship the new version of the redistributable if at all possible, as users may have not updated using Windows Update.

What are the benefits to referencing 762 instead of 4053 in your SP1 applications?

1) If you have existing applications shipped and you need to rebuild any components shipped, then new MSM or vcredist_x86.exe containing 4053 versions do not need to be shipped. You can continue to ship existing components with 762 versions.

2) If you have existing third party static libraries that reference 762, then you need not rebuild them to reference 4053.
Does VC2008 SP1 security update have a similar issue?
Yes, it does, if you use _BIND_TO_CURRENT_VCLIBS_VERSION in your project. It will bind to the security update version instead of the SP1 version. You can use a similar technique as described above (step 3 is not required) to get around this problem.

For VC2008 SP1 the values for the current versions of the CRT/MFC/ATL have changed slightly, instead of _forceCRTManifest, you should use _forceCRTManifestCUR.  The same thing applies for MFC/ATL (add the CUR). And of course, the version numbers you’re dealing with are different: SP1 9.0.30729.1 vs the new SP1+security update which is 9.0.30729.4148

/ 译文 /

VC分发包安全更新--KB971090的修正之道

[注]

KB971090的描述:http://support.microsoft.com/kb/971090/zh-cn

KB971090的下载地址:http://www.microsoft.com/downloads/details.aspx?familyid=7C8729DC-06A2-4538-A90D-FF9464DC0197&displaylang=zh-cn

[问题描述]

在安装了Visual C++ 2005 SP1的KB971090安全更新后,VC生成的manifest中引用的ATL/MFC/CRT库的版本从8.0.50727.762变成了8.0.50727.4053。

正因为上面的变动,导致了应用程序开发者必须重新编译所有的组件使它们在manifest中指向4053版本的ATL/MFC/CRT库,同时在发布应用程序的时候还必须部署一个新的vcredist_x86.exe(对应8.0.50727.4053版本)或者在安装文件中内嵌包含了最新4053版本的ATL/MFC/CRG库的MSM文件。

[解决之道]

除了卸载KB971090更新之外,我们还可以强制使用8.0.50727.762版本的库来替换此时默认8.0.50727.4053的库。Microsoft提供了一种在manifest文件中指定使用哪种版本编译库的机制。

使得你的应用程序从指向8.0.50727.4053变为指向8.0.50727.762的步骤如下:

1) 创建一个名为targetsxs.h的头文件,填入下面的内容,保存在某个固定目录下。

#ifndef __midl
#define _SXS_ASSEMBLY_VERSION "8.0.50727.762"
#define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

#ifdef __cplusplus
extern "C" {
#endif
    __declspec(selectany) int _forceCRTManifest;
    __declspec(selectany) int _forceMFCManifest;
    __declspec(selectany) int _forceAtlDllManifest;
    __declspec(selectany) int _forceCRTManifestRTM;
    __declspec(selectany) int _forceMFCManifestRTM;
    __declspec(selectany) int _forceAtlDllManifestRTM;
#ifdef __cplusplus
}
#endif
#endif

2) 你需要在每个你希望编译的项目中包含上面的头文件。

可以通过两种方法来达成这个目的。第一个方法是涉及到修改源代码。第二个方法涉及到修改项目设置。到底选择方法A好还是方法B好?这适合取决于你当前的应用环境:

A) 在你的每一个stdafx.h头文件的头部包含"targetsxs.h"头文件

(使用你保存targetsxs.h的路径)

B) 强制使用(/FI)编译选项来保证每个文件编译时都包含上面的头文件(targetsxs.h)。为了达到这个目的,你可以在你的编译器选项中添加如下的命令行

/FIc:\path\targetsxs.h

(c:\path是你在第一步中创建的targetsxs.h的保存位置)

可以使用两个方法在编译器选项中到达这个目的:在你的工程中直接设置或者通过编译器环境变量来设置:

方法1:

将上面的命令添加到C/C++工程属性的命令行中

方法2:

用上面提到的/FI语法创建一个名为CL的环境变量

当你有很多工程的时候,你肯定不希望一个一个地去修改它们的工程属性,这个时候方法2就方便很多,但同时这个环境变量也可能会影响到你机器上的其他工程。

3) 对于你项目清单中的每个MFC DLL工程,你需要在stdafx.cpp文件的底部添加下面一行代码

#include "..\src\mfc\dllmodul.cpp"

只有当你使用了MFC DLL工程的时候,这一步才是必需的(之所以是必需的是因为在MFC DLL中处理汇编代码(assembly versions)时的一个Bug - 如果没有包含dllmodul.cpp的话,步骤一设置的东西就不会被包含而编译器会始终引用最新版本的DLL)。

4) 编译你的项目清单中的所有工程。

5) 检查manifeset文件(就是编译器生成的那些*.intermediate.manifest文件)以确保4053不会出现在任何manifest文件中。

6) 在一台没有安装4053版本WinSxS组件机器上运行你的应用程序来验证它可以正常运行。

重要提示:如果你被ATL控件的安全性问题所影响(而必须要安装这个更新)的话,还是请你安装此更新以便使用更加安全的ATL控件。此时,简单的重编译可能并不足够,比需要从下面的视频中得到更多的信息:

http://channel9.msdn.com/posts/Charles/Out-of-Band-Inside-the-ATL-Security-Update/

Q&A

1.使用762版本的组件来代替4053是否会使得你的应用程序安全性降低?

不会。微软提供了一种WinSxS重定位策略,所以任何引用到762版本ATL的应用程序都最终会应用到4053版本(如果你安装了它们的话)。这个ATL安全更新已经作为Window Update的更新发布了,所以一旦你保持了与Window Update同步的更新,那么你就已经准备好使用4053版本的ATL了,即使你的应用程序仍然引用了762版本的ATL,你最终还是会使用4053版本的ATL。

*重要提示:如果可能的话,你最好还是把最新版本的分发包随你的应用程序一起发布,因为用户有可能并不会使用Window Update来更新最新的组件。

2.在你的SP1应用程序中引用762版本来代替4053有什么好处么?

1) 如果你有一些应用程序已经发布了但是必须重新编译某些已经发布出去的组件,那么你就不用再发布新的MSM或者包含4053版本的vcrdist_x86.exe了。你可以继续使用762版本来发布现有的组件。

2) 如果你有使用引用到762版本的第三方静态库的话,你也不需要将它们重新编译到4053版本。

3.VC2008 SP1安全更新是否有同样的问题呢?

是的,如果你在你的工程中使用了_BING_TO_CURRENT_VCLIBS_VERSION,那么就会有同样的问题。它将会绑定到最新版本的安全更新来代替原来的SP1版本。你同样可以使用上面描述的方法(步骤3不需要)来解决这个问题。
对于VC2008 SP1,CRT/MFC/ATL的当前版本号有些许变化,你应该使用_forceCRTManifestCUR来代替_forceCRTManifest。对于MFC/ATL也必须使用同样的设置(添加CUR)。当然,此时你所面对的版本号也是不同的:SP1是9.0.30729.1,而最新的SP1+安全更新则是9.0.30729.4148。

PS:由于个人实在无法忍受,每次编译出来的DLL都要手动去修改其资源文件中的Manifest(使用ResHacker删除掉有关4053版本的Manifest节点),所以今天一狠心,直接将工作机上所有关于VC2005的东东全部干掉,再重新安装一次,虽然浪费了很多时间,但是还是这种釜底抽薪的方法最有效。

转载于:https://www.cnblogs.com/mixiyou/archive/2010/02/09/1663620.html

终结VC2005分发包版本问题相关推荐

  1. python分发包_Python 分发包中添加额外文件的方法

    在制作一个 Python 分发包时经常需要把一些文件添加到包中.最常见的例子是你希望通过 pip install命令安装 Python 包时会在 /etc/ 等目录下自动添加默认配置文件,由此可以让 ...

  2. uPython - 分发包、包管理和部署应用程序 - 以 microdot 为例

    分发包.包管理和部署应用程序 - 以 microdot 为例 目录 分发包.包管理和部署应用程序 - 以 microdot 为例 概述 安装 mip 手动安装包 - microdot 参考资料 正如& ...

  3. 卖方研究正临多重困境:万八佣金有待终结,分仓模式屡被敲打,未来谁为研究买单?多家券商开单转型

    2019-01-06 转发自 https://mp.weixin.qq.com/s/LTE7F4Uh7TRhDKDf1qXREg 卖方研究正临多重困境:万八佣金有待终结,分仓模式屡被敲打,未来谁为研究 ...

  4. 鸿蒙系统国内和国外的区别,鸿蒙系统分海外版本和国内版本吗?

    [分享交流] 鸿蒙系统分海外版本和国内版本吗? 9766 电梯直达 huafen271782395 初窥门径 发表于 2021-3-8 23:32:29 来自:HUAWEI Mate 30 Pro 最 ...

  5. Pandoc提供二进制分发包了

    在服务器(尤其是操作系统相对老)的服务器安装软件是一个让人头大的事情.Conda和Docker的出现让软件安装相对轻松了很多. Linux学习 - 命令运行监测和软件安装 一文掌握Conda软件安装: ...

  6. 四川师范大学自然地理(1-地球)90分以上版本

    1.基本概念 宇宙由各种形态的物质构成的(物质性).是在不断运动和发展变化的(运动性).上下四方曰宇,古往今来曰宙,宇宙在空间上无边无际,在时间上无终无始.用时间和空间来表达宇宙的内涵. 天体:又称星 ...

  7. 四川师范大学区域规划(3-区域发展的经济社会背景分析)90分以上版本

    第三章 区域发展的经济社会背景分析 第一节 区域经济与文化背景分析 一.区域经济背景 ㈠经济特色与经济地位 从一定意义上讲,区域经济就是在一国范围内,以客观存在的地域单元为基础,按照劳动地域分工原则建 ...

  8. 四川师范大学自然地理(2-地壳)90分以上版本

    (1) 地壳上部的沉积岩石圈是组成自然地理环境的四个基本地圈之一. (2) 地壳是地球内部圈层结构的最外层,它与大气圈.水圈.生物圈等地球外部圈层的联系最为紧密. (3) 地壳运动使地球内部物质和能量 ...

  9. Python使用setuptools打包自己的分发包并使用举例(setup.py)

    Python文件制作tar.gz包(源码包) setup.py文件的编写 setup.py中主要执行一个 setup函数,该函数中大部分是描述性东西,最主要的是packages参数,列出所有的pack ...

  10. 四川师范大学地信概论(1-绪论)90分以上版本

    第一章 概论 1.1 GIS基本概念 1.1.1基本概念 数据 (data) 是人类在认识世界和改造世界过程中,定性或定量对事物和环境描述的直接或间接原始记录,是一种未经加工的原始资料,是客观对象的表 ...

最新文章

  1. 编写程序判断等腰、等边或者普通三角形
  2. 2019年上半年收集到的人工智能深度学习方向干货文章
  3. Android性能优化典范第四季
  4. Linux下MySql出现#1036 – Table ‘ ‘ is read only 错误解决方法
  5. 浅谈中大型企业CMDB的建设
  6. [JZOJ4788] 【NOIP2016提高A组模拟9.17】序列
  7. 天津计算机中级职称需要什么,天津市中级职称评定条件是什么
  8. spring mvc学习(41):restful的crud的项目原型介绍
  9. 让皮肤美白细致的七大DIY - 生活至上,美容至尚!
  10. Python入门到精通三天速成第一讲——创建自定义类
  11. Effective Java(一)—— 创建和销毁对象
  12. ElementUI-自定义模板包含编辑与删除的功能
  13. 美图秀秀丰胸一秒变身D罩杯图片美容处理软件
  14. 基于java的智能手表_基于安卓Android智能手环(计步器)APP设计(含录像)
  15. 如何去除U盘文件夹的隐藏属性
  16. 双线性插值bilinear interpolation
  17. Spiral Matrix(Medium)
  18. cmd 如何打开资源管理器
  19. Java面向对象的知识(二)
  20. 【分布式事务】如何基于消息中间件实现分布式事务?万字长文给你答案!!

热门文章

  1. 一种低侵入性的组件化方案 之 组件化需要考虑的几个问题
  2. Maven:org.apache.maven.archiver.MavenArchiver.getManifest错误
  3. 大数据应用让医疗护理更高效
  4. MySQL数据库数据存放位置修改
  5. android Adapter笔记
  6. 自己写的一个简单的php快速开发框架(JPrass)
  7. 人生值得珍藏的80句话
  8. 3月2日 ESC CAN 比特率 波特率 带宽与容量 香农定理 奈奎斯特定理 信噪比
  9. ImageView中的几个属性
  10. 交叉编译cross compiling