2

While parsing my NTFS formatted hard disk, I found some invalid entries of INDX while Windows is still able to list all the root directory contents!

The structure of the Index Record in NTFS 3.1 is clear (NTFS doc):

Offset      Description
-------------------------------------
0x00        MFT Reference of the file
0x08        Size of the index entry
0x0A        Offset to the filename
...
0x52        Filename
...

However, I found some entries where their size is faulty as well as their MFT Reference (which is a bunch of zeros)!

I enclose a screenshot that shows a part of INDX along side with their text representations where each line is of width 0x20. I highlighted the faulty part.

The invalid entries of INDX

The figure shows that entries were parsed rationally until the last correct entry at 0x0628:

  • MFT Reference (8 bytes): 66 30 00 00 00 00 01 00
  • Size of entry (2 bytes): 70 00 So the entry ends at 0x0697.

Thereafter, things got weird! Entries at 0x0698:

  • MFT Reference (8 bytes): 00 00 00 00 00 00 00 00 Seems invalid
  • Size of entry (2 bytes): 10 00 Of course invalid because the size is less than the entry structure minimum size that includes the filename at 0x52 for instance.

For me, it seems that "Buziol Games" was a deleted folder on the root directory of the harddisk, I am not sure. Anyway, Windows explorer is not facing troubles on listing the contents.

Do anybody understand how does it work? How do Windows continue parsing?

EDIT: In addition, please find the hex dump as a pure text on pastebin

  • what have you highlighted the INDEX_RECORD_ENTRY should be preceded by INDEX_HEADER which should have a magic signature INDX i don't see a INDX magic sign in your screen shot ? 8200a000 49 4e 44 58 offset to index entries @ 18 8200a010 0a 00 00 00 00 00 00 00-28 00 00 00 ie 0x28 – blabb Jul 21 '17 at 20:08
  • @blabb, indeed the INDEX_HEADER is at address zero. I already parsed several INDEX_RECORD_ENTRY (ies) without any problem. My question is about the invalid INDEX_RECORD_ENTRY at address 0x0698. Anyway, the whole INDX (including INDEX_HEADER) is found at the pastebin attached – Mohamad-Jaafar NEHME Jul 21 '17 at 20:18
  • if that was the last entry with an mft reference of 0 then size would be 10 is correct iirc it is mentioned in the pdf you linked somewhere you cna also check this thread woodmann.com/forum/showthread.php?15188-NTFS-MFT-Internals/… – blabb Jul 21 '17 at 20:32
  • from your pastebin the size of index entries is 690 it matches with 620+70 = 690 so any reason to parse further ? Offset(h) 00 01 02 03 0000001C 90 06 00 00 .... – blabb Jul 21 '17 at 21:47
  • offset 58+52 $Attrdef 0xc0+52 $BadCluster 0x128+52 $bitmap 0x188+52 $boot 0x1e8+52 $extend 0x248+52 $logfile 0x2b0+52 $Mft 0x310+53 $MftMirr 0x378+52 $Secure 0x3d8+52 $upcase 0x438+52 $Volume 0x498+52 . (dot directory) 0x4f0+52 Ahmad 0x550+52 AutoExec.bat 5c0+52 boot.ini and buziol games – blabb Jul 21 '17 at 22:04
2
+50

The INDEX_RECORD_ENTRY should be preceded by INDEX_HEADER with the magic signature INDX

without the header deciphering the INDEX_RECORD_ENTRIES is difficult as shown in your screen shot

the following observations are based on the pastebin dump you edited in later

i converted the hex to binary with a bat file thus

rem make a copy 
copy %1 %2
rem compare both
fc %1 %2
rem dump the first line for visualizing
head -1 %2
rem strip the address,colon and space 
rem this is to make it compatible with xxd input
sed s/.*:\x20//g %2 > %3
rem dump the ripped hex file first line 
head -1 %3
rem convert hex to binary 
xxd -r -p %3 > %4
rem check the size and compare with word count
rem both should be same 
ls -l %4
wc -w %3

executing the bat file on the downloaded pastebin dump

C:\indx>converthextobin.bat indx_$i30_dump.txt indxhex.txt indxstripped.txt indxbin.bin

C:\indx>rem make a copy
C:\indx>copy indx_$i30_dump.txt indxhex.txt
        1 file(s) copied.

C:\indx>rem compare both
C:\indx>fc indx_$i30_dump.txt indxhex.txt
Comparing files indx_$i30_dump.txt and INDXHEX.TXT
FC: no differences encountered

C:\indx>rem dump the first line for visualizing
C:\indx>head -1 indxhex.txt
0000: 49 4E 44 58 28 00 09 00 D2 92 87 08 00 00 00 00

C:\indx>rem strip the address,colon and space
C:\indx>rem this is to make it compatible with xxd input
C:\indx>sed s/.*:\x20//g indxhex.txt  1>indxstripped.txt

C:\indx>rem dump the ripped hex file first line
C:\indx>head -1 indxstripped.txt
49 4E 44 58 28 00 09 00 D2 92 87 08 00 00 00 00

C:\indx>rem convert hex to binary
C:\indx>xxd -r -p indxstripped.txt  1>indxbin.bin

C:\indx>rem check the size and compare with word count
C:\indx>rem both should be same
C:\indx>ls -l indxbin.bin
-rw-rw-rw-  1 HP 0 6656 2017-07-22 15:20 indxbin.bin
C:\indx>wc -w indxstripped.txt
6656 indxstripped.txt

now that we have a binary form we can start exploring

lets dump the INDEX_HEADER and verify

@echo off
xxd -s00 -g4 -l4 indxbin.bin &^
xxd -s04 -g2 -l2 indxbin.bin &^
xxd -s06 -g2 -l2 indxbin.bin &^
xxd -s08 -g8 -l8 indxbin.bin &^
xxd -s16 -g8 -l8 indxbin.bin &^
xxd -s24 -g4 -l4 indxbin.bin &^
xxd -s28 -g4 -l4 indxbin.bin &^
xxd -s32 -g4 -l4 indxbin.bin &^
xxd -s36 -g1 -l1 indxbin.bin &^
xxd -s37 -g3 -l3 indxbin.bin &^
xxd -s40 -g2 -l2 indxbin.bin

executed we get the INDEX_HEADER

C:\indx>dumpindxheader.bat
0000000: 494e4458                             INDX
0000004: 2800                                     (.
0000006: 0900                                     ..
0000000: 494e445828000900                   INDX(...
0000010: 0000000000000000                   ........
0000018: 40000000                             @...
000001c: 90060000                             ....
0000020: e80f0000                             ....
0000024: 00
0000025: 000000                                 ...
0000028: 1e02                                     ..

we can see the INDEX_RECORD_ENTRY relative to HEADER_OFFSET is 0x40 (i haven't tried to control the Endiannes in xxd output)

so the INDEX_RECORD_ENTRY (terminology may be incorrect ) starts at 0x40+0x18 = 0x58
it is a variable sized structure padded appropriately to boundaries

dumping the record entry

@echo off
xxd -s88 -g8 -l8 indxbin.bin &^
xxd -s96 -g2 -l2 indxbin.bin &^
xxd -s98 -g2 -l2 indxbin.bin &^
xxd -s100 -g2 -l2 indxbin.bin &^
xxd -s102 -g2 -l2 indxbin.bin &^
xxd -c8 -s104 -g8 -l64 indxbin.bin &^
xxd -s168 -g1 -l1 indxbin.bin &^
xxd -s169 -g1 -l1 indxbin.bin &^
xxd -s170 -g1 -l22 indxbin.bin

executing the bat file

C:\indx>dumpindxrecordentry.bat
0000058: 0400000000000400                   ........
0000060: 6800                                     h.
0000062: 5200                                     R.
0000064: 0000                                     ..
0000066: 0000                                     ..
0000068: 0500000000000500  ........
0000070: d07fa49ac58cd201  ........
0000078: d07fa49ac58cd201  ........
0000080: d07fa49ac58cd201  ........
0000088: d07fa49ac58cd201  ........
0000090: 0090000000000000  ........
0000098: a08c000000000000  ........
00000a0: 0600000000000000  ........
00000a8: 08                                               .
00000a9: 03                                               .
00000aa: 24 00 41 00 74 00 74 00 72 00 44 00 65 00 66 00  $.A.t.t.r.D.e.f.
00000ba: 00 00 00 00 00 00                                ......

the size 68 is relative to self so the next entry would be at 0x58+0x68 == 0xc0

the offset to file name is relative to self so file name would be at 0x58+0x52 = 0xaa as dumped

so you can now go ahead by dumping the next entry by providing the appropriate seek address to xxd viz 0xc0 or 0n192

the last entry is at 0x628 whose size is 0x70 so it ends at 0x698

the very last entry is 0x10 bytes long with an mft reference 0

quoted from the pdf linked in your original post
last entry has a size of 0x10 (just large enough for the flags (and a mft ref of zero)

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000690                          00 00 00 00 00 00 00 00          ........
000006A0  10 00 00 00 02 00 00 00                          ........
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.