Windows Internals - Pavel Yosifovich - E-Book

Windows Internals E-Book

Pavel Yosifovich

0,0

Beschreibung

Der Standard-Leitfaden – komplett aktualisiert auf Windows 10 und Windows Server 2016 Tauchen Sie in die Architektur und die inneren Mechanismen von Windows ein und lernen Sie die Kernkomponenten kennen, die hinter den Kulissen arbeiten. Dieser klassische Leitfaden wurde von einem Expertenteam für die inneren Mechanismen von Windows verfasst und vollständig auf Windows 10 und Windows Server 2016 aktualisiert. Dieses Buch gibt Entwicklern und IT-Profis entscheidende Insiderinformationen über die Funktionsweise von Windows. Durch praktische Experimente können Sie das interne Verhalten selbst erfahren und nützliche Kenntnisse zur Verbesserung des Designs Ihrer Anwendungen, zur Steigerung der Leistung, für Debugging und Support gewinnen. In diesem Buch lernen Sie: - Wie die Systemarchitektur von Windows aufgebaut ist und wie ihre wichtigsten Elemente aussehen, insbesondere Prozesse und Threads - Wie Prozesse Ressourcen und Threads verwalten - Wie Windows virtuellen und physischen Arbeitsspeicher verwaltet - Wie es in den Tiefen des E/A-Systems von Windows aussieht, wie Gerätetreiber funktionieren und wie sie mit dem Rest des Systems zusammenwirken - Wie das Sicherheitsmodell von Windows Zugriff, Überwachung und Autorisierung handhabt und welche neuen Mechanismen es in Windows 10 und Windows Server 2016 gibt

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 1373

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Zu diesem Buch – sowie zu vielen weiteren dpunkt.büchern – können Sie auch das entsprechende E-Book im PDF-Format herunterladen. Werden Sie dazu einfach Mitglied bei dpunkt.plus+:

www.dpunkt.plus

Für meine Familie: meine Frau Idit und unsere Kinder Danielle, Amit und Yoav. Danke für eure Geduld und eure Ermutigung während dieser anspruchsvollen Arbeit.

– Pavel Yosifovich

Für meine Eltern, die mich angeleitet und angeregt haben, meine Träume zu verfolgen, und für meine Familie, die während all dieser zahllosen Abende hinter mir gestanden hat.

– Alex Ionescu

Für unsere Eltern, die uns angeleitet und angeregt haben, unsere Träume zu verfolgen.

– Mark E. Russinovich und David A. Solomon

Windows Internals

Band 1: Systemarchitektur, Prozesse, Threads, Speicherverwaltung, Sicherheit und mehr

Übersetzung der 7. englischsprachigen Auflage

Pavel Yosifovich

Alex Ionescu

Mark E. Russinovich

David A. Solomon

Pavel Yosifovich

Alex Ionescu

Mark E. Russinovich

David A. Solomon

Lektorat: Sandra Bollenbacher

Übersetzung: G&U Language & Publishing Services GmbH, www.gundu.com

Copy-Editing: Petra Heubach-Erdmann

Satz: G&U Language & Publishing Services GmbH, www.gundu.com

Umschlaggestaltung: Helmut Kraus, exclam.de

Druckerei: C.H.Beck

ISBN:

Print978-3-86490-538-4

PDF978-3-96088-338-8

ePub978-3-96088-339-5

mobi978-3-96088-340-1

Translation Copyright für die deutschsprachige Ausgabe © 2018 dpunkt.verlag GmbH Wieblinger Weg 17

69123 Heidelberg

Authorized translation from the English language edition, entitled WINDOWS INTERNALS, PART 1: SYSTEM ARCHITECTURE, PROCESSES, THREADS, MEMORY MANAGEMENT, AND MORE, 7th Edition by PAVEL YOSIFOVICH, ALEX IONESCU, MARK RUSSINOVICH, DAVID SOLOMON, published by Pearson Education, Inc, publishing as Microsoft Press, Copyright © 2017 by Pavel Yosifovich, Alex Ionescu, Mark E. Russinovich and David A. Solomon

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc.

German language edition published by dpunkt.verlag GmbH, Copyright © 2018

ISBN of the English language edition: 978-0-7356-8418-8

Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.

Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.

Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autor noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buchs stehen.

5 4 3 2 1 0

Inhaltsverzeichnis

Einleitung

Kapitel 1

Begriffe und Werkzeuge

Versionen des Betriebssystems Windows

Windows 10 und zukünftige Windows-Versionen

Windows 10 und OneCore

Grundprinzipien und -begriffe

Die Windows-API

Dienste, Funktionen und Routinen

Prozesse

Threads

Jobs

Virtueller Arbeitsspeicher

Kernel- und Benutzermodus

Hypervisor

Firmware

Terminaldienste und mehrere Sitzungen

Objekte und Handles

Sicherheit

Die Registrierung

Unicode

Die internen Mechanismen von Windows untersuchen

Leistungsüberwachung und Ressourcenmonitor

Kernel-Debugging

Windows Software Development Kit

Windows Driver Kit

Sysinternals-Werkzeuge

Zusammenfassung

Kapitel 2

Systemarchitektur

Anforderungen und Designziele

Das Modell des Betriebssystems

Die Architektur im Überblick

Portierbarkeit

Symmetrisches Multiprocessing

Skalierbarkeit

Unterschiede zwischen den Client- und Serverversionen

Testbuild

Die virtualisierungsgestützte Sicherheitsarchitektur im Überblick

Hauptsystemkomponenten

Umgebungsteilsysteme und Teilsystem-DLLs

Weitere Teilsysteme

Exekutive

Der Kernel

Die Hardwareabstraktionsschicht

Gerätetreiber

Systemprozesse

Zusammenfassung

Kapitel 3

Prozesse und Jobs

Prozesse erstellen

Argumente der CreateProcess*-Funktionen

Moderne Windows-Prozesse erstellen

Andere Arten von Prozessen erstellen

Interne Mechanismen von Prozessen

Geschützte Prozesse

Protected Process Light (PPL)

Unterstützung für Drittanbieter-PPLs

Minimale und Pico-Prozesse

Minimale Prozesse

Pico-Prozesse

Trustlets (sichere Prozesse)

Der Aufbau von Trustlets

Richtlinien-Metadaten für Trustlets

Attribute von Trustlets

Integrierte System-Trustlets

Trustlet-Identität

IUM-Dienste

Für Trustlets zugängliche Systemaufrufe

Der Ablauf von CreateProcess

Phase 1: Parameter und Flags konvertieren und validieren

Phase 2: Das auszuführende Abbild öffnen

Phase 3: Das Windows-Exekutivprozessobjekt erstellen

Phase 4: Den ursprünglichen Thread mit seinem Stack und Kontext erstellen

Phase 5: Spezifische Prozessinitialisierung für das Windows-Teilsystem durchführen

Phase 6: Ausführung des ursprünglichen Threads starten

Phase 7: Prozessinitialisierung im Kontext des neuen Prozesses durchführen

Einen Prozess beenden

Der Abbildlader

Frühe Prozessinitialisierung

DLL-Namensauflösung und -Umleitung

Die Datenbank der geladenen Module

Importanalyse

Prozessinitialisierung nach dem Import

SwitchBack

API-Sets

Jobs

Grenzwerte für Jobs

Umgang mit Jobs

Verschachtelte Jobs

Windows-Container (Serversilos)

Zusammenfassung

Kapitel 4

Threads

Threads erstellen

Interne Strukturen von Threads

Datenstrukturen

Geburt eines Threads

Die Threadaktivität untersuchen

Einschränkungen für Threads in geschützten Prozessen

Threadplanung

Überblick über die Threadplanung in Windows

Prioritätsstufen

Threadstatus

Die Dispatcherdatenbank

Das Quantum

Prioritätserhöhung

Kontextwechsel

Mögliche Fälle bei der Threadplanung

Leerlaufthreads

Anhalten von Threads

Einfrieren und Tiefgefrieren

Threadauswahl

Mehrprozessorsysteme

Threadauswahl auf Mehrprozessorsystemen

Prozessorauswahl

Heterogene Threadplanung (big.LITTLE)

Gruppengestützte Threadplanung

Dynamische gleichmäßige Planung (DFSS)

Grenzwerte für die CPU-Rate

Dynamisches Hinzufügen und Ersetzen von Prozessoren

Arbeitsfactories (Threadpools)

Erstellen von Arbeitsfactories

Zusammenfassung

Kapitel 5

Speicherverwaltung

Einführung in den Speicher-Manager

Komponenten des Speicher-Managers

Große und kleine Seiten

Die Speichernutzung untersuchen

Interne Synchronisierung

Vom Speicher-Manager bereitgestellte Dienste

Seitenstatus und Speicherzuweisungen

Gesamter zugesicherter Speicher und Zusicherungsgrenzwert

Seiten im Arbeitsspeicher festhalten

Granularität der Zuweisung

Gemeinsam genutzter Arbeitsspeicher und zugeordnete Dateien

Speicherschutz

Datenausführungsverhinderung

Kopieren beim Schreiben

AWE (Address Windowing Extensions)

Kernelmodusheaps (Systemspeicherpools)

Poolgrößen

Die Poolnutzung überwachen

Look-Aside-Listen

Der Heap-Manager

Prozessheaps

Arten von Heaps

NT-Heaps

Heapsynchronisierung

Der Low-Fragmentation-Heap

Segmentheaps

Sicherheitseinrichtungen von Heaps

Debugging einrichten für Heaps

Der Seitenheap

Der fehlertolerante Heap

Layouts für virtuelle Adressräume

x86-Adressraumlayouts

Das Layout des x86-Systemadressraums

x86-Sitzungsraum

System-Seitentabelleneinträge

ARM-Adressraumlayout

64-Bit-Adressraumlayout

Einschränkungen bei der virtuellen Adressierung auf x64-Systemen

Dynamische Verwaltung des virtuellen Systemadressraums

Kontingente für den virtuellen Systemadressraum

Layout des Benutzeradressraums

Adressübersetzung

Übersetzung virtueller Adressen auf x86-Systemen

Der Look-Aside-Übersetzungspuffer für die Übersetzung

Übersetzung virtueller Adressen auf x64-Systemen

Übersetzung virtueller Adressen auf ARM-Systemen

Seitenfehler

Ungültige PTEs

Prototyp-PTEs

Einlagerungs-E/A

Seitenfehlerkollisionen

Seitencluster

Auslagerungsdateien

Gesamter zugesicherter Speicher und systemweiter Zusicherungsgrenzwert

Der Zusammenhang zwischen dem gesamten zugesicherten Speicher und der Größe der Auslagerungsdatei

Stacks

Benutzerstacks

Kernelstacks

Der DPC-Stack

VADs

Prozess-VADs

Umlauf-VADs

NUMA

Abschnittsobjekte

Arbeitssätze

Auslagerung bei Bedarf

Der logische Prefetcher und ReadyBoot

Platzierungsrichtlinien

Verwaltung von Arbeitssätzen

Der Balance-Set-Manager und der Swapper

Systemarbeitssätze

Speicherbenachrichtigungsereignisse

Die PFN-Datenbank

Seitenlistendynamik

Seitenpriorität

Die Schreibthreads für geänderte und für zugeordnete Seiten

PFN-Datenstrukturen

Reservierungen in der Auslagerungsdatei

Grenzwerte für den physischen Speicher

Speichergrenzwerte für Windows-Clienteditionen

Speicherkomprimierung

Ablauf der Komprimierung

Komprimierungsarchitektur

Speicherpartitionen

Speicherzusammenführung

Die Suchphase

Die Klassifizierungsphase

Die Zusammenführungsphase

Vom privaten zum gemeinsamen PTE

Freigabe von zusammengeführten Seiten

Speicherenklaven

Programmierschnittstellen

Initialisierung von Speicherenklaven

Aufbau von Enklaven

Daten in eine Enklave laden

Eine Enklave initialisieren

Vorausschauende Speicherverwaltung (SuperFetch)

Komponenten

Ablaufverfolgung und Protokollierung

Szenarien

Seitenpriorität und Rebalancing

Leistungsstabilisierung

ReadyBoost

ReadyDrive

Prozessreflexion

Zusammenfassung

Kapitel 6

Das E/A-System

Komponenten des E/A-Systems

Der E/A-Manager

Typische E/A-Verarbeitung

IRQ-Ebenen und verzögerte Prozeduraufrufe

IRQ-Ebenen

Verzögerte Prozeduraufrufe

Gerätetreiber

Arten von Gerätetreibern

Aufbau eines Treibers

Treiber- und Geräteobjekte

Geräte öffnen

E/A-Verarbeitung

Verschiedene Arten der E/A

E/A-Anforderungspakete

E/A-Anforderungen an einen einschichtigen Hardwaretreiber

E/A-Anforderungen an geschichtete Treiber

Threadagnostische E/A

Abbrechen der E/A

E/A-Vervollständigungsports

E/A-Priorisierung

Containerbenachrichtigungen

Treiberüberprüfung

E/A-Überprüfungsoptionen

Speicherüberprüfungsoptionen

Der PnP-Manager

Der Grad der Unterstützung für Plug & Play

Geräteauflistung

Gerätestacks

Treiberunterstützung für Plug & Play

Installation von Plug-&-Play-Treibern

Laden und Installieren von Treibern

Treiber laden

Treiberinstallation

Windows Driver Foundation

Kernel-Mode Driver Framework

Das E/A-Modell von KMDF

User-Mode Driver Framework

Energieverwaltung

Verbundener und moderner Standbymodus

Funktionsweise der Energieverwaltung

Energieverwaltung durch die Treiber

Steuerung der Geräteenergiezustände durch den Treiber und die Anwendung

Das Framework für die Energieverwaltung

Energieverfügbarkeitsanforderungen

Zusammenfassung

Kapitel 7

Sicherheit

Sicherheitseinstufungen

Trusted Computer System Evaluation Criteria

Common Criteria

Systemkomponenten für die Sicherheit

Virtualisierungsgestützte Sicherheit

Credential Guard

Device Guard

Objekte schützen

Zugriffsprüfungen

Sicherheitskennungen

Virtuelle Dienstkonten

Sicherheitsdeskriptoren und Zugriffssteuerung

Dynamische Zugriffssteuerung

Die AuthZ-API

Bedingte Zugriffssteuerungseinträge

Privilegien und Kontorechte

Kontorechte

Privilegien

Superprivilegien

Zugriffstokens von Prozessen und Threads

Sicherheitsüberwachung

Überwachung des Objektzugriffs

Globale Überwachungsrichtlinie

Erweiterte Überwachungsrichtlinienkonfiguration

Anwendungscontainer

UWP-Apps im Überblick

Anwendungscontainer

Anmeldung

Initialisierung durch Winlogon

Die einzelnen Schritte der Benutzeranmeldung

Sichere Authentifizierung

Das Windows-Biometrieframework

Windows Hello

Benutzerkontensteuerung und Virtualisierung

Virtualisierung des Dateisystems und der Registrierung

Rechteerhöhung

Schutz gegen Exploits

Abwehrmaßnahmen auf Prozessebene

Control Flow Integrity

Zusicherungen

Anwendungsidentifizierung

AppLocker

Richtlinien für Softwareeinschränkung

Kernelpatchschutz

PatchGuard

HyperGuard

Zusammenfassung

Index

Einleitung

Dieses Buch ist für Computerexperten (Entwickler, Sicherheitsforscher und Systemadministratoren) gedacht, die die Funktionsweise der Kernkomponenten von Microsoft Windows 10 und Windows Server 2016 kennenlernen möchten. Mit diesen Kenntnissen können Entwickler beim Schreiben von Anwendungen für die Windows-Plattform die Gründe für bestimmte Designentscheidungen besser verstehen. Sie helfen ihnen auch beim Debugging komplizierter Probleme. Auch Systemadministratoren profitieren von diesen Informationen, da das Wissen, wie das System in seinem Inneren »tickt«, sein Verhalten verständlicher macht und die Störungssuche erleichtert. Sicherheitsforscher erfahren hier, welche Fehlverhalten Softwareanwendungen und das Betriebssystem an den Tag legen können, wie sie missbraucht werden können und welche Schutzmaßnahmen und Sicherheitsfunktionen moderne Windows-Versionen dagegen bieten. Nach der Lektüre dieses Buches haben Sie ein besseres Verständnis darüber, wie Windows funktioniert und welche Gründe hinter seinem Verhalten stehen.

Die Geschichte dieses Buches

Dies ist die siebente Ausgabe eines Buches, das ursprünglich Inside Windows NT hieß (Microsoft Press, 1992) und noch vor der Erstveröffentlichung von Windows NT 3.1 von Helen Custer geschrieben wurde. Es war das erste Buch, das es je über Windows NT gab, und es bot wichtige Einsichten in die Architektur und das Design des Systems. Inside Windows NT, Second Edition (Microsoft Press, 1998) wurde von David Solomon geschrieben. Es deckte auch Windows NT 4.0 ab und ging weit tiefer in die technischen Details.

Inside Windows 2000, Third Edition (Microsoft Press, 2000) wurde von David Solomon und Mark Russinovich geschrieben. Hier kamen viele neue Themen wie Starten und Herunterfahren, interne Mechanismen von Diensten und der Registrierung, Dateisystemtreiber und Netzwerkanbindung hinzu. Auch die Änderungen am Kernel in Windows 2000 wurden erläutert, darunter das Windows Driver Model (WDM), Plug & Play, Energieverwaltung, Windows-Verwaltungsinstrumentation (Windows Management Instrumentation, WMI), Verschlüsselung, Jobobjekte und Terminaldienste. Windows Internals, Fourth Edition (Microsoft Press, 2004) war die neue Ausgabe für Windows XP und Windows Server 2003 mit zusätzlichen Inhalten, um IT-Fachleuten zu helfen, ihre Kenntnisse über die internen Mechanismen von Windows praktisch anzuwenden, z. B. durch die Werkzeuge von Sysinternals und die Analyse von Absturzabbildern.

Mit Windows Internals, Fifth Edition (Microsoft Press, 2009) wurde das Buch auf Windows Vista und Windows Server 2008 aktualisiert. Da Mark Russinovich eine Vollzeitstelle bei Microsoft annahm (wo er jetzt als CTO für Azure arbeitet), kam der neue Co-Autor Alex Ionescu hinzu. Zu den neuen Inhalten gehörten der Abbildlader, Einrichtungen für das Debugging im Benutzermodus, ALPC (Advanced Local Procedure Call) und Hyper-V. Die nächste Ausgabe, Windows Internals, Sixth Edition (Microsoft Press, 2012) war komplett aktualisiert, um viele Änderungen am Kernel in Windows 7 und Windows Server 2008 R2 abzudecken. Außerdem kamen viele neue praktische Experimente hinzu, um die Änderungen an den Werkzeugen deutlich zu machen.

Änderungen in dieser Auflage

Seit der letzten Aktualisierung dieses Buches hat Windows mehrere neue Releases durchlaufen und ist jetzt bei Windows 10 und Windows Server 2016 angekommen. Dabei ist Windows 10 jetzt praktisch der neue Name für Windows. Seit der Produktionsfreigabe hat es wiederum mehrere Releases gegeben. Bezeichnet werden sie jeweils mit einer vierstelligen Zahl, die sich aus dem Jahr und dem Monat der Veröffentlichung zusammensetzt, also z. B. Windows 10 Version 1703 für die Version vom März 2017. Zum Zeitpunkt der Abfassung dieses Buches hat Windows also seit Windows 7 mindestens sechs Versionen durchlaufen.

Beginnend mit Windows 8 hat Microsoft mit einer Zusammenführung seiner Betriebssysteme begonnen, was für die Entwicklung und für das Windows-Konstruktionsteam von Vorteil ist. Windows 8 und Windows Phone 8 verwendeten bereits einen gemeinsamen Kernel, und mit Windows 8.1 und Windows Phone 8.1 kam auch eine Vereinheitlichung bei modernen Apps hinzu. Mit Windows 10 war die Zusammenführung abgeschlossen: Dieses Betriebssystem läuft auf Desktops, Laptops, Servern, der Xbox One, Smartphones (Windows Mobile 10), der Holo-Lens und verschiedenen IoT-Geräten (Internet of Things).

Angesichts dieser großen Vereinheitlichung war die Zeit reif für eine neue Ausgabe dieses Buches, um die Änderungen von fast einem halben Jahrzehnt aufzuarbeiten, die zu einer stabileren Kernelarchitektur geführt haben. Daher deckt dieses Buch verschiedene Aspekte des Betriebssystems von Windows 8 bis Windows 10 Version 1703 ab. Des Weiteren heißen wir Pavel Yosifovich als neuen Co-Autor willkommen.

Praktische Experimente

Auch ohne Zugriff auf den Windows-Quellcode können Sie mithilfe des Kerneldebuggers, der Sysinternals-Tools und der eigens für dieses Buch entwickelten Werkzeuge viel über die internen Mechanismen von Windows herausfinden. Immer wenn ein Aspekt des internen Verhaltens von Windows mit einem der Tools sichtbar gemacht oder veranschaulicht werden kann, erfahren Sie in den mit »Experiment« betitelten Abschnitten, wie Sie dieses Tool selbst ausprobieren können. Diese Abschnitte sind über das ganze Buch verteilt, und wir raten Ihnen dazu, diese Experimente bei der Lektüre auszuführen. Es ist viel eindrucksvoller, die sichtbaren Auswirkungen der internen Mechanismen von Windows zu beobachten, als nur darüber zu lesen.

Nicht behandelte Themen

Windows ist ein umfangreiches und vielschichtiges Betriebssystem. In diesem Buch können wir nicht sämtliche internen Mechanismen von Windows abdecken, sondern konzentrieren uns auf die grundlegenden Systemkomponenten. Beispielsweise werden COM+, die verteilte objektorientierte Programmierinfrastruktur von Windows, und Microsoft .NET Framework, die Grundlage für Anwendungen mit verwaltetem Code, in diesem Buch nicht behandelt. Da es ein Buch über die »Interna« von Windows ist und kein Leitfaden für die Benutzung, die Programmierung oder die Systemadministration, erfahren Sie hier auch nicht, wie Sie Windows verwenden, programmieren oder konfigurieren.

Warnung

Dieses Buch beschreibt nicht dokumentierte Aspekte der internen Architektur und Funktionsweise von Windows (wie interne Kernelstrukturen und -funktionen), die sich zwischen den einzelnen Releases ändern können.

Das soll nicht heißen, dass sie sich zwangsläufig ändern, sondern nur, dass Sie sich nicht auf ihre Unveränderbarkeit verlassen können. Software, die sich auf solche nicht dokumentierten Schnittstellen oder auf Insiderkenntnisse über das Betriebssystem verlässt, kann in zukünftigen Releases von Windows unter Umständen nicht mehr funktionieren. Software, die im Kernelmodus läuft (z. B. Gerätetreiber) und diese nicht dokumentierten Schnittstellen nutzt, kann bei der Ausführung in einer neueren Windows-Version sogar einen Systemabsturz und damit möglicherweise einen Datenverlust für den Benutzer hervorrufen.

Kurz: Bei der Entwicklung von Software für Endbenutzersysteme und allgemein für jegliche Zwecke außer Forschung und Dokumentation sollten Sie niemals auf die in diesem Buch erwähnten internen Windows-Einrichtungen, Registrierungsschlüssel, Verhaltensweisen, APIs oder sonstigen nicht dokumentierten Elemente zurückgreifen. Suchen Sie immer erst auf MSDN (Microsoft Software Developer Network) nach einer offiziellen Dokumentation.

Zielgruppe

In diesem Buch wird vorausgesetzt, dass die Leser mit Windows auf dem Niveau von »Power-Usern« vertraut sind und Grundkenntnisse über Betriebssystem- und Hardwareelemente wie CPU-Register, Arbeitsspeicher, Prozesse und Threads mitbringen. In einigen Abschnitten sind auch Grundkenntnisse über Funktionen, Zeiger und ähnliche Konstrukte der Programmiersprache C von Nutzen.

Der Aufbau dieses Buches

Ebenso wie die sechste Ausgabe ist auch diese in zwei Bände aufgeteilt, von denen Sie den ersten in Händen halten.

Kapitel 1

, »Begriffe und Werkzeuge«, gibt eine allgemeine Einführung in die Grundbegriffe von Windows und in die wichtigsten Werkzeuge, die wir in diesem Buch einsetzen werden. Es ist sehr wichtig, dieses Kapitel als erstes zu lesen, da es die Hintergrundinformationen für das Verständnis des Restes gibt.

Kapitel 2

, »Systemarchitektur«, zeigt die Architektur und die Hauptkomponenten auf, aus denen Windows besteht, und erläutert sie. Mehrere dieser Komponenten werden in den folgenden Kapiteln noch ausführlicher beschrieben.

Kapitel 3

, »Prozesse und Jobs«, erklärt, wie Prozesse in Windows implementiert sind, und zeigt die verschiedenen Vorgehensweisen zu ihrer Bearbeitung auf. Des Weiteren werden Jobs beschrieben, die eine Möglichkeit bieten, um eine Gruppe von Prozessen zu steuern und die Containerunterstützung von Windows zu aktivieren.

Kapitel 4

, »Threads«, beschreibt ausführlich, wie Threads verwaltet, geplant und auf sonstige Weise in Windows bearbeitet werden.

Kapitel 5

, »Speicherverwaltung«, zeigt, wie der Speicher-Manager physischen und virtuellen Arbeitsspeicher verwendet, und erklärt die verschiedenen Möglichkeiten, mit denen Prozesse und Treiber den Arbeitsspeicher bearbeiten und nutzen können.

Kapitel 6

, »Das E/A-System«, beschreibt, wie das E/A-System von Windows funktioniert und wie es mit den Gerätetreibern zusammenwirkt, um die Mechanismen für E/A-Peripheriegeräte bereitzustellen.

Kapitel 7

, »Sicherheit«, beschreibt ausführlich die verschiedenen Sicherheitsmechanismen von Windows einschließlich systemeigener Schutzmaßnahmen gegen Exploits.

Schreibweisen

In diesem Buch gelten die folgenden Schreibweisen:

Fettschrift

wird für Text verwendet, den Sie in einer Schnittstelle eingeben müssen.

Kursivschrift

kennzeichnet neue Begriffe sowie die Bezeichnungen von GUI-Elementen, Dateinamen und Webadressen.

Codeelemente stehen in

nichtproportionaler Schrift

.

Bei Tastaturkürzeln steht ein Pluszeichen zwischen den Bezeichnungen der einzelnen Tasten. Beispielsweise bedeutet + + , dass Sie gleichzeitig die Tasten , und drücken müssen.

Begleitmaterial

Damit Sie aus diesem Buch noch größeren Nutzen ziehen können, haben wir Begleitmaterial zusammengestellt, das Sie von der folgenden Seite herunterladen können:

https://dpunkt.de/windowsinternals1

Den Quellcode der Tools, die wir eigens für dieses Buch geschrieben haben, finden Sie auf https://github.com/zodiacon/windowsinternals.

Danksagungen

Als Erstes möchten wir Pavel Yosifovich dafür danken, dass er sich uns für dieses Projekt angeschlossen hat. Seine Beteiligung war für die Veröffentlichung entscheidend. Die vielen Nächte, die er damit zugebracht hat, Einzelheiten von Windows zu studieren und über Änderungen während der Zeit von sechs Releases zu schreiben, haben dieses Buch erst möglich gemacht.

Ohne die Rückmeldungen und die Unterstützung von wichtigen Mitgliedern des Windows-Entwicklungsteams und anderer Fachleute von Microsoft wäre dieses Buch auch technisch nicht so tief schürfend und nicht so präzise geworden, wie es ist. Daher möchten wir den folgenden Personen danken, die es auf technische Korrektheit durchgesehen, Informationen gegeben oder die Autoren auf andere Weise unterstützt haben: Akila Srinivasan, Alessandro Pilotti, Andrea Allievi, Andy Luhrs, Arun Kishan, Ben Hillis, Bill Messmer, Chris Kleynhans, Deepu Thomas, Eugene Bak, Jason Shirk, Jeremiah Cox, Joe Bialek, John Lambert, John Lento, Jon Berry, Kai Hsu, Ken Johnson, Landy Wang, Logan Gabriel, Luke Kim, Matt Miller, Matthew Woolman, Mehmet Iyigun, Michelle Bergeron, Minsang Kim, Mohamed Mansour, Nate Warfield, Neeraj Singh, Nick Judge, Pavel Lebedynskiy, Rich Turner, Saruhan Karademir, Simon Pope, Stephen Finnigan und Stephen Hufnagel.

Wir möchten auch Ilfak Guilfanov von Hex-Rays (http://www.hex-rays.com) für die IDA Pro Advanced- und Hey-Rays-Lizenzen danken, die er Alex Ionescu vor mehr als einem Jahrzehnt zur Verfügung gestellt hat, um das Reverse-Engineering des Windows-Kernels zu beschleunigen, und für die fortlaufende Unterstützung und Entwicklung der Decompilerfeatures, die es überhaupt erst möglich gemacht haben, ein solches Buch ohne Zugriff auf den Quellcode zu schreiben.

Zu guter Letzt möchten die Autoren den großartigen Mitarbeitern bei Microsoft Press denken, die dieses Buch verwirklicht haben. Devon Musgrave hat zum letzten Mal als unser Akquiseleiter gearbeitet, während Kate Shoup den Titel als Projektleiterin beaufsichtigt hat. Auch Shawn Morningstar, Kelly Talbot und Corina Lebegioara haben zu der Qualität dieses Buches beigetragen.

Errata

Wir haben uns gewissenhaft darum bemüht, dieses Buch und das Begleitmaterial so korrekt wie möglich zu gestalten. Jegliche Fehler in der englischen Originalausgabe, die seit der Veröffentlichung des Buches gemeldet wurden, sind auf der Website von Microsoft Press unter folgender Adresse aufgeführt:

https://aka.ms/winint7ed/errata

Mit Anmerkungen, Fragen oder Verbesserungsvorschlägen zu diesem Buch können Sie sich aber auch an den deutschen dpunkt.verlag wenden:

[email protected]

Bitte beachten Sie, dass über unsere E-Mail-Adressen kein Support für Software und Hardware angeboten wird.

Für Supportinformationen bezüglich der Soft- und Hardwareprodukte besuchen Sie die Microsoft-Website http://support.microsoft.com.

Kontakt

Bei Microsoft Press steht Ihre Zufriedenheit an oberster Stelle. Daher ist Ihr Feedback für uns sehr wichtig. Lassen Sie uns auf dieser englischsprachigen Website wissen, wie Sie dieses Buch finden:

https://aka.ms/tellpress

Wir wissen, dass Sie viel zu tun haben. Darum finden Sie auf der Webseite nur wenige Fragen. Ihre Antworten gehen direkt an das Team von Microsoft Press. (Es werden keine persönlichen Informationen abgefragt.) Im Voraus vielen Dank für Ihre Unterstützung.

Über Ihr Feedback per E-Mail freut sich außerdem der dpunkt.verlag über:

[email protected]

Falls Sie News, Updates usw. zu Microsoft Press-Büchern erhalten möchten, können Sie uns auf Twitter folgen:

http://twitter.com/MicrosoftPress (Englisch)

https://twitter.com/dpunkt_verlag (Deutsch)

KAPITEL 1

Begriffe und Werkzeuge

In diesem Kapitel führen wir Kernbegriffe des Betriebssystems Microsoft Windows ein, die wir in dem gesamten Buch verwenden werden, z. B. Windows-API, Prozesse, Threads, virtueller Speicher, Kernel- und Benutzermodus, Objekte, Handles, Sicherheit und Registrierung. Außerdem stellen wir die Werkzeuge vor, mit denen Sie die inneren Mechanismen von Windows erkunden können, darunter den Kernel-Debugger, die Leistungsüberwachung und die wichtigsten Werkzeuge aus Windows Sysinternals (http://www.microsoft.com/technet/sysinternals). Des Weiteren erklären wir, wie Sie das Windows Driver Kit (WDK) und das Windows Software Developer Kit (SDK) verwenden können, um mehr über Windows-Interna zu erfahren.

In dem Rest dieses Buches wird vorausgesetzt, dass Sie die in diesem Kapitel eingeführten Begriffe kennen.

Versionen des Betriebssystems Windows

In diesem Buch geht es um die neueste Version der Client- und Serverbetriebssysteme von Microsoft, nämlich Windows 10 (eine 32-Bit-Version für x86 und ARM sowie eine 64-Bit-Version für x64) und Windows Server 2016 (wovon es nur eine 64-Bit-Version gibt). Sofern nicht ausdrücklich anders angegeben, bezieht sich der Text auf alle diese Versionen. Als Hintergrundinformation finden Sie in Tabelle 1–1 die Produktnamen, internen Versionsnummern und Veröffentlichungsdaten der bisherigen Windows-Versionen.

Produktname

Interne Versionsnummer

Veröffentlichungsdatum

Windows NT 3.1

3.1

Juli 1993

Windows NT 3.5

3.5

September 1994

Windows NT 3.51

3.51

Mai 1995

Windows NT 4.0

4.0

Juli 1996

Windows 2000

5.0

Dezember 1999

Windows XP

5.1

August 2001

Windows Server 2003

5.2

März 2003

Windows Server 2003 R2

5.2

Dezember 2005

Windows Vista

6.0

Januar 2007

Windows Server 2008

6.0 (Service Pack 1)

März 2008

Windows 7

6.1

Oktober 2009

Windows Server 2008 R2

6.1

Oktober 2009

Windows 8

6.2

Oktober 2012

Windows Server 2012

6.2

Oktober 2012

Windows 8.1

6.3

Oktober 2013

Windows Server 2012 R2

6.3

Oktober 2013

Windows 10

10.0 (Build 10240)

Juli 2015

Windows 10 Version 1511

10.0 (Build 10586)

November 2015

Windows 10 Version 1607 (Anniversary Update)

10.0 (Build 14393)

Juli 2016

Windows Server 2016

10.0 (Build 14393)

Oktober 2016

Tabelle 1–1Windows-Betriebssysteme

Beginnend mit Windows 7 scheint bei der Vergabe der Versionsnummern von einem wohldefinierten Muster abgewichen worden zu sein. Die Versionsnummer dieses Betriebssystems lautete nicht 7, sondern 6.1. Als mit Windows Vista die Versionsnummer auf 6.0 erhöht wurde, konnten manche Anwendungen das richtige Betriebssystem nicht erkennen. Das lag daran, dass die Entwickler aufgrund der Beliebtheit von Windows XP nur auf eine Überprüfung auf Hauptversionsnummern größer oder gleich 5 und Nebenversionsnummern größer oder gleich 1 durchführten. Diese Bedingung aber war bei Windows Vista nicht gegeben. Microsoft hatte die Lektion daraus gelernt und im Folgenden die Hauptversion bei 6 belassen und die Nebenversionsnummer auf mindestens 2 (größer 1) festgelegt, um solche Inkompatibilitäten zu minimieren. Mit Windows 10 wurde die Versionsnummer jedoch auf 10.0 heraufgesetzt.

Beginnend mit Windows 8 gibt die FunktionGetVersionExder Windows-API als Betriebssystemnummer unabhängig vom tatsächlich vorhandenen Betriebssystem standardmäßig 6.2 (Windows 8) zurück. (Diese Funktion ist außerdem als unerwünscht eingestuft.) Das dient zur Minimierung von Kompatibilitätsproblemen, zeigt aber auch, dass die Überprüfung der Betriebssystemversion in den meisten Fällen nicht die beste Vorgehensweise ist, weil manche Komponenten unabhängig von einem bestimmten offiziellen Windows-Release installiert werden können. Wenn Sie dennoch die tatsächliche Betriebssystemversion benötigen, können Sie sie indirekt bestimmen, indem Sie die FunktionVerifyVersionInfooder die neuen Hilfs-APIs für die Versionsbestimmung wieIsWindows80rGreater,IsWindows8Point 10rGreater,IsWindows100rGreater,IsWindowsServeru. Ä. verwenden. Außerdem lässt sich die Betriebssystemkompatibilität im Manifest der ausführbaren Datei angeben, was die Ergebnisse dieser Funktion ändert. (Einzelheiten entnehmen Sie bitte Kapitel 8, »Systemmechanismen«, in Band 2.)

Informationen über die Windows-Version können Sie mit dem Befehlszeilenwerkzeug ver oder grafisch durch Ausführen von winver einsehen. Der folgende Screenshot zeigt das Ergebnis von winver in Windows 10 Enterprise Version 1511:

Das Dialogfeld zeigt auch die Buildnummer (hier 10586.218), die für Windows-Insider hilfreich sein mag (also für diejenigen, die sich registriert haben, um Vorabversionen von Windows zu erhalten). Sie ist auch praktisch für die Verwaltung von Sicherheitsaktualisierungen, da sie zeigt, welche Patches installiert sind.

Windows 10 und zukünftige Windows-Versionen

Mit dem Erscheinen von Windows 10 hat Microsoft angekündigt, Windows jetzt in schnellerer Folge zu aktualisieren als zuvor. Es wird kein offizielles Windows 11 geben. Stattdessen wird Windows Update (oder ein anderes Bereitstellungsmodell) das vorhandene Windows 10 auf eine neue Version aktualisieren. Zurzeit hat es schon zwei solcher Aktualisierungen gegeben, nämlich im November 2015 (Version 1511, wobei sich die Nummer auf Jahr und Monat der Bereitstellung bezieht) und im Juli 2016 (Version 1607, die auch unter der Bezeichnung Anniversary Update vermarktet wurde).

Intern wird Windows nach wie vor phasenweise weiterentwickelt. Beispielsweise trug das ursprüngliche Release von Windows 10 den Codenamen Threshold 1 und die Aktualisierung von November 2015 die Bezeichnung Threshold 2. Die nächsten drei Phasen sind Redstone 1 (Version 1607), auf die Redstone 2 und Redstone 3 folgen werden.

Windows 10 und OneCore

Mit den Jahren wurden verschiedene Geschmacksrichtungen von Windows entwickelt. Neben dem Standard-Windows für PCs gibt es auch das Betriebssystem für die Spielkonsole Xbox 360, bei dem es sich um eine Fork von Windows 2000 handelt. Die Variante Windows Phone 7 basierte auf Windows CE (dem Echtzeit-Betriebssystem von Microsoft). Die Pflege und Erweiterung all dieses Codes ist naturgemäß nicht einfach. Daher hat man bei Microsoft entschieden, die Kernels und die Binärdateien für die grundlegende Plattform in einer einzigen zusammenfassen. Das begann bei Windows 8 und Windows Phone 8, die bereits über einen gemeinsamen Kernel verfügten (wobei Window 8.1. und Windows Phone 8.1 auch eine gemeinsame Windows-Laufzeit-API hatten). Mit Windows 10 ist diese Zusammenlegung abgeschlossen. Die gemeinsame Plattform heißt OneCore und läuft auf PCs, Smartphones, der Spielkonsole Xbox One, der HoloLens und auf IoT-Geräten (für das »Internet der Dinge«) wie dem Raspberry Pi 2.

Diese Geräte unterscheiden sich in ihrer physischen Gestalt sehr stark voneinander, weshalb einige Merkmale nicht überall zur Verfügung stehen. So ist es beispielsweise nicht sinnvoll, für HoloLens-Geräte eine Unterstützung für Maus und Tastatur anzubieten, weshalb diese Teile in der Windows 10-Version dafür nicht vorhanden sind. Aber der Kernel, die Treiber und die Binärdateien der grundlegenden Plattform sind im Prinzip identisch (mit registrierungs- oder richtliniengestützten Einstellungen, wo dies für die Leistung oder aus anderen Gründen sinnvoll ist). Ein Beispiel für solche Richtlinien finden Sie im Abschnitt »API-Sets« in Kapitel 3, »Prozesse und Jobs«.

In diesem Buch geht es um die inneren Mechanismen des OneCore-Kernels unabhängig von dem Gerät, auf dem er läuft. Die Experimente in diesem Buch sind jedoch für Desktop-Computer mit Maus und Tastatur ausgelegt, allerdings hauptsächlich aus praktischen Gründen, da es nicht einfach (und manchmal sogar unmöglich) ist, die gleichen Versuche auf Geräten wie Smartphones oder Xbox One durchzuführen.

Grundprinzipien und -begriffe

In den folgenden Abschnitten geben wir eine Einführung in die Grundprinzipien und -begriffe von Windows, deren Kenntnis für das Verständnis dieses Buches unverzichtbar ist. Viele der hier genannten Elemente wie Prozesse, Threads und virtueller Speicher werden in den nachfolgenden Kapiteln noch ausführlicher dargestellt.

Die Windows-API

Die Windows-API ist die Systemprogrammierschnittstelle der Windows-Betriebssystemfamilie für den Benutzermodus. Vor der Einführung der 64-Bit-Versionen von Windows wurde die 32-Bit-APi als Win32API bezeichnet, um sie von der ursprünglichen 16-Bit-API zu unterscheiden. Die Bezeichnung Windows-API in diesem Buch bezieht sich sowohl auf die 32- als auch die 64-Bit-Programmierschnittstelle von Windows.

Manchmal verwenden wir auch den Begriff Win32API statt Windows-API. Aber auch dann ist sowohl die 32- als auch die 64-Bit-Variante gemeint.

Die Windows-API wird in der Dokumentation des Windows-SDK beschrieben (siehe den Abschnitt »Windows Software Development Kit« weiter hinten in diesem Kapitel), die kostenlos auf https://developer.microsoft.com/en-us/windows/desktop/develop zur Verfügung steht und in allen Abonnements von MSDN, dem Microsoft-Unterstützungsprogramm für Entwickler, eingeschlossen ist. Eine hervorragende Beschreibung der Programmierung für die grundlegende Windows-API finden Sie in dem Buch Windows via C/C++, Fifth Edition von Jeffrey Richter und Christophe Nasarre (Microsoft Press, 2007).

Varianten der Windows-API

Die Windows-API bestand ursprünglich nur aus C-artigen Funktionen. Heutzutage können Entwickler auf Tausende solcher Funktionen zurückgreifen. Bei der Erfindung von Windows bot sich die Sprache C an, da sie den kleinsten gemeinsamen Nenner darstellte (weil sie auch von anderen Sprachen aus zugänglich war) und maschinennah genug, um Betriebssystemdienste bereitzustellen. Der Nachteil bestand in einer ungeheuren Menge von Funktionen ohne konsistente Benennung und logische Gruppierung (etwa durch einen Mechanismus wie die Namespaces von C++). Aufgrund dieser Schwierigkeiten wurden schließlich neuere APIs verwendet, die einen anderen API-Mechanismus einsetzten, nämlich das Component Object Model (COM).

COM wurde ursprünglich entwickelt, um Microsoft Office-Anwendungen die Kommunikation und den Datenaustausch zwischen Dokumenten zu ermöglichen (z. B. die Einbettung eines Excel-Diagramms in ein Word-Dokument oder eine PowerPoint-Präsentation). Diese Fähigkeit wird als OLE (Object Linking and Embedding) bezeichnet und wurde ursprünglich mit dem alten Windows-Messagingmechanismus DDE (Dynamic Data Exchange) implementiert. Aufgrund der Einschränkungen, die DDE zu eigen waren, wurde allerdings eine neue Kommunikationsmöglichkeit entwickelt, und das war COM. Als COM um 1993 veröffentlicht wurde, hieß es sogar ursprünglich OLE 2.

COM basiert auf zwei Grundprinzipien: Erstens kommunizieren Clients mit Objekten (manchmal COM-Serverobjekte genannt) über Schnittstellen. Dies sind wohldefinierte Kontrakte mit einem Satz logisch verwandter Methoden, die durch einen Zuteilungsmechanismus für virtuelle Tabellen gruppiert werden. Dies ist eine übliche Vorgehensweise von C++-Compilern zur Implementierung einer Zuteilung für virtuelle Funktionen. Sie resultiert in Binärkompatibilität und verhindert Probleme durch Namensverstümmelung im Compiler. Dadurch wird es möglich, die Methoden von vielen Sprachen (und Compilern) aufzurufen, z. B. C, C++, Visual Basic, .NET-Sprachen, Delphi usw. Das zweite Prinzip lautet, dass die Implementierung von Komponenten dynamisch geladen und nicht statisch mit dem Client verlinkt wird.

Der Begriff COM-Server bezieht sich gewöhnlich auf eine DLL (Dynamic Link Library) oder eine ausführbare Datei (EXE), in der die COM-Klassen implementiert sind. COM weist noch weitere wichtige Merkmale zu Sicherheit, prozessübergreifendem Marshalling, Threading usw. auf. Eine umfassende Darstellung von COM können wir in diesem Buch nicht leisten. Eine hervorragende Abhandlung über COM finden Sie in dem Buch Essential COM von Don Box (Addison-Wesley, 1998).

Über COM zugängliche APIs sind beispielsweise DirectShow, Windows Media Foundation, DirectX, DirectComposition, WIC (Windows Imaging Component) und BITS (Background Intelligent Transfer Service).

Die Windows-Laufzeitumgebung

Mit Windows 8 wurden eine neue API und eine neue Laufzeitumgebung eingeführt, die Windows Runtime (manchmal auch als WinRT abgekürzt; nicht zu verwechseln mit dem inzwischen eingestellten Betriebssystem Windows RT für ARM-Prozessoren). Die Windows-Laufzeitumgebung besteht aus Plattformdiensten für die Entwickler von sogenannten Windows-Apps (die früher auch als Metro Apps, Modern Apps, Immersive Apps und Windows Store Apps bezeichnet wurden). Windows-Apps können auf unterschiedlichen physischen Geräten ausgeführt werden, von kleinen IoT-Geräten über Telefone und Tablets bis zu Laptop- und Desktop-Computern und sogar auf Geräten wie die Xbox One und die Microsoft HoloLens.

Aus der Sicht der API setzt WinRT auf COM auf und erweitert die grundlegende COM-Infrastruktur. Beispielsweise sind in WinRT vollständige Typmetadaten verfügbar (die im .NET-Metadatenformat in WINMDF-Dateien gespeichert werden), was die COM-Typbibliotheken erweitert. Mit Namespace-Hierarchien, konsistenter Benennung und Programmiermustern ist WinRT auch viel zusammenhängender gestaltet als klassische Windows-API-Funktionen.

Anders als normale Windows-Anwendungen (die jetzt als Windows-Desktop-Anwendungen oder klassische Windows-Anwendungen bezeichnet werden) unterliegen Windows-Apps neuen Regeln. Diese Regeln werden in Kapitel 9, »Verwaltungsmechanismen«, von Band 2 beschrieben.

Die Beziehungen zwischen den verschiedenen APIs und Anwendungen sind nicht offensichtlich. Desktop-Anwendungen können einen Teil der WinRT-APIs verwenden, Windows-Apps dagegen eine der Win32- und COM-APIs. Um jeweils genau zu erfahren, welche APIs für welche Anwendungsplattformen zur Verfügung stehen, schlagen Sie bitte in der MSDN-Dokumentation nach. Beachten Sie jedoch, dass die WinRT-API auf der grundlegenden binären Ebene immer noch auf den älteren Binärdateien und APIs von Windows basiert, auch wenn bestimmte APIs nicht unterstützt werden und ihre Verfügbarkeit nicht dokumentiert ist. Es gibt keine neue »native« API für das System. Das ist vergleichbar mit .NET, das nach wie vor auf die traditionelle Windows-API zurückgreift.

Anwendungen, die in C++, C#, anderen .NET-Sprachen oder JavaScript geschrieben sind, können WinRT-APIs dank der für diese Plattformen entwickelten Sprachprojektionen leicht nutzen. Für C++ hat Microsoft eine nicht standardmäßige Erweiterung namens C++/CX erstellt, die die Verwendung von WinRT-Typen vereinfacht. Die normale COM-Interop-Schicht für .NET (zusammen mit einigen unterstützenden Laufzeiterweiterungen) erlaubt allen .NET-Sprachen die natürliche und einfache Nutzung von WinRT-APIs wie in reinem .NET. Für JavaScript-Entwickler gibt es die Erweiterung WinJS für den Zugriff auf WinRT. Für die Gestaltung der Benutzeroberfläche müssen JavaScript-Entwickler allerdings nach wie vor HTML einsetzen.

HTML kann zwar in Windows-Apps eingesetzt werden, allerdings handelt es sich dabei immer noch um eine lokale Client-App und nicht um eine von einem Web-server abgerufene Webanwendung.

.NET Framework

.NET Framework gehört zu Windows. Tabelle 1–2 gibt an, welche Version davon jeweils in den einzelnen Windows-Versionen installiert ist. Es ist jedoch immer möglich, auch eine neuere Version zu installieren.

Windows-Version

.NET Framework-Version

Windows 8

4.5

Windows 8.1

4.5.1

Windows 10

4.6

Windows 10 Version 1511

4.6.1

Windows 10 Version 1607

4.6.2

Tabelle 1–2.NET Framework-Standardinstallation in Windows

.NET Framework besteht aus den beiden folgenden Hauptkomponenten:

CLR (Common Language Runtime)

    Dies ist die Laufzeit-Engine für .NET. Sie umfasst einen JIT-Compiler (Just In Time), der CIL-Anweisungen (Common Intermediate Language) in die Maschinensprache der CPU übersetzt, einen Garbage Collector, Typverifizierung, Codezugriffssicherheit usw. Sie ist als In-Process-COM-Server (DLL) implementiert und nutzt verschiedene Einrichtungen, die von der Windows-API bereitgestellt werden.

.NET Framework-Klassenbibliothek (FCL)

    Dies ist eine umfangreiche Sammlung von Typen für die Funktionalität, die Client- und Serveranwendungen gewöhnlich benötigen, z. B. Benutzerschnittstellendienste, Netzwerkzugriff, Datenbankzugriff usw.

Durch diese und weitere Merkmale, darunter neue High-Level-Programmiersprachen (C#, Visual Basic, F#) und Unterstützungswerkzeuge, steigert .NET Framework die Produktivität von Entwicklern und erhöht Sicherheit und Zuverlässigkeit der Anwendungen. Abb. 1–1 zeigt die Beziehung zwischen .NET Framework und dem Betriebssystem.

Abbildung 1–1Die Beziehung zwischen .NET und Windows

Dienste, Funktionen und Routinen

Mehrere Begriffe in der Windows-Dokumentation für Benutzer und für Programmierer haben je nach Kontext eine unterschiedliche Bedeutung. Beispielsweise kann es sich bei einem Dienst um eine aufrufbare Routine im Betriebssystem, um einen Gerätetreiber oder um einen Serverprozess handeln. Die folgende Aufstellung gibt an, was in diesem Buch mit den genannten Begriffen gemeint ist:

Windows-API-Funktionen

    Dies sind dokumentierte, aufrufbare Subroutinen in der Windows-API, beispielsweise

CreateProcess

,

CreateFile

und

GetMessage

.

Native Systemdienste (Systemaufrufe)

    Dies sind nicht dokumentierte, zugrunde liegende Dienste im Betriebssystem, die vom Benutzermodus aus aufgerufen werden können. Beispielsweise ist

NtCreateUserProcess

der interne Systemdienst, den die Windows-Funktion

CreateProcess

aufruft, um einen neuen Prozess zu erstellen.

Kernelunterstützungsfunktionen (Routinen)

    Dies sind Subroutinen in Windows, die ausschließlich im Kernelmodus aufgerufen werden können (der weiter hinten in diesem Kapitel erklärt wird). Beispielsweise ist

ExAllocatePoolWithTag

die Routine, die Gerätetreiber aufrufen, um Speicher von den Windows-Systemheaps (den sogenannten

Pools

) zuzuweisen.

Windows-Dienste

    Dies sind Prozesse, die vom Dienststeuerungs-Manager von Windows gestartet werden. Beispielsweise wird der Taskplaner-Dienst in einem Benutzermodusprozess ausgeführt, der den Befehl

schtasks

unterstützt (der den UNIX-Befehlen

at

und

cron

ähnelt). (In der Registrierung werden Windows-Gerätetreiber zwar als »Dienste« bezeichnet, nicht aber in diesem Buch.)

DLLs (Dynamic Link Libraries)

    Eine DLL ist eine Binärdatei, zu der aufrufbare Subroutinen verknüpft worden sind und die von Anwendungen, die diese Subroutinen nutzen, dynamisch geladen werden kann, beispielsweise

Msvcrt.dll

(die C-Laufzeitbibliothek) und

Kernel32.dll

(eine der Teilsystem-Bibliotheken der Windows-API). Komponenten des Windows-Benutzermodus und Anwendungen nutzen DLLs ausgiebig. Der Vorteil von DLLs gegenüber statischen Bibliotheken besteht darin, dass Anwendungen sie gemeinsam nutzen, wobei Windows dafür sorgt, dass es im Arbeitsspeicher nur ein einziges Exemplar des DLL-Codes gibt, auf die alle Anwendungen zugreifen. Bibliotheks-Assemblies von .NET werden als DLLs kompiliert, aber ohne nicht verwaltete, exportierte Subroutinen. Stattdessen parst die CLR die kompilierten Metadaten, um auf die entsprechenden Typen und Elemente zuzugreifen.

Prozesse

Programme und Prozesse scheinen zwar oberflächlich gesehen ähnlich zu sein, unterscheiden sich aber grundlegend voneinander. Ein Programm ist eine statische Folge von Anweisungen, wohingegen es sich bei einem Prozess um einen Container für einen Satz von Ressourcen handelt, die bei der Ausführung einer Instanz des Programms genutzt werden. Grob gesehen, besteht ein Windows-Prozess aus folgenden Elementen:

Privater virtueller Adressraum

    Dies ist ein Satz von virtuellen Speicheradressen, die der Prozess nutzen kann.

Ausführbares Programm

    Das Programm definiert den ursprünglichen Code und die Daten und wird auf den virtuellen Adressraum des Prozesses abgebildet.

Ein Satz offener Handles

    Diese Handles werden verschiedenen Systemressourcen zugeordnet, z. B. Semaphoren, Synchronisierungsobjekten und Dateien, und sind von allen Threads im Prozess aus zugänglich.

Sicherheitskontext

    Hierbei handelt es sich um ein

Zugriffstoken

, das den Benutzer, die Sicherheitsgruppen, die Rechte, Attribute, Claims und Fähigkeiten, den Virtualisierungsstatus der Benutzerkontensteuerung, die Sitzung und den Zustand des eingeschränkten Benutzerzugriffs angibt, die mit dem Prozess verbunden sind. Des Weiteren legt der Kontext den Bezeichner des Anwendungscontainers fest und enthält Angaben über die zugehörige Sandbox.

Prozesskennung

    Dieser eindeutige Bezeichner ist Teil eines weiteren Bezeichners, nämlich der

Clientkennung

.

Mindestens ein Ausführungsthread

    Ein »leerer« Prozess ist zwar möglich, aber (meistens) nicht sinnvoll.

Es gibt eine Reihe von Werkzeugen, um Prozesse und Prozessinformationen einzusehen und zu bearbeiten. Die folgenden Experimente zeigen die verschiedenen Ansichten von Prozessinformationen, die Sie mit einigen dieser Tools gewinnen können. Manche dieser Werkzeuge sind in Windows selbst, im Debugging Tool for Windows oder im Windows SDK enthalten, während es sich bei anderen um eigenständige Programme von Sysinternals handelt. Viele dieser Werkzeuge zeigen die gleichen Kerninformationen über Prozesse und Threads an, manchmal jedoch unter unterschiedlichen Bezeichnungen.

Das wahrscheinlich am häufigsten verwendete Werkzeug zur Untersuchung von Prozessaktivitäten ist der Task-Manager. (Der Name ist allerdings etwas eigenartig, da es im Windows-Kernel keine »Tasks« gibt.) Das folgende Experiment führt einige der Grundfunktionen dieses Programms vor.

Experiment: Prozessinformationen im Task-Manager einsehen

Der im Lieferumfang von Windows enthaltene Task-Manager gibt eine Übersicht über die Prozesse im System. Sie können ihn auf vier verschiedene Weisen starten:

Drücken Sie .Rechtsklicken Sie auf die Taskleiste und wählen Sie Task-Manager starten.Drücken Sie und klicken Sie auf die Schaltfläche Task-Manager starten.Starten Sie die ausführbare Datei Taskmgr.exe.

Wenn Sie den Task-Manager zum ersten Mal starten, befindet er sich im Übersichtsmodus, in dem nur die Prozesse angezeigt werden, für die es ein sichtbares Fenster gibt:

In diesem Fenster können Sie allerdings nicht viel sehen. Klicken Sie daher auf die Erweiterungsschaltfläche Details, um in die Vollansicht zu wechseln. Dabei liegt standardmäßig die Registerkarte Prozesse oben:

Die Registerkarte Prozesse zeigt eine Liste der Prozesse mit vier Spalten: CPU, Arbeitsspeicher, Datenträger und Netzwerk. Wenn Sie auf die Kopfzeile rechtsklicken, können Sie noch weitere Spalten einblenden lassen. Zur Verfügung stehen Prozessname (Abbild), Prozess-ID, Typ, Status, Herausgeber und Befehlszeile. Einige Prozesse können erweitert werden, sodass Sie erkennen können, welche sichtbaren Fenster von ihnen erstellt werden.

Um noch mehr Einzelheiten zu den Prozessen einzusehen, klicken Sie auf die Registerkarte Details. Sie können auch auf einen Prozess rechtsklicken und Zu Details wechseln auswählen. Dadurch gelangen Sie auf die Registerkarte Details, wobei der betreffende Prozess schon ausgewählt ist.

Die Registerkarte Prozesse im Task-Manager von Windows 7 entspricht ungefähr der Registerkarte Details im Task-Manager von Windows 8 und höher. Im Task-Manager von Windows 7 zeigt die Registerkarte Anwendungen nur Prozesse mit sichtbaren Fenstern, und nicht sämtliche Prozesse. Diese Angaben sind jetzt auf der Registerkarte Prozesse des neuen Task-Managers von Windows 8 und höher enthalten.

Die Registerkarte Details zeigt ebenfalls Prozesse, aber auf kompaktere Art und Weise. Sie gibt die von den Prozessen erstellten Fenster nicht an, enthält aber eine breitere Auswahl von Informationsspalten.

Prozesse werden anhand ihres Namens bezeichnet und mit einem Symbol dargestellt, das angibt, wovon sie eine Instanz darstellen. Anders als viele andere Objekte in Windows können Prozesse keine globalen Namen bekommen. Um weitere Einzelheiten einzublenden, rechtsklicken Sie auf die Kopfzeile und wählen Spalten auswählen. Dadurch wird eine Liste von Spalten angezeigt:

Unter anderem gibt es folgende wichtige Spalten:

Threads    Die Spalte Threads zeigt die Anzahl der Threads in jedem Prozess. Normalerweise sollte sie mindestens eins betragen, da es keine unmittelbare Möglichkeit gibt, um einen Prozess ohne Thread zu erstellen (und ein solcher Prozess auch nicht sehr sinnvoll wäre). Werden für einen Prozess null Threads angezeigt, so bedeutet das gewöhnlich, dass der Prozess aus irgendeinem Grund nicht gelöscht werden kann, wahrscheinlich, weil der Treibercode fehlerhaft ist.Handles    Die Spalte Handles zeigt die Anzahl der Handles von Kernelobjekten, die die Threads in dem Prozess geöffnet haben. (Dieser Vorgang wird weiter hinten in diesem Kapitel sowie ausführlich in Kapitel 8 von Band 2 beschrieben.)Status    Die Spalte Status ist etwas knifflig. Bei Prozessen ohne Benutzerschnittstelle sollte hier normalerweise Wird ausgeführt angezeigt werden, wobei es jedoch sein kann, dass alle Threads auf irgendetwas warten, etwa auf ein Signal an ein Kernelobjekt oder den Abschluss einer E/A-Operation. Die andere Möglichkeit für einen solchen Prozess ist Angehalten, was angezeigt wird, wenn alle Threads in dem Prozess angehalten sind. Es ist sehr unwahrscheinlich, dass dies durch den Prozess selbst verursacht wird, lässt sich aber programmgesteuert durch den Aufruf der nicht dokumentierten nativen API NtSuspendProcess für den Prozess erreichen, gewöhnlich mithilfe eines Tools (beispielsweise gibt es in dem weiter hinten beschriebenen Process Explorer eine solche Option). Für Prozesse mit Benutzerschnittstelle bedeutet der Statuswert Wird ausgeführt, dass die Benutzerschnittstelle reagiert. Mit anderen Worten, der Thread, der die Fenster erstellt hat, wartet auf Benutzereingaben (technisch gesehen auf die mit ihm verbundene Nachrichtenwarteschlange). Der Zustand Angehalten ist ebenso möglich wie bei Prozessen ohne Benutzerschnittstelle, allerdings tritt er bei Windows-Apps (also denen mit Windows Runtime) gewöhnlich auf, wenn die Anwendung vom Benutzer minimiert wird und dadurch ihren Vordergrundstatus einbüßt. Solche Prozesse werden nach fünf Sekunden angehalten, damit sie keine CPU- und Netzwerkressourcen verbrauchen. Dadurch kann die neue Vordergrundanwendung alle Computerressourcen erhalten. Das ist insbesondere auf akkubetriebenen Geräten wie Tablets und Smartphones wichtig. Dieser und ähnliche Mechanismen werden ausführlich in Kapitel 9 von Band 2 beschrieben. Der dritte mögliche Wert für Status lautet Reagiert nicht. Das kann geschehen, wenn ein Thread in dem Prozess für die Benutzerschnittstelle seine Nachrichtenwarteschlange für Aktivitäten im Zusammenhang mit der Schnittstelle mindestens fünf Sekunden lang nicht überprüft hat. Der Prozesse (eigentlich der Thread, dem das Fenster gehört) kann mit irgendwelchen CPU-intensiven Arbeiten beschäftigt sein oder auf etwas völlig anderes warten (z. B. auf den Abschluss einer E/A-Operation). In jedem Fall friert die Benutzeroberfläche ein, was Windows dadurch kennzeichnet, dass die fraglichen Fenster blasser dargestellt und ihren Titeln der Zusatz (reagiert nicht) hinzugefügt wird.

Jeder Prozess verweist außerdem auf seinen Elternprozess (bei dem es sich um seinen Erstellerprozess handeln kann, aber nicht muss). Existiert der Elternprozess nicht mehr, so wird diese Angabe auch nicht mehr aktualisiert. Daher kann es sein, dass ein Prozess auf einen Elternprozess verweist, den es nicht mehr gibt. Das ist jedoch kein Problem, da es nichts gibt, was eine aktuelle Angabe darüber benötigt. Dieses Verhalten wird durch das folgende Experiment veranschaulicht. (Im Tool Process Explorer wird der Startzeitpunkt des Elternprozesses berücksichtigt, um zu verhindern, dass ein Kindprozess auf der Grundlage einer wiederverwendeten Prozesskennung angefügt wird.)

Wann ist der Elternprozess nicht mit dem Erstellerprozess identisch? Bei einigen Prozessen, die von bestimmten Benutzeranwendungen erstellt werden, kann die Hilfe eines Makler- oder Hilfsprozesses erforderlich sein, der die API zur Prozesserstellung aufruft. In einem solchen Fall wäre es verwirrend (oder sogar falsch, wenn eine Vererbung von Handles oder Adressräumen erforderlich ist), den Maklerprozess als Ersteller anzuzeigen, weshalb eine Umdefinition des Elternprozesses erfolgt. Mehr darüber erfahren Sie in Kapitel 7, »Sicherheit«.

Experiment: Die Prozessstruktur einsehen

Die meisten Werkzeuge zeigen für einen Prozess nicht die ID des Eltern- oder des Erstellerprozesses an. Diesen Wert können Sie jedoch in der Leistungsüberwachung (oder programmgesteuert) gewinnen, indem Sie Prozesskennung erstellen abrufen (was eigentlich »Kennung des erstellenden Prozesses« heißen müsste). In Tlist.exe aus den Debugging Tools for Windows können Sie die Prozessstruktur mithilfe des Optionsschalters /t anzeigen lassen. Im Folgenden sehen Sie eine Beispielausgabe von tlist /t:

System Process (0)

System (4)

smss.exe (360)

csrss.exe (460)

wininit.exe (524)

services.exe (648)

svchost.exe (736)

unsecapp.exe (2516)

WmiPrvSE.exe (2860)

WmiPrvSE.exe (2512)

RuntimeBroker.exe (3104)

SkypeHost.exe (2776)

ShellExperienceHost.exe (3760) Windows Shell Experience Host

ApplicationFrameHost.exe (2848) OleMainThreadWndName

SearchUI.exe (3504) Cortana

WmiPrvSE.exe (1576)

TiWorker.exe (6032)

wuapihost.exe (5088)

svchost.exe (788)

svchost.exe (932)

svchost.exe (960)

svchost.exe (976)

svchost.exe (68)

svchost.exe (380)

VSSVC.exe (1124)

svchost.exe (1176)

sihost.exe (3664)

taskhostw.exe (3032) Task Host Window

svchost.exe (1212)

svchost.exe (1636)

spoolsv.exe (1644)

svchost.exe (1936)

OfficeClickToRun.exe (1324)

MSOIDSVC.EXE (1256)

MSOIDSVCM.EXE (2264)

MBAMAgent.exe (2072)

MsMpEng.exe (2116)

SearchIndexer.exe (1000)

SearchProtocolHost.exe (824)

svchost.exe (3328)

svchost.exe (3428)

svchost.exe (4400)

svchost.exe (4360)

svchost.exe (3720)

TrustedInstaller.exe (6052)

lsass.exe (664)

csrss.exe (536)

winlogon.exe (600)

dwm.exe (1100) DWM Notification Window

explorer.exe (3148) Program Manager

OneDrive.exe (4448)

cmd.exe (5992) C:\windows\system32\cmd.exe - tlist /t

conhost.exe (3120) CicMarshalWnd

tlist.exe (5888)

SystemSettingsAdminFlows.exe (4608)

Die Einrückungen in der Liste zeigen die Beziehungen zwischen Eltern- und Kindprozessen. Prozesse, deren Elternprozesse nicht mehr existieren, sind nicht eingerückt (wie explorer.exe im vorstehenden Beispiel), denn selbst wenn der Großelternprozess noch vorhanden wäre, gäbe es keine Möglichkeit, diese Beziehung herauszufinden. Windows führt nur die Kennungen der Erstellerprozesse, aber keine Verbindungen zurück zu den Erstellern der Ersteller usw.

Die Zahl in Klammern ist die Prozesskennung, der bei einigen Prozessen folgende Test der Titel des Fensters, das von dem Prozess angelegt wurde.

Um zu beweisen, dass Windows sich nicht mehr merkt als die Kennung des Elternprozesses, führen Sie die folgenden Schritte aus:

1. Drücken Sie , geben Sie cmd ein und drücken Sie , um eine Eingabeaufforderung zu öffnen.2. Geben Sie titel Parent ein, um den Titel des Fensters in Parent zu ändern.3. Geben Sie start cmd ein, um eine zweite Eingabeaufforderung zu öffnen.4. Geben Sie titel Child an der zweiten Eingabeaufforderung ein.5. Geben Sie an der zweiten Eingabeaufforderung mspaint ein, um Microsoft Paint zu starten.6. Kehren Sie wieder zu der zweiten Eingabeaufforderung zurück und geben Sie exit ein. Paint wird weiterhin ausgeführt.7. Drücken Sie , um den Task-Manager zu öffnen.8. Wenn sich der Task-Manager im Übersichtsmodus befindet, klicken Sie auf Details.9. Klicken Sie auf die Registerkarte Prozesse.10. Suchen Sie die Anwendung Windows Command Processor und erweitern Sie ihren Knoten. Wie im folgenden Screenshot sollten Sie jetzt den Titel Parent sehen.11. Rechtsklicken Sie auf Windows Command Processor und wählen Sie Zu Details wechseln.12. Rechtsklicken Sie auf diesen cmd.exe-Prozess und wählen Sie Prozessstruktur beenden.13. Klicken Sie im Bestätigungsdialogfeld des Task-Managers auf Prozessstruktur beenden.

Das Fenster mit der ersten Eingabeaufforderung verschwindet, aber das Paint-Fenster wird nach wie vor angezeigt, da es nur der Enkel des beendeten Eingabeaufforderungsprozesses ist. Da der Zwischenprozess (der Elternprozess von Paint) beendet wurde, gibt es keine Verbindung mehr zwischen dem Elternprozess und seinem Enkel.

Der Process Explorer aus Sysinternals zeigt mehr Einzelheiten über Prozesse und Threads an als jedes andere verfügbare Werkzeug, weshalb wir ihn in vielen Experimenten in diesem Buch verwenden. Unter anderem gibt Ihnen Process Explorer die folgenden einzigartigen Angaben und Möglichkeiten:

Ein Prozesssicherheitstoken, z. B. Listen von Gruppen und Rechten und des Virtualisierungszustands

Hervorhebungen von Veränderungen in der Liste der Prozesse, Threads, DLLs und Handles

Eine Liste der Dienste in Diensthostingprozessen einschließlich Anzeigename und Beschreibung

Eine Liste zusätzlicher Prozessattribute wie Abschwächungsrichtlinien und deren Prozessschutzebene

Prozesse, die zu einem Job gehören, und Angaben zu dem Job

Prozesse für .NET-Anwendungen mit .NET-spezifischen Angaben wie die Aufzählung der Anwendungsdomänen, der geladenen Assemblies sowie CLR-Leistungsindikatoren

Prozesse für Windows Runtime (immersive Prozesse)

Startzeitpunkt von Prozessen und Threads

Vollständige Liste aller Dateien, die im Speicher zugeordnet wurden (nicht nur der DLLs)

Die Möglichkeit, einen Prozess oder Thread anzuhalten

Die Möglichkeit, einen einzelnen Thread zwangsweise zu beenden

Leichte Identifizierung der Prozesse, die im Laufe der Zeit die meisten CPU-Ressourcen verbrauchen

Die Leistungsüberwachung kann die CPU-Nutzung eines Satzes von Prozessen darstellen, zeigt dabei aber nicht automatisch auch Prozesse an, die nach dem Start dieser Überwachungssitzung erstellt wurden. Das können Sie nur mit einer manuellen Ablaufverfolgung im binären Ausgabeformat erreichen.

Des Weiteren bietet Process Explorer leichten, zentralen Zugriff auf Informationen wie die folgenden:

Die Prozessstruktur, wobei es möglich ist, einzelne Teile davon reduziert darzustellen

Offene Handles in einem Prozess, einschließlich nicht benannter Handles

Liste der DLLs (und im Arbeitsspeicher zugeordneten Dateien) in einem Prozess

Threadaktivität in einem Prozess

Thread-Stacks im Benutzer- und im Kernelmodus, einschließlich der Zuordnung von Adressen zu Namen mithilfe der

Dbghelp.dll

, die in den Debugging Tools for Windows enthalten ist

Genauere Angabe des prozentualen CPU-Anteils mithilfe des Threadzykluszählers – eine noch bessere Darstellung der genauen CPU-Aktivität (siehe

Kapitel 4

, »

Threads

«)

Integritätsebene

Einzelheiten des Speicher-Managers wie Spitzenwert des festgelegten virtuellen Speichers und Grenzwerte für ausgelagerte und nicht ausgelagerte Pools des Kernelspeichers (während andere Werkzeuge nur die aktuelle Größe zeigen)

Das folgende Experiment dient zur Einführung in Process Explorer.

Experiment: Einzelheiten über Prozesse mit Process Explorer einsehen

Laden Sie die neueste Version von Process Explorer von Sysinternals herunter und führen Sie sie aus. Das können Sie mit Standardbenutzerrechten tun, aber alternativ auch auf die ausführbare Datei rechtsklicken und Als Administrator ausführen wählen. Wenn Sie Process Explorer mit Administratorrechten ausführen, wird ein Treiber installiert, der mehr Funktionen bietet. Die folgende Beschreibung funktioniert jedoch unabhängig davon, wie Sie Process Explorer starten.

Bei der ersten Ausführung von Process Explorer sollten Sie die Symbole konfigurieren, da Sie anderenfalls eine entsprechende Meldung bekommen, wenn Sie auf einen Prozess doppelklicken und die Registerkarte Threads wählen. Bei ordnungsgemäßer Konfiguration kann Process Explorer auf Symbolinformationen zugreifen, um die Symbolnamen für die Startfunktion des Threads sowie die Funktion auf seinem Aufrufstack anzuzeigen. Das ist praktisch, um zu ermitteln, was die Threads innerhalb eines Prozesses tun. Für den Zugriff auf Symbole müssen die Debugging Tools for Windows installiert sein (siehe die Beschreibung weiter hinten in diesem Kapitel). Klicken Sie auf Options, wählen Sie Configure Symbols und geben Sie den Pfad zu Dbghelp.dll im Ordner von Debugging Tools sowie einen gültigen Symbolpfad an. Wenn die Debugging Tools for Windows auf einem 64-Bit-System im Rahmen des WDK im Standardspeicherort installiert sind, können Sie beispielsweise folgende Konfiguration verwenden:

Hier wird der Symbolserver verwendet, um auf Symbole zuzugreifen, und die Symboldateien werden auf dem lokalen Computer im Ordner C:\symbols gespeichert. (Wenn Sie Speicherplatz sparen müssen, können Sie diesen Ordner auch durch einen anderen Ordner ersetzen, auch durch einen auf einem anderen Laufwerk.) Weitere Informationen darüber, wie Sie die Verwendung des Symbolservers einrichten, erhalten Sie auf https://msdn.microsoft.com/en-us/library/windows/desktop/ee416588.aspx.

Sie können den Microsoft-Symbolserver einrichten, indem Sie die Umgebungsvariable_NT_SYMBOL_PATHauf den Wert aus der vorstehenden Abbildung setzen. Mehrere Werkzeuge suchen automatisch nach dieser Variablen, darunter Process Explorer, die Debugger aus den Debugging Tools for Windows, Visual Studio u. a. Dadurch können Sie es sich ersparen, jedes Tool einzeln zu konfigurieren.

Beim Start zeigt Process Explorer standardmäßig die Prozessstruktur an. Sie können den unteren Bereich erweitern, um die offenen Handles oder die im Arbeitsspeicher zugeordneten DLLs und anderen Dateien anzuzeigen (siehe auch Kapitel 5, »Speicherverwaltung«, und Kapitel 8 von Band 2). Wenn Sie den Mauszeiger über den Namen eines Prozesses halten, werden auch QuickInfos über die Prozessbefehlszeile und den Pfad eingeblendet. Bei einigen Arten von Prozessen enthält die QuickInfo auch zusätzliche Angaben, darunter die folgenden:

Die Dienste innerhalb eines Diensthostingprozesses (z. B. Svchost.exe)Die Tasks innerhalb eines Taskhostingprozesses (z. B. TaskHostw.exe)Das Ziel eines Runddl32.exe-Prozesses für Elemente der Systemsteuerung und andere MerkmaleAngaben zur COM-Klasse, wenn sich der Prozess in einem Dllhost.exe-Prozess befindet (auch Standard-COM+-Ersatz genannt)Anbieterinformationen für WMI-Hostprozesse (Windows Management Instrumentation) wie WMIPrvSE.exe (siehe Kapitel 8 in Band 2)Paketinformationen für Windows-Apps-Prozesse (Prozesse mit Windows Runtime, die weiter vorn in diesem Kapitel im Abschnitt »Die Windows-Laufzeitumgebung« vorgestellt wurden)

Führen Sie die folgenden Schritte aus, um einige Grundfunktionen von Process Explorer kennenzulernen:

Machen Sie sich mit den farbigen Hervorhebungen vertraut: Prozesse für Dienste werden standardmäßig rosa hinterlegt, Ihre eigenen Prozesse dagegen blau. Diese Farben können Sie ändern, indem Sie das Dropdownmenü öffnen und Options > Configure Colors auswählen.Halten Sie den Mauszeiger über den Imagenamen eines Prozesses. In einer QuickInfo wird der vollständige Pfad angezeigt. Wie zuvor erwähnt, enthält die QuickInfo bei bestimmten Arten von Prozessen weitere Angaben.Klicken Sie auf der Registerkarte Process Image auf View und wählen Sie Select Columns, um den Imagepfad hinzuzufügen.Klicken Sie auf den Kopf der Spalte Process, um die Prozesse zu sortieren. Dabei verschwindet die Strukturansicht. (Sie können nur entweder die Struktur anzeigen lassen oder eine Sortierung nach einer der Spalten durchführen.) Klicken Sie erneut auf den Kopf von Process, um eine Sortierung von Z zu A zu erreichen. Klicken Sie ein drittes Mal darauf, um wieder die Strukturansicht anzuzeigen.Öffnen Sie das Menü View und deaktivieren Sie Show Processes from All Users, damit nur Ihre Prozesse angezeigt werden.Klicken Sie auf das Menü Options, wählen Sie Difference Highlight Duration und ändern Sie den Wert auf drei Sekunden. Starten Sie dann einen (beliebigen) neuen Prozess. Dabei wird der neue Prozess drei Sekunden lang grün hervorgehoben. Beenden Sie den neuen Prozess. Dabei wird er drei Sekunden lang rot hervorgehoben, bevor er aus der Anzeige verschwindet. Diese Funktion ist nützlich, um sich einen Überblick über die Prozesse zu verschaffen, die auf dem System erstellt und beendet werden.Doppelklicken Sie auf einen Prozess und schauen Sie sich die verschiedenen Registerkarten an, die in der Anzeige der Prozesseigenschaften zur Verfügung stehen. (In verschiedenen Experimenten in diesem Buch werden wir auf diese Registerkarten hinweisen und die darauf befindlichen Angaben erklären.)

Threads

Ein Thread ist eine Entität in einem Prozess, die Windows zur Ausführung einplant. Ohne einen Thread kann das Programm des Prozesses nicht ausgeführt werden. Ein Thread schließt die folgenden grundlegenden Komponenten ein:

Den Inhalt eines Satzes von CPU-Registern, die den Zustand des Prozessors darstellen

Zwei Stacks: einen für Kernel- und einen für den Benutzermodus

Einen privaten Speicherbereich, der als lokaler Threadspeicher (

Thread-Local Storage, TLS

) bezeichnet und von Teilsystemen, Laufzeitbibliotheken und DLLs verwendet wird

Einen eindeutigen Bezeichner, der als

Threadkennung

oder

Thread-ID

bezeichnet wird (und der zu einer internen Struktur namens

Client-ID

gehört; Prozess- und Thread-IDs werden aus demselben Namespace generiert, weshalb sie niemals überlappen)

Darüber hinaus haben Threads manchmal auch einen eigenen Sicherheitskontext oder ein Token, das häufig von Multithread-Serveranwendungen verwendet wird, um den Sicherheitskontext der Clients anzunehmen, deren Anforderungen sie verarbeiten.

Die flüchtigen Register, die Stacks und der private Speicherbereich bilden den sogenannten Kontext des Threads. Da sie sich zwischen den einzelnen Maschinenarchitekturen unterscheiden, auf denen Windows läuft, ist diese Struktur notgedrungen architekturspezifisch. Die Windows-Funktion GetThreadContext bietet Zugriff auf diese architekturspezifischen Informationen (den sogenannten CONTEXT-Block).

Da an der Umschaltung der Ausführung von einem Thread zu einem anderen der Kernelscheduler beteiligt ist, kann dieser Vorgang sehr kostspielig sein, insbesondere wenn dies häufig zwischen immer denselben Threads geschieht. In Windows gibt es zwei Mechanismen, um die Kosten dafür zu senken, nämlich Fibers und UMS (User-Mode Scheduling).

Die Threads einer 32-Bit-Anwendung, die auf einer 64-Bit-Version von Windows läuft, enthalten sowohl 32- als auch 64-Bit-Kontexte, was Wow64 (Windows on Windows) dazu verwendet, die Anwendung bei Bedarf vom 32- in den 64-Bit-Modus umzuschalten. Diese Threads haben zwei Benutzerstacks und zweiCONTEXT-Blöcke. Die üblichen Windows-API-Funktionen geben stattdessen aber den 64-Bit-Kontext zurück, die FunktionWow64GetThreadContextdagegen den 32-Bit-Kontext. Mehr Informationen über Wow64 erhalten Sie in Kapitel 8 in Band 2.

Fibers

Fibers ermöglichen es einer Anwendung, ihre eigenen Ausführungsthreads zu planen, anstatt sich auf den prioritätsgestützten Mechanismus von Windows zu verlassen. Sie werden oft auch als schlanke Threads (»lightweight threads«) bezeichnet. Da sie in Kernel32.dll im Benutzermodus implementiert sind, sind sie für den Kernel nicht sichtbar. Um Fibers zu nutzen, müssen Sie zunächst die Windows-Funktion ConvertThreadToFiber aufrufen, die den Thread in eine laufende Fiber umwandelt. Anschließend können Sie die neue Fiber nutzen, um mit der Funktion CreateFiber weitere Fibers zu erstellen. (Jede Fiber kann ihren eigenen Satz von Fibers haben.) Anderes als bei einem Thread jedoch beginnt die Ausführung einer Fiber erst dann, wenn sie über einen Aufruf der Funktion SwitchToFiber manuell ausgewählt wird. Die neue Fiber wird ausgeführt, bis sie mit einem Aufruf von SwitchToFiber beendet wird, der eine andere Fiber zur Ausführung auswählt. Weitere Informationen entnehmen Sie bitte der Dokumentation des Windows SDK über Fiberfunktionen.

Es ist gewöhnlich nicht gut, Fibers zu verwenden, da sie für den Kernel nicht sichtbar sind. Außerdem gibt es bei ihnen Probleme durch die gemeinsame Nutzung des lokalen Threadspeichers (TLS), da in einem Thread mehrere Fibers laufen können. Es gibt zwar auch lokalen Fiberspeicher (FLS), der allerdings nicht alle Probleme der gemeinsamen Verwendung löst. An die E/A gebundene Fibers zeigen auch bei der Verwendung von FLS eine schlechte Leistung. Des Weiteren können Fiber nicht gleichzeitig auf mehreren Prozessoren laufen und sind auf ko-operatives Multitasking beschränkt. In den meisten Situationen ist es besser, dem Windows-Kernel die Planung zu überlassen, indem Sie die geeigneten Threads für die vorliegende Aufgabe auswählen.

UMS-Threads

UMS-Threads (User-Mode Scheduling) stehen nur in den 64-Bit-Versionen von Windows zur Verfügung. Sie bieten die gleichen grundlegenden Vorteile wie Fibers, aber nur wenige von deren Nachteilen. UMS-Threads haben ihren eigenen Kernelthreadstatus und sind daher für den Kernel sichtbar, was es ermöglicht, dass mehrere UMS-Threads Ressourcen gemeinsam nutzen, darum konkurrieren und blockierende Systemaufrufe ausgeben. Wenn zwei oder mehr UMS-Threads Arbeit im Benutzermodus verrichten müssen, können sie regelmäßig den Ausführungskontext im Benutzermodus wechseln (durch Zurücktreten eines Threads zugunsten eines anderen), anstatt den Scheduler zu bemühen. Aus der Sicht des Kernels läuft weiterhin derselbe Kernelthread, weshalb sich für ihn nichts geändert hat. Führt ein UMS-Thread eine Operation durch, die einen Eintritt in den Kernel erfordert (z. B. einen Systemaufruf), dann schaltet er zu seinem eigenen Kernelmodusthread um (was als direkter Kontextwechsel bezeichnet wird). Es ist zwar immer noch nicht möglich, UMS-Threads gleichzeitig auf mehreren Prozessoren auszuführen, doch zumindest folgen sie einem präemptiven und nicht vollständig kooperativen Modell.

Threads haben zwar ihren eigenen Ausführungskontext, doch alle Threads in einem Prozess teilen sich seinen virtuellen Adressraum (neben den anderen Ressourcen des Prozesses) und haben vollständigen Lese- und Schreibzugriff darauf. Allerdings ist es nicht möglich, dass ein Thread versehentlich auf den Adressraum eines anderen Prozesses verweist, sofern nicht dieser andere Prozess Teile seines privaten Adressraums als freigegebenen Speicherbereich verfügbar macht (was in der Windows-API als Dateizuordnungsobjekt [File Mapping Object] bezeichnet wird) oder ein Prozess das Recht hat, andere Prozesse zur Verwendung von prozessübergreifenden Speicherfunktionen zu öffnen, z. B. ReadProcessMemory und WriteProcessMemory. (Dieses Recht kann ein Prozess, der in demselben Benutzerkonto und nicht innerhalb eines Anwendungscontainers oder einer anderen Art von Sandbox läuft, standardmäßig erwerben, wenn der Zielprozess keine entsprechenden Schutzvorkehrungen aufweist.)

Neben dem privaten Adressraum und einem oder mehr Threads verfügt jeder Prozess auch über einen Sicherheitskontext und einen Satz von offenen Handles für Kernelobjekte wie Dateien, freigegebene Speicherbereiche oder Synchronisierungsobjekte wie Mutexe, Ereignisse oder Semaphoren (siehe Abb. 1–2).

Abbildung 1–2Ein Prozess und seine Ressourcen

Der Sicherheitskontext eines Prozesses wird jeweils in einem Objekt namens Zugriffstoken gespeichert. Es enthält die Sicherheitsidentifizierung und die Anmeldeinformationen für den Prozess. Standardmäßig haben Threads keine eigenen Zugriffstokens. Sie können allerdings eines erwerben, sodass einzelne Threads die Identität des Sicherheitskontextes eines anderes Prozesses annehmen können – auch von Prozessen auf einem anderen Windows-System –, ohne andere Threads in dem Prozess zu beeinträchtigen. (Weitere Einzelheiten zur Prozess- und Threadsicherheit erhalten Sie in Kapitel 7.)

Die VADs (Virtual Address Descriptors) sind Datenstrukturen, die der Speicher-Manager nutzt, um sich über die vom Prozess verwendeten virtuellen Adressen auf dem neuesten Stand zu halten. Diese Datenstrukturen werden in Kapitel 5 ausführlicher beschrieben.

Jobs

In Windows gibt es Jobs als Erweiterung des Prozessmodells. Der Hauptzweck von Jobs besteht darin, die Verwaltung und Bearbeitung von Prozessgruppen als eine Einheit zu ermöglichen. Diese Objekte erlauben es, bestimmte Attribute zu steuern, und bieten Grenzwerte für die mit ihnen verknüpften Prozesse. Sie zeichnen auch grundlegende Buchführungsinformationen für alle verknüpften Prozesse auf, sowohl die aktuellen als auch diejenigen, die bereits beendet wurden. In gewisser Hinsicht bilden Jobs einen Ersatz für den fehlenden strukturierten Prozessbaum in Windows. In manchen Aspekten sind sie jedoch leistungsfähiger als ein Prozessbaum nach Art von UNIX.

Der Process Explorer kann die von einem Job verwalteten Prozesse anzeigen (standardmäßig in Braun), aber diese Funktion müssen Sie erst aktivieren. Dazu öffnen Sie das Menü Options und wählen Configure Colors. Auf den Eigenschaftenseite solcher Prozesse gibt es außerdem die zusätzliche Registerkarte Jobs, auf der Sie Informationen über das zugehörige Jobobjekt finden.

Weitere Informationen über die interne Struktur von Prozessen und Jobs erhalten Sie in Kapitel 3. Threads und Algorithmen zu ihrer Planung sind Thema von Kapitel 4.

Virtueller Arbeitsspeicher

Windows richtet ein virtuelles Speichersystem auf der Grundlage eines linearen Adressraums ein, das jedem Prozess die Illusion gibt, über einen riesigen, privaten Adressraum für sich selbst zu verfügen. Der virtuelle Speicher bietet eine logische Sicht des Arbeitsspeichers, die nicht unbedingt mit dem physischen Aufbau übereinstimmen muss. Zur Laufzeit bildet der Speicher-Manager, unterstützt von der Hardware, die virtuellen Adressen auf die physischen Adressen ab (oder ordnet sie ihnen zu), an denen die Daten tatsächlich gespeichert werden. Durch Schutzvorkehrungen und durch Steuern dieser Zuordnung sorgt das Betriebssystem dafür, dass einzelne Prozesse nicht kollidieren und gegenseitig Betriebssystemdaten überschreiben.