reprospect.testing.binaries.sass.sequence.sequence module
Combine matchers from reprospect.testing.binaries.sass.instruction into sequence matchers.
- class reprospect.testing.binaries.sass.sequence.sequence.AllInSequenceMatcher(matcher)View on GitHub
Bases:
objectUse
InSequenceMatcherto find all matches formatcherin a sequence of instructions.- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | list[list[InstructionMatch]]View on GitHub
- matcher: InSequenceMatcher
- class reprospect.testing.binaries.sass.sequence.sequence.AnyOfMatcher(*matchers: SequenceMatcher | InstructionMatcher)View on GitHub
Bases:
SequenceMatcherMatch any of the
matchers.Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(*matchers: SequenceMatcher | InstructionMatcher) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
Loop over the
matchersand return the first match.
- matchers: Final[tuple[SequenceMatcher | InstructionMatcher, ...]]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.CountInSequenceMatcher(matcher: InstructionMatcher, count: int)View on GitHub
Bases:
SequenceMatcherCount how many times it matches in a sequence.
Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matcher: InstructionMatcher, count: int) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matcher: Final[InstructionMatcher]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.Fluentizer(matcher: InstructionMatcher)View on GitHub
Bases:
InstructionMatcherNote
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matcher: InstructionMatcher) NoneView on GitHub
- final match(inst: Instruction | str) InstructionMatch | NoneView on GitHub
- matcher: Final[InstructionMatcher]
- one_or_more_times() OneOrMoreInSequenceMatcherView on GitHub
Match
matcherone or more times (consecutively).
- times(num: int) InSequenceAtMatcher | OrderedInSequenceMatcherView on GitHub
Match
matchernum times (consecutively).Note
If num is 0, it tests for the absence of a match.
- with_modifier(modifier: str, index: int | None = None) FluentizerView on GitHub
>>> from reprospect.testing.binaries.sass.sequence import instruction_is >>> from reprospect.testing.binaries.sass.instruction import AnyMatcher >>> matcher = instruction_is(AnyMatcher()).with_modifier(modifier='U32').with_operand(index=0, operand='R4') >>> matcher.match(inst='IMAD.WIDE.U32 R4, R7, 0x4, R4') InstructionMatch(opcode='IMAD', modifiers=('WIDE', 'U32'), operands=('R4', 'R7', '0x4', 'R4'), predicate=None, additional=None)
- with_operand(operand: str | AddressMatcher | ConstantMatcher | RegisterMatcher, index: int | None = None) FluentizerView on GitHub
>>> from reprospect.testing.binaries.sass.sequence import instruction_is >>> from reprospect.testing.binaries.sass.instruction import Fp32AddMatcher, RegisterMatcher >>> from reprospect.tools.binaries.sass.decoder import RegisterType >>> matcher = instruction_is(Fp32AddMatcher()).with_operand(index = 1, operand = RegisterMatcher(rtype = RegisterType.GPR, index = 8)) >>> matcher.match(inst = 'FADD R5, R9, R10') >>> matcher.match(inst = 'FADD R5, R8, R9') InstructionMatch(opcode='FADD', modifiers=(), operands=('R5', 'R8', 'R9'), predicate=None, additional={'dst': ['R5']})
- with_operands(operands: Collection[tuple[int, str | AddressMatcher | ConstantMatcher | RegisterMatcher]]) FluentizerView on GitHub
Similar to
with_operand()for many operands.>>> from reprospect.testing.binaries.sass.sequence import instruction_is >>> from reprospect.testing.binaries.sass.instruction import Fp32AddMatcher >>> matcher = instruction_is(Fp32AddMatcher()).with_operands( ... operands = ((1, 'R8'), (2, 'R9')), ... ) >>> matcher.match(inst = 'FADD R5, R9, R10') >>> matcher.match(inst = 'FADD R5, R8, R9') InstructionMatch(opcode='FADD', modifiers=(), operands=('R5', 'R8', 'R9'), predicate=None, additional={'dst': ['R5']})
- zero_or_more_times() ZeroOrMoreInSequenceMatcherView on GitHub
Match
matcherzero or more times (consecutively).
- class reprospect.testing.binaries.sass.sequence.sequence.InSequenceAtMatcher(matcher: InstructionMatcher)View on GitHub
Bases:
SequenceMatcherCheck that the element matches exactly.
Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matcher: InstructionMatcher) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matcher: Final[InstructionMatcher]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.InSequenceMatcher(matcher: SequenceMatcher | InstructionMatcher)View on GitHub
Bases:
SequenceMatcherCheck that a sequence contains an element that matches exactly.
Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matcher: SequenceMatcher | InstructionMatcher) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matcher: Final[SequenceMatcher | InstructionMatcher]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.OneOrMoreInSequenceMatcher(matcher: InstructionMatcher)View on GitHub
Bases:
SequenceMatcherMatch one or more times.
Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matcher: InstructionMatcher) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matcher: Final[InstructionMatcher]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.OrderedInSequenceMatcher(matchers: Iterable[SequenceMatcher | InstructionMatcher])View on GitHub
Bases:
SequenceMatcherMatch a sequence of
matchersin the order they are provided.Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matchers: Iterable[SequenceMatcher | InstructionMatcher]) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matchers: Final[tuple[SequenceMatcher | InstructionMatcher, ...]]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.OrderedInterleavedInSequenceMatcher(matchers: Iterable[SequenceMatcher | InstructionMatcher])View on GitHub
Bases:
SequenceMatcherMatch a sequence of
matchersin the order they are provided, allowing interleaved unmatched instructions in between.Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matchers: Iterable[SequenceMatcher | InstructionMatcher]) NoneView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matchers: Final[tuple[InSequenceMatcher, ...]]
- property next_index: intView on GitHub
- class reprospect.testing.binaries.sass.sequence.sequence.SequenceMatcherView on GitHub
Bases:
ABCBase class for matchers of a sequence of instructions.
- final assert_matches(instructions: Sequence[Instruction | str]) list[InstructionMatch]View on GitHub
Derived matchers are allowed to provide a nice message by implementing
explain().
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- abstractmethod match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
Note
The instructions may be consumed more than once, e.g. in
reprospect.testing.binaries.sass.sequence.sequence.UnorderedInSequenceMatcher. Therefore, it must be atyping.Sequence, not atyping.Iterable.
- abstract property next_index: intView on GitHub
Return the next index in the sequence of instructions that can be matched.
This is the index after the last matched instruction during the last call to
match(), i.e. how far this matcher consumed the sequence “plus one”.The return value is only meaningful if the last call to
match()returned a non-Nonevalue.
- class reprospect.testing.binaries.sass.sequence.sequence.UnorderedInSequenceMatcher(matchers: Iterable[SequenceMatcher | InstructionMatcher])View on GitHub
Bases:
SequenceMatcherMatch a sequence of
matchersin some permutation of the order they are provided.Note
It is not decorated with
dataclasses.dataclass()because of https://github.com/mypyc/mypyc/issues/1061.- __init__(matchers: Iterable[SequenceMatcher | InstructionMatcher]) NoneView on GitHub
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matchers: Final[tuple[SequenceMatcher | InstructionMatcher, ...]]
- property next_index: intView on GitHub
- classmethod search(*, instructions: Sequence[Instruction | str], offset: int, matchers: tuple[SequenceMatcher | InstructionMatcher, ...]) tuple[int, list[InstructionMatch]] | NoneView on GitHub
Backtracking problem.
- class reprospect.testing.binaries.sass.sequence.sequence.UnorderedInterleavedInSequenceMatcher(matchers: Iterable[SequenceMatcher | InstructionMatcher])View on GitHub
Bases:
UnorderedInSequenceMatcherMatch a sequence of
matchersin any order, allowing interleaved unmatched instructions in between.- __init__(matchers: Iterable[SequenceMatcher | InstructionMatcher]) NoneView on GitHub
- matchers: Final[tuple[SequenceMatcher | InstructionMatcher, ...]]
- class reprospect.testing.binaries.sass.sequence.sequence.ZeroOrMoreInSequenceMatcher(matcher: InstructionMatcher)View on GitHub
Bases:
OneOrMoreInSequenceMatcherMatch zero or more times.
- explain(*, instructions: Sequence[Instruction | str]) strView on GitHub
- match(instructions: Sequence[Instruction | str]) list[InstructionMatch] | NoneView on GitHub
- matcher: Final[InstructionMatcher]
- reprospect.testing.binaries.sass.sequence.sequence.any_of(*matchers: InstructionMatcher | SequenceMatcher) AnyOfMatcherView on GitHub
Match a sequence of instructions against any of the matchers.
Note
Returns the first match.
>>> from reprospect.testing.binaries.sass.sequence import any_of >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> matcher = any_of( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... OpcodeModsMatcher(opcode = 'NOP', operands = False), ... ) >>> matcher.match(instructions = ('FADD R1, R1, R2',)) is None True >>> matcher.match(instructions=('NOP',)) is not None True >>> matcher.matched 1
- reprospect.testing.binaries.sass.sequence.sequence.findall(matcher: InstructionMatcher, instructions: Sequence[Instruction | str]) list[InstructionMatch]View on GitHub
- reprospect.testing.binaries.sass.sequence.sequence.findall(matcher: SequenceMatcher, instructions: Sequence[Instruction | str]) list[list[InstructionMatch]]
Find all matches for matcher in a sequence of instructions. Similarly to
re.findall(), return an empty list if no match found.>>> from reprospect.testing.binaries.sass.sequence import findall >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> findall( ... OpcodeModsMatcher(opcode='FADD', operands=True), ... ( ... 'NOP', ... 'FADD R1, R1, R2', ... 'NOP', ... 'FADD R3, R4, R5', ... )) [InstructionMatch(opcode='FADD', modifiers=(), operands=('R1', 'R1', 'R2'), predicate=None, additional=None), InstructionMatch(opcode='FADD', modifiers=(), operands=('R3', 'R4', 'R5'), predicate=None, additional=None)]
- reprospect.testing.binaries.sass.sequence.sequence.findunique(matcher: InstructionMatcher, instructions: Sequence[Instruction | str]) InstructionMatchView on GitHub
- reprospect.testing.binaries.sass.sequence.sequence.findunique(matcher: SequenceMatcher, instructions: Sequence[Instruction | str]) list[InstructionMatch]
Ensure that
findall()matches once.
- reprospect.testing.binaries.sass.sequence.sequence.instruction_count_is(matcher: InstructionMatcher, count: int) CountInSequenceMatcherView on GitHub
Match only if the matcher matches count times in the sequence.
>>> from reprospect.testing.binaries.sass.sequence import instruction_count_is >>> from reprospect.testing.binaries.sass.instruction import Fp32AddMatcher >>> matcher = instruction_count_is(Fp32AddMatcher(), count=2) >>> matcher.match(instructions=('FADD R2, R2, R3',)) >>> matcher.match(instructions=('FADD R2, R2, R3', 'FADD R4, R4, R5')) [InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']}), InstructionMatch(opcode='FADD', modifiers=(), operands=('R4', 'R4', 'R5'), predicate=None, additional={'dst': ['R4']})]
- reprospect.testing.binaries.sass.sequence.sequence.instruction_is(matcher: InstructionMatcher) FluentizerView on GitHub
Match the current instruction with matcher.
>>> from reprospect.testing.binaries.sass.sequence import instruction_is >>> from reprospect.testing.binaries.sass.instruction import Fp32AddMatcher >>> instruction_is(Fp32AddMatcher()).match(inst = 'FADD R2, R2, R3') InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']}) >>> instruction_is(Fp32AddMatcher()).one_or_more_times().match(instructions = ('FADD R2, R2, R3', 'FADD R4, R4, R5')) [InstructionMatch(opcode='FADD', modifiers=(), operands=('R2', 'R2', 'R3'), predicate=None, additional={'dst': ['R2']}), InstructionMatch(opcode='FADD', modifiers=(), operands=('R4', 'R4', 'R5'), predicate=None, additional={'dst': ['R4']})]
- reprospect.testing.binaries.sass.sequence.sequence.instructions_are(*matchers: InstructionMatcher | SequenceMatcher) OrderedInSequenceMatcherView on GitHub
Match a sequence of instructions against matchers.
>>> from reprospect.testing.binaries.sass.sequence import instructions_are >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> instructions_are( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... instruction_is(OpcodeModsMatcher(opcode = 'NOP', operands = False)).zero_or_more_times(), ... ).match(instructions = ('YIELD', 'NOP', 'NOP')) [InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None)]
- reprospect.testing.binaries.sass.sequence.sequence.instructions_contain(matcher: InstructionMatcher | SequenceMatcher) InSequenceMatcherView on GitHub
Check that a sequence of instructions contains at least one instruction matching matcher.
Note
Stops on the first match.
>>> from reprospect.testing.binaries.sass.sequence import instructions_are, instructions_contain >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> matcher = instructions_contain(instructions_are( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... OpcodeModsMatcher(opcode = 'FADD', operands = True), ... )) >>> matcher.match(instructions = ('NOP', 'NOP', 'YIELD', 'FADD R1, R1, R2')) [InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='FADD', modifiers=(), operands=('R1', 'R1', 'R2'), predicate=None, additional=None)] >>> matcher.next_index 4
- reprospect.testing.binaries.sass.sequence.sequence.interleaved_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) OrderedInterleavedInSequenceMatcherView on GitHub
Match a sequence of instructions against matchers, allowing matched instructions to be interleaved with unmatched instructions.
>>> from reprospect.testing.binaries.sass.sequence import interleaved_instructions_are >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> matcher = interleaved_instructions_are( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... OpcodeModsMatcher(opcode = 'NOP', operands = False), ... ) >>> matcher.match(instructions = ('YIELD', 'NOP')) is not None True >>> matcher.match(instructions = ('NOP', 'YIELD')) is None True >>> matcher.match(instructions = ('YIELD', 'FADD R0, R1, R2', 'NOP')) is not None True
- reprospect.testing.binaries.sass.sequence.sequence.unordered_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) UnorderedInSequenceMatcherView on GitHub
Match a sequence of instructions against matchers (unordered).
>>> from reprospect.testing.binaries.sass.sequence import unordered_instructions_are >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> unordered_instructions_are( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... OpcodeModsMatcher(opcode = 'NOP', operands = False), ... ).match(instructions = ('NOP', 'YIELD')) [InstructionMatch(opcode='NOP', modifiers=(), operands=(), predicate=None, additional=None), InstructionMatch(opcode='YIELD', modifiers=(), operands=(), predicate=None, additional=None)]
- reprospect.testing.binaries.sass.sequence.sequence.unordered_interleaved_instructions_are(*matchers: InstructionMatcher | SequenceMatcher) UnorderedInterleavedInSequenceMatcherView on GitHub
Match a sequence of instructions against matchers (unordered), allowing matched instructions to be interleaved with unmatched instructions.
>>> from reprospect.testing.binaries.sass.sequence import unordered_interleaved_instructions_are >>> from reprospect.testing.binaries.sass.instruction import OpcodeModsMatcher >>> matcher = unordered_interleaved_instructions_are( ... OpcodeModsMatcher(opcode = 'YIELD', operands = False), ... OpcodeModsMatcher(opcode = 'NOP', operands = False), ... ) >>> matcher.match(instructions = ('YIELD', 'NOP')) is not None True >>> matcher.match(instructions = ('NOP', 'YIELD')) is not None True >>> matcher.match(instructions = ('YIELD', 'FADD R0, R1, R2', 'NOP')) is not None True >>> matcher.match(instructions = ('YIELD',)) is None True