В последнее время я возился с NTFS, чтобы выполнить быстрый поиск (путем анализа MFT), который должен обнаруживать файлы с определенными расширениями (даже если они были удалены) и находить их путь. Первая странная вещь, с которой я столкнулся, - это то, что во всех случаях, которые я видел (3), диск C содержит много недопустимых записей MFT (более 3/4). Большинство из них (если не все) не проходят проверку подписи.
Обычно я думаю, что эти записи не используются, но есть еще одна проблема, которая заставляет меня думать, что что-то не так: когда все записи файлов с требуемым расширением найдены, некоторые записи указывают на родительские записи MFT, которые не проходят проверку из-за та же самая причина. Но файлы помечены как «используемые», и я вижу их в проводнике. Кроме того, еще одна странность заключается в том, что каталог, в котором они находятся, действителен, поскольку есть файлы, которые находятся в том же каталоге / подкаталогах, которые указывают на допустимые каталоги (например, у меня есть файл log.txt, который находится на рабочем столе и указывает на недопустимая запись файла. Существует также папка data (на рабочем столе тоже), которая содержит файл info.txt, а «data» указывает на допустимую запись файла).
Проверка подписи (упрощенная):
struct FILE_RECORD_HEADER
{
uint32 Magic; //Should match FILE_RECORD_SIGNATURE
uint16 OffsetOfUS; //Offset of Update Sequence
uint16 SizeOfUS; //Size in 2-byte ints of Update Sequence Number & Array
uint64 LSN; //$LogFile Sequence Number
uint16 SeqNo; //Sequence number
uint16 Hardlinks; //Hard link count
uint16 OffsetOfAttr; //Offset of the first Attribute
uint16 Flags; //Flags
uint32 RealSize; //Real size of the FILE record
uint32 AllocSize; //Allocated size of the FILE record
uint64 RefToBase; //File reference to the base FILE record. Low 6B - file reference, high 2B - MFT record sequence number
uint16 NextAttrId; //Next Attribute Id
uint16 Align; //Align to 4 uint8 boundary
uint32 RecordNo; //Number of this MFT Record
};
#define FILE_RECORD_SIGNATURE 'ELIF'
FILE_RECORD_HEADER * header = (FILE_RECORD_HEADER *)rawFileRecord; //where rawFileRecord is a pointer to a block of memory in which a file record is stored
if(header->Magic != FILE_RECORD_SIGNATURE) //The file record is invalid
Получение LCN родителя:
struct ATTR_FILE_NAME
{
uint64 ParentRef; //File reference to the parent directory. Low 6B - file reference, high 2B - MFT record sequence number
uint64 CreateTime; //File creation time
uint64 AlterTime; //File altered time
uint64 MFTTime; //MFT changed time
uint64 ReadTime; //File read time
uint64 AllocSize; //Allocated size of the file
uint64 RealSize; //Real size of the file
uint32 Flags; //Flags
uint32 ER; //Used by EAs and Reparse
uint8 NameLength; //Filename length in characters
uint8 NameSpace; //Filename space
uint16 Name[1]; //Filename
};
ATTR_FILE_NAME * attr = (ATTR_FILE_NAME*)filenameAttr; //where filenameAttr is a pointer to the beginning of filename attribute somewhere in the rawFileRecord
uint64 parentLCN = attr->ParentRef & 0x0000FFFFFFFFFFFF;
Возможно ли потерять (с точки зрения поиска) файлы из-за несоответствия подписи (думаю, да, но хочу быть уверенным)? Почему одни записи файлов указывают на недопустимых родителей, а другие - на действительных (предполагается, что они имеют одного и того же родителя)?