Что флаг компоновщика /TSAWARE делает с исполняемым файлом PE?
-
12-09-2019 - |
Вопрос
После добавления флага компоновщика /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
изменено только поле характеристик DLL в необязательном заголовке PE.
Кто-нибудь может мне это объяснить?Это ошибка в компоновщике или исполняемый файл, измененный editbin, может в конечном итоге не работать в определенных системах?
Решение
Только предположение:в системе терминального сервера вы хотите, чтобы в образе было записано как можно больше страниц.Если страница памяти, соответствующая образу, не изменена, одна страница физической оперативной памяти может быть отображена в каждый сеанс, использующий этот образ.Если страница изображения изменена, система должна выполнить операцию копирования при записи для каждого экземпляра страницы среди всех сеансов и использовать другой блок физической памяти для представления страницы в каждом сеансе.
Поскольку импорт изображения часто необходимо исправлять, если импортируемую DLL необходимо переместить, страницы, содержащие импорт, часто изменяются и, следовательно, не могут участвовать в совместном использовании между сеансами.Если компоновщик объединяет импортированные данные с другими данными, которые обычно не изменяются, это может без необходимости увеличить количество страниц копирования при записи.
Это может быть своего рода оптимизацией, которая помогает уменьшить количество копируемых страниц между сеансами.
Но, как я уже сказал, это всего лишь предположение.
Другие советы
Комментарий от @WarrenP верен.В соответствии с Документация MSDN:
Параметр /TSAWARE устанавливает флаг в поле IMAGE_OPTIONAL_HEADER DllCharacteristics в необязательном заголовке образа программы.Когда установлен этот флаг, сервер терминалов не будет вносить определенные изменения в приложение.
Когда приложение не поддерживает сервер терминалов (также известное как устаревшее приложение), Terminal Server вносит определенные изменения в устаревшее приложение, чтобы заставить его должным образом работать в многопользовательской среде.Например, сервер терминалов создаст виртуальную папку Windows, так что каждый пользователь получит папку Windows вместо системного каталога Windows.Это дает пользователям доступ к их собственным INI-файлам.Кроме того, Terminal Server вносит некоторые изменения в реестр для устаревшего приложения.Эти изменения замедляют загрузку устаревшего приложения на сервере терминала .
Если приложение поддерживает сервер терминалов, оно не должно ни полагаться на файлы INI, ни выполнять запись в реестр HKEY_CURRENT_USER во время установки.
Если вы используете /TSAWARE и ваше приложение по-прежнему использует INI-файлы, файлы будут доступны всем пользователям системы.Если это приемлемы, вы все равно можете связать приложение с /TSAWARE;в противном случае вам нужно использовать /TSAWARE:NO .
Здесь лишь намекается на то, что теневые ключи включены только для процессов, которые не осведомлены о TS.