fix: update unicorn-engine API and improve justfile discoverability

- Update test.rs to use unicorn-engine 2.x API:
  - Replace Permission with Prot for memory permissions
  - Change mem_map/mem_protect size parameter from usize to u64
  - Use bitwise OR instead of insert() for Prot flags

- Reorganize justfile for better discoverability:
  - Add help command showing all available recipes
  - Add ci recipe that runs full lint + test pipeline
  - Align recipes with CI workflow (nightly for fmt/clippy)
  - Organize into clear sections: build, lint, test, dev
  - Add fmt-check for formatting verification without changes
This commit is contained in:
Claude 2026-01-07 08:46:34 +00:00 committed by Willi Ballenthin
parent 87dc6a57ce
commit 2a07b8611c
2 changed files with 140 additions and 56 deletions

View file

@ -101,7 +101,7 @@ pub fn emu_from_shellcode32(code: &[u8]) -> crate::emu::Emulator {
#[cfg(test)]
pub mod uc {
use byteorder::{ByteOrder, LittleEndian};
use unicorn_engine::unicorn_const::{uc_error, Arch, Mode, Permission};
use unicorn_engine::unicorn_const::{uc_error, Arch, Mode, Prot};
use super::load_shellcode64;
use crate::{
@ -127,8 +127,8 @@ pub mod uc {
let section_size = section.virtual_range.end - section.virtual_range.start;
emu.mem_map(
section.virtual_range.start,
crate::util::align(section_size, PAGE_SIZE as u64) as usize,
Permission::WRITE,
crate::util::align(section_size, PAGE_SIZE as u64),
Prot::WRITE,
)
.unwrap();
@ -147,20 +147,20 @@ pub mod uc {
page_addr += PAGE_SIZE as u64;
}
let mut prot = Permission::NONE;
let mut prot = Prot::NONE;
if section.permissions.intersects(Permissions::W) {
prot.insert(Permission::WRITE);
prot = prot | Prot::WRITE;
}
if section.permissions.intersects(Permissions::R) {
prot.insert(Permission::READ);
prot = prot | Prot::READ;
}
if section.permissions.intersects(Permissions::X) {
prot.insert(Permission::EXEC);
prot = prot | Prot::EXEC;
}
emu.mem_protect(
section.virtual_range.start,
crate::util::align(section_size, PAGE_SIZE as u64) as usize,
crate::util::align(section_size, PAGE_SIZE as u64),
prot,
)
.unwrap();
@ -294,7 +294,7 @@ pub mod uc {
.reg_write(unicorn_engine::RegisterX86::RIP, m.address_space.base_address)
.unwrap(); // 0x0
uc.emu.mem_map(0x5000, 0x2000, Permission::ALL).unwrap();
uc.emu.mem_map(0x5000, 0x2000, Prot::ALL).unwrap();
uc.emu.reg_write(unicorn_engine::RegisterX86::RSP, 0x6000).unwrap();
uc.emu.reg_write(unicorn_engine::RegisterX86::RBP, 0x6000).unwrap();

178
justfile
View file

@ -1,4 +1,134 @@
# build with various profiles to populate the rustc cache
# lancelot justfile - run `just` or `just help` to see available commands
# Default recipe - show help
default: help
# Show available commands
help:
@echo "lancelot build system"
@echo ""
@echo "Usage: just <recipe>"
@echo ""
@echo "Common recipes:"
@echo " build - Build the project (stable toolchain)"
@echo " build-release - Build with optimizations"
@echo " test - Run all tests"
@echo " lint - Run all lints (check, clippy, fmt)"
@echo " ci - Run full CI pipeline (lint + test)"
@echo ""
@echo "Individual lint recipes:"
@echo " check - Run cargo check"
@echo " clippy - Run clippy lints"
@echo " fmt - Run rustfmt"
@echo " fmt-check - Check formatting without modifying"
@echo ""
@echo "Individual test recipes:"
@echo " test-core - Test lancelot core library"
@echo " test-flirt - Test lancelot-flirt library"
@echo " test-pylancelot - Test pylancelot (Rust + Python)"
@echo " test-pyflirt - Test pyflirt (Rust + Python)"
@echo ""
@echo "Development recipes (uses cranelift for faster builds, requires nightly):"
@echo " dev-build - Fast build with cranelift"
@echo " dev-check - Fast check with cranelift"
@echo " warmup - Populate rustc cache with various profiles"
# ============================================================================
# Main build recipes
# ============================================================================
# Build the project (stable toolchain)
build:
cargo build
# Build with optimizations
build-release:
cargo build --release
# ============================================================================
# Lint recipes (matches CI workflow)
# ============================================================================
# Run cargo check
check:
cargo check
# Run clippy with warnings as errors (requires nightly)
clippy:
cargo +nightly clippy -- -D warnings
# Format code with rustfmt (requires nightly for all features)
fmt:
cargo +nightly fmt --all
# Check formatting without modifying files
fmt-check:
cargo +nightly fmt --all -- --check
# Run all lints: check, clippy, and format check
lint: check clippy fmt-check
# ============================================================================
# Test recipes (matches CI workflow)
# ============================================================================
# Run all tests
test: test-core test-flirt test-pylancelot test-pyflirt
# Test lancelot core library
test-core:
cargo test -p lancelot
# Test lancelot-flirt library
test-flirt:
cargo test -p lancelot-flirt
# Test pylancelot Rust code
test-pylancelot-rs:
cd pylancelot && cargo test
# Test pylancelot Python code
test-pylancelot-py:
bash .github/scripts/pytest-pylancelot.sh
# Test pylancelot (both Rust and Python)
test-pylancelot: test-pylancelot-rs test-pylancelot-py
# Test pyflirt Rust code
test-pyflirt-rs:
cd pyflirt && cargo test
# Test pyflirt Python code
test-pyflirt-py:
bash .github/scripts/pytest-pyflirt.sh
# Test pyflirt (both Rust and Python)
test-pyflirt: test-pyflirt-rs test-pyflirt-py
# ============================================================================
# CI recipe - run the full pipeline
# ============================================================================
# Run full CI pipeline (matches GitHub Actions workflow)
ci: lint test
# ============================================================================
# Development recipes (optional - uses cranelift for faster builds)
# ============================================================================
# Fast build with cranelift (requires nightly)
dev-build:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend
# Fast check with cranelift (requires nightly)
dev-check:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly check -Zcodegen-backend
# Fast clippy with cranelift (requires nightly)
dev-clippy:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly clippy -Zcodegen-backend
# Build with various profiles to populate the rustc cache
warmup:
# build with cranelift
-env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend
@ -6,52 +136,6 @@ warmup:
-cargo build
# build in release profile
-cargo build --release
# build unicorn dep, which is only used in tests, and takes a while
-cd core && env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly test -Zcodegen-backend
-cd core && cargo test
check:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly check -Zcodegen-backend
clippy:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly clippy -Zcodegen-backend
fmt:
cargo +nightly fmt
lint: check clippy fmt
test-core:
cd core && \
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly test -Zcodegen-backend
test-flirt:
cd flirt && \
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly test -Zcodegen-backend
test-pylancelot-rs:
cd pylancelot && \
cargo test # can't use cranelift when linking to python
test-pylancelot-py:
bash .github/scripts/pytest-pylancelot.sh
test-pylancelot: test-pylancelot-rs test-pylancelot-py
test-pyflirt-rs:
cd pyflirt && \
cargo test # can't use cranelift when linking to python
test-pyflirt-py:
bash .github/scripts/pytest-pyflirt.sh
test-pyflirt: test-pyflirt-rs test-pyflirt-py
test: test-core test-flirt test-pylancelot test-pyflirt
build:
env CARGO_PROFILE_DEV_CODEGEN_BACKEND=cranelift cargo +nightly build -Zcodegen-backend
build-release:
cargo build --release