4 Stimmen

Wie wirkt sich das Linker-Flag /TSAWARE auf die ausführbare PE-Datei aus?

Nachdem ich das Linker-Flag /TSAWARE zu einem meiner Projekte (Visual Studio 6) hinzugefügt hatte, war ich überrascht, einen neuen Abschnitt in der PE-Datei (.idata) zu finden. Wenn ich das Flag nicht setze, werden die Importe in .rdata zusammengeführt.

Um das "Problem" zu veranschaulichen, beginnen wir mit einem einfachen Konsolenprogramm:

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

und kompilieren mit: cl /Og /O1 /GF /WX /c main.c

Dann verlinken Sie mit

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

Vergleichen wir die Dumpbin-Ausgabe:

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

Aus irgendeinem Grund entscheidet der Linker also, dass die Importe nicht zusammengeführt werden können.

Aber wenn wir die editbin /TSAWARE a.exe wird nur das Feld DLL-Merkmale im optionalen PE-Header geändert.

Kann mir das jemand erklären? Ist dies ein Fehler im Linker oder kann die ausführbare Datei, die von editbin geändert wurde, auf bestimmten Systemen nicht mehr funktionieren?

5voto

Michael Burr Punkte 320591

Nur eine Vermutung: Auf einem Terminalserver-System soll ein Image mit möglichst wenigen Seiten beschrieben werden. Wenn eine Speicherseite, die dem Abbild entspricht, nicht verändert wird, kann eine einzelne Seite des physischen Arbeitsspeichers auf eine Sitzung abgebildet werden, die dieses Abbild verwendet. Wenn eine Seite eines Bildes geändert wird, muss das System für jede Instanz der Seite in allen Sitzungen eine Copy-on-Write-Operation durchführen und für jede Sitzung einen anderen Block des physischen Speichers verwenden, um die Seite darzustellen.

Da die Importe für ein Bild oft korrigiert werden müssen, wenn die DLL, die importiert wird, verschoben werden musste, werden die Seiten, die die Importe enthalten, oft geändert und können daher nicht an der gemeinsamen Nutzung durch die Sitzungen teilnehmen. Wenn der Linker die Importe mit anderen Daten zusammenführt, die normalerweise nicht verändert werden, kann er die Anzahl der Copy-on-Write-Seiten unnötig erhöhen.

Dies kann eine Art Optimierung sein, die dazu beiträgt, die Anzahl der kopierten Seiten über mehrere Sitzungen hinweg zu verringern.

Aber wie gesagt - das ist nur eine Vermutung.

1voto

Helge Klein Punkte 8947

Der Kommentar von @WarrenP ist richtig. Laut der MSDN-Dokumentation :

Die Option /TSAWARE setzt ein Flag in der Datei IMAGE_OPTIONAL_HEADER DllCharacteristics-Feld im optionalen Header des Programmabbilds. Wenn dieses Flag gesetzt ist, nimmt Terminal Server bestimmte Änderungen an der Anwendung nicht vor. Anwendung vor.

Wenn eine Anwendung nicht Terminal Server-fähig ist (auch bekannt als Legacy-Anwendung), nimmt der Terminal Server bestimmte Änderungen an Änderungen an der Legacy-Anwendung vor, damit sie in einer Mehrbenutzer Umgebung funktioniert. Zum Beispiel erstellt Terminal Server einen virtuellen Windows-Ordner, so dass jeder Benutzer einen Windows-Ordner erhält, anstatt das Windows-Verzeichnis des Systems erhält. Dadurch erhalten die Benutzer Zugang zu ihre eigenen INI-Dateien. Darüber hinaus nimmt Terminal Server einige Anpassungen an der Registrierung für eine Legacy-Anwendung vor. Diese Änderungen verlangsamen das Laden der Legacy-Anwendung auf dem Terminal Server.

Wenn eine Anwendung Terminal Server-kompatibel ist, darf sie sich weder auf INI-Dateien angewiesen sein und darf während der Einrichtung nicht in die Registrierung HKEY_CURRENT_USER schreiben.

Wenn Sie /TSAWARE verwenden und Ihre Anwendung weiterhin INI-Dateien verwendet, wird die Dateien von allen Benutzern des Systems gemeinsam genutzt werden. Wenn Sie das akzeptabel ist, können Sie Ihre Anwendung trotzdem mit /TSAWARE verknüpfen; Andernfalls müssen Sie /TSAWARE:NO verwenden.

Eine Sache, die hier nur angedeutet wird, ist, dass Schattenschlüssel nur für Prozesse aktiviert sind, die nicht TS-bewusst sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X