Что делает флаг компоновщика / TSAWARE с исполняемым файлом PE? - PullRequest
3 голосов
/ 11 августа 2009

После добавления флага компоновщика / 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

Давайте сравним вывод дампа:

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, то будет изменено только поле характеристик DLL в необязательном заголовке PE.

Может кто-нибудь объяснить это мне? Это ошибка в компоновщике или исполняемый файл, измененный с помощью editbin, не работает на некоторых системах?

Ответы [ 2 ]

4 голосов
/ 30 августа 2009

Только предположение: в системе с терминальным сервером вы хотите, чтобы в изображение было записано несколько страниц. Если страница памяти, которая соответствует образу, не изменена, отдельная страница физического ОЗУ может быть сопоставлена ​​с сеансом eash, использующим это изображение. Если страница из изображения модифицируется, система должна выполнить операцию копирования при записи для каждого экземпляра страницы среди всех сеансов и использовать отдельный блок физической памяти для представления страницы в каждом сеансе.

Поскольку импорт изображения часто требуется исправить, если необходимо перенести импортируемую DLL, страницы, содержащие импорт, часто модифицируются и поэтому не могут участвовать в обмене между сеансами. Если компоновщик объединяет импорт с другими данными, которые обычно не модифицируются, он может излишне увеличить количество страниц, копируемых при записи.

Это может быть своего рода оптимизация, которая помогает уменьшить количество копируемых страниц между сеансами.

Как я уже сказал - это всего лишь предположение.

1 голос
/ 13 марта 2012

Комментарий от @WarrenP правильный. Согласно документации MSDN :

Параметр / TSAWARE устанавливает флаг в IMAGE_OPTIONAL_HEADER Поле DllCharacteristics в необязательном заголовке образа программы. когда этот флаг установлен, сервер терминалов не будет вносить определенные изменения в применение.

Когда приложение не распознает сервер терминалов (также называется устаревшее приложение), Terminal Server вносит определенные изменения в унаследованное приложение для правильной работы в многопользовательском режиме среда. Например, Terminal Server создаст виртуальный Папка Windows, так что каждый пользователь получает папку Windows вместо получение системного каталога Windows. Это дает пользователям доступ к их собственные файлы INI. Кроме того, Terminal Server делает некоторые корректировки реестра для устаревшего приложения. Эти модификации замедляют загрузку устаревшего приложения на Терминале Сервер.

Если приложение поддерживает сервер терминалов, оно не должно полагаться на INI-файлы и запись в реестр HKEY_CURRENT_USER во время установки.

Если вы используете / TSAWARE, а ваше приложение все еще использует INI-файлы, Файлы будут доступны всем пользователям системы. Если это допустимо, вы все равно можете связать свою заявку с / TSAWARE; в противном случае вам нужно использовать /TSAWARE:NO.

Здесь только намекают на то, что теневые ключи включены только для процессов, которые не поддерживают TS.

...