Skip to content

Commit b15e910

Browse files
committed
Rename methods, add docstrings
Improves the naming of a couple of the new extension class methods to more accurately reflect the return type, and adds docstrings to extensions class methods.
1 parent 8428e81 commit b15e910

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

volatility3/framework/plugins/windows/mftscan.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def parse_standard_information_records(
131131
try:
132132
# There should only be one STANDARD_INFORMATION attribute, but we
133133
# do this just in case.
134-
for std_information in mft_record.standard_information_attributes():
134+
for std_information in mft_record.standard_information_entries():
135135
yield 0, cls.MFTScanResult(
136136
format_hints.Hex(std_information.vol.offset),
137137
str(mft_record.get_signature()),
@@ -162,7 +162,7 @@ def parse_filename_records(
162162

163163
# File Name Attribute
164164
try:
165-
for filename_info in mft_record.filename_attributes():
165+
for filename_info in mft_record.filename_entries():
166166

167167
# If we don't have a valid enum, coerce to hex so we can keep the record
168168
try:

volatility3/framework/symbols/windows/extensions/mft.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def attributes(self) -> Iterator["MFTAttribute"]:
4747
yield from self._attrs
4848

4949
def longest_filename(self) -> Optional[objects.String]:
50-
names = [name.get_full_name() for name in self.filename_attributes()]
50+
names = [name.get_full_name() for name in self.filename_entries()]
5151
if not names:
5252
return None
5353

@@ -91,9 +91,17 @@ def _attributes(self) -> Iterator["MFTAttribute"]:
9191
)
9292
return
9393

94-
def standard_information_attributes(self) -> Iterator[objects.StructType]:
94+
def standard_information_entries(
95+
self,
96+
) -> Iterator[objects.StructType]:
97+
"""
98+
Yields a STANDARD_INFORMATION struct for each of the
99+
STANDARD_INFORMATION attributes in this MFT record (although there
100+
should only be one per record).
101+
"""
95102
for attr in self.attributes:
96-
if attr.Attr_Header.AttrType.lookup() != "STANDARD_INFORMATION":
103+
attr_type = attr.Attr_Header.AttrType.lookup()
104+
if attr_type != "STANDARD_INFORMATION":
97105
continue
98106

99107
si_object = (
@@ -102,10 +110,16 @@ def standard_information_attributes(self) -> Iterator[objects.StructType]:
102110

103111
yield attr.Attr_Data.cast(si_object)
104112

105-
def filename_attributes(self) -> Iterator["MFTFileName"]:
113+
def filename_entries(self) -> Iterator["MFTFileName"]:
114+
"""
115+
Yields an MFT Filename for each of the FILE_NAME attributes contained
116+
in this MFT record. There are often two - one for the long filename,
117+
and the other with the DOS 8.3 short name.
118+
"""
106119
for attr in self.attributes:
107120
try:
108-
if attr.Attr_Header.AttrType.lookup() != "FILE_NAME":
121+
attr_type = attr.Attr_Header.AttrType.lookup()
122+
if attr_type != "FILE_NAME":
109123
continue
110124

111125
fn_object = self.symbol_table_name + constants.BANG + "FILE_NAME_ENTRY"
@@ -128,11 +142,18 @@ def _data_attributes(self):
128142
yield attr
129143

130144
def resident_data_attributes(self) -> Iterator["MFTAttribute"]:
145+
"""
146+
Yields all MFT attributes that contain resident data for the primary
147+
stream.
148+
"""
131149
for attr in self._data_attributes():
132150
if attr.Attr_Header.NameLength == 0:
133151
yield attr
134152

135153
def alternate_data_streams(self) -> Iterator["MFTAttribute"]:
154+
"""
155+
Yields all MFT attributes that contain alternate data streams (ADS).
156+
"""
136157
for attr in self._data_attributes():
137158
if attr.Attr_Header.NameLength != 0:
138159
yield attr
@@ -142,6 +163,9 @@ class MFTFileName(objects.StructType):
142163
"""This represents an MFT $FILE_NAME Attribute"""
143164

144165
def get_full_name(self) -> objects.String:
166+
"""
167+
Returns the UTF-16 decoded filename.
168+
"""
145169
output = self.Name.cast(
146170
"string", encoding="utf16", max_length=self.NameLength * 2, errors="replace"
147171
)
@@ -152,6 +176,9 @@ class MFTAttribute(objects.StructType):
152176
"""This represents an MFT ATTRIBUTE"""
153177

154178
def get_resident_filename(self) -> Optional[objects.String]:
179+
"""
180+
Returns the resident filename (typically for an Alternate Data Stream (ADS)).
181+
"""
155182
# 4MB chosen as cutoff instead of 4KB to allow for recovery from format /L created file systems
156183
# Length as 512 as its 256*2, which is the maximum size for an entire file path, so this is even generous
157184
if (
@@ -178,6 +205,10 @@ def get_resident_filename(self) -> Optional[objects.String]:
178205
return None
179206

180207
def get_resident_filecontent(self) -> Optional[objects.Bytes]:
208+
"""
209+
Returns the file content that is resident within this MFT attribute,
210+
for either the primary or an alternate data stream.
211+
"""
181212
# smear observed in mass testing of samples
182213
# 4MB chosen as cutoff instead of 4KB to allow for recovery from format /L created file systems
183214
if (

0 commit comments

Comments
 (0)