Add in validation caching for JSON schema use and only record success when actual validation occurs.

This commit is contained in:
Mike Auty
2016-11-07 01:17:08 +00:00
parent 96a7a56edd
commit 62fb752c82
3 changed files with 41 additions and 6 deletions
+8 -1
View File
@@ -2,9 +2,16 @@
Stores all the constant values that are generally fixed throughout volatility
This includes default scanning block sizes, etc."""
import os.path
import sys
PLUGINS_PATH = [os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "plugins"))]
BANG = "!"
PACKAGE_VERSION = "3.0.0_alpha1"
if sys.platform == 'windows':
CACHE_PATH = os.path.join(os.environ.get("APPDATA", os.path.expanduser("~")), "volatility3")
else:
CACHE_PATH = os.path.join(os.path.expanduser("~"), ".cache", "volatility3")
os.makedirs(CACHE_PATH, exist_ok = True)
+5 -5
View File
@@ -5,6 +5,7 @@ import urllib.parse
from volatility import schemas
from volatility.framework import class_subclasses, constants, exceptions, interfaces, objects
from volatility.framework.exceptions import SymbolSpaceError
vollog = logging.getLogger(__name__)
@@ -21,7 +22,7 @@ def _construct_delegate_function(name, is_property = False):
class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
def __init__(self, name, idd_filepath, native_types = None, validate = False):
def __init__(self, name, idd_filepath, native_types = None):
# Check there are no obvious errors
url = urllib.parse.urlparse(idd_filepath)
if url.scheme != 'file':
@@ -35,10 +36,9 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
with open(url.path, "r") as fp:
json_object = json.load(fp)
# Validation is expensive, we should either explicitly demand it, or build a caching mechanism
# to store the hashes of successfully validated files
if validate:
schemas.validate(json_object)
# Validation is expensive, but we cache to store the hashes of successfully validated json objects
if not schemas.validate(json_object):
raise SymbolSpaceError("File does not pass version validation: {}".format(url.geturl()))
metadata = json_object.get('metadata', None)
+28
View File
@@ -1,9 +1,32 @@
import hashlib
import json
import logging
import os
from volatility.framework import constants
vollog = logging.getLogger(__name__)
cached_validation_filepath = os.path.join(constants.CACHE_PATH, "valid_idf.cache")
def load_cached_validations():
"""Loads up the list of successfully cached json objects, so we don't need to revalidate them"""
validhashes = set()
if os.path.exists(cached_validation_filepath):
with open(cached_validation_filepath, "r") as f:
validhashes.update(json.load(f))
return validhashes
def record_cached_validations(validations):
"""Record the cached validations, so we don't need to revalidate them in future"""
with open(cached_validation_filepath, "w") as f:
json.dump(list(validations), f)
cached_validations = load_cached_validations()
def validate(input):
"""Validates an input JSON file based upon """
@@ -23,6 +46,9 @@ def validate(input):
def valid(input, schema):
"""Validates a json schema"""
input_hash = hashlib.sha1(bytes(json.dumps(input, sort_keys = True), 'utf-8')).hexdigest()
if input_hash in cached_validations:
return True
try:
import jsonschema
jsonschema.validate(input, schema)
@@ -32,4 +58,6 @@ def valid(input, schema):
return True
except:
return False
cached_validations.add(input_hash)
record_cached_validations(cached_validations)
return True