#DFIR: One byte makes the difference: MFT Resident File

Hi, minions:

Are you ready for some good coffee? Let's go!

A short time ago I took up a pending project. A project, of many, that I have been 'abandoning' along the way. Specifically, this project deals with the removal of a certain type of files and then extract the content of those same files, without the need to recover it.

Along the way with this project I have found doubts, worries and some gaps in the understanding of how and why of things. Gaps that I have felt the need to fill with curiosity, the need to know how and why things work. Gaps that I have clarified with this research.

One of those gaps I've come across has to do with a feature of the MFT: 'Resident File'.

I have come across many Blogs and articles that mention this characteristic of NTFS file systems, stating that they are files with a size of 'X' (each publication varies the figure of that 'X'), and with some articles that state that the different attributes are always in a certain position (when this fact varies according to a certain condition), all without reliable proof of it. I have not seen much documented material about it. I have been very struck by this fact, given the importance of this characteristic in this DFIR field. Given the high importance, and value, that has the analysis of the MFT in any case.

That is why I thought it would be appropriate and interesting to publish this research material, given the lack of documentation on the subject, and I have decided to carry out my own tests. 
In this DFIR field, everything has an explanation. Just look for it. 
Although it is true that this explanation can be very complex to find, remember that we move between '0' and '1', (in this case, between bytes and hexadecimal values).

I am in a position to shed a little more light on this attribute of the files resident in the MFT. Along the way, in search of the information I needed, I went to Harlan Carvey's Blog (http://windowsir.blogspot.com), which has mentioned this feature on several occasions, in several of his articles. Specifically, one of those Harlan articles, published on November 13, 2013, led me to another article, written by Hal Pomeranz, under the title "Resident $DATA Residue in NTFS MFT Entries". And this has been my starting point.
I consider it interesting to read everything that falls into our hands and to pay attention to the references used because, on many occasions, the information we are looking for can be found in those references used.
I remember commenting something in passing about MFT in the article I wrote in 'Follow the White Rabbit', entitled "What happened? The ABC of the MACB". Like then, I'm not going to disentangle the whole structure of the MFT and how the files are saved in it. At the end of this article I will mention some interesting links to you on this subject, if you want to delve deeper into it.

Introduction


Before we begin... I think it's convenient to explain a little bit about how files are saved in the MFT. I say again that I am not going to explain each and every one of the attributes that we can find in the MFT because, for it, it would need several extensive articles. So, I will only mention those that I consider of interest for this case: Resident files and non-resident files.
Everything in the NTFS file system is a file and everything that is a file is recorded in the MFT.
When is a resident file? A file is resident when all its information, the complete data of the file, is housed only in the MFT. That is to say, that a resident file does not occupy space in disk, (obviating the own one that uses the MFT to record that record).

The size assigned in the MFT for each file record is 1024 bytes. This means that if a sector has a size of 512 bytes, the record of a file in the MFT will occupy two sectors. The size of the cluster assigned to the system or device is irrelevant. It is not related. Whether it is a cluster of 512 bytes, or a cluster of 4096 bytes, the MFT will assign for each record 1024 bytes, (two sectors).

A different thing is if the file is not resident in the MFT because, in that case (where the file does occupy disk space), the information in that file will occupy the space assigned to the corresponding cluster. That is to say, if there is a file with a size of, for example, 2000 bytes and the size assigned to the cluster is 512 bytes, then it will occupy that cluster, (or clusters), assigned, (2048 bytes, 4 sectors), while if the size assigned to the cluster is 4096 bytes, then it will occupy that assigned cluster, (4096 bytes, 8 sectors).

The full explanation of this topic is available on Microsoft's official website.


The records recorded in the MFT are represented in hexadecimal values and each hexadecimal value, (each shift), represents one byte.

Taking into account all the above, each record will contain a total of 1024 bytes or, which is the same, 1024 hexadecimal values, (although not all the space has to be occupied, nor do all the attributes have to exist in that record). That is to say, that, although that space is assigned to a record, a record recorded in the MFT does not have to cover the 1024 bytes, although I will show you examples of it.

Scrolling in bytes starts from byte '0', as first byte.

A record recorded in the MFT presents a list of attributes, according to a list that you can consult on Microsoft's official site.

Note that not all attributes have to be present in a record, nor do records have to have the same attributes.

Each record starts with the value '46494C45', (FILE), which has a length of 4 bytes. This is the header for each record housed in the MFT. That is, the beginning of each record occupies the first four bytes. (Bytes from '0 to 3').

Up to byte 151, (where the attribute '$10' ends), all records have the same type of attributes, (of course, with different values). The differences, as far as attributes are concerned, start at byte 152.

The information that will indicate whether a file is resident or non-resident is found within the attribute '$DATA', which begins with the value '80000000', whose location varies, depending on the case. Specifically, it is in the fifth byte, counted from the end of the header of this attribute. If it is a resident file it will have a value of '00', while if it is a non-resident file it will have a value of '01'.

The MFT displays at the end of each record the value 'FFFFFFFF', (ÿÿÿÿ), with a length of 4 bytes.

After those last four bytes that indicate the end of the file record, there are another four bytes.

The headers of each attribute have a length of 4 bytes.

My intention was to explain the situation that has to be given for a file to be resident, or not. But in my research I have found up to six different situations, six conditions. (I confess that from this point on, my head has been aching to think about how to structure the content). 

The tests


Where to start testing? Well, the first of them, by the creation of a few hundred files, each file being created one byte more than the previous one and with correlative names. To do this, I wrote a small batch file, taking into account that each alphanumeric character represents a byte. I could have done this with fsutil, directly assigning the desired size, but then I could not edit those generated files, which is necessary to observe the behavior of a resident file.



The result of the execution of this small batch file...


Oh, my God! What have I gotten myself into? 😱😱😱😱😱😱😱😱😱😭 I wanna cry!

It's time to have a lot of coffee, (large doses of coffee), do a lot of manual work and have a lot of patience, because it's time to check each of the files.

After performing this first test that I mentioned earlier and after spending many hours to study the situation of all these files, I have come to a conclusion.

Do you want to know when a file is resident and when it is not? Are you ready to know the exact size for a file to be resident, or not? Well, the answer is... Depends 🤪🤪🤪

It depends on whether they are generated automatically or if they are created with an 'X' editor. It depends on whether the file is given a short name or a long name. It depends on whether the creation of 8.3 file names is disabled. Depends on several factors.

I'll explain. I explain. Because some tests have led me to others, that have led me to others, that have led me to others, ...


Test environment


The tests I have carried out have been carried out on the following systems and devices:
  • Windows 7, (version 6.1.7601)
  • Windows 7, (version 6.1.7600)
  • Windows 10, (version 10.0.17763.404)
  • Windows 10, (version 10.0.18343.1)
  • Windows 10, (version 10.0.18890.1000)
  • SanDisk Cruzer Blade 32GB device, (in NTFS format)
The tools I have chosen to determine if a file is resident in the MFT, or not, and to study that type of files, have been:
I have chosen to choose these tools to contrast data, to validate results between one and the other, and thus avoid errors in the interpretation of the same. I consider that Active Disk Editor is a very comfortable option to carry out this study.

The tests


592 bytes resident file; 593 bytes non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

This is the first test that I have carried out, by means of the execution of that batch file that I have mentioned previously. Note that these files have been generated automatically, without going through a text editor, and assigning a long file name. Of all the files that have been created, I have kept two of them.


A file with a size of 592 bytes and a file with a size of 593 bytes.
The 592 bytes file is a MFT resident file while the 593 bytes file is not MFT resident.

As you can see in the image above, the file with a size of 592 bytes does not occupy disk space, while the file with a size of 593 bytes does occupy disk space. Specifically, the file with a size of 593 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

592 bytes resident file


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151)..
  2. Two attributes '$30', ($FILE_NAME):
    • The first attribute '$30', which corresponds to the short filename, starts at byte 152 and has a length of 120 bytes, (up to byte 271).
    • The second attribute '$30', which corresponds to the long filename, starts at byte 272 and has a length of 128 bytes, (up to byte 399).
  3. An attribute '$80', ($DATA), which starts at byte 400 and has a length of 616 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 408, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 424 is the beginning of the content of the file, (21 bytes after the end of the header of this attribute).
  4. The end of the file record is in byte 1016.
  5. The last four bytes of the register have the value '82790200'.

593 bytes non-resident file


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 414.

The attribute '$DATA', which starts at byte 400, has a length of 72 bytes, (up to byte 471).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 408), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 465, and the cluster assigned to it, which is cluster 3.156.345, in byte 466.

The end of the record is in byte 472.

The last four bytes of the record have the value '82794711'.



If I were not conscientious and meticulous, I would have left the matter here, because I already have an answer. But I like to check the tests I do because I like to talk about insurance (as much as possible). So I have continued to run other kinds of tests. And I have taken these files as a reference for the remaining tests.

The next test I carried out was on the USB device. And it is from here that I have set my brain in motion to everything it gives of itself. Why? Because when I created those two files on that device I was surprised that the two files were resident files.

What have I done wrong? What has failed? What have I done wrong? Nothing. I've gone crazy, literally, looking for an explanation, looking at all kinds of configurations and studying a lot of options, until I've found the key, (and never better said).

712 byte resident file; 713 byte non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

It turns out that the USB device I used to perform this other test was formatted on a different system than the ones I usually use. And it turns out that the system in question had a modification that I don't usually use.

The answer? In the modification of a value that is in the key of the beehive of the Registry:
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation'.

Windows allows you to enable or disable the creation of short file names, both on the system volume itself and on external volumes. As a result, the settings are saved to the device. That is to say, if you format a USB device in a system that presents a certain configuration, that configuration is applied to that device, forever, until a new formatting.

This setting, moreover, does not apply retroactively. That is to say, the system files that are recorded in their corresponding MFT will keep all that recorded information and the changes will not be applied until the system is restarted, only for the new records.

Discovered' this, I have proceeded to run, again, that batch file to create hundreds of other files inside that USB device, (and another system that I have modified for this job). Note that these files have been generated automatically, without going through a text editor, and assigning a long file name. Of all the files that have been created, I have kept two of them.

A file with a size of 712 bytes and a file with a size of 713 bytes.
The 712-byte file is an MFT resident file while the 713-byte file is not MFT resident.

As you can see in the image above, the file with a size of 712 bytes does not occupy disk space, while the file with a size of 713 bytes does occupy disk space. Specifically, the file with a size of 713 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

712 bytes resident file


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. An attribute '$30', ($FILE_NAME), which starts at byte 152 and has a length of 128 bytes, (up to byte 279), so it corresponds to the long filename.
  3. An attribute '$80', ($DATA), which starts at byte 280 and has a length of 736 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 288, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 304 is the beginning of the file content, (21 bytes after the end of the header of this attribute).
  4. The end of the file record is in byte 1016.
  5. The last four bytes of the register have the value '82790200'.

Non-resident file of 713 bytes


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 294.

The attribute '$DATA', which starts at byte 280, has a length of 72 bytes, (up to byte 351).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 288), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 345, and the cluster assigned to it, which is cluster 3.150.984, in byte 346.

The end of the record is in byte 352.

The last four bytes of the record have the value '82794711'.


In view of this second test that I have performed, the first conclusion I draw from all this is that, when an attribute is not present, in the record of a file, the space that that absent attribute should occupy is assigned to the attribute '$DATA'

How did I get there? In the test performed with the 592 bytes resident file, the length of the attribute '$DATA' is 616 bytes, while in this test with the 712 bytes resident file, the length of the attribute '$DATA' is 736. So if we subtract '736 - 616' we get a result of 120 bytes, which is, coincidentally, the length of the absent attribute '$30', corresponding to the short file name.

Again, I could have left this here, because I already have another answer with a certain logic. But seeing this... has given me some more thought. To go a little further. So I took a piece of paper and a pencil and started taking notes to see how and under what conditions I can create files.

552 byte resident file; 553 byte non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

So, I've run another test. On this occasion I have created a few text files, (many), manually, with different sizes, assigning, as in the previous cases, a long file name, but the creation has been by editing in the Windows notepad. Of all the files I've created, I've kept two of them.

A file with a size of 552 bytes and a file with a size of 553 bytes.
The 552 byte file is a MFT resident file while the 553 byte file is not MFT resident.

As you can see in the image above, the file with a size of 552 bytes does not occupy disk space, while the file with a size of 553 bytes does occupy disk space. Specifically, the file with a size of 553 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

Resident file of 552 bytes


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. Two attributes '$30', ($FILE_NAME):
    • The first attribute '$30', which corresponds to the short filename, starts at byte 152 and has a length of 120 bytes, (up to byte 271).
    • The second attribute '$30', which corresponds to the long filename, starts at byte 272 and has a length of 128 bytes, (up to byte 399).
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 400 and has a length of 40 bytes, (up to byte 439).
  4. An attribute '$80', ($DATA), which starts at byte 440 and has a length of 676 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 448, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 464 is the beginning of the content of the file, (21 bytes after the end of the header of this attribute).
  5. The end of the file record is in byte 1016.
  6. The last four bytes of the register have the value '82790F00'.

Non-resident file of 553 bytes


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 454.

The attribute '$DATA', which begins in byte 440, has a length of 72 bytes, (up to byte 411).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 448), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 505, and the cluster assigned to it, which is cluster 3.149.052, in byte 506.

The end of the record is in byte 512.

The last four bytes of the record have the value '82794711'.


A new attribute has appeared on the playing field. This is the attribute '$40', which belongs to the '$OBJECT_ID'. A 'curious' detail that appears this attribute only with the edition of the file. Why hasn't it been manifested before?

With this test I am able to affirm, without fear of making a mistake, that the space that an attribute that is absent should occupy is assigned to the attribute '$DATA'.

I continue with my tests... With the options that occur to me... And...

Translated with www.DeepL.com/Translator

672-byte resident file; 673-byte non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

I am changing the value of the registry key again:
'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation', 
to avoid creating short file names in the MFT file records and create the same files as before, assigning a long file name and manually, using the notepad.

Now I only create two files, because I already know how to play this.

If we start from the first of the examples, as a reference file, where the 592 bytes file was a resident file, which has been created automatically and without disabling the generation of short filenames...

592 bytes of the file, added to the 120 bytes that would occupy the attribute '$30', (corresponding to the short file name), and subtracted from 40 bytes, that will occupy the attribute '$40'... we have a result of 672 bytes. That is to say, if I generate two text files, of 672 bytes and 673 bytes, manually, with the notepad, and the generation of short names in the MFT registry is disabled, the first of those files must be resident, but the second must not be resident.

So I keep a file with a size of 672 bytes and a file with a size of 673 bytes.
Así que guardo un archivo con un tamaño de 672 bytes y un archivo con un tamaño de 673 bytes.

As you can see in the image above, the file with a size of 672 bytes does not occupy disk space, while the file with a size of 673 bytes does occupy disk space. Specifically, the file with a size of 673 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

Resident file of 672 bytes


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. An attribute '$30', ($FILE_NAME), which starts at byte 152 and has a length of 128 bytes, (up to byte 279), so it corresponds to the long filename.
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 280 and has a length of 40 bytes, (up to byte 319).
  4. An attribute '$80', ($DATA), which starts at byte 320 and has a length of 696 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 328, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 344 is the beginning of the content of the file, (21 bytes after the end of the header of this attribute).
  5. The end of the file record is in byte 1016.
  6. The last four bytes of the register have the value '82790200'.

673 bytes non-resident file


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 334.

The attribute '$DATA', which begins in byte 320, has a length of 72 bytes, (up to byte 391).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 328), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 385, and the cluster assigned to it, which is cluster 3.156.283, in byte 386.

The end of the record is in byte 392.

The last four bytes of the record have the value '82794711'.


Mmmmm. I find it very curious how the recording of files in the MFT works. I can think of some more things to try...

680-byte resident file; 681-byte non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

On this occasion, I have created two new files, with two different sizes, manually, using the notepad, but this time assigning a short file name. Specifically, an 8-character name.

If we go back to the first example, as a reference file, where the 592 byte file was a resident file, which has been created automatically and without disabling the generation of short file names... and taking into account that the attribute '$30', corresponding to the short file name, occupies 120 bytes, while the attribute '$30', corresponding to the long file name, occupies 128 bytes, ...

592 bytes of the file, added to the 128 bytes that would occupy the attribute '$30', (corresponding to the long file name), and subtracted from 40 bytes, that will occupy the attribute '$40'... we have a result of 680 bytes. That is to say, if I generate two text files, of 680 bytes and 681 bytes, manually, with the notepad, and I assign it a short file name, in the MFT register, the first of those files must be resident, but the second must not be resident.

So I keep a file with a size of 680 bytes and a file with a size of 681 bytes.
The 680-byte file is a file resident in the MFT while the 681-byte file is not resident in the MFT.

As you can see in the image above, the file with a size of 680 bytes does not occupy disk space, while the file with a size of 681 bytes does occupy disk space. Specifically, the file with a size of 681 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

Resident file of 680 bytes


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. An attribute '$30', ($FILE_NAME), which starts at byte 152 and has a length of 120 bytes, (up to byte 271), so it corresponds to the short filename.
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 280 and has a length of 40 bytes, (up to byte 311).
  4. An attribute '$80', ($DATA), which starts at byte 312 and has a length of 704 bytes, (up to byte 1015).
    1. The information that tells us if it is a resident file, or not, is found in byte 320, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 336 is the beginning of the file content, (21 bytes after the end of the header of this attribute).
  5. The end of the file record is in byte 1016.
  6. The last four bytes of the register have the value '82799E00'.

Non-resident file of 681 bytes


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 326.

The attribute '$DATA', which begins in byte 312, has a length of 72 bytes, (up to byte 383).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 320), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 377, and the cluster assigned to it, which is cluster 3.148.935, in byte 378.

The end of the record is in byte 384.

The last four bytes of the record have the value '82794711'.


As we have just seen, when we assign a short file name to a file, only the information corresponding to the short file name attribute '$30' will be recorded in the corresponding record. Why? Because the system does not need more information to complete the information in that file. That's why it dispenses with the 128 bytes that correspond to the attribute '$30', with a long file name.

Now... I wonder if...

What happens if I give it an even shorter name?

696 bytes resident file; 697 bytes non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

On this occasion, I have created two new files, with two different sizes, manually, using the notepad, but this time assigning a short file name. Specifically, a name of only 1 alphanumeric character.

If we go back to the first example, as a reference file, where the 592 byte file was a resident file, which has been created automatically and without disabling the generation of short file names... and taking into account that the attribute '$30', corresponding to the short file name, occupies 120 bytes, while the attribute '$30', corresponding to the long file name, occupies 128 bytes, ...

592 bytes of the file, added to the 128 bytes that would occupy the attribute '$30', (corresponding to the long file name), and subtracted from 40 bytes, that will occupy the attribute '$40'... we have a result of 680 bytes. That is, in this case, if I generate two text files, of 680 bytes and 681 bytes, manually, with the notepad, and I assign it a short file name, in the MFT register, and theoretically, the first of those files should be resident, but the second should not be resident.

But that would be theoretically. Because the '$30' attribute has a maximum size, but it also has a minimum size.

In this particular case, where I have only used an alphanumeric character to name a file...

I keep a file with a size of 696 bytes and a file with a size of 697 bytes. (16 bytes more than in the previous case).
The 696-byte file is an MFT resident file while the 697-byte file is not MFT resident.

As you can see in the image above, the file with a size of 696 bytes does not occupy disk space, while the file with a size of 697 bytes does occupy disk space. Specifically, the file with a size of 697 bytes, occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

Resident file of 696 bytes


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. An attribute '$30', ($FILE_NAME), which starts at byte 152 and has a length of 104 bytes, (up to byte 255), so it corresponds to the short filename.
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 256 and has a length of 40 bytes, (up to byte 295).
  4. An attribute '$80', ($DATA), which starts at byte 296 and has a length of 720 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 304, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 320 is the beginning of the content of the file, (21 bytes after the end of the header of this attribute).
  5. The end of the file record is in byte 1016.
  6. The last four bytes of the register have the value '82790400'.

Non-resident file of 697 bytes


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 310.

The attribute '$DATA', which begins in byte 296, has a length of 72 bytes, (up to byte 367).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 304), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 361, and the cluster assigned to it, which is cluster 3.148.938, in byte 362.

The end of the record is in byte 384.

The last four bytes of the record have the value '82794711'.


Mmmmm... Very curious. I'm going to try to explain it in a simple way.

As I said a little above, the attribute '$30', corresponding to the short filename, has a maximum size of 120 bytes, but also has a minimum size that, if not busy, the system fills with '00'. To see this difference I have created another identical file, but I have assigned a three-digit name. So let's compare three short file names: The file named as 'File0680.txt', the file named as 'A.txt' and the file named as '696.txt'.


In the image above, as you can see, (I hope), is the attribute '$30', relative to the short filename. Within this attribute is at the end, highlighted, the short file name, which begins at byte 92 within this attribute. The filename is the last information recorded in this attribute.

The file named as 'File696.txt', which starts at the same position, (byte 92 within the attribute itself), is composed of 12 unicode characters, which happens to have 24 ASCII characters, because after each character is assigned the value '00', (which corresponds to a '.'). That is, the name of this file has a length of 24 bytes. But, if you look at the image, the system assigns six more hexadecimal values, with values of '00'. So we have a total of 30 bytes.

The file named as 'A.txt', following the same structure as the previous file, is composed of 5 unicode characters, which becomes 10 ASCII characters. But the system marks '00' the last four bytes. That is, the name of this file has a length of 14 bytes.

It is exactly the same with the file '696.txt', which is composed of 7 unicode characters, which happens to have 14 ASCII characters, but in this case the system does not mark the last bytes to '00'. So this file also has a length of 14 bytes.

So, if you subtract the 30 bytes of the file named as 'File696' from the 14 bytes of the files named as 'A.txt' and '696.txt', the difference is 16 bytes. The difference in size between the previous case and this one.

According to these tests, the minimum size reserved for the short filename within the '$30' attribute is 14 bytes. Why does this happen? To see it graphically I have created some files, named as 'A', 'AA', 'AAA', ... up to a total of eight.


The filename information begins in byte 92, inside the attribute itself, which coincides with the third byte of the first octet. The system does not terminate the attribute information until it completes an octet. So the system, when a file name starts an octet, but does not end it, assigns values to '00' until the end of that octet.

So, with the creation of files manually and depending on the length of the short filename, the difference between one resident file and another is not going to be in one byte, but in eight bytes. For example, while a file named as 'A.txt' is resident with a maximum size of 696 bytes, a file named as 'AAAA.txt' will be resident with a maximum size of 688 bytes.

To finish with the possible ways to create files and see their respective sizes to determine when they can be resident files...

728 byte resident file; 729 byte non-resident file


The file on the left corresponds to a resident file. The file on the right corresponds to a non-resident file.

I think I have yet to show what happens to a file with an assigned short name and an automatic creation. To do this, I used the same batch file as in previous tests to create a couple of files. But this time the generation of short file names is disabled, changing the value of the registry key I mentioned before.


Following the same dynamics as in the previous example, a file named 'A.txt' can be resident with a maximum size of 720 bytes, while a file named 'File728.txt' can be resident with a maximum size of 728 bytes. This happens because we have to add the 40 bytes corresponding to the attribute '$40' that we are not going to find in that record.

So, for this example, I keep a file with a size of 728 bytes and a file with a size of 729 bytes.
The 728-byte file is a file resident in the MFT while the 729-byte file is not resident in the MFT.

As you can see in the image above, the file with a size of 728 bytes does not occupy disk space, while the file with a size of 729 bytes does occupy disk space. Specifically, the file with a size of 729 bytes occupies 4096 bytes on disk, which is the size assigned to the cluster, (8 sectors).

Resident file of 728 bytes


In this case, we find the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. An attribute '$30', ($FILE_NAME), which starts at byte 152 and has a length of 112 bytes, (up to byte 263).
  3. An attribute '$80', ($DATA), which starts at byte 264 and has a length of 752 bytes, (up to byte 1015).
    1. The information that indicates if it is a resident file, or not, is found in byte 272, (the fifth byte since the end of the header of this attribute), and presents a value of '00', which indicates that it is resident.
    2. In byte 2884 is the beginning of the file content, (21 bytes after the end of the header of this attribute).
  4. The end of the file record is in byte 1016.
  5. The last four bytes of the register have the value '82790800'.

Non-resident file of 729 bytes


In this case we find the same types of attributes as in the previous case, with some difference. This difference starts from byte 278.

The attribute '$DATA', which begins in byte 264, has a length of 72 bytes, (up to byte 351).

The information that indicates if a file is resident, or not, is found in the same byte as in the previous case, (byte 272), that has a value of '01' and that indicates that it is a non-resident file.

As this file does occupy disk space, it has an assigned cluster. And the record shows that the number of clusters used by that file is one, in byte 329, and the cluster assigned to it, which is cluster 3.187.319, in byte 330.

The end of the record is in byte 336.

The last four bytes of the record have the value '82794711'.


These are the tests that have occurred to me to carry out, as for the creation of files, assigning different lengths of names, generating them of different way and with enable and disable of short file name.

Again, I could have left this matter here, but I need to know how a resident file behaves, when it is edited, when it is modified.

Behavior of a resident file


To carry out this test I have chosen to take the file used as reference for all the others, the file named as '00Fichero592.txt', and edit it, adding in it the word 'Marcos'. Thus, the file goes from a size of 592 bytes to a size of 598 bytes. So it ceases to be a resident file.

After its edition in Windows 7, the file has the following attributes::
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. Two attributes '$30', ($FILE_NAME):
    • The first attribute '$30', which corresponds to the short filename, starts at byte 152 and has a length of 120 bytes, (up to byte 271).
    • The second attribute '$30', which corresponds to the long filename, starts at byte 272 and has a length of 128 bytes, (up to byte 399).
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 400 and has a length of 40 bytes, (up to byte 439).
  4. An attribute '$80', ($DATA), which starts at byte 440 and has a length of 72 bytes, (up to byte 511).
    1. The information that indicates if it is a resident file, or not, is found in byte 448, (the fifth byte since the end of the header of this attribute), and presents a value of '01', which indicates that it is a non-resident file.
    2. The number of clusters used by the file is in byte 505.
    3. The cluster assigned to the file is located in byte 506
  5. The end of the file record is in byte 512.
  6. The last four bytes of the register have the value '82794711'.
The surprise comes after the supposed end of the file record, because the content that existed before in that record can be found in the same way when the file ceases to be a resident file. 


In addition to finding part of the file information in that record, it is also found in the assigned cluster, corresponding to cluster 32.664 in this case.


I edit that same file again, deleting the added word 'Frames', to return it to its original size of 592 bytes. The result is that this file is not a resident file again, although its contents are shown in that record.


And the updated information is also shown in the same cluster that was assigned to it when it is no longer a resident file.


That is to say, in a Windows 7 system, when a resident file is modified so that it ceases to be a resident file, the information will be saved to a new cluster, but it will also keep part of that information in the file registry itself, always maintaining that assigned cluster.

I make the same operation on Windows 10, and after its edition, with a size of 598 bytes, the file happens to have the following attributes:
  1. An attribute '$10', ($TANDARD_INFORMATION), which starts at byte 56 and has a length of 96 bytes, (up to byte 151).
  2. Two attributes '$30', ($FILE_NAME):
    • The first attribute '$30', which corresponds to the short filename, starts at byte 152 and has a length of 120 bytes, (up to byte 271).
    • The second attribute '$30', which corresponds to the long filename, starts at byte 272 and has a length of 128 bytes, (up to byte 399).
  3. An attribute '$40', ($OBJECT_ID), which starts at byte 400 and has a length of 40 bytes, (up to byte 439).
  4. An attribute '$80', ($DATA), which starts at byte 440 and has a length of 72 bytes, (up to byte 511).
    1. The information that indicates if it is a resident file, or not, is found in byte 448, (the fifth byte since the end of the header of this attribute), and presents a value of '01', which indicates that it is a non-resident file.
    2. The number of clusters used by the file is in byte 505.
    3. The cluster assigned to the file is located in byte 506.
  5. The end of the file record is in byte 512.
  6. The last four bytes of the register have the value '82794711'.

After the end of the file record, the information that was previously resident is no longer resident, because it passes in its entirety to the assigned cluster at the moment it exceeds the maximum size for a resident file.


I edit that same file again, deleting the added word so that it has the size of 592 bytes again, and it presents exactly the same information, except for a new cluster where the information of the file is stored. If in the previous example the system assigned cluster 3.264.719 to the file that had ceased to be resident, now it has assigned cluster 50.179, still not being a resident file, despite having the right size to be one.


That is to say, with each edition of a resident file, in a Windows 10 system, a new cluster will be assigned to the information of that file. And that information will remain there until it is overwritten by another record, in case it finds itself without assigning that cluster.

We are finishing with this small work...

Conclusions


Is there a single size for a file to be resident in the MFT or not? No. There is no single size for that condition, because it depends on several factors.

Space that is not used by attributes that are not present in the file record is assigned to the '$DATA' attribute. So, for example, if we have a record without an attribute '$40', which has a length of 40 bytes, those 40 bytes are assigned to the attribute '$DATA', so the file has 40 bytes more for it to be a resident file.

The first factor that influences the size for a file to be resident, or not, is how it is created. If a file is automatically created in the system or device, it will have more space for it to be a resident file than if we create the file by editing it in the system.

If the system is configured so that the short file names (8.3) are not generated in the file register, that file will have 120 bytes more (which are assigned to the attribute '$DATA'), so that it can be a file resident in the MFT.

The disabling or enabling of short file names, (8.3), does not apply retroactively. In other words, if 'X' files with 'X' attributes are stored in the MFT, the system will keep that information until the appropriate reboot and will apply the changes only to the new records.

If an external device, (or any other volume) is formatted in NTFS, that device will save the same configuration as that system, until a new formatting.

In all my tests, at the end of the recording of a non-resident file in the MFT, after the value 'FFFFFFFF', I have obtained the same value '82794711', varying the last two values in case of resident files.

In the case that a short name is assigned to a file, (up to 8 characters), the maximum size for a file to be resident, or not, will depend on the octets that occupy the length of the name, because the system, when it has a name that starts an octet but does not end it, records it at '00' until the end of that octet. A file named with only one character will be resident with the same size as a file named with three characters, for that reason.

I know that you probably haven't read all the content of the text and I know that you like tables for a better understanding. So I leave you a small table with the data I have obtained in my tests.

In the table,
  • Automatic creation means any file created that has not been edited directly by the user.
  • A long name is a file with a name of more than 8 characters.
  • An edition is any file that is created by the user himself, using an editor.
  • A short name is any file whose name consists of 8 characters or less.
  • Understand by 'Without 8.3', every file that has been created, having disabled the short filename creation feature, from the Registry.
First of all I show you the results of my tests, concerning the long file names, with the maximum size so that it can be a resident file and with the size so that it no longer has that condition.


Now I show you another table, with the results obtained from the generation of short filenames, since it depends on the length of the filename, it can be resident with one size or another. As in the previous table, I show you the maximum size for a file to be resident in the MFT and the size for it to cease to be resident, with the length of the filename, since it depends on it for one condition or another to occur.


To finish, I leave below some links of interest and references.

Interesting links and references



If you want to do some tests yourself, you can:
  • Download from here the file to create files of 592 bytes and 593 bytes, with long file name.
  • Download from here the file to create files of 712 bytes and 713 bytes, with long file name, having disabled the generation of short file names, (8.3)
  • Download here the file to create files of 728 bytes and 729 bytes, with short file name, (7 characters).
  • Do your own tests 😉😉



I hope this information is useful to someone. That is all,

Share:
spacer

No hay comentarios:

Publicar un comentario