【问题标题】:What does the /TSAWARE linker flag do to the PE executable?/TSAWARE 链接器标志对 PE 可执行文件有什么作用?
【发布时间】:2010-11-18 16:16:32
【问题描述】:

将 /TSAWARE 链接器标志添加到我的一个项目 (Visual Studio 6) 后,我惊讶地发现 PE 文件 (.idata) 中有一个新部分。如果我不设置标志,则导入将合并到 .rdata 中。

为了说明“问题”,我们从一个简单的控制台程序开始:

#include <stdio.h>
int main() 
{
    printf("hello world\n");
    return 0;
}

并编译为:cl /Og /O1 /GF /WX /c main.c

然后用

链接
  • link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:a.exe main.obj
  • link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:b.exe /TSAWARE main.obj

让我们比较一下dumpbin的输出:

Dump of file a.exe

File Type: EXECUTABLE IMAGE

  Summary

        4000 .data
        1000 .rdata
        5000 .text

Dump of file b.exe

File Type: EXECUTABLE IMAGE

  Summary

        4000 .data
        1000 .idata
        1000 .rdata
        5000 .text

因此,由于某种原因,链接器决定无法合并导入。

但如果我们运行editbin /TSAWARE a.exe,则只有 PE 可选标头中的 DLL 特性字段会发生变化。

谁能给我解释一下?这是链接器中的错误,还是 editbin 更改的可执行文件最终无法在某些系统上运行?

【问题讨论】:

    标签: windows visual-c++ linker visual-c++-6 portable-executable


    【解决方案1】:

    只是一个猜测:在终端服务器系统上,您希望图像尽可能多地写入几页。如果与映像对应的内存页面未修改,则可以将物理 RAM 的单个页面映射到使用该映像的 eash 会话中。如果图像中的页面被修改,系统必须对所有会话中的每个页面实例执行写时复制操作,并使用不同的物理内存块来表示每个会话中的页面。

    如果必须重新定位正在导入的 DLL,通常需要修复图像的导入,因此保存导入的页面经常会被修改,因此无法参与会话之间的共享。如果链接器将导入与其他通常未修改的数据合并,则可能会不必要地增加写时复制页的数量。

    这可能是一种优化,有助于减少跨会话复制页面的数量。

    就像我说的那样 - 这纯粹是一个猜测。

    【讨论】:

    • 这也是我的猜测,除非 MS 有人回应,否则我想我们永远不会知道。
    • 根据 Microsoft 自己的文档,/TSAWARE 链接器标志设置一个 EXE PE 标志以禁用 C:\Windows 主目录重定向、注册表重定向和其他 TS 环境黑客,旨在在您运行TS 环境中的非 TS 感知应用。
    【解决方案2】:

    @WarrenP 的评论是正确的。根据MSDN documentation

    /TSAWARE 选项在 IMAGE_OPTIONAL_HEADER 中设置一个标志 程序映像的可选标头中的 DllCharacteristics 字段。什么时候 设置此标志,终端服务器不会对 应用。

    当应用程序不支持终端服务器时(也称为 旧应用程序),终端服务器对 遗留应用程序使其在多用户中正常工作 环境。例如,终端服务器将创建一个虚拟 Windows 文件夹,这样每个用户都会获得一个 Windows 文件夹,而不是 获取系统的 Windows 目录。这使用户可以访问 他们自己的INI文件。此外,终端服务器使一些 对遗留应用程序的注册表进行调整。这些 修改会减慢终端上旧应用程序的加载速度 服务器。

    如果一个应用程序是终端服务器感知的,它不能依赖于 INI 文件,也不会在安装过程中写入 HKEY_CURRENT_USER 注册表。

    如果您使用 /TSAWARE 而您的应用程序仍使用 INI 文件,则 文件将由系统的所有用户共享。如果那是 可接受,您仍然可以将您的应用程序与 /TSAWARE 链接; 否则你需要使用 /TSAWARE:NO.

    这里只提示的一件事是影子键仅对不支持 TS 的进程启用。

    【讨论】:

    • 这个问题是关于修改的链接器行为超出了文档描述的范围
    猜你喜欢
    • 2011-10-01
    • 2011-02-23
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    相关资源
    最近更新 更多