Umrechnung virtueller in physische Adressen

Analysiert man den Arbeitsspeicher, so muss man früher oder später virtuelle in physische Adressen umrechnen. Beim ersten Mal kann das durchaus Schwierigkeiten bereiten. Dieser Artikel erklärt das Vorgehen anhand eines Beispiels.

Zur Einführung in die Thematik und Erläuterung der technischen Hintergründe empfehle ich die Lektüre von

  • Undocumented Windows 2000, Kapitel 4, von Sven B. Schreiber
  • Windows Internals (4. Aufl.), Kapitel 7, von Mark Russinovich und David Salomon.

Außerdem sollten Sie sich unbedingt die kostenlose Dokumentation für den Pentium-Prozessor von Intel besorgen. Kapitel 3.7 im Band 3A erklärt die Funktionsweise der 32-Bit Adressierung. Warum man die überhaupt verstehen muß? Diese Frage beantwortet der folgende Ausschnitt aus einer Sitzung mit dem Debugger:

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 829516a0  SessionId: 0  Cid: 0008    Peb: 00000000  ParentCid: 0000
    DirBase: 00030000  ObjectTable: 82976108  TableSize: 235.
    Image: System

PROCESS 8246c6a0 SessionId: 0 Cid: 00a4 Peb: 7ffdf000 ParentCid: 0008
DirBase: 04e4b000 ObjectTable: 8246cd88 TableSize: 33. Image: SMSS.EXE

PROCESS 82442020 SessionId: 0 Cid: 00bc Peb: 7ffdf000 ParentCid: 00a4 DirBase: 07409000 ObjectTable: 824ec9a8 TableSize: 399. Image: CSRSS.EXE

PROCESS 824038c0 SessionId: 0 Cid: 00d0 Peb: 7ffdf000 ParentCid: 00a4 DirBase: 07dce000 ObjectTable: 82404ae8 TableSize: 422. Image: WINLOGON.EXE

Ist es nicht seltsam, dass alle Prozesse den selben Process Environment Block (Peb) zu verwenden scheinen? Der Peb ist eine große Struktur, die unter anderem auch auf das Abbild der in den Arbeitsspeicher geladenen Programmdatei verweist. Offensichtlich können deshalb nicht alle Prozesse den selben Peb verwenden! Die Lösung dieses Problems ist überraschend einfach: bei der Adresse 0x7ffdf000 des Peb handelt es sich um eine virtuelle Adresse. Sie ist deshalb nur im Kontext des jeweiligen Prozesses gültig. Das hilft Ihnen aber nicht viel, wenn Ihnen für Ihre Untersuchung lediglich ein Abbild des Arbeitsspeichers zur Verfügung steht, denn nun müssen Sie die virtuelle Adresse in eine physische Umrechnen (und diese dann nochmals in einen Offset innerhalb des Abbildes, aber das ist eine andere Geschichte).

Für das folgende Beispiel verwende ich das erste Abbild aus der DFRWS Memory Analysis Challenge. Zum einen ist es frei erhältlich. Zum anderen wurde es mit dd erstellt. Physische Adresse und Dateioffset sind deshalb identisch.

Betrachten Sie bitte den Peb des Prozesses UMGR32.EXE. Wie Sie aus der Dokumentation von Intel ersehen können, ist der Ausgangspunkt für die Umrechnung von virtuellen in physische Adressen das Control Register CR3 der CPU. Sein Wert wird sich für jeden Prozess unterscheiden, denn jeder Prozess verfügt über seinen eigenen individuellen virtuellen Adressraum. Der jeweilige Wert von CR3 ist in der Variablen DirectoryTableBase der Struktur EPROCESS gespeichert. Ich habe PTfinder leicht verändert, so dass es diesen Wert in der Spalte "PDB" ausgibt.

> ptfinder.pl --nothreads dfrws2005-physical-memory1.dmp

No. Type PID TID Time created Offset PDB Remarks ---- ---- ------ ------ ------------------- ---------- ---------- ---------------- 4 Proc 668 2005-06-05 00:55:08 0x0095f020 0x075a7000 UMGR32.EXE

Und damit kann es jetzt endlich losgehen. Zunächst gilt es die (virtuelle) Adresse des Peb herauszufinden. Öffnen Sie dazu das Speicherabbild in einem Hexeditor und betrachten Sie den Offset 0x0095f020. Tragen Sie ab hier den Offset zum Peb ab (0x1b0 für Windows 2000). Auf diese Weise finden Sie die Bytefolge 0x00 0xf0 0xfd 0x7f. Die Adresse des Peb lautet also 0x7ffdf000.

Schreiben Sie diese Adresse als Binärzahl auf. Die 10 höherwertigsten Bits geben Ihnen den Index in das Page Directory an. In diesem Beispiel lautet der Index 0x1ff.

Berechnung des Page Directory Index
Page Directory IndexRest
31 - 2221-0
01111111111111011111000000000000
0x1ff (511) 

Wie oben gezeigt beginnt das Page Directory an der physischen Adresse 0x075a7000. Jeder Page Directory Entry (PDE) ist 4 Bytes groß. Die Adresse für den Eintrag Nr. 0x1ff ist also 0x075a7000+0x1ff*4 = 0x075a77fc. Der PDE enthält den Wert 0x05cee067.

Der Page Directory Entry
Page Table Base AddressunusedGPS0ACDWTU/SR/WP
31 - 1211109876543210
00000101110011101110000001100111
0x5cee 

Als erstes sollten Sie die Page Size (PS) überprüfen. Wenn diesesFlag gesetzt ist, liegt die Adresse innerhalb einer Speicherseite von 4 MB Umfang. Windows verwendet diese großen Seiten nur, um den Code des Kernels zu speichern. Es ist deshalb nicht überraschend, dass die Adresse des Peb in einer kleinen (4 kB) Speicherseite liegt. Das Flag Present (P) zeigt an, dass diese Seite tatsächlich im physischen Speicher gehalten wird und nicht etwa ausgelagert wurde. Damit kann es weitergehen.

Da die Adresse innerhalb einer kleinen Speicherseite liegt, geben die nächsten 10 Bit (21 bis 12) den Index in der sog. Page Table an. Die restlichen 12 Bit enthalten den Offset innerhalb der Seite.

Berechnung des Page Table Index
Page Directory IndexPage Table IndexOffset in der Speicherseite
31 - 2221 - 1211 - 0
01111111111111011111000000000000
0x1ff (511)0x3df (991) 0

Die Page Table beginnt an der Adresse 0x5cee * 0x1000. Jeder Page Table Entry (PDE) ist 4 Bytes lang. Dies führt auf den Eintrag Nr. 0x3df an der physischen Adresse 0x5cee * 0x1000 + 0x3df * 4 = 0x5ceef7c. Er enthält den Wert 0x0532f047.

Der Page Table Entry
Page Base AddressunusedGPATDACDWTU/SR/WP
31 - 1211109876543210
00000101001100101111000001000111
0x0532f 

Das ergibt nun endlich die Page Base Address von 0x0532f * 0x1000. Der Offset innerhalb dieser Seite ist 0. Für die virtuelle Adresse 0x7ffdf000 lautet die physische Adresse damit 0x0532f * 0x1000 + 0 = 0x532f000.

Archiv

Impressum

Dieses Blog ist ein Projekt von:
Andreas Schuster
Im Äuelchen 45
D-53177 Bonn
impressum@forensikblog.de

Copyright © 2005-2012 by
Andreas Schuster
Alle Rechte vorbehalten.
Powered by Movable Type 5.12