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

StackOverflow https://stackoverflow.com/questions/1261291

Вопрос

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top