MFT kolegi Nirvanowca będzie jak przykład!
Każdy zapis zawiera nagłówek stałego formatu, dalej idzie spis atrybutów zmiennej długości.
nagłówek MFT:
offset(w bajtach)/rozmiar(w bajtach)
0/4 - sygnatura MFT - "FILE"
4/2 - offset masywu korygowania zapisu Update Sequence
6/2 - rozmiar masywu zapisów Update Sequence
8/8 - numer kolejności pliku transakcji($LogFile Sequence Number)
10/2 - ostatni numer sektora w zapisu MFT
12/2 - licznik linków
14/2 - offset początku spisu atrybutów
16/2 - flagi, zaznaczające stan zapisu MFT : zawartości
00 - zapis nie wykorzystuje się
01 - zapis wykorzystuje się i opisuje plik (file)
02 - zapis nie wykorzystuje się i opisuje katalog (directory)
03 - zapis wykorzystuje się i opisuje katalog (directory)
18/4 - realny rozmiar zapisu MFT
1C/4 - rozmiar pamięci zajętej zapisem MFT
20/8 - numer (File Reference) bazowy zapis MFT
28/2 - maksymalna zawartość identyfikatora atrybutu, powiększonego o 1
2A/2 - Masyw korygowania zapisu MFT rozmiarem2*(N-1), gdzie N - zawartość rozmiaru masywu korygowania z pola z offset'em 0x06
2C/4 - dla XP index danego zapisu (number of this MFT record)
/2 - dla wszystkich numer kolejności aktualizacji (update sequence number)
/2S-2 - dla wszystkich, masyw kolejności aktualizacji (update sequence number)
Atrybuty: zgodnie z zawartością 14/2=0x0030 offset spisu atrybutów to 30h
Atrybut składa się z nagłówka, w którym jest:
offset(w bajtach)/rozmiar(w bajtach)
0/4 - typ atrybutu n.p. 0x00000010=$10 $STANDARD_INFORMATION
4/4 - rozmiar atrybutu w bajtach n.p. 0x00000060 60h i dodając tą zawartość wyliczamy offset kolejnego atrybutu 30h+60h=90h
90h
0/4 - typ atrybutu 0x00000030 $30 $FILE_NAME
4/4 - rozmiar atrybutu 0x00000068 68h + 90h =F8
F8H
0/4 - typ atrybutu 0x00000080 $80 $DATA
4/4 - rozmiar atrybutu 0x00000048 48h + F8 = 140H
140H
0/4 - typ atrybutu 0x000000B0 $B0 $BITMAP
4/4 - rozmiar atrybutu 0x00000048 48 + 140 = 188H
188H FF FF FF FF sygnatura końca spisu atrybutów
Każdy z atrybutów rozpatrzymy osobno.. ale to trochę później, jak będę miał trochę czasu, opisze wszystkie zawartości i flagi.
Adresy i rozmiar atrybutów nauczyliśmy się już wyliczać, teraz o samych atrybutach. Każdy atrybut zawiera nagłówek i ciało (body) obszar danych, adresy typu i rozmiar już opisany, dlatego zaczniemy od kolejnych zawartości nagłówka.
offset(w bajtach)/rozmiar(w bajtach)
0/4 - typ
4/4 - rozmiar
8/1 - flaga nierezydentnego atrybutu (00 rezydentny, 01 nierezydentny)
9/1 - długość nazwy atrybutu (00 atrybut nie ma nazwy)
A/2 - offset obszaru danych (body) atrybutu
C/2 - flaga skompresowanego/zaszyfrowanego atrybutu
E/2 - identyfikator atrybutu
$STANDARD_INFORMATION
18/8 - Data i czas utworzenia pliku
20/8 - Data i czas ostatniej modyfikacji pliku
28/8 - Data i czas ostatniej zmiany zapisu MFT tego pliku
30/8 - Data i czas ostatniego zgłoszenia do pliku
38/4 - Flagi dostępu
3C/12 - Zarezerwowane
--
Data i czas: to liczba interwalów o długości 100ns od 1 stycznia 1601 roku, czasu UTC.
Flagi dostępu: to zbiór osobnych bitów, połączonych przy pomocy operacji logiczniej (OR - LUB)
Bity
0x0001 - dla pliku lub folderu dozwolone tylko czytanie
0x0002 - ukryty plik lub folder
0x0004 - plik lub folder systemowy
0x0020 - plik był zarchiwizowany
0x0400 - dowiązanie symboliczne (Symbolic Link)
0x0800 - plik lub folder skompresowany
$FILE_NAME
Ten atrybut zawsze jest rezydentny.
Dla pliku lub folderu może być utworzono kilka takich atrybutów, zawierających imiona w rożnych przestrzeniach imion (Filename spaces).
1.imiona w standardzie POSIX - mogą być dowolne znaki oprócz 0 i "/"
2.imiona w standardzie o/s Mircrosoft Windows - ograniczenia MS WIN
3.imiona w standardzie "8.3' o/s MS-DOS - ograniczenia MS-DOS
offset(w bajtach)/rozmiar(w bajtach)
18/8 - numer zapisu MFT dla folderu, zawierającego ten plik
20/8 - Data i czas utworzenia pliku
28/8 - Data i czas ostatniej modyfikacji pliku
30/8 - Data i czas ostatniej zmiany zapisu MFT tego pliku
38/8 - Data i czas ostatniego zgłoszenia do pliku
40/8 - Rozmiar przestrzeni dyskowej wykorzystanej dla przechowywania pliku
48/8 - Realna długość pliku
50/8 - Flagi dostępu
58/1 - Długość imienia pliku N
59/1 - Kod przestrzeni imienia pliku
5A/2*N - Imię pliku. To pole ma długość 2*N, gdzie N - długość imienia pliku z pola po offset'u 58h
Informacja o dacie i czasie a także flagi dostępu dublują się, i są tak samo w
$STANDARD_INFORMATION. Jeżeli flaga dostępu ma zawartość 0x1000000, to imię należy do folderu a nie do pliku.
$DATA
W zależności od wielkości pliku, może być rezydentny lub nierezydentny ( jeżeli wielkość pliku pozwala ulokować dane pliku w samym MFT, to ten atrybut nazywa się rezydentny, jeżeli dla danych pliku wydzielone są klastry przestrzeni partycji NTFS wówczas ten atrybut nazywa się nierezydentny).
Rezydentny atrybut $DATA
offset(w bajtach)/rozmiar(w bajtach)
10/4 - Rozmiar bloku danych
14/2 - Offset bloku danych
16/2 - Flaga indeksowanego atrybutu
Tu najważniejszym (dla odzyskiwania danych) można liczyć rozmiar i offset bloku danych. Wyliczając je możemy odzyskać dane rezydentnego atrybutu.
Nierezydentny atrybut
$DATA
offset(w bajtach)/rozmiar(w bajtach)
10/8 - Początkowy numer VCN (starting VCN)
18/8 - Końcowy numer VCN (last VCN)
20/2 - Offset spisu ekstentow Runlist (data runs)
22/2 - Kod metody kompresowania( pakowania) atrybutu (compression unit size)
24/4 - 00h
28/8 - Rozmiar obszaru danych, zajętego przez plik na dysku (allocated size)
30/8 - Realna długość pliku (real size)
38/8 - Rozmiar inicjalizowanego obszaru pamięci dyskowej, wydzielonej dla przechowywania pliku
Z tego najbardziej nas będzie ciekawił spis ekstentow ( odcinkow "fragmentow")
runlist ( data runs). Każdy element
runlist opisuje rozmiar i ulokowanie jednego ekstenta ( odcinka) pliku.
A także metoda kompresowania, rozmiar obszaru danych, wydzielonego obszaru i realnie zajętego plikiem .
Offset
runlist wyliczamy z pola 20/2 tu mamy 0040h to oznacza ze
runlist jest po offsecie 40h od początku atrybutu. Teraz co do samego
runlist, w tym konkretnym pliku kolegi Nirvanowca mamy
runlist 11 28 04 00 . Jak to odczytać?
A tak: pierwszy bajt 11h w nim młodszy nibl 01h opisuje pole długości odcinku, a starszy nibl 01h rozmiar pola dla początkowego klastra. Z tego wynika ze nasz plik zaczyna się z klastra 04h i ma długość 28h klastrów. Sygnatura
00 oznacza ze to ostatni odcinek w
runlist.
Teraz przykład wielu odcinkowego opisu
runlist np. mamy 04h - 427h, 946h - 1078h, 1786h - 2899h temu będzie odpowiadał taki run-list
12 23 04 04 22 32 07 46 09 22 13 11 86 17 00. tu widzimy ze pierwszy odcinek zawiera: młodszy nibl 02h to 0423h, starszy nibl 01h to 04h , to i jest nasz odcinek na dysku 04 - (0423h+04h) zaczyna się z 4 klastra i kończy się na 1063 klastrze i t.d.
Teraz co do kodu metody kompresowania, tu mamy 00 to oznacza ze atrybut nie używa ani kompresji ani szyfrowania. Jeżeli kod byłby równy 4 to atrybut może być kompresowany lub zaszyfrowany.
"Real size" tu jest równy 28000h = 163840bajt
To samo i w przypadku "allocated size"..