A Rust library for tracing executable memory in Linux userspace using eBPF.
It tracks syscalls like mmap
and mprotect
to monitor memory regions that gain execution permissions, and dumps their contents for further analysis.
- Structure
- Requirements
- Building
- Usage
- Example
- Project Architecture
- eBPF Internals
- Testing
- CI
- Limitations and Future Work
- Acknowledgments
- License
emt/
├── src/
│ ├── lib.rs # Main library interface
│ ├── tracer.rs # Tracer lifecycle management
│ ├── bpf_runtime.rs # eBPF program management
│ ├── event_handler.rs # Memory event processing
│ ├── models.rs # Data structures (Event, EventType, Page)
│ ├── error.rs # Error types and handling
│ ├── utils.rs # Utility functions
│ └── bpf/
│ └── memory_tracer.bpf.c # eBPF program for kernel-space tracing
├── examples/
│ ├── example.rs # Basic usage example
│ ├── test_memory_changes.rs # Test program with dynamic memory operations
│ └── test_file_mapping.rs # Test program for file-backed memory mapping
├── tests/
│ ├── integration_test.rs # Integration tests
│ └── common/
│ └── mod.rs # Common test utilities
├── docs/ # Detailed documentations
├── build.rs # Build script for this project
├── Cargo.toml # Project dependencies and configuration
└── README.md # Project documentation
- Rust
- Clang/LLVM and libbpf
- Linux kernel with BPF support
- Root privileges or CAP_BPF or CAP_SYS_ADMIN
- bpftool
# 0. Install packages required on Ubuntu 24.04.2 LTS
sudo apt install rustup libbpf-dev llvm clang pkg-config
# 1. Clone
git clone [email protected]:ma/emt.git && cd emt
# 2. Build
cargo build --release
# 3. Test
sudo cargo test
use emt::Tracer;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tracer = Tracer::new(2077);
// start tracing
tracer.start()?;
// monitor for a while
std::thread::sleep(std::time::Duration::from_secs(10));
// stop and collect results
let pages = tracer.stop()?;
// analysis captured pages
for page in pages {
println!(
"0x{:016x} - 0x{:016x} - {} bytes",
page.addr,
page.addr + page.size - 1,
page.size
);
}
Ok(())
}
- Target process, see test_memory_changes.rs
# copy the output PID
cargo run --example test_memory_changes
- Tracer process, see example.rs
# paste the PID here
sudo cargo run --example example [PID]
Expected output:
Page 1: 0x00000000158a0000 - 0x00000000158a0fff (4096 bytes) at 2077-10-23 03:39:31.124
Content: 43 79 63 6c 65 20 33 20 2d 20 50 52 45 2d 50 52 ...
Page 2: 0x0000000015910000 - 0x0000000015910fff (4096 bytes) at 2077-10-23 03:39:30.123
Content: 43 79 63 6c 65 20 32 20 2d 20 50 52 45 2d 50 52 ...
see architecture.md
see ebpf.md
see testing.md
see CI.md
see limitations_and_future_work.md
This project was developed under the supervision of Prof. Aurélien Francillon and Marco Cavenati at EURECOM during Spring 2025.
With the exception of eBPF code, everything is distributed under the terms of the MIT license.
All eBPF code is distributed under the terms of the GPL-2.0-only.