Skip to content

qilinO-o/rWABIDB

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rWABIDB

Instrument WebAssembly Binaries Using Rust. This repository uses Walrus as a parse backend in order to be up-to-date with the latest wasm standards and proposals.

Building

All done by cargo.

Instrumentation

rWABIDB basically provides the ability to modify a wasm binary, which is also potentially useful for individual usage in other projects.

All tests under tests directory give a basic usage of the APIs.

API

Important: All inserted instructions should be carefully designed to maintain a still balanced stack after insertions.

Match-and-Insert Instrumentation

rWABIDB provides a match-and-insert semantic api. It finds expressions in functions that match the Matcher Fn, and insert certain instructions before and after the matching point. A Modifier Fn can be optionally provided to modify the pre and post fragments before each insertion, allowing more dynamic capability.

Note that these targets MUST be orthogonal(Or we say the target in front is matched first).

fn instrument(&mut self, operations: &Vec<InstrumentOperation>) -> InstrumentResult

struct InstrumentOperation {
    pub targets: InstrMatcher,
    pub pre_instructions: Vec<Instr>,
    pub post_instructions: Vec<Instr>,
    pub modifier: Option<FragmentModifier>,
}

type InstrMatcher = Box<dyn Fn(&Instr) -> bool + 'static>;
type FragmentModifier = Box<dyn Fn(&(Instr, InstrLocId), &mut Vec<Instr>, &mut Vec<Instr>) + 'static>;

Match-and-Hook Instrumentation

Similar to the previous one, except it replaces the matched instructions with a call to the hook function.

fn instrument_hook(&mut self, hooks: &Vec<InstrumentHook>) -> InstrumentResult

struct InstrumentHook {
    pub targets: InstrMatcher,
    // Make sure the type of the hook function is identical to that of those target instructions
    pub hook_id: FunctionId,
}

Add & Get Declaration

// Add
fn add_global(&mut self, ty: ValType, mutable: bool, value: Value) -> GlobalId
fn add_memory(&mut self, shared: bool, init_pages: u64, max_pages: Option<u64>) -> MemoryId
fn add_funtion<MakerFn>(&mut self, name: Option<String>, args: &[ValType], locals: &[ValType], rets: &[ValType], func_maker: MakerFn) -> FunctionId 
    where MakerFn: Fn(&mut InstrSeqBuilder, &[LocalId])
fn add_export(&mut self, name: &str, item: impl Into<ExportItem>) -> ExportId

// Get
fn get_global_by_name(&mut self, name: &String) -> Option<&mut Global>
fn get_global_by_id(&mut self, id: GlobalId) -> &mut Global
fn get_memory_by_name(&mut self, name: &String) -> Option<&mut Memory>
fn get_memory_by_id(&mut self, id: MemoryId) -> &mut Memory
fn get_function_by_name(&mut self, name: &String) -> Option<&mut Function>
fn get_function_by_id(&mut self, id: walrus::FunctionId) -> &mut Function
fn get_local_by_id(&self, id: LocalId) -> &Local
fn get_export_by_id(&self, id: ExportId) -> &Export

Print & Write to File

fn print(&mut self)
fn write_binary(&mut self) -> Result<()>
fn get_binary(&mut self) -> Vec<u8>

Scope

instrument() and instrument_hook() will be performed on functions in the scope. The scope contains all defined(unimport) functions of the original binary by default. You can modify the scope using following APIs.

fn function_scope_add(&mut self, func_id: FunctionId) -> bool
fn function_scope_remove(&mut self, func_id: &FunctionId) -> bool
fn function_scope_contains(&mut self, func_id: &FunctionId) -> bool
fn function_scope_clear(&mut self)

Misc

A Rust version of my WABIDB. Rust is good.

About

Instrument WebAssembly Binaries Using Rust

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages