Commit the initial JSON schema for the intermediate format.

This commit is contained in:
Mike Auty
2016-11-06 01:48:01 +00:00
parent 7b12483719
commit 96a7a56edd
4 changed files with 327 additions and 1 deletions
+34
View File
@@ -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))
+8 -1
View File
@@ -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
+35
View File
@@ -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
+250
View File
@@ -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
}