class SqliteTestStruct(rdf_structs.RDFProtoStruct): """Custom struct for testing schema generation.""" type_description = type_info.TypeDescriptorSet( rdf_structs.ProtoString(name="string_field", field_number=1), rdf_structs.ProtoBinary(name="bytes_field", field_number=2), rdf_structs.ProtoUnsignedInteger(name="uint_field", field_number=3), rdf_structs.ProtoSignedInteger(name="int_field", field_number=4), rdf_structs.ProtoFloat(name="float_field", field_number=5), rdf_structs.ProtoDouble(name="double_field", field_number=6), rdf_structs.ProtoEnum(name="enum_field", field_number=7, enum_name="EnumField", enum={ "FIRST": 1, "SECOND": 2 }), rdf_structs.ProtoBoolean(name="bool_field", field_number=8), rdf_structs.ProtoRDFValue(name="urn_field", field_number=9, rdf_type="RDFURN"), rdf_structs.ProtoRDFValue(name="time_field", field_number=10, rdf_type="RDFDatetime"), rdf_structs.ProtoRDFValue(name="time_field_seconds", field_number=11, rdf_type="RDFDatetimeSeconds"), rdf_structs.ProtoRDFValue(name="duration_field", field_number=12, rdf_type="Duration"), rdf_structs.ProtoEmbedded(name="embedded_field", field_number=13, nested=TestEmbeddedStruct))
class FastGrrMessageList(rdf_structs.RDFProtoStruct): """A Faster implementation of GrrMessageList.""" type_description = type_info.TypeDescriptorSet( rdf_structs.ProtoList( rdf_structs.ProtoEmbedded( name="job", field_number=1, nested=StructGrrMessage)))
def _GenerateOutputClass(self, class_name, tables): """Generates output class with a given name for a given set of tables.""" output_class = type(utils.SmartStr(class_name), (rdfvalue.RDFProtoStruct, ), {}) if not tables: raise RuntimeError( "Can't generate output class without Rekall table " "definition.") field_number = 1 output_class.AddDescriptor( structs.ProtoEmbedded(name="metadata", field_number=field_number, nested=rdfvalue.ExportedMetadata)) field_number += 1 output_class.AddDescriptor( structs.ProtoString(name="section_name", field_number=field_number)) field_number += 1 output_class.AddDescriptor( structs.ProtoString(name="text", field_number=field_number)) # All the tables are merged into one. This is done so that if plugin # outputs multiple tables, we get all possible columns in the output # RDFValue. used_names = set() for table in tables: for column_header in table: column_name = None try: column_name = column_header["cname"] except KeyError: pass if not column_name: column_name = column_header["name"] if not column_name: raise RuntimeError( "Can't determine column name in table header.") if column_name in used_names: continue field_number += 1 used_names.add(column_name) output_class.AddDescriptor( structs.ProtoString(name=column_name, field_number=field_number)) return output_class
def _GenerateOutputClass(self, class_name, context_dict): """Generates output class with a given name for a given context.""" output_class = type(utils.SmartStr(class_name), (rdfvalue.RDFProtoStruct, ), {}) if "t" not in context_dict: raise RuntimeError( "Can't generate output class without Rekall table " "definition.") field_number = 1 output_class.AddDescriptor( structs.ProtoEmbedded(name="metadata", field_number=field_number, nested=rdfvalue.ExportedMetadata)) field_number += 1 output_class.AddDescriptor( structs.ProtoString(name="section_name", field_number=field_number)) field_number += 1 output_class.AddDescriptor( structs.ProtoString(name="text", field_number=field_number)) for column_header in context_dict["t"]: field_number += 1 column_name = None try: column_name = column_header["cname"] except KeyError: pass if not column_name: column_name = column_header["name"] if not column_name: raise RuntimeError( "Can't determine column name in table header.") output_class.AddDescriptor( structs.ProtoString(name=column_name, field_number=field_number)) return output_class
def MakeFlatRDFClass(self, value): """Generates flattened RDFValue class definition for the given value.""" def Flatten(self, metadata, value_to_flatten): if metadata: self.metadata = metadata for desc in value_to_flatten.type_infos: if desc.name == "metadata": continue if hasattr(self, desc.name) and value_to_flatten.HasField( desc.name): setattr(self, desc.name, getattr(value_to_flatten, desc.name)) output_class = type(self.ExportedClassNameForValue(value), (rdf_structs.RDFProtoStruct, ), dict(Flatten=Flatten)) # Metadata is always the first field of exported data. output_class.AddDescriptor( rdf_structs.ProtoEmbedded(name="metadata", field_number=1, nested=ExportedMetadata)) for number, desc in sorted(value.type_infos_by_field_number.items()): # Name 'metadata' is reserved to store ExportedMetadata value. if desc.name == "metadata": logging.debug("Ignoring 'metadata' field in %s.", value.__class__.__name__) continue # Copy descriptors for primivie values as-is, just make sure their # field number is correct. if isinstance( desc, (type_info.ProtoBinary, type_info.ProtoString, type_info.ProtoUnsignedInteger, type_info.ProtoEnum)): # Incrementing field number by 1, as 1 is always occuppied by metadata. output_class.AddDescriptor(desc.Copy(field_number=number + 1)) if (isinstance(desc, type_info.ProtoEnum) and not isinstance(desc, type_info.ProtoBoolean)): # Attach the enum container to the class for easy reference: setattr(output_class, desc.enum_name, desc.enum_container) return output_class
class LateBindingTest(structs.RDFProtoStruct): type_description = type_info.TypeDescriptorSet( # A nested protobuf referring to an undefined type. structs.ProtoEmbedded(name="nested", field_number=1, nested="UndefinedYet"), structs.ProtoRDFValue(name="rdfvalue", field_number=6, rdf_type="UndefinedRDFValue", description="An undefined RDFValue field."), # A repeated late bound field. structs.ProtoList( structs.ProtoRDFValue(name="repeated", field_number=7, rdf_type="UndefinedRDFValue2", description="An undefined RDFValue field.")), )
class DynamicTypeTest(structs.RDFProtoStruct): """A protobuf with dynamic types.""" type_description = type_info.TypeDescriptorSet( structs.ProtoString( name="type", field_number=1, # By default return the TestStruct proto. default="TestStruct", description="A string value"), structs.ProtoDynamicEmbedded( name="dynamic", # The callback here returns the type specified by the type member. dynamic_cb=lambda x: structs.RDFProtoStruct.classes.get(x.type), field_number=2, description="A dynamic value based on another field."), structs.ProtoEmbedded( name="nested", field_number=3, nested=rdf_client.User))
field_number=7, enum_name="Type", enum=dict(FIRST=1, SECOND=2, THIRD=3), default=3, description="An enum field"), structs.ProtoFloat(name="float", field_number=8, description="A float number", default=1.1), ) # In order to define a recursive structure we must add it manually after the # class definition. TestStruct.AddDescriptor( structs.ProtoEmbedded(name="nested", field_number=4, nested=TestStruct), ) TestStruct.AddDescriptor( structs.ProtoList( structs.ProtoEmbedded(name="repeat_nested", field_number=5, nested=TestStruct)), ) class PartialTest1(structs.RDFProtoStruct): """This is a protobuf with fewer fields than TestStruct.""" type_description = type_info.TypeDescriptorSet( structs.ProtoUnsignedInteger(name="int", field_number=2), ) class DynamicTypeTest(structs.RDFProtoStruct):