mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-22 01:24:51 +02:00
Commit the initial JSON schema for the intermediate format.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
from volatility import schemas
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser("Validates ")
|
||||
parser.add_argument("-s", "--schema", dest = "schema", default = None)
|
||||
parser.add_argument("filenames", metavar = "FILE", nargs = '+')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
schema = None
|
||||
if args.schema:
|
||||
basepath = os.path.abspath(os.path.dirname(__file__))
|
||||
with open(os.path.join(basepath, args.schema), 'r') as s:
|
||||
schema = json.load(s)
|
||||
for filename in args.filenames:
|
||||
if os.path.exists(filename):
|
||||
with open(filename, 'r') as t:
|
||||
test = json.load(t)
|
||||
|
||||
if args.schema:
|
||||
result = schemas.valid(test, schema)
|
||||
else:
|
||||
result = schemas.validate(test)
|
||||
|
||||
if result:
|
||||
print("[+] Validation successful: {}".format(filename))
|
||||
else:
|
||||
print("[-] Validation failed: {}".format(filename))
|
||||
else:
|
||||
print("[x] File not found: {}".format(filename))
|
||||
@@ -3,6 +3,7 @@ import json
|
||||
import logging
|
||||
import urllib.parse
|
||||
|
||||
from volatility import schemas
|
||||
from volatility.framework import class_subclasses, constants, exceptions, interfaces, objects
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
@@ -20,7 +21,7 @@ def _construct_delegate_function(name, is_property = False):
|
||||
|
||||
|
||||
class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
def __init__(self, name, idd_filepath, native_types = None):
|
||||
def __init__(self, name, idd_filepath, native_types = None, validate = False):
|
||||
# Check there are no obvious errors
|
||||
url = urllib.parse.urlparse(idd_filepath)
|
||||
if url.scheme != 'file':
|
||||
@@ -33,6 +34,12 @@ class IntermediateSymbolTable(interfaces.symbols.SymbolTableInterface):
|
||||
self._versions = dict([(x.version, x) for x in class_subclasses(ISFormatTable)])
|
||||
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)
|
||||
|
||||
metadata = json_object.get('metadata', None)
|
||||
|
||||
# Determine the delegate or throw an exception
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
vollog = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def validate(input):
|
||||
"""Validates an input JSON file based upon """
|
||||
format = input.get('metadata', {}).get('format', None)
|
||||
if not format:
|
||||
vollog.debug("No schema format defined")
|
||||
return False
|
||||
basepath = os.path.abspath(os.path.dirname(__file__))
|
||||
schema_path = os.path.join(basepath, 'schema-' + format + '.json')
|
||||
if not os.path.exists(schema_path):
|
||||
vollog.debug("Schema for format not found: {}".format(schema_path))
|
||||
return False
|
||||
with open(schema_path, 'r') as s:
|
||||
schema = json.load(s)
|
||||
return valid(input, schema)
|
||||
|
||||
|
||||
def valid(input, schema):
|
||||
"""Validates a json schema"""
|
||||
try:
|
||||
import jsonschema
|
||||
jsonschema.validate(input, schema)
|
||||
except ImportError:
|
||||
vollog.info("Dependency for validation unavailable: jsonschema")
|
||||
vollog.debug("All validations will return true")
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
@@ -0,0 +1,250 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"id": "http://volatilityfoundation.org/intermediate-format/schema",
|
||||
"title": "Symbol Container",
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
"element_metadata": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"format": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]+.[0-9]+.[0-9]+$"
|
||||
},
|
||||
"source": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"producer": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"datetime": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"format"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"element_enum": {
|
||||
"properties": {
|
||||
"length": {
|
||||
"type": "integer"
|
||||
},
|
||||
"base": {
|
||||
"type": "string"
|
||||
},
|
||||
"constants": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"element_symbol": {
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "number"
|
||||
},
|
||||
"linkage_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"requiredProperties": [
|
||||
"address"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"element_base_type": {
|
||||
},
|
||||
"element_user_type": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^(struct|union|class)$"
|
||||
},
|
||||
"length": {
|
||||
"type": "integer"
|
||||
},
|
||||
"fields": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/field"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requiredProperties": [
|
||||
"kind",
|
||||
"length",
|
||||
"fields"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"field": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"$ref": "#/definitions/type_descriptor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type_descriptor": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/type_pointer"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_base"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_array"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_struct"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_enum"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_function"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/type_bitfield"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type_pointer": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^pointer$"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type_base": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^base$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type_array": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^array$"
|
||||
},
|
||||
"subtype": {
|
||||
"$ref": "#/definitions/type_descriptor"
|
||||
},
|
||||
"count": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type_struct": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^(struct|class|union)$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type_enum": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^enum$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"type_function": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^function$"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type_bitfield": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"pattern": "^bitfield$"
|
||||
},
|
||||
"bit_position": {
|
||||
"type": "integer"
|
||||
},
|
||||
"bit_length": {
|
||||
"type": "integer"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/definitions/type_descriptor"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"metadata": {
|
||||
"$ref": "#/definitions/element_metadata"
|
||||
},
|
||||
"base_types": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/element_base_type"
|
||||
}
|
||||
},
|
||||
"user_types": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/element_user_type"
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/element_enum"
|
||||
}
|
||||
},
|
||||
"symbols": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/element_symbol"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"metadata",
|
||||
"base_types",
|
||||
"user_types",
|
||||
"enums",
|
||||
"symbols"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
Reference in New Issue
Block a user