iptr-decoder

Crates.ioiptr-decoder
lib.rsiptr-decoder
version0.1.2
created_at2026-01-17 14:17:21.692569+00
updated_at2026-01-18 12:03:46.785585+00
descriptionIdiomatic Rust-style low-level Intel PT trace handler.
homepagehttps://github.com/Evian-Zhang/iptr/
repositoryhttps://github.com/Evian-Zhang/iptr/
max_upload_size
id2050495
size104,871
EvianZhang (Evian-Zhang)

documentation

README

iptr-decoder

iptr-decoder is a crate of iptr project, providing idiomatic Rust-style low-level Intel PT trace handling APIs.

To use this crate, add this crate to your Cargo.toml:

[dependencies]
iptr-decoder = "0.1"

Basic usage

The core functionalities are designed within the trait HandlePacket. A typical usage example is like the following code snippet.

use iptr_decoder::{DecoderContext, DecodeOptions, HandlePacket};

struct MyPtHandler;

impl HandlePacket for MyPtHandler {
    // We don't produce high-level errors for simplicity
    type Error = std::convert::Infallible;

    // Required method, will be invoked at the begining of decoding
    fn at_decode_begin(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }

    // One of the provided methods, will be invoked when a short
    // TNT packet is encountered. The actual byte is `packet_byte`, and
    // `highest_bit` refers to the index of highest bit that represents
    // a Taken/Not-Taken bit.
    fn on_short_tnt_packet(
        &mut self,
        context: &DecoderContext,
        packet_byte: std::num::NonZero<u8>,
        highest_bit: u32,
    ) -> Result<(), Self::Error> {
        println!("Short TNT packet get! Byte is {packet_byte:x}");
        Ok(())
    }
}

// Use the defined `MyPtHandler` to decode Intel PT traces
fn handle_pt_trace(pt: &[u8]) {
    let mut packet_handler = MyPtHandler;
    iptr_decoder::decode(pt, DecodeOptions::default(), &mut packet_handler).unwrap();
}

The HandlePacket trait has a lot of provided methods, each of which is corresponding to a type of PT packet. When a PT packet is decoded, the right method will be invoked with extracted values. The default implementation for each packet handlers is an NOP, and you can override each implementation like the code snippet above.

Supported PT packet types

List of supported PT packet types
  • Short TNT
  • Long TNT
  • TIP
  • TIP.PGE
  • TIP.PGD
  • FUP
  • PIP
  • MODE
  • TraceStop
  • CBR
  • TSC
  • MTC
  • TMA
  • CYC
  • VMCS
  • OVF
  • PSB
  • PSBEND
  • MNT
  • PAD
  • PTW
  • EXSTOP
  • MWAIT
  • PWRE
  • RWRX
  • BBP
  • BIP
  • BEP
  • CFE
  • EVD

Advanced Usage

Apart from customized HandlePacket implementors, this crate also provides some common packet handlers, which are organized in the iptr_decoder::packet_handler module.

For example, the PacketHandlerRawLogger logs all packet's information, and PacketCounter can tell us how many PT packets are decoded in total.

Moreover, we provide a powerful CombinedPacketHandler. With this structure, you can use the provided common packet handlers alongwith your own customized HandlePacket implementors:

use iptr_decoder::{
    DecodeOptions, DecoderContext, HandlePacket,
    packet_handler::{combined::CombinedPacketHandler, log::PacketHandlerRawLogger},
};

struct MyPtHandler;
impl HandlePacket for MyPtHandler {
    type Error = std::convert::Infallible;
    fn at_decode_begin(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }
    // Other methods...
}

fn handle_pt_trace(pt: &[u8]) {
    let my_packet_handler = MyPtHandler;
    let log_handler = PacketHandlerRawLogger::default();
    let mut packet_handler = CombinedPacketHandler::new(log_handler, my_packet_handler);
    iptr_decoder::decode(pt, DecodeOptions::default(), &mut packet_handler).unwrap();
}

When running the handle_pt_trace, both the log_handler and my_packet_handler will be invoked, which is very useful when debugging your own packet handler.

If you want to get the branch and basic block information, you can refer to the iptr-edge-analyzer crate, which provides a more comprehensive, complex and efficient solution.

Features

This crate has the following features:

  • log_handler

    Enable iptr_decoder::packet_handler::log, which includes handler for logging low level packets.

    This feature is not enabled by default.

  • alloc

    Enable the alloc dependency. Used only for log_handler feature for now.

    This feature is not enabled by default.

Commit count: 119

cargo fmt