-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
NTFS - MFT FILE Record.tpl
382 lines (350 loc) · 14.7 KB
/
NTFS - MFT FILE Record.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
template "NTFS - MFT FILE Record"
// Costas Katsavounidis - 2021.1a
// kacos2000 [at] gmail.com
// https://github.com/kacos2000
//
// To be applied to the NTFS Master File Table's (MFT's) FILE records.
// Fix-up values are not corrected/replaced which will result in errors.
description "NTFS - MFT FILE Record"
applies_to file/disk //Can be used with MFT file only
sector-aligned
read-only //Just in case
//multiple 1024
// -------------------------HEADER---------------------------------
begin
Section "Header"
char[4] "Signature" // eg. FILE, BAAD, etc
uint16 "Offset to update sequence"
uint16 "Number of fix up byte pairs" // usually 3
int64 "Logfile sequence number" // LSN
uint16 "MFT Record Sequence Nr." // Number of times this record was re-used
uint16 "Hard-link count"
uint16 "Offset_to_first_attribute"
hex 2 "Flags"
move -2
uint_flex "0" "-Bit 15 - In Use"
move -4
uint_flex "1" "-Bit 14 - 0 = File, 1 = Directory" // Directory = has Index_Root attribute
move -4
uint_flex "2" "-Bit 13 - Is in Extend Directory"
move -4
uint_flex "3" "-Bit 12 - Has View_Index" //(other than I30)
move -2
uint32 "Logical_size_of_this_record"
uint32 "Physical_size_of_this_record"
uint48 "Base record (0= itself)"
uint16 "Base record Sequence Number"
uint16 "Next_available_attribute_ID" // The ID nr that will be assigned to the next attribute
move 2
uint32 "MFT Record Nr" // MFT record Number
goto "Offset to update sequence"
hex 2 "FixUp" // Check or fixup. Must match bytes at 0x1FE & 0x3FE
move -2
uint16 "Update sequence number" // Nr if times the record was updated
hex 2 "Fixup_Value 1" // replaces 0x1FE
hex 2 "Fixup_Value 2" // replaces 0x3FE
endsection // End of Header section
// ------------------------ATTRIBUTES--------------------------------------
//Process General Attribute info
goto Offset_to_first_attribute
numbering 1
{
Section "Attribute #~"
uint32 "Attribute_type"
IfEqual "Attribute_type" 4294967295 // "FFFFFFFF" = end of Attributes
endsection
ExitLoop
EndIf
IfEqual "Attribute_type" 0 // "00000000" = unused or invalid Attribute type
endsection
ExitLoop
EndIf
move -4
hex 4 "Attribute type (Hex)"
uint16 "Attribute_length" // Get the Length of the attribute
IfEqual "Attribute_length" 0 // Skip loop if Length is 0
endsection
ExitLoop
EndIf
move 2
uint8 "Resident_(1=non-resident)"
uint8 "Length_of_Stream_Name" // Nr. of Unicode characters
uint16 "Offset_to_Stream_Name" // From start of the Attribute
uint16 "Attribute Flags"
uint16 "Attribute ID"
uint32 "Size_of_Resident_Content"
uint16 "Content_offset"
IfEqual "Attribute_type" 48
uint8 "Indexed flag (1= Indexed)"
move -23 // Go back to start of the Attribute
else
move -22 // Go back to start of the Attribute
endIf
// Get Stream Name
// ................................................................
IfGreater "Length_of_Stream_Name" 0 // Get Attribute's Stream Name
move Offset_to_Stream_Name
little-endian string16 "Length_of_Stream_Name" "Stream Name (Unicode)"
move (Length_of_Stream_Name*(-2))
hex ((Length_of_Stream_Name)*2) "Stream Name (Hex)"
move (Length_of_Stream_Name*(-2)) // Move back (Stream name length * 2) bytes
move (Offset_to_Stream_Name*(-1)) // move back to Start of the Attribute
EndIf
// Get Stream specific content
// ................................................................
// Stream Name $Info (only in the $UpCase file) since Win 8
IfEqual "Stream Name (Hex)" 0x240049006E0066006F00
move Content_offset
uint32 "Stream content size"
move 4
hex 8 "CRC64"
uint32 "OS Version (Major)"
uint32 "OS Version (Minor)"
uint32 "Windows Build Nr."
uint16 "Service Pack (Major)"
uint16 "Service Pack (Minor)"
move -32
move (Content_offset*(-1))
EndIf
// Stream Name $Max (only in the $UsnJrnl file)
IfEqual "Stream Name (Hex)" 0x24004D0061007800
move Content_offset
int64 "Change Journal - Maximum Size"
int64 "Change Journal - Alloc. Delta Size"
filetime "Change Journal - Creation Time"
int64 "Lowest Valid USN"
move -32
move (Content_offset*(-1))
EndIf
// Stream Name $TXF_DATA
IfEqual "Stream Name (Hex)" 0x24005400580046005F004400410054004100
move Content_offset
uint48 "$MFT Record Nr of RM root"
uint16 "$MFT Record Sequence Nr of RM root"
hex 8 "Flags"
int64 "TxF file ID"
int64 "LSN for NTFS Metadata"
int64 "LSN for User Data"
int64 "LSN for Directory Index"
int64 "USN index"
move -56
move (Content_offset*(-1))
EndIf
// Stream Name $DSC
IfEqual "Stream Name (Hex)" 0x2400440053004300
move Content_offset
uint32 "Storage Tier Class"
uint32 "Flags"
move (Size_of_Resident_Content*(-1))
move (Content_offset*(-1))
EndIf
// Get NON-RESIDENT Attribute info
// ................................................................
IfEqual "Resident_(1=non-resident)" 1
move (Content_offset+(16))
int64 "Start VCN"
int64 "End VCN"
uint16 "Datarun_Offset"
uint16 "Compression Unit Size"
move 4 // Skip padding bytes
int64 "Allocated size"
int64 "Actual size"
int64 "Initialized size"
move -64 // Return to start of the Content
move "Datarun_Offset" // Jump to Datarun offset
hex ((Attribute_length)-(Datarun_Offset)) "Datarun"
move (Datarun_Offset*(-1))
move (((Attribute_length)-(Datarun_Offset))*(-1))
move (Content_offset*(-1)) // Return to start of the Attribute
EndIf
// Get RESIDENT Attribute specific info
// .........................................................
IfEqual "Resident_(1=non-resident)" 0
// Attribute type 0x10: $Standard_Information
// Always Resident
IfEqual "Attribute_type" 16
move Content_offset
FileTime "Creation in UTC"
FileTime "Modification in UTC"
FileTime "Record change in UTC"
FileTime "Last access in UTC"
hexadecimal uint32 Flags // https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
uint32 "Max Nr. of Versions"
uint32 "Version Nr."
move -4
uint8 "1 = Is Case Sensitive"
uint_flex "3,2,1,0" "Reserve Storage ID"
move -1
uint32 "Class ID"
uint32 "Owner ID"
uint32 "Security ID"
int64 "Quota Charged"
int64 "Update sequence number"
move -72
move (Content_offset*(-1))
EndIf
// Attribute type 0x20: $Attribute_List
IfEqual "Attribute_type" 32
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
endIf
// Attribute type 0x30: $File_Name
// Always Resident
IfEqual "Attribute_type" 48
move Content_offset
uint48 "Parent FILE record"
uint16 "Parent Sequence Nr"
FileTime "Creation in UTC"
FileTime "Modification in UTC"
FileTime "Record change in UTC"
FileTime "Last access in UTC"
int64 "File Allocated Size"
int64 "File Real Size"
hex 4 "File Flags" // https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
// +
// 0x10000000 = Directory
// 0x20000000 = Has Index_view
hex 4 "Used by EAs and Reparse"
uint8 "File_name_length" //Nr of unicode characters
uint8 "Filename type" //Namespace
little-endian string16 "File_name_length" "Filename"
move -66
move (File_name_length*(-2))
move (Content_offset*(-1))
EndIf
// Attribute type 0x40: $Object_ID
// Always Resident
IfEqual "Attribute_type" 64
move Content_offset
guid "Object ID" // Get only the main ObjectID
move -16
move (Content_offset*(-1))
EndIf
// Attribute type 0x50: $Security_Descriptor
IfEqual "Attribute_type" 80
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// Attribute type 0x60: $Volume_Name
// Always Resident
IfEqual "Attribute_type" 96
move Content_offset
little-endian string16 (Size_of_Resident_Content/2) "Volume Name"
move (Size_of_Resident_Content*(-1))
move (Content_offset*(-1))
EndIf
// Attribute type 0x70: $Volume_Information
// Always Resident
IfEqual "Attribute_type" 112
move Content_offset
move 8
uint8 "NTFS Major Version"
uint8 "NTFS Minor Version"
hex 2 "Volume Flags"
move -12
move (Content_offset*(-1))
EndIf
// Attribute type 0x80: $Data
IfEqual "Attribute_type" 128
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// Attribute type 0x90: $Index_Root
// Always Resident
// template does not support nested if loops to get index nodes
IfEqual "Attribute_type" 144
move Content_offset
hex 4 "Index_Attribute_type"
hex 4 "Collation_Sorting_Rule"
// "00000000" = "Binary"
// "00000001" = "File Name"
// "00000002" = "Unicode String"
// "00000010" = "Unsigned Long"
// "00000011" = "SID"
// "00000012" = "Security Hash"
// "00000013" = "Multiple Unsigned Longs"
uint32 "Size of Index Record"
uint32 "Nr of Clusters"
uint32 "Offset_to_1st_Entry"
uint32 "Offset_to_end_of_used_buffer"
uint32 "Offset_to_end_of_allocated_buffer"
uint32 "Flag: Index [0] in 0x90, [1] in 0xA0"
move -16
move Offset_to_1st_Entry
hex ((Offset_to_end_of_used_buffer)-(Offset_to_1st_Entry)) "Index Root content"
move (((Offset_to_end_of_used_buffer)-(Offset_to_1st_Entry))*(-1))
move -32
move (Offset_to_1st_Entry*(-1))
move (Content_offset*(-1))
EndIf
// Attribute type 0xA0: $Index_Allocation
// Might be resident (according to $AttrDef)
IfEqual "Attribute_type" 160
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// Attribute type 0xB0: $Bitmap
// Resident (usually when paired with a stream name)
IfEqual "Attribute_type" 176
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// Attribute type 0xC0: Reparse_Point
IfEqual "Attribute_type" 192
move Content_offset
hexadecimal uint32 "Reparse Point Tag"
uint16 "Reparse_Point_Data_Size"
move 2
hex "Reparse_Point_Data_Size" "Reparse Point Data"
move -8
move (Reparse_Point_Data_Size*(-1))
move (Content_offset*(-1))
EndIf
// Attribute type 0xD0: $EA_Information
// Always Resident
IfEqual "Attribute_type" 208
move Content_offset
uint16 "Size of the EA entry"
uint16 "Nr of EAs which NEED_EA set"
uint32 "Size of EA data"
move -8
move (Content_offset*(-1))
EndIf
// Attribute type 0xE0: $EA
IfEqual "Attribute_type" 224
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// Attribute type 0x100: $LOGGED_UTILITY_STREAM
// Always Resident
IfEqual "Attribute_type" 256
move Content_offset
hex Size_of_Resident_Content "Resident Content"
move (Content_offset*(-1))
move (Size_of_Resident_Content*(-1))
EndIf
// --------------------------------------------------------------
EndIf // End non-resident Attribute part
move "Attribute_length"
endsection //End Attribute section
}[((Next_available_attribute_ID)-1)]
// --------------------------------------------------------------------------
Goto 0
ifGreater "Physical_size_of_this_record" 0
move "Physical_size_of_this_record"
else
Move 1024
endIf
end