Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Trailofbits Fickling Trace Run

From Leeroopedia
Knowledge Sources
Domains Security, Reverse_Engineering, Forensics
Last Updated 2026-02-14 14:00 GMT

Overview

Concrete tool for step-by-step pickle VM execution tracing provided by the Fickling library.

Description

The Trace class wraps an Interpreter instance and executes it one opcode at a time via interpreter.step(). After each step, it computes state diffs (stack changes, memo changes, new statements) and invokes callback methods that print the trace to stdout. The run() method drives the full tracing loop and returns the final AST.

Usage

Use this for forensic analysis of suspicious pickle files. Create a Trace from an Interpreter (which must not have been run yet) and call run() to see the full execution trace.

Code Reference

Source Location

  • Repository: fickling
  • File: fickling/tracing.py
  • Lines: L7-66

Signature

class Trace:
    def __init__(self, interpreter: Interpreter):
        """
        Args:
            interpreter: An Interpreter instance that has not been run yet.
        """

    def run(self) -> ast.AST:
        """Execute all opcodes with tracing and return the final AST.

        Side effect: Prints step-by-step trace to stdout showing
        opcode names, stack pushes/pops, memo operations, and
        generated statements.

        Returns:
            ast.AST (same as interpreter.to_ast())
        """

    def on_opcode(self, opcode: Opcode): ...
    def on_pop(self, popped_value: ast.expr | MarkObject): ...
    def on_push(self, pushed_value: ast.expr | MarkObject): ...
    def on_memoize(self, index: int, value: ast.expr): ...
    def on_update_memo(self, index: int, old_value: ast.expr, new_value: ast.expr): ...
    def on_statement(self, statement: ast.stmt): ...

Import

from fickling.tracing import Trace
from fickling.fickle import Interpreter

I/O Contract

Inputs

Name Type Required Description
interpreter Interpreter Yes An Interpreter instance constructed from Pickled; must not have been run yet

Outputs

Name Type Description
run() returns ast.AST The final AST (same as interpreter.to_ast())
Side effect stdout Step-by-step trace printed to stdout

Usage Examples

Trace a Pickle File

from fickling.fickle import Pickled, Interpreter
from fickling.tracing import Trace

with open("suspect.pkl", "rb") as f:
    pickled = Pickled.load(f)

interpreter = Interpreter(pickled)
trace = Trace(interpreter)

# Run with tracing - prints step-by-step to stdout
ast_result = trace.run()

# Also get decompiled source
import ast
print("\n--- Decompiled Source ---")
print(ast.unparse(ast_result))

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment