Skip to content

Commit 0c80ae4

Browse files
committed
Automagic: Check file datetime to determine whether to recache
1 parent d09f23a commit 0c80ae4

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

volatility3/framework/automagic/symbol_cache.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
33
#
44
import base64
5+
import datetime
56
import json
67
import logging
78
import os
@@ -170,6 +171,7 @@ def __init__(self, filename: str):
170171
def _connect_storage(self, path: str) -> sqlite3.Connection:
171172
database = sqlite3.connect(path)
172173
database.row_factory = sqlite3.Row
174+
173175
database.cursor().execute(
174176
f'CREATE TABLE IF NOT EXISTS database_info (schema_version INT DEFAULT {constants.CACHE_SQLITE_SCHEMA_VERSION})')
175177
schema_version = database.cursor().execute('SELECT schema_version FROM database_info').fetchone()
@@ -259,10 +261,31 @@ def update(self, progress_callback = None):
259261
cache_update = set()
260262
files_to_timestamp = on_disk_locations.intersection(cached_locations)
261263
if files_to_timestamp:
262-
result = self._database.cursor().execute("SELECT location FROM cache WHERE local = 1 "
264+
result = self._database.cursor().execute("SELECT location, cached FROM cache WHERE local = 1 "
263265
f"AND cached < date('now', '{self.cache_period}');")
264266
for row in result:
265-
if row['location'] in files_to_timestamp:
267+
location = row['location']
268+
stored_timestamp = datetime.datetime.fromisoformat(row['cached'])
269+
timestamp = stored_timestamp # Default to requiring update
270+
271+
# See if the file is a local URL type we can handle:
272+
parsed = urllib.parse.urlparse(location)
273+
pathname = None
274+
if parsed.scheme == 'file':
275+
pathname = urllib.request.url2pathname(parsed.path)
276+
if parsed.scheme == 'jar':
277+
inner_url = urllib.parse.urlparse(parsed.path)
278+
if inner_url.scheme == 'file':
279+
pathname = inner_url.path.split('!')[0]
280+
281+
if pathname:
282+
timestamp = datetime.datetime.fromtimestamp(os.stat(pathname).st_mtime)
283+
else:
284+
vollog.log(constants.LOGLEVEL_VVVV,
285+
"File location in database classed as local but not file/jar URL")
286+
287+
# If we're supposed to include it, and our last check is older than (or equal to) the file timestamp
288+
if row['location'] in files_to_timestamp and stored_timestamp < timestamp:
266289
cache_update.add(row['location'])
267290

268291
idextractors = list(framework.class_subclasses(IdentifierProcessor))

0 commit comments

Comments
 (0)