polytracker.tracing

A module defining the abstract classes used for represenging a program trace.

tracing classes

BasicBlock

class polytracker.tracing.BasicBlock(function: Function, index_in_function: int)

Bases: object

A class representing a basic block in an instrumented program.

Note

This is a static basic block instance, not a basic block that is observed during a runtime trace.

For runtime trace events, see BasicBlockEntry.

__init__(function: Function, index_in_function: int)

Initializes a basic block.

Caution

This constructor will call:

function.basic_blocks.append(self)
Parameters:
  • function – The function in which this basic block is contained.

  • index_in_function – An ID for the basic block, unique among all basic blocks in function.

children: Set[BasicBlock]

All basic blocks to which this block can jump.

abstract entries() Iterator[BasicBlockEntry]

Yields all trace events associated with entering this basic block.

is_conditional(trace: ProgramTrace) bool

Returns whether this basic block contains a conditional branch.

is_loop_entry(trace: ProgramTrace) bool

Calculates whether this basic block is an entry to a loop.

predecessors: Set[BasicBlock]

All basic blocks that precede this basic block.

abstract taints() Taints

Returns the set of all taints operated on by this basic block across an entire trace.

BasicBlockEntry

class polytracker.tracing.BasicBlockEntry(uid: int)

Bases: ControlFlowEvent

A trace event associated with entering a basic block.

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

abstract property basic_block: BasicBlock

The basic block that was executing during which this event took place.

property called_function: FunctionInvocation | None

The function invocation called from this basic block, or None if this basic block does not call a function

property consumed_tokens: Iterable[bytes]

The collection of tokens consumed during this basic block event.

This is equivalent to:

tuple(r.value for r in self.taints().regions())
entry_count() int

Calculates the number of times this basic block has been entered in the current stack frame.

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

next_basic_block_in_function() BasicBlockEntry | None

Finds the next basic block in this function in the trace

next_basic_block_in_function_that_touched_taint() BasicBlockEntry | None

Finds the next basic block in this function in the trace that touched taint

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

BasicBlockType

class polytracker.tracing.BasicBlockType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntFlag

Basic block types

This should be kept in parity with the enum in /polytracker/include/polytracker/basic_block_types.h

CONDITIONAL = 2

Any BB that contains a conditional branch

FUNCTION_CALL = 128

A BB that contains a CallInst

FUNCTION_ENTRY = 16

A BB that is the first inside of its function

FUNCTION_EXIT = 32

A BB that exits a function (i.e., it contains a return instruction)

FUNCTION_RETURN = 64

A BB that is executed immediately after a CallInst returns

LOOP_ENTRY = 6

A BB that is an entrypoint into a loop

LOOP_EXIT = 10

A BB that is an exit to a loop

STANDARD = 1

A standard, unremarkable BB

UNKNOWN = 0

We don’t know what kind of BB this is

__contains__(other)

Returns True if self has at least the same flags set as other.

__dir__()

Returns public methods and other interesting attributes.

classmethod __getitem__(name)

Return the member matching name.

__init__(*args, **kwds)
__iter__()

Returns flags in definition order.

static _generate_next_value_(name, start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

classmethod _iter_member_(value)

Extract all members from the value in definition (i.e. increasing value) order.

classmethod _iter_member_by_def_(value)

Extract all members from the value in definition order.

classmethod _iter_member_by_value_(value)

Extract all members from the value in definition (i.e. increasing value) order.

classmethod _missing_(value)

Create a composite member containing all canonical members present in value.

If non-member values are present, result depends on _boundary_ setting.

as_integer_ratio()

Return a pair of integers, whose ratio is equal to the original int.

The ratio is in lowest terms and has a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()

Returns self, the complex conjugate of any int.

denominator

the denominator of a rational number in lowest terms

from_bytes(byteorder='big', *, signed=False)

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag

the imaginary part of a complex number

is_integer()

Returns True. Exists for duck type compatibility with float.is_integer.

numerator

the numerator of a rational number in lowest terms

real

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

ByteAccessType

class polytracker.tracing.ByteAccessType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntFlag

Bitfield enum defining the context in which taints were accessed.

This should be kept in parity with the enum in /polytracker/include/polytracker/output.h

CMP_ACCESS = 2
INPUT_ACCESS = 1
READ_ACCESS = 4
UNKNOWN_ACCESS = 0
__contains__(other)

Returns True if self has at least the same flags set as other.

__dir__()

Returns public methods and other interesting attributes.

classmethod __getitem__(name)

Return the member matching name.

__init__(*args, **kwds)
__iter__()

Returns flags in definition order.

static _generate_next_value_(name, start, count, last_values)

Generate the next value when not given.

name: the name of the member start: the initial start value or None count: the number of existing members last_values: the last value assigned or None

classmethod _iter_member_(value)

Extract all members from the value in definition (i.e. increasing value) order.

classmethod _iter_member_by_def_(value)

Extract all members from the value in definition order.

classmethod _iter_member_by_value_(value)

Extract all members from the value in definition (i.e. increasing value) order.

classmethod _missing_(value)

Create a composite member containing all canonical members present in value.

If non-member values are present, result depends on _boundary_ setting.

as_integer_ratio()

Return a pair of integers, whose ratio is equal to the original int.

The ratio is in lowest terms and has a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()

Returns self, the complex conjugate of any int.

denominator

the denominator of a rational number in lowest terms

from_bytes(byteorder='big', *, signed=False)

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag

the imaginary part of a complex number

is_integer()

Returns True. Exists for duck type compatibility with float.is_integer.

numerator

the numerator of a rational number in lowest terms

real

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

ByteOffset

class polytracker.tracing.ByteOffset(source: Input, offset: int)

Bases: TaintedRegion

A TaintedRegion of length 1.

__bytes__()

Equivalent to self.value

__getitem__(index_or_slice: int | slice) TaintedRegion

Gets a ByteOffset or sliced TaintedRegion from this region

__init__(source: Input, offset: int)

Initializes a tainted region.

Parameters:
  • source – The input that tainted this region.

  • offset – The byte offset of the input in which this region starts.

  • length – The number of bytes in this region.

property value: bytes

The actual bytes from the input file associated with this region.

Raises:

ValueError – If the input did not have its content stored to the database (e.g., if the instrumented binary was run with POLYSAVEINPUT=0) and self.source.path does not exist.

CallIndirect

class polytracker.tracing.CallIndirect(uid: int)

Bases: FunctionEvent

A trace event associated with making an indirect call (ex: function pointers)

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

property basic_block: BasicBlock

The basic block that called return. For the return site of the function, use self.returning_to

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

CallUninst

class polytracker.tracing.CallUninst(uid: int)

Bases: FunctionEvent

A trace event associated with calling an uninstrumented function

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

property basic_block: BasicBlock

The basic block that called return. For the return site of the function, use self.returning_to

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

ControlFlowEvent

class polytracker.tracing.ControlFlowEvent(uid: int)

Bases: TraceEvent

An abstract base class for events that have to do with control flow.

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

abstract property basic_block: BasicBlock

The basic block that was executing during which this event took place.

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

Function

class polytracker.tracing.Function(name: str, function_index: int)

Bases: object

A class representing a function inside of an instrumented program.

Note

This is a static function instance, not a function that is observed during a runtime trace.

For runtime trace events, see FunctionInvocation, FunctionEntry, and FunctionReturn.

__init__(name: str, function_index: int)

Initializes a Function.

Parameters:
  • name – The name of the function

  • function_index – A unique ID for the function.

basic_blocks: List[BasicBlock]

A list of basic blocks contained in this function.

abstract called_from() Set[Function]

Returns the set of functions from which this function is called, potentially including itself (if recursive)

abstract calls_to() Set[Function]

Returns the set of functions to which this function calls, potentially including itself (if recursive).

property demangled_name: str

The demangled name of this function.

abstract taints() Taints

Returns all taints operated on by this function across all invocations of the function in a trace.

FunctionEntry

class polytracker.tracing.FunctionEntry(uid: int)

Bases: FunctionEvent

An abstract class representing the entry into a function.

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

property basic_block: BasicBlock

Returns the entrypoint of this function.

For the basic block that called into this function, use FunctionEntry.caller()

property caller: BasicBlockEntry | None

The BasicBlockEntry event associated with the basic block that called this function.

property entrypoint: BasicBlockEntry | None

Returns the BasicBlockEntry event associated with the first basic block entered in this function.

property function: Function

Returns the function that was called

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

abstract property function_return: FunctionReturn | None

The FunctionReturn event that returned from this function.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

FunctionEvent

class polytracker.tracing.FunctionEvent(uid: int)

Bases: ControlFlowEvent

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

abstract property basic_block: BasicBlock

The basic block that was executing during which this event took place.

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

FunctionInvocation

class polytracker.tracing.FunctionInvocation(function_entry: FunctionEntry)

Bases: ControlFlowEvent

A conglomerated trace event representing an entire function invocation.

This includes associating a FunctionEntry with its FunctionReturn event, and allows for reasoning about any sub-invocations (i.e., other functions called from within this function).

__init__(function_entry: FunctionEntry)

Initializes a function invocation.

Parameters:

function_entry – The function entry event that initiated this invocation.

__iter__() Iterator[BasicBlockEntry | FunctionInvocation]

Iterates all of the basic block entries that took place during this function invocation. Any functions that are called from this function are yielded as a FunctionInvocation.

property basic_block: BasicBlock

The basic block that called to this function.

This is equivalent to:

self.function_entry.basic_block
basic_blocks() Iterator[BasicBlockEntry]

Yields all of the basic blocks executed in this function, not including any basic blocks inside called functions.

calls() Iterator[FunctionInvocation]

Yields all of the functions called inside of this invocation, in order

property function: Function

The function that was executing during which this event took place.

property function_entry: FunctionEntry

The function entry event associated with the stack frame in which this event occurred, if one exists.

property function_return: FunctionReturn | None
property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

taints() Taints

Returns all taints operated on by this function or any functions called by this function.

property touched_taint: bool

Whether or not this event touched taint.

FunctionReturn

class polytracker.tracing.FunctionReturn(uid: int)

Bases: ControlFlowEvent

A trace event associated with returning from a function.

Caution

The function associated with this event is the function to which we are returning, not the function from which we are returning. Use FunctionReturn.returning_from() to get the latter.

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

property basic_block: BasicBlock

The basic block that called return. For the return site of the function, use self.returning_to

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

property returning_from: Function

The function from which we are returning.

property returning_to: BasicBlockEntry | None

The basic block to which the function returned.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

ProgramTrace

class polytracker.tracing.ProgramTrace

Bases: ABC

An abstract class for representing a program trace.

abstract __contains__(uid: int)

Returns whether an event with the given ID exists in this trace.

Equivalent to:

self.has_event(uid)
abstract __getitem__(uid: int) TraceEvent

Returns the trace event associated with the given identifier.

Raises:

KeyError – if the event does not exist.

Equivalent to:

self.get_event(uid)
__init__()
abstract __iter__() Iterator[TraceEvent]

Iterates over all of the events in this trace, in order

abstract __len__() int

Returns the total number of events in this trace

abstract access_sequence() Iterator[TaintAccess]

Yields the taint accesses in this trace, in order.

abstract property basic_blocks: Iterable[BasicBlock]

The static basic blocks operated on by the trace.

property cfg: DiGraph[BasicBlock]

The static control flow graph associated with this trace.

cfg_roots() Iterable[BasicBlock]
property entrypoint: FunctionInvocation | None

Returns the entrypoint to this trace (i.e., its first FunctionInvocation, typically main).

abstract file_offset(node: TaintForestNode) ByteOffset

The file offset associated with a taint forest node

property function_cfg: DiGraph[Function]
function_trace() Iterator[FunctionEntry]

Iterates over all of the FunctionEntry events in this trace.

This is equivalent to:

iter(event for event in self if isinstance(event, FunctionEntry))
abstract property functions: Iterable[Function]

The static functions operated on by the trace.

abstract get_event(uid: int) TraceEvent

Gets a trace event by its ID.

abstract get_function(name: str) Function

Looks up a function by its name.

Raises:

KeyError – if a function of that name was not executed in the trace

abstract has_event(uid: int) bool

Returns whether an event with the given ID exists in this trace.

abstract has_function(name: str) bool

Returns whether a function of the given name was executed in this trace.

input_properties(source: Input) InputProperties
abstract property inputs: Iterable[Input]

The taint sources operated on in this trace.

inputs_affecting_control_flow() Taints

Returns the set of byte offsets that affected control flow

is_cfg_connected() bool

Calculates whether the trace’s control flow graph is connected.

next_function_entry(after: FunctionEntry | None = None) FunctionEntry | None

Returns the next function entry, or None if none exists

abstract property num_accesses: int

The number of taint accesses in this trace.

num_basic_block_entries() int

Returns the number of basic block entries in this trace.

num_function_calls() int

Returns the number of function calls in this trace.

num_function_calls_that_touched_taint() int
abstract property output_taints: Iterable[TaintOutput]

Iterates over all of the outputs written in the trace

abstract property outputs: Iterable[Input] | None

The taint syncs written to in this trace.

abstract property taint_forest: TaintForest

The taint forest associated with this trace.

taints(nodes: Iterable[TaintForestNode]) Taints

TaintAccess

class polytracker.tracing.TaintAccess(access_id: int, event: TraceEvent, label: int, access_type: ByteAccessType)

Bases: object

An abstract class for representing a taint access event.

__init__(access_id: int, event: TraceEvent, label: int, access_type: ByteAccessType)

Initializes a taint access.

Parameters:
  • access_id – A unique, incrementally assigned identifier for this access.

  • event – The trace event associated with this access.

  • label – The taint label accessed.

  • access_type – The type of access.

taints() Taints

Returns the collection of taints associated with this access

TaintDiff

class polytracker.tracing.TaintDiff(taints1: Taints, taints2: Taints)

Bases: object

A diff of two sets of taints.

__bool__()

Equivalent to bool(self.bytes_only_in_first) or bool(self.bytes_only_in_second)

__init__(taints1: Taints, taints2: Taints)

Initializes a taint diff.

Parameters:
  • taints1 – the first set of taints to compare.

  • taints2 – the second set of taints to compare.

property bytes_only_in_first: List[ByteOffset]

Returns a list of all of the tainted byte offsets only in the first set of taints.

property bytes_only_in_second: List[ByteOffset]

Returns a list of all of the tainted byte offsets only in the second set of taints.

property regions_only_in_first: Iterator[TaintedRegion]

Returns a list of all of the tainted byte regions only in the first set of taints.

property regions_only_in_second: Iterator[TaintedRegion]

Returns a list of all of the tainted byte regions only in the second set of taints.

TaintOutput

class polytracker.tracing.TaintOutput(source: Input, output_offset: int, label: int)

Bases: object

An abstract class for representing tainted bytes written to an output (file, network socket, etc).

__init__(source: Input, output_offset: int, label: int)
Parameters:
  • output_offset – offset within the output file

  • label – The taint label of the output

abstract taints() Taints

TaintedChunk

class polytracker.tracing.TaintedChunk(start_offset: int, end_offset: int)

Bases: object

An abstract class for representing tainted input chunks.

__init__(start_offset: int, end_offset: int)

TaintedRegion

class polytracker.tracing.TaintedRegion(source: Input, offset: int, length: int)

Bases: object

Base class representing a tainted region of code

__bytes__()

Equivalent to self.value

__getitem__(index_or_slice: int | slice) TaintedRegion

Gets a ByteOffset or sliced TaintedRegion from this region

__init__(source: Input, offset: int, length: int)

Initializes a tainted region.

Parameters:
  • source – The input that tainted this region.

  • offset – The byte offset of the input in which this region starts.

  • length – The number of bytes in this region.

property value: bytes

The actual bytes from the input file associated with this region.

Raises:

ValueError – If the input did not have its content stored to the database (e.g., if the instrumented binary was run with POLYSAVEINPUT=0) and self.source.path does not exist.

Taints

class polytracker.tracing.Taints(byte_offsets: Iterable[ByteOffset])

Bases: object

A class for representing a collection of tainted regions

__bool__()

Returns whether this taint collection has at least one tainted byte.

This is equivalent to:

bool(len(self))
__contains__(byte_sequence: int | str | bytes)

Checks whether this taint collection contains at least one matching byte sequence.

This is equivalent to:

try:
    next(iter(self.find(byte_sequence)))
    return True
except StopIteration:
    return False
__init__(byte_offsets: Iterable[ByteOffset])

Initializes a taint collection.

Parameters:

byte_offsets – The tainted byte offsets to include in this collection.

__iter__() Iterator[ByteOffset]

Iterates over all of the individual byte offsets in this collection, grouped by source.

Note

The byte offsets are guaranteed to be yielded in increasing order of byte offset per source, but the order of sources is arbitrary.

__len__()

The total number of tainted bytes in this collection.

diff(other: Taints) TaintDiff

Diffs this taint collection with another collection.

This is equivalent to:

TaintDiff(self, other)
Parameters:

other – The other collection against which to compare.

Returns:

The diff of the two taint collections.

find(byte_sequence: int | str | bytes) Iterator[TaintedRegion]

Yields all matching tainted subsequences in this collection.

Parameters:

byte_sequence – The individual byte (int), string (str), or byte sequence (bytes) to find

Returns:

All matching regions in this collection.

from_source(source: Input) Taints

Returns a subset of the taints in this collection that come from a specific source

regions() Iterator[TaintedRegion]

Iterates over all of the contiguous regions of taint in this collection.

The regions are yielded in increasing order of offset.

Caution

The regions will not be grouped by source! Regions from different sources will be intermixed. Use Taints.from_source() if you want to differentiate regions by source.

This is equivalent to:

return Taints.to_regions(self, is_sorted=True)
sources() Set[Input]

Returns the set of sources from which this collection of taints originates.

static to_regions(offsets: Iterable[ByteOffset], is_sorted: bool = False) Iterator[TaintedRegion]

Converts the list of byte offsets into contiguous regions.

TraceEvent

class polytracker.tracing.TraceEvent(uid: int)

Bases: object

An abstract base class for all trace events.

Note

This class should ideally extend off of collections.abc.ABC. The reason why it does not is because it is extended through multiple inheritance in polytracker.database along with a SQLAlchemy base class, and SQLAlchemy does not play well with ABCMeta.

__init__(uid: int)

Initializes a trace event.

Parameters:

uid – An identifier for this event that is unique across the entire trace.

abstract property basic_block: BasicBlock

The basic block that was executing during which this event took place.

property function: Function

The function that was executing during which this event took place.

abstract property function_entry: FunctionEntry | None

The function entry event associated with the stack frame in which this event occurred, if one exists.

property next_control_flow_event: ControlFlowEvent | None

The next control flow event in the trace that occurred in the same thread, if one exists.

abstract property next_event: TraceEvent | None

The next event in the trace that occurred in the same thread, if one exists.

For the next event from any thread, see TraceEvent.next_global_event().

abstract property next_global_event: TraceEvent | None

The next event that occurred in the trace, regardless of thread, if one exists.

property previous_control_flow_event: ControlFlowEvent | None

The previous control flow event in the trace that occurred in the same thread, if one exists.

abstract property previous_event: TraceEvent | None

The previous event in the trace that occurred in the same thread, if one exists.

For the previous event from any thread, see TraceEvent.previous_global_event().

abstract property previous_global_event: TraceEvent | None

The previous event that occurred in the trace, regardless of thread, if one exists.

abstract taints() Taints

The set of taints operated on during this event.

property touched_taint: bool

Whether or not this event touched taint.

tracing functions

common_parent_directory

polytracker.tracing.common_parent_directory(*paths: Path | str) Path

Returns the deepest parent directory common to every path in paths