PE-Metadaten
Dieser Artikel enthält zusätzliche Details zu Control Flow Guard-Metadaten (CFG) in PE-Images. Es wird vorausgesetzt, dass Sie mit der Struktur von CFG-Metadaten in PE-Images vertraut sind. Im Thema PE-Format finden Sie eine dokumentation auf hoher Ebene für CFG-Metadaten in PE-Images.
Funktionen, bei denen es sich um gültige indirekte Aufrufziele handelt, werden in der GuardCFFunctionTable aufgeführt, die an das Auslastungskonfigurationsverzeichnis angefügt ist. Aus Gründen der Übersichtlichkeit wird dies manchmal als GFIDS-Tabelle bezeichnet. Dies ist eine sortierte Liste relativer virtueller Adressen (RVA), die Informationen zu gültigen CFG-Aufrufzielen enthalten. Hierbei handelt es sich im Allgemeinen um Adresssymbole für Funktionssymbole. Ein Bild, das cfg erzwingt, muss alle adressiert verwendeten Funktionssymbole in der zugehörigen GFIDS-Tabelle auflisten. Die RVA-Liste in der GFIDS-Tabelle muss ordnungsgemäß sortiert werden, andernfalls wird das Image nicht geladen. Die GFIDS-Tabelle ist ein Array von 4 + n Bytes, wobei n von ((GuardFlags & IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK) >> IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT) angegeben wird. "GuardFlags" ist das Feld GuardFlags des Auslastungskonfigurationsverzeichnisses. Dadurch können in Zukunft zusätzliche Metadaten an CFG-Aufrufziele angefügt werden. Die einzigen derzeit definierten Metadaten sind ein optionales Feld mit zusätzlichen 1-Byte-Flags ("GFIDS-Flags"), das an jeden GFIDS-Eintrag angefügt wird, wenn Aufrufziele Metadaten enthalten. Es sind zwei GFIDS-Flags definiert:
IMAGE_GUARD_FLAG_FID_SUPPRESSED/0x1 Das Aufrufziel wird explizit unterdrückt (für CFG-Zwecke nicht als gültig behandelt). IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED/0x2 Das Aufrufziel wird unterdrückt. Weitere Informationen finden Sie unter Exportunterdrückung. Aus Gründen der zukünftigen Kompatibilität sollten Tools keine GFIDS-Flags festlegen, die noch nicht definiert wurden, und keine zusätzlichen GFIDS-Metadatenbytes über das derzeit definierte 1-Byte hinaus enthalten, da die Bedeutungen für andere Flags oder zusätzliche Metadaten noch nicht zugewiesen sind. Beispiele für Images, die zusätzliche Metadatenbytes enthalten, finden Sie, indem Sie die GFIDS-Tabelle mit Binärdateien wie Ntdll.dll in einer modernen Windows 10 Betriebssystemversion abspeichern.
Tools sollten Funktionssymbole nur als gültige Aufrufziele deklarieren, was zusätzliche Überlegungen für Assemblercode erfordern kann, bei dem Bezeichnungen adressiert werden können. Aus historischen Gründen kann der Assemblercode von anderen Codebezeichnungen als PROC oder .altentry abhängig sein, da er vom Linker nicht in CFG-Aufrufziele konvertiert wird.
Aus historischen Gründen kann Code auch absichtlich als Daten deklariert werden, um die Aufnahme in die GFIDS-Tabelle zu vermeiden. Beispielsweise kann eine Objektdatei ein Symbol als Code implementieren, während eine andere als Daten deklarieren kann, um die Adresse des Symbols zu übernehmen, ohne einen gültigen CFG-Zieldatensatz zu generieren. Aus Kompatibilitätsgründen wird empfohlen, dass Toolsets diese Vorgehensweise unterstützen.
Images, die CFG unterstützen und CFG-Überprüfungen wünschen oder ausführen, sollten die IMAGE_GUARD_CF_INSTRUMENTED und IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT GuardFlags-Bits und das IMAGE_DLLCHARACTERISTICS_GUARD_CF DllCharacteristics-Bit in den Imageheadern festlegen.
Das Ladekonfigurationsverzeichnis kündigt zwei Funktionszeiger an: GuardCFCheckFunctionPointer und GuardCFDispatchFunctionPointer (letzteres wird nur für bestimmte Architekturen wie AMD64 unterstützt). Diese Funktionszeiger sollten auf schreibgeschützten Speicher verweisen, damit CFG-Sicherheit effektiv ist. Das DLL-Ladeprogramm des Betriebssystems schützt den Arbeitsspeicher während des Ladens von Images vorübergehend erneut, um die Funktionszeiger zu speichern. Die typische Verwendung kann darin bestehen, diese in demselben Abschnitt zusammenzuführen, der die Import Address Table (IAT) enthält. Der GuardCFCheckFunctionPointer stellt die Adresse eines vom Betriebssystemladeprogramm bereitgestellten Symbols bereit, das mit einem Funktionszeiger im ersten Integerargumentregister (ECX auf x86) aufgerufen werden kann, das bei Erfolg zurückgibt oder den Prozess abbricht, wenn das Aufrufziel kein gültiges CFG-Ziel ist. Der GuardCFDispatchFunctionPointer stellt die Adresse eines vom Betriebssystemladeprogramm bereitgestellten Symbols bereit, das ein Aufrufziel im Rax-Register akzeptiert und eine kombinierte CFG-Überprüfung und einen optimierten Aufruf des Endbranchs an das Aufrufziel ausführt (Register R10/R11 sind für die Verwendung durch GuardCFDispatchFunctionPointer reserviert, und ganzzahlige Argumentregister sind für die Verwendung durch das endgültige Aufrufziel reserviert). Die Standardadresse der CFG-Symbole in einem Bild sollte auf eine Funktion verweisen, die nur zurückgibt (GuardCFCheckFunctionPointer) oder ein symbol mit Schutzunterdrückung zurückgibt (oder vorzugsweise vollständig aus dem GFIDS-Tabellensymbol weggelassen wird), die eine "jmp rax"-Anweisung ausführt. Wenn für AMD64 GuardCFDispatchFunctionPointer ein Image auf einem CFG-fähigen Betriebssystem geladen wird und CFG aktiviert ist, installiert das BETRIEBSSYSTEM-DLL-Ladeprogramm entsprechende Funktionszeiger, die abwärtskompatibel sind. Ein Image kann 0 für GuardCFDispatchFunctionPointer in der Ladekonfiguration bereitstellen, wenn die CFG-Dispatchfunktion nicht verwendet werden soll. Dies sollte für Nicht-AMD64-Architekturen aus Gründen der zukünftigen Kompatibilität erfolgen, falls diese Architekturen letztendlich den CFG-Verteilungsmechanismus in irgendeiner Form unterstützen. Beachten Sie, dass Windows 8.1 AMD64 die CFG-Verteilung nicht unterstützt hat und den Standardfunktionszeiger für GuardCFDispatchFunctionPointer belassen würde. CFG-Dispatch wird nur unter Windows 10 und späteren Betriebssystemen unterstützt.
CfG im Benutzermodus wird möglicherweise nur für Bilder erzwungen, die als ASLR-kompatibel (Address Space Layout Randomization) markiert sind (angegeben durch die Option /DYNAMICBASE mit dem Microsoft-Linker). Dies liegt daran, wie das Betriebssystem CFG intern verarbeitet, wo es im Wesentlichen mit der ASLR-Infrastruktur verkabelt ist. Im Allgemeinen sollten Benutzer von CFG ASLR als ersten Schritt für ihre Images aktivieren. Tools sollten nicht davon ausgehen, dass das Betriebssystem CFG immer ignoriert, ohne DASS ASLR festgelegt ist, aber im Allgemeinen beide gleichzeitig festlegen sollten.
Compilerdirektiven
Aufrufziele können mit dem Modifizierer __declspec(guard(suppress)) oder mit der /guardsym:symname,S-Linkerdirektive (z.B. für asm-Code) als explizit unterdrückt markiert werden. Dies bewirkt, dass das Aufrufziel in die GFIDS-Tabelle aufgenommen, aber so gekennzeichnet wird, dass das Aufrufziel vom Betriebssystem als ungültig behandelt wird. Einige Nicht-Produktionsszenarien, z. B. bei einer bestimmten Instrumentierung der Anwendungsüberprüfung, die für einige ältere Betriebssysteme aktiviert ist, können es ermöglichen, unterdrückte Aufrufziele als gültig zu behandeln, aber im Allgemeinen werden diese Szenarien nicht als Produktionsszenarien erwartet. Diese Direktive ist nützlich, um "gefährliche" Funktionen zu kommentieren, die nicht als gültige Aufrufziele betrachtet werden sollten, obwohl sie in der normalen CFG-Regel enthalten wären.
Code kann darauf hinweisen, dass CFG-Überprüfungen mit dem modifizierer __declspec(guard(nocf)) nicht erwünscht sind. Dadurch wird der Compiler aufgefordert, keine CFG-Überprüfungen für die gesamte Funktion einzufügen. Der Compiler sollte darauf achten, diese Direktive an jeglichen Code weiterzuleiten, der von einer inline-Funktion beigetragen wird, die als keine CFG-Überprüfungen gewünscht markiert ist. Dieser Ansatz wird in der Regel nur selten in bestimmten Situationen verwendet, in denen der Programmierer den "CFG-äquivalenten" Schutz manuell eingefügt hat. Der Programmierer weiß, dass er über eine schreibgeschützte Funktionstabelle aufruft, deren Adresse durch schreibgeschützte Speicherverweise abgerufen wird und für die der Index mit dem Funktionstabellenlimit maskiert ist. Dieser Ansatz kann auch auf kleine Wrapperfunktionen angewendet werden, die nicht inline sind und nur einen Aufruf über einen Funktionszeiger durchführen. Da die falsche Verwendung dieser Direktive die Sicherheit von CFG gefährden kann, muss der Programmierer mit der -Direktive sehr vorsichtig sein. In der Regel ist diese Verwendung auf sehr kleine Funktionen beschränkt, die nur eine Funktion aufrufen.
Importverarbeitung
Aufrufe über die IAT sollten keinen CFG-Schutz verwenden. Die IAT ist nur in modernen Bildern schreibbar (vorausgesetzt, die IAT wird in den PE-Headern deklariert, in diesem Fall muss sie sich auf eigenen Seiten befinden). Die IAT kann verwendet werden, um Funktionen zu erreichen, die unterdrückt werden, sodass dies eine Richtigkeitsanforderung ist. Schreibgeschützter Speicherschutz durch die IAT ersetzt den von CFG, da die Aufrufzielbindung unveränderlich ist, nachdem die Imageimport-Snaps aufgelöst wurden und die Bindungsauflösung fein abgestuft ist.
Geschütztes Verzögertes Laden: Aufrufe über die Verzögerungslade-IAT sollten aus denselben Gründen wie die Standard-IAT keinen CFG-Schutz verwenden. Die Verzögerungslade-IAT sollte sich in einem eigenen Abschnitt und das Image sollte das IMAGE_GUARD_CF_PROTECT_DELAYLOAD_IAT GuardFlags-Bit festlegen. Dies gibt an, dass das DLL-Ladeprogramm des Betriebssystems den Schutz für die Verzögerungslade-IAT während der Exportauflösung ändern sollte, wenn die Verzögerte Auslastung des Betriebssystems native Unterstützung für Windows 8 und höhere Betriebssysteme unterstützt. Die Synchronisierung dieses Schritts wird vom Betriebssystem-DLL-Ladeprogramm verwaltet, wenn unterstützung für systemeigenes Betriebssystem verzögertes Laden verwendet wird (z. B. ResolveDelayLoadedAPI), sodass keine andere Komponente die Seiten, die den deklarierten Verzögerungslade-IAT umfassen, erneut schützen sollte. Aus Gründen der Abwärtskompatibilität mit älteren Prä-CFG-Betriebssystemen können Tools die Option aktivieren, den Verzögerungslade-IAT in einen eigenen Abschnitt zu verschieben (kanonisch ".didat"), als Lese-/Schreibzugriff in den Imageheadern geschützt und zusätzlich das flag IMAGE_GUARD_CF_DELAYLOAD_IAT_IN_ITS_OWN_SECTION festlegen. Diese Einstellung bewirkt, dass CFG-fähige Betriebssystem-DLL-Lademodule den gesamten Abschnitt, der die IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT Tabelle enthält, erneut schützen, um während des Ladens des Images nur Speicher zu lesen. Die Option zum Platzieren der IAT für verzögertes Laden in einem eigenen Abschnitt ist möglicherweise nicht erforderlich, wenn Sie kein Image auf Betriebssystemen ausführen möchten, die cfg-Unterstützung voraussetzen. Tools sollten diese Entscheidung jedoch basierend auf der minimalen Betriebssystemunterstützung treffen, die ein Image benötigt.
Wenn ein Image die native Verzögerungsladeunterstützung des Betriebssystems nicht verwendet, kann es trotzdem die guardFlags-Bits im Zusammenhang mit der geschützten Verzögerungslast festlegen. In dieser Konfiguration bietet das Betriebssystemladeprogramm lediglich Unterstützung zum Schutz der Verzögerungslade-IAT als schreibgeschützt zur Laufzeit, wenn dies von der Plattform unterstützt wird, und es liegt in der Verantwortung der internen Verzögerungsladeauflösungsstubs des Images für die Synchronisierung und Verwaltung des Schutzes der IAT für verzögerte Auslastung. Vorausgesetzt, dass die Ladekonfigurationstabelle im schreibgeschützten Speicher gespeichert ist (was empfohlen wird), kann das Vorhandensein oder Fehlen des geschützten IAT-Bits für verzögerte Ladezeiten im Feld GuardFlags des Images als interner Hinweis auf die stubs der internen Verzögerungsladeauflösung des Images nützlich sein, um anzugeben, ob die Verzögerungslade-IAT geschützt werden soll.
Es wird empfohlen, das geschützte verzögerte Laden standardmäßig zu aktivieren, wenn CFG aktiviert ist. Images, die unter älteren Betriebssystemversionen ausgeführt werden und die native Unterstützung für verzögerte Auslastung des Betriebssystems verwenden, wie bereits erwähnt, können die IAT für verzögertes Laden in einem eigenen Abschnitt zur Abwärtskompatibilität verwenden. Dies steht im Gegensatz dazu, die Verzögerungslade-IAT als schreibgeschützt zu markieren und mit einem anderen Abschnitt zusammenzuführen. Dies würde bei älteren Betriebssystemen, die geschützte Verzögerungsladevorgänge nicht verstehen, unterbrechen und die native Unterstützung für die Auflösung von Verzögertlasten bereitstellen. Alle Windows 10 Releases und die ersten Windows 8.1/Windows Server 2012 R2-Builds, die CFG unterstützten (d. h. das Update vom November 2014), führen unterstützung für geschütztes verzögertes Laden im Betriebssystem ein.
Funktionsausrichtung
- Funktionen, die adressiert sind und daher in der GFIDS-Tabelle enthalten sind, sollten nach Möglichkeit auf 16 Byte ausgerichtet werden. Dies ist möglicherweise nicht immer möglich. Beispielsweise muss der Benutzer des Tools, das die Dateien erstellt hat, für Nicht-COMDAT-Funktionen, die Teil von Objektdateien sind, die als eine Einheit von nicht CFG-fähigen Tools zusammengesetzt sind, die von einigen Assemblern erzeugt werden können, die Ausrichtung entsprechend festlegen. Tools können in dieser Situation eine Diagnosewarnung ausstellen, damit der Benutzer entsprechende Korrekturmaßnahmen ergreifen kann. Der Grund dafür ist, dass CFG Aufrufziele für 16-Byte-Grenzen als gültig oder ungültig markiert, um die Effizienz schneller CFG-Überprüfungen zu erzielen. Wenn eine Funktion nicht auf 16 Byte ausgerichtet ist, muss der gesamte 16-Byte-Slot als gültig markiert werden, was nicht so sicher ist, da Sie falsch ausgerichteten Code aufrufen können, der sich nicht am Anfang einer Funktion befindet. Dieses Szenario wird unterstützt, um die Interoperabilität zu erleichtern, wenn CFG zum ersten Mal für ein Projekt eingerichtet wird. Nicht CFG-fähige Bilder sind aus Kompatibilitätsgründen auf ähnliche Weise als gültig für jede Ausrichtung des Aufrufziels gekennzeichnet. Wie zuvor verringern falsch ausgerichtete Aufrufziele die Sicherheitsvorteile von CFG, sodass Tools automatisch an einer 16-Byte-Grenze für alles in der GFIDS-Tabelle ausgerichtet werden sollten, wenn CFG für ein Image gewünscht ist. Symbole, die sich nicht in der GFIDS-Tabelle befinden, müssen keine bestimmten Ausrichtungen für CFG aufweisen.
Exportunterdrückung
Die CFG-Exportunterdrückung (CFG ES) ist ein optionaler Modus, der es einem Prozess ermöglicht, anzugeben, dass Aufrufziele, die nur gültig waren, weil sie dllexport-Symbole waren und die noch nicht dynamisch von GetProcAddress aufgelöst wurden, für CFG als ungültig betrachtet werden. Dadurch wird die Oberfläche von CFG von System-DLL-Exporten reduziert. Die Exportunterdrückung umfasst die Kommunikation berechtigter "exportierter" DLLExport-Aufrufziele, indem sie mit den IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED GFIDS-Flags gekennzeichnet werden. Dllexportsymbole und der PE-Imageeinstiegspunkt sollten implizit als Adresse betrachtet werden, die von Tools zum Generieren der GFIDS-Tabelle verwendet wird. Wenn ein Exportsymbol auf 16 Byte ausgerichtet ist und es aus keinem anderen Grund als dllexport adressiert wird, kann es mit dem unterdrückten GFIDS-Flag für den Export in der Funktionstabelle markiert werden. Aufrufziele, die nicht auf 16 Byte ausgerichtet sind, dürfen nicht mit dem IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED GFIDS-Flag markiert werden und können nicht darauf beschränkt werden, dass sie nur dynamisch als gültige Aufrufziele zur GetProcAddress-Zeit aktiviert werden.
Ein Image, das CFG ES unterstützt, enthält eine GuardAddressTakenIatEntryTable, deren Anzahl von GuardAddressTakenIatEntryCount als Teil des Auslastungskonfigurationsverzeichnisses bereitgestellt wird. Diese Tabelle ist strukturell genauso formatiert wie die GFIDS-Tabelle. Es verwendet den gleichen GuardFlags-IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK Mechanismus, um zusätzliche optionale Metadatenbytes in der IAT-Adresstabelle zu codieren, obwohl alle Metadatenbytes für die IAT-Adresstabelle 0 (null) sein müssen und reserviert sind. Die IAT-Adresstabelle gibt ein sortiertes Array von RVAs von Importthunks an, deren importierte als Symboladresse als Aufrufziel übernommen wird. Dieses Konstrukt unterstützt adressgesteuerte Symbole, die in einem Remotemodul vorhanden sind und dllexports sind, wobei CFG ES verwendet wird. Ein Beispiel für ein solches Codekonstrukt wäre:
mov rcx, [__imp_DefWindowProc] call foo ; where foo takes the actual address of DefWindowProc.Alle diese Adressen, für die Importthunks verwendet werden, müssen aufzählt werden, damit das Betriebssystemladeprogramm sie finden und die entsprechenden Aufrufziele beim Laden eines Images und beim Ausrichten der Importe gültig machen kann. Die Tabelle und die Anzahl können 0 (0) sein, wenn keine Importthunks vorhanden sind, die adressiert wurden.
Ein Modul legt das IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT GuardFlags-Bit fest, um anzugeben, dass alle Adressen, die Thunks in der IAT-Adresstabelle entnommen wurden, aufzählt und dass alle Exporte, die CFG ES-berechtigt sind, mit dem GFIDS-Flag IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED gekennzeichnet sind. Beachten Sie, dass es 0 (null) solcher Thunks und auch 0 (null) solcher dllexport-Symbole geben kann. Wenn die IAT-Adresstabelle nicht verwaltet wird, kann dies ein Problem mit der Richtigkeit sein, da einige Aufrufziele möglicherweise nicht gültig sind, wenn sie zur DLL-Ladezeit vorliegen sollten.
Ein Modul legt das IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION GuardFlags-Bit fest, um anzugeben, dass CFG ES für den Prozess aktiviert werden soll. In der Praxis ist dies derzeit nur für EXEs sinnvoll. Ein Prozess, der CFG ES aktiviert, sollte keine DLLs laden, die nicht mit CFG ES erstellt wurden, oder Laufzeitfehler können aufgrund von nicht konfigurierten IAT-Symbolen auftreten. Die Unterstützung für die Aktivierung von CFG ES sollte eine separate Option zur Aktivierung von CFG sein. Die Bereitstellung von CFG ES-Metadaten ist sicher und wird standardmäßig mit CFG empfohlen. Toolsets müssen jedoch darauf achten, dass sie die richtigen Metadaten erzeugen. Falls nicht, werden die generierten Images in einem CFG ES-Prozess möglicherweise nicht ordnungsgemäß ausgeführt. Diese Unterstützung sollte in einem Testprozess, der CFG ES erzwingt, gründlich getestet werden. Die integrierten System-DLLs des Betriebssystems unterstützen CFG ES-Metadaten für moderne Windows 10 Betriebssystemversionen, die CFG ES verstehen. Betriebssystemversionen vor dieser Unterstützung verstehen CFG ES überhaupt nicht und ignorieren alle CFG ES-bezogenen Anweisungen im Image. Solche Images sind immer noch abwärtskompatibel mit älteren Betriebssystemversionen.
CfG ES-Unterstützung ist aus Toolsetperspektive optional, es wird jedoch empfohlen, dass Toolsets zumindest Unterstützung enthalten, um genügend Informationen aufzuzählen, damit Bilder in einem Prozess ausgeführt werden können, der CFG ES anstrebe. Wie bereits erwähnt, ist es wichtig, dass die Toolsetunterstützung gründlich getestet wird, um sicherzustellen, dass sie mit CFG ES kompatibel ist, da die meisten Prozesse CFG ES noch nicht aktivieren.
Ausnahmebehandlung und -entladung
Sprachspezifische Handler wie __C_specific_handler, die durch die Ausnahmehandlerinformationen in einer PDATA-Registrierung festgelegt werden, sollten nicht als gültige Aufrufziele in der GFIDS-Tabelle gekennzeichnet werden. Stattdessen werden sie durch Durchlaufen des schreibgeschützten Arbeitsspeichers gesucht. Auf ähnliche Weise verwendet der sprachspezifische Microsoft C-Handler schreibgeschützte Speichersuchen, um Funclets für Ausnahmehandler zu suchen, und deklariert daher seine Funclets nicht als gültige Aufrufziele in der GFIDS-Tabelle.
Long Jump-Behandlung (für Nicht-x86-Ziele wie AMD64): Toolsets, die mit CFG kompiliert werden und setjmp()/longjmp() unterstützen, sollten Long Jump als "sicherer Long Jump" implementieren, der mit der strukturierten Ausnahmebehandlung (SEH) interoperiert. Dies bedeutet, dass long jump als Aufruf von RtlUnwindEx mit STATUS_LONGJUMP als Statuscode im bereitgestellten Ausnahmedatensatz und einem Standard-_JUMP_BUFFER implementiert wird, auf den exceptionInformation[0] verweist. Das Ziel für die Sprungentladung sollte das TargetIp der Entladung sein. Der Sprungpuffer stellt den Registerkontext dar, der vom Betriebssystem nach Abschluss des langen Sprungs wiederhergestellt wird. RtlUnwind(Ex) hat beim Aufruf mit STATUS_LONGJUMP besondere Bedeutung für CFG. Das Weitsprungziel (_JUMP_BUFFER. Rip oder _JUMP_BUFFER. Lr unter ARM64) wird in der liste geladener Module gesucht, die vom Betriebssystem im schreibgeschützten Arbeitsspeicher verwaltet wird. Wenn für das enthaltende Modul für das Sprungziel (das "Zielmodul") das IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT-Flag im Feld GuardFlags festgelegt ist, verfügt das Auslastungskonfigurationsverzeichnis über eine GuardLongJumpTargetTable, die eine Elementanzahl darstellt, die im Feld GuardLongJumpTargetCount der Auslastungskonfiguration angegeben ist. Diese Tabelle ist strukturell gleich formatiert wie die GFIDS-Tabelle und verwendet den gleichen GuardFlags-IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK Mechanismus, um optionale zusätzliche Metadatenbytes in der Long Jump-Tabelle zu codieren. Alle Metadatenbytes müssen für die Long Jump-Tabelle 0 (null) sein und sind reserviert.
Die Long Jump-Tabelle stellt ein sortiertes Array von RVAs dar, die gültige Long Jump-Ziele sind. Wenn ein Long Jump-Zielmodul IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT im Feld GuardFlags festlegt, müssen alle Long Jump-Ziele in der LongJumpTargetTable aufzählt werden. Selbst wenn ein Modul über keine Long Jump-Ziele verfügt, sollte es dennoch das flag IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT festlegen, wenn das Toolset die lange Sprunghärtung für CFG unterstützt. Dies bedeutet explizit, dass das Image über keine Long Jump-Ziele verfügt und kein altes Image ist, von dem das Betriebssystem annehmen muss, dass es gültige Long Jump-Ziele an nicht markierten Stellen haben kann, für die es keine Long Jump-Zielüberprüfung durchführen kann.
Es wird empfohlen, die Lange Sprunghärtung standardmäßig zu aktivieren, wenn CFG unterstützt wird. Dies ist die Disposition von Microsoft-Compilern. Betriebssysteme, die die lange Sprunghärtung (vor Windows 10 oder ältere Windows 10 Versionen) nicht verstehen, führen keine Überprüfungen der langen Sprunghärtung durch und ignorieren keine Metadaten für die lange Sprunghärtung, sodass die Long Jump-Härtung abwärtskompatibel mit älteren Betriebssystemversionen ist.
Bei Kernelmodusimages sollte die Wächter-Long Jump-Zieltabelle nicht in einem verwerfbaren Abschnitt enthalten sein. Die Guard-Long Jump-Zieltabelle sollte immer im schreibgeschützten Speicher gespeichert werden, damit ihre Sicherheitseigenschaften effektiv sind.
COFF-Informationen
Es gibt Objektdateimarkierungen, um zu deklarieren, ob eine Objektdatei CFG entspricht oder nicht. Eine Objektdatei, die CFG entspricht, listet die gültigen Aufrufziele auf, die explizit erstellt werden, sowie alle adressenadressisierten IAT-Metadaten. Für eine Objektdatei, die cfg nicht entspricht, müssen Aufrufziele abgeleitet werden, indem die COFF-Verschiebungen der Obj-Datei untersucht werden, um Verschiebungen zu finden, die auf den Anfang eines Funktionssymbols zeigen. Dies kann gültige CFG-Aufrufziele überschätzen, sodass es wünschenswert ist, dass Tools ihre OBJ-Dateien markieren, die CFG-fähigen sind, und die CFG-Obj-Dateimetadaten einschließen, wenn sie mit CFG kompiliert werden.
Es gibt Objektdateimarkierungen zum Deklarieren von Long Jump-Zielen für cfggehärteten Long Jump, die für den CFG-Kompilierungsmodus aufgefüllt werden sollten.