!chkimg
Die Erweiterung !chkimg erkennt Beschädigungen in den Images ausführbarer Dateien, indem sie diese mit der Kopie in einem Symbolspeicher oder einem anderen Dateispeicher vergleicht.
!chkimg [Options] [-mmw LogFile LogOptions] [Module]
Parameter
Optionen Eine beliebige Kombination der folgenden Optionen:
-p **** SearchPath
Durchsucht SearchPath rekursiv nach der Datei, bevor er auf den Symbolserver zugreift.
-f
Behebt Fehler im Image. Wenn der Scan Unterschiede zwischen der Datei im Symbolspeicher und dem Image im Speicher feststellt, wird der Inhalt der Datei im Symbolspeicher auf das Image kopiert. Wenn Sie Live-Debugging durchführen, können Sie eine Dump-Datei erstellen, bevor Sie die Erweiterung !chkimg -f ausführen.
-nar
Verhindert, dass das gemappte Image der Datei auf dem Symbolserver verschoben wird. Wenn sich die Kopie der Datei auf dem Symbolserver befindet und in den Speicher eingeblendet wird, verschiebt !chkimg standardmäßig das Image der Datei auf dem Symbolserver. Wenn Sie jedoch die Option -nar verwenden, wird das Image der Datei auf dem Server nicht verschoben.
Das ausführbare Image, das sich bereits im Speicher befindet (d.h. das Image, das gerade durchsucht wird), wird verschoben, da der Debugger Images, die er lädt, immer verschiebt.
Dieser Schalter ist nur dann sinnvoll, wenn das Betriebssystem das Original-Image bereits verschoben hat. Falls das Image noch nicht verschoben wurde, !chkimg und der Debugger wird das Image verschieben. Dieser Schalter wird nur selten benutzt.
-ss **** SectionName
Schränkt die Suche auf die Abschnitte ein, deren Namen die Zeichenfolge SectionName enthalten. Der Scan schließt jeden nicht zu verwerfenden Abschnitt ein, dessen Name diese Zeichenfolge enthält. SectionName unterscheidet Groß- und Kleinschreibung und darf nicht länger als 8 Zeichen sein.
-als
Bewirkt, dass der Scan alle Bereiche des Images mit Ausnahme der zu verwerfenden Bereiche umfasst. Standardmäßig (wenn Sie nicht -as oder -ss verwenden) überspringt der Scan Abschnitte, die schreibbar sind, Abschnitte, die nicht ausführbar sind, Abschnitte, die „PAGE“ in ihrem Namen haben, und zu verwerfende Abschnitte.
-r **** StartAdresse **** EndAdresse
Begrenzt die Suche auf den Speicherbereich, der mit StartAddress beginnt und mit EndAddress endet. Innerhalb dieses Bereichs werden alle Abschnitte gescannt, die normalerweise gescannt werden würden. Wenn sich ein Abschnitt teilweise mit diesem Bereich überschneidet, wird nur der Teil des Abschnitts gescannt, der sich mit diesem Bereich überschneidet. Die Suche ist auf diesen Bereich beschränkt, auch wenn Sie zusätzlich den Schalter -as oder -ss verwenden.
-nospec
Bewirkt, dass der Scan die reservierten Abschnitte von Hal.dll und Ntoskrnl.exe einschließt. Standardmäßig überprüft !chkimg bestimmte Teile dieser Dateien nicht.
-noplock
Zeigt Bereiche an, die nicht übereinstimmen, indem sie einen Byte-Wert von 0x90 (eine nop Anweisung) und einen Byte-Wert von 0xF0 (eine lock Anweisung) haben. Standardmäßig werden diese Unstimmigkeiten nicht angezeigt.
-np
Bewirkt, dass gepatchte Anweisungen erkannt werden.
-d
Zeigt eine Zusammenfassung aller nicht übereinstimmenden Bereiche an, während der Scanvorgang läuft. Weitere Informationen zu diesem zusammenfassenden Text finden Sie im Abschnitt „Remarks“.
-db
Zeigt nicht übereinstimmende Bereiche in einem Format an, das dem db debugger-Befehl ähnelt. Daher zeigt jede Anzeigezeile die Adresse des ersten Bytes in der Zeile, gefolgt von bis zu 16 hexadezimalen Bytewerten. Auf die Byte-Werte folgen unmittelbar die entsprechenden ASCII-Werte. Alle nicht druckbaren Zeichen, wie Wagenrücklauf und Zeilenvorschub, werden als Punkte (.) angezeigt. Die nicht übereinstimmenden Bytes sind durch ein Sternchen (*) gekennzeichnet.
-lo **** lines
Begrenzt die Anzahl der Ausgabezeilen, die -d oder -db anzeigen, auf die Anzahl der Zeilen.
-v
Zeigt ausführliche Informationen an.
-Mmw
Erzeugt eine Protokolldatei und zeichnet die Aktivitäten von !chkimg in dieser Datei auf. Jede Zeile der Protokolldatei steht für eine einzelne Fehlanpassung.
LogFile
Gibt den vollständigen Pfad der Protokolldatei an. Wenn Sie einen relativen Pfad angeben, ist der Pfad relativ zum aktuellen Pfad.
LogOptions
Gibt den Inhalt der Protokolldatei an. LogOptions ist eine Zeichenfolge, die aus einer Verkettung verschiedener Buchstaben besteht. Jede Zeile in der Protokolldatei enthält mehrere Spalten, die durch Kommas getrennt sind. Diese Spalten enthalten die Elemente, die die folgenden Optionsbuchstaben angeben, in der Reihenfolge, in der die Buchstaben in der Zeichenfolge LogOptions erscheinen. Sie können die folgenden Optionen mehrfach angeben. Sie müssen mindestens eine Option angeben.
Log-Option | In der Protokolldatei enthaltene Informationen |
---|---|
v |
Die virtuelle Adresse der Fehlanpassung |
r |
Der Offset (relative Adresse) der Abweichung innerhalb des Moduls |
s |
Das Symbol, das der Adresse der Fehlanpassung entspricht |
S |
Der Name des Abschnitts, der die Fehlanpassung enthält |
e |
Der korrekte Wert, der an der Stelle der Fehlanpassung erwartet wurde |
w |
Der falsche Wert, der sich an der Abweichungsstelle befand |
LogOptions kann auch einige oder keine der folgenden zusätzlichen Optionen enthalten.
Log-Option | Effekt |
---|---|
o |
Wenn eine Datei mit dem Namen LogFile bereits existiert, wird die bestehende Datei überschrieben. Standardmäßig hängt der Debugger neue Informationen an das Ende einer vorhandenen Datei an. |
tString |
Fügt eine zusätzliche Spalte in die Protokolldatei ein. Jeder Eintrag in dieser Spalte enthält String. Die Option tString ist nützlich, wenn Sie neue Informationen an eine bestehende Protokolldatei anhängen und die neuen Datensätze von den alten unterscheiden müssen. Sie können keine Leerzeichen zwischen t und String hinzufügen. Wenn Sie die Option tIString verwenden, muss dies die letzte Option in LogOptions sein, da String alle Zeichen vor dem nächsten Leerzeichen umfasst. |
Wenn z. B. LogOptions rSewo ist, enthält jede Zeile der Protokolldatei die relative Adresse und den Abschnittsnamen der Abweichungsstelle sowie die erwarteten und tatsächlichen Werte an dieser Stelle. Diese Option führt auch dazu, dass alle vorherigen Dateien überschrieben werden. Sie können den Schalter -mmw mehrfach verwenden, wenn Sie mehrere Protokolldateien mit unterschiedlichen Optionen erstellen möchten. Sie können bis zu 10 Protokolldateien gleichzeitig erstellen.
Modul
Gibt das zu prüfende Modul an. Modul kann der Name des Moduls, die Anfangsadresse des Moduls oder eine beliebige Adresse sein, die im Modul enthalten ist. Wenn Sie Module weglassen, verwendet der Debugger das Modul, das den aktuellen Befehlszeiger enthält.
DLL
Windows XP und höher |
Ext.dll |
Hinweise
Wenn Sie !chkimg verwenden, vergleicht es das Image einer ausführbaren Datei im Speicher mit der Kopie der Datei, die sich in einem Symbolspeicher befindet.
Alle Abschnitte der Datei werden verglichen, mit Ausnahme von Abschnitten, die verworfen werden können, die beschreibbar sind, die nicht ausführbar sind, die „PAGE“ in ihrem Namen haben oder die aus INITKDBG stammen. Sie können dieses Verhalten mit den Schaltern -ss, -as oder -r ändern.
!chkimg zeigt jede Nichtübereinstimmung zwischen dem Image und der Datei als Imagefehler an, mit den folgenden Ausnahmen:
Adressen, die von der Importadresstabelle (IAT) belegt sind, werden nicht geprüft.
Bestimmte Adressen in Hal.dll und Ntoskrnl.exe werden nicht überprüft, da beim Laden dieser Abschnitte bestimmte Änderungen auftreten. Um diese Adressen zu überprüfen, fügen Sie die Option -nospec hinzu.
Wenn der Byte-Wert 0x90 in der Datei vorhanden ist und wenn der Wert 0xF0 im entsprechenden Byte des Images vorhanden ist (oder umgekehrt), wird diese Situation als Übereinstimmung betrachtet. In der Regel enthält der Symbolserver eine Version einer Binärdatei, die sowohl in einer Uniprozessor- als auch in einer Multiprozessorversion existiert. Auf einem x86-basierten Prozessor ist der lock Befehl 0xF0, und dieser Befehl entspricht einem nop (0x90) Befehl in der Uniprozessor-Version. Wenn Sie möchten, dass !chkimg dieses Paar als Nichtübereinstimmung anzeigt, setzen Sie die Option -noplock.
Hinweis Wenn Sie die Option -f verwenden, um Imageabweichungen zu korrigieren, korrigiert !chkimg nur die Abweichungen, die es als Fehler betrachtet. Zum Beispiel ändert !chkimg ein 0x90-Byte nicht in ein 0xF0-Byte, es sei denn, Sie schließen -noplock ein.
Wenn Sie die Option -d einschließen, zeigt !chkimg eine Zusammenfassung aller nicht übereinstimmenden Bereiche an, während der Scan ausgeführt wird. Jede Unstimmigkeit wird in zwei Zeilen angezeigt. Die erste Zeile enthält den Beginn des Bereichs, das Ende des Bereichs, die Größe des Bereichs, den Symbolnamen und den Offset, der dem Beginn des Bereichs entspricht, sowie die Anzahl der Bytes seit dem letzten Fehler (in Klammern). Die zweite Zeile ist in Klammern eingeschlossen und enthält die erwarteten hexadezimalen Byte-Werte, einen Doppelpunkt und dann die tatsächlich im Image gefundenen hexadezimalen Byte-Werte. Wenn der Bereich länger als 8 Bytes ist, werden nur die ersten 8 Bytes vor und nach dem Doppelpunkt angezeigt. Das folgende Beispiel zeigt diese Situation.
be000015-be000016 2 bytes - win32k!VeryUsefulFunction+15 (0x8)
[ 85 dd:95 23 ]
Gelegentlich ändert ein Treiber einen Teil des Microsoft Windows-Kernels, indem er Hooks, Umleitungen oder andere Methoden verwendet. Auch ein Treiber, der sich nicht mehr auf dem Stack befindet, kann einen Teil des Kernels verändert haben. Sie können die Erweiterung !chkimg als Dateivergleichswerkzeug verwenden, um festzustellen, welche Teile des Windows-Kernels (oder eines anderen Images) von Treibern verändert werden und wie genau die Teile verändert werden. Dieser Vergleich ist bei vollständigen Dumpdateien am effektivsten.
Jedes geladene Modul prüfen
Sie können auch !chkimg zusammen mit der Erweiterung !for_each_module verwenden, um das Image eines jeden geladenen Moduls zu überprüfen. Das folgende Beispiel zeigt diese Situation.
!for_each_module !chkimg @#ModuleName
!analysiere Beispiel
Angenommen, Sie stoßen zum Beispiel auf eine Fehlerprüfung und beginnen mit !analyze.
kd> !analyze
....
BugCheck 1000008E, {c0000005, bf920e48, baf75b38, 0}
Probably caused by : memory_corruption
CHKIMG_EXTENSION: !chkimg !win32k
....
In diesem Beispiel deutet die Ausgabe !analyze darauf hin, dass eine Speicherbeschädigung aufgetreten ist, und enthält eine CHKIMG_EXTENSION-Zeile, die nahelegt, dass Win32k.sys das beschädigte Modul sein könnte. (Auch wenn diese Zeile nicht vorhanden ist, sollten Sie eine mögliche Beschädigung des Moduls oben auf dem Stapel in Betracht ziehen) Beginnen Sie mit der Verwendung von !chkimg ohne irgendwelche Schalter, wie das folgende Beispiel zeigt.
kd> !chkimg win32k
Number of different bytes for win32k: 31
Das folgende Beispiel zeigt, dass es in der Tat zu Speicherfehlern kommt. Verwenden Sie !chkimg -d, um alle Fehler für das Win32k-Modul anzuzeigen.
kd> !chkimg win32k -d
bf920e40-bf920e46 7 bytes - win32k!HFDBASIS32::vSteadyState+1f
[ 78 08 d3 78 0c c2 04:00 00 00 00 00 01 00 ]
bf920e48-bf920e5f 24 bytes - win32k!HFDBASIS32::vHalveStepSize (+0x08)
[ 8b 51 0c 8b 41 08 56 8b:00 00 00 00 00 00 00 00 ]
Number of different bytes for win32k: 31
Wenn Sie versuchen, das beschädigte Image des zweiten aufgelisteten Abschnitts zu disassemblieren, könnte die folgende Ausgabe erscheinen.
kd> u win32k!HFDBASIS32::vHalveStepSize
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 0000 add [eax],al
bf920e4a 0000 add [eax],al
bf920e4c 0000 add [eax],al
bf920e4e 0000 add [eax],al
bf920e50 7808 js win32k!HFDBASIS32::vHalveStepSize+0x12 (bf920e5a)
bf920e52 d3780c sar dword ptr [eax+0xc],cl
bf920e55 c20400 ret 0x4
bf920e58 8b510c mov edx,[ecx+0xc]
Verwenden Sie dann !chkimg -f, um die Speicherbeschädigung zu beheben.
kd> !chkimg win32k -f
Warning: Any detected errors will be fixed to what we expect!
Number of different bytes for win32k: 31 (fixed)
Jetzt können Sie die korrigierte Ansicht zerlegen und die von Ihnen vorgenommenen Änderungen sehen.
kd> u win32k!HFDBASIS32::vHalveStepSize
win32k!HFDBASIS32::vHalveStepSize:
bf920e48 8b510c mov edx,[ecx+0xc]
bf920e4b 8b4108 mov eax,[ecx+0x8]
bf920e4e 56 push esi
bf920e4f 8b7104 mov esi,[ecx+0x4]
bf920e52 03c2 add eax,edx
bf920e54 c1f803 sar eax,0x3
bf920e57 2bf0 sub esi,eax
bf920e59 d1fe sar esi,1
Untersuchen Sie die Beschädigung von Speicher und Speicherplatz
Zufällige Datei- und Speicherbeschädigungen können schwer zu untersuchen sein. In manchen Situationen ist es ratsam, eine zusätzliche Speicherprüfung zu aktivieren, z. B. mit Driver Verifier. Informationen über Driver Verifier finden Sie unter Driver Verifier.
Zum Testen des physischen Speichers verwenden Sie das Windows-Speicherdiagnosetool. Seine Verwendung und andere allgemeine Techniken sind in Blue Screen Data beschrieben.
Verwenden Sie das Dienstprogramm „Scan Disk“, um Dateisystemfehler zu erkennen. Halten Sie das zu scannende Laufwerk gedrückt (oder klicken Sie mit der rechten Maustaste darauf) und wählen Sie Eigenschaften. Wählen Sie Tools aus. Wählen Sie die Schaltfläche Jetzt prüfen.