Source code for boofuzz.blocks.block

from ..fuzzable_block import FuzzableBlock
from typing import List


[docs] class Block(FuzzableBlock): """The basic building block. Can contain primitives, sizers, checksums or other blocks. :param name: Name, for referencing later. Names should always be provided, but if not, a default name will be given, defaults to None :type name: str, optional :param default_value: Value used when the element is not being fuzzed - should typically represent a valid value, defaults to None :type default_value: Any, optional :param request: Request this block belongs to, defaults to None :type request: boofuzz.Request, optional :param children: Children of this block, defaults to None :type children: boofuzz.Fuzzable, optional :param group: Name of group to associate this block with, defaults to None :type group: str, optional :param encoder: Optional pointer to a function to pass rendered data to prior to return, defaults to None :type encoder: callable, optional :param dep: Optional primitive whose specific value this block is dependant on, defaults to None :type dep: str, optional :param dep_value: Value that field "dep" must contain for block to be rendered, defaults to None :type dep_value: bytes, optional :param dep_values: Values that field "dep" may contain for block to be rendered, defaults to None :type dep_values: list, optional :param dep_compare: Comparison method to apply to dependency (==, !=, >, >=, <, <=), defaults to None :type dep_compare: str, optional """ def __init__( self, name=None, default_value=None, request=None, children=None, group=None, encoder=None, dep=None, dep_value=None, dep_values=None, dep_compare="==", *args, **kwargs ): if dep_value is not None and not isinstance(dep_value, bytes): raise TypeError("dep_value must be of bytes type") if dep_values is not None and not ( isinstance(dep_values, list) and all(isinstance(x, bytes) for x in dep_values) ): raise TypeError("dep_values must be of list of bytes type") super(Block, self).__init__( name=name, default_value=default_value, request=request, children=children, *args, **kwargs ) self.request = request self.group = group self.encoder = encoder self.dep = dep self.dep_value = dep_value self.dep_values = dep_values self.dep_compare = dep_compare self._rendered = b"" # rendered block contents. self.group_idx = 0 # if this block is tied to a group, the index within that group. self._fuzz_complete = False # whether or not we are done fuzzing this block. self._mutant_index = 0 # current mutation index. def mutations(self, default_value, skip_elements=None): for item in self.stack: self.request.mutant = item for mutations in item.get_mutations(): yield mutations if self.group is not None: group = self.request.resolve_name(self.context_path, self.group) for group_mutations in group.get_mutations(): for item in self.stack: self.request.mutant = item for mutations in item.get_mutations(): yield group_mutations + mutations def num_mutations(self, default_value=None): n = super(Block, self).num_mutations(default_value=default_value) if self.group is not None: n += n * self.request.resolve_name(self.context_path, self.group).get_num_mutations() return n def _do_dependencies_allow_render(self, mutation_context): if self.dep: dependent_value = self.request.resolve_name(self.context_path, self.dep).get_value(mutation_context) if self.dep_compare == "==": if self.dep_values and dependent_value not in self.dep_values: return False elif not self.dep_values and dependent_value != self.dep_value: return False if self.dep_compare == "!=": if self.dep_values and dependent_value in self.dep_values: return False elif dependent_value == self.dep_value: return False if self.dep_compare == ">" and self.dep_value <= dependent_value: return False if self.dep_compare == ">=" and self.dep_value < dependent_value: return False if self.dep_compare == "<" and self.dep_value >= dependent_value: return False if self.dep_compare == "<=" and self.dep_value > dependent_value: return False return True def encode(self, value, mutation_context): if self._do_dependencies_allow_render(mutation_context=mutation_context): child_data = super(Block, self).get_child_data(mutation_context=mutation_context) else: child_data = b"" if self.encoder: return self.encoder(child_data) else: return child_data