{"id":13546117,"url":"https://github.com/dwrensha/seer","last_synced_at":"2025-04-05T01:05:49.447Z","repository":{"id":37493420,"uuid":"93796987","full_name":"dwrensha/seer","owner":"dwrensha","description":"symbolic execution engine for Rust","archived":false,"fork":false,"pushed_at":"2018-07-17T02:57:12.000Z","size":634,"stargazers_count":336,"open_issues_count":5,"forks_count":8,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-04-14T07:19:35.822Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dwrensha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-08T22:31:34.000Z","updated_at":"2024-03-18T03:17:34.000Z","dependencies_parsed_at":"2022-08-29T07:41:18.109Z","dependency_job_id":null,"html_url":"https://github.com/dwrensha/seer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwrensha%2Fseer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwrensha%2Fseer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwrensha%2Fseer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwrensha%2Fseer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dwrensha","download_url":"https://codeload.github.com/dwrensha/seer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247271528,"owners_count":20911587,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T12:00:31.982Z","updated_at":"2025-04-05T01:05:49.433Z","avatar_url":"https://github.com/dwrensha.png","language":"Rust","funding_links":[],"categories":["Vulnerability Assessment","Verifiers"],"sub_categories":["Symbolic Execution"],"readme":"# Seer: Symbolic Execution Engine for Rust\n\n[![Build Status](https://travis-ci.org/dwrensha/seer.svg?branch=master)](https://travis-ci.org/dwrensha/seer)\n[![crates.io](http://meritbadge.herokuapp.com/seer)](https://crates.io/crates/seer)\n\nSeer is a fork of [miri](https://github.com/solson/miri)\nthat adds support for symbolic execution, using\n[z3](https://github.com/Z3Prover/z3) as a solver backend.\n\nGiven a program written in Rust, Seer attempts to exhaustively\nenumerate the possible execution paths through it.\nTo achieve this, Seer represents the program's input in a _symbolic_ form,\nmaintaining a set of constraints on it.\nWhen Seer reaches a branch point in the program, it\ninvokes its solver backend to compute which continuations\nare possible given the current constraints. The possible\ncontinuations are then enqueued for exploration, augmented with the\nrespective new constraints learned from the branch condition.\n\nSeer considers any bytes read in through `::std::io::stdin()`\nas symbolic input. This means that once\nSeer finds an interesting input for your program,\nyou can easily compile your program with\nplain rustc and run it on that input.\n\n## example: decode base64 given only an encoder\n\n[[source code](/example/standalone/base64.rs)]\n\nSuppose we are given a base64 encoder function:\n\n```rust\nfn base64_encode(input: \u0026[u8]) -\u003e String { ... }\n```\n\nand suppose that we would like to _decode_ a base64-encoded string,\nbut we don't want to bother to actually write the corresponding\n`base64_decode()` function. We can write the following program and\nask Seer to execute it:\n\n\n```rust\nfn main() {\n    let value_to_decode = \"aGVsbG8gd29ybGQh\";\n    let mut data: Vec\u003cu8\u003e = vec![0; (value_to_decode.len() + 3) / 4 * 3];\n    std::io::stdin().read_exact(\u0026mut data[..]).unwrap();\n\n    let result = base64_encode(\u0026data[..]);\n\n    if result.starts_with(value_to_decode) {\n        panic!(\"we found it!\");\n    }\n}\n```\n\nSeer will then attempt to find input values that can trigger the panic.\nIt succeeds after a few seconds:\n\n```\n$ cargo run --bin seer -- example/standalone/base64.rs\n    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs\n     Running `target/debug/seer example/standalone/base64.rs`\nExecutionComplete { input: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33], result: Err(Panic) }\nas string: Ok(\"hello world!\")\nhit an error. halting\n\n```\n\nThere is our answer! Our string decodes as \"hello world!\"\n\n## using the helper crate\nThe helper crate provides some extra conveniences. The input that triggers a panic can be split by variable and types that implement `Debug` are printed in their debug representation instead of using the underlying bytes:\n\n```rust\n#[macro_use]\nextern crate seer_helper;\nseer_helper_init!();\n\n#[derive(Debug)]\nstruct MyStruct {\n    a: u32,\n    b: u64,\n}\n\nfn main() {\n    let mut t = MyStruct { a: 0, b: 0 };\n    seer_helper::mksym(\u0026mut t);\n    if t.a == 123 \u0026\u0026 t.b == 321 {\n        panic!();\n    }\n}\n```\n\nFor the formatting to work, it is necessary to build MIR for the standard library, so we will use [Xargo](https://github.com/japaric/xargo):\n```\n$ RUSTFLAGS=\"-Z always-encode-mir\" xargo seer\n...\nExecutionComplete { input: [stdin: [], t: \"MyStruct { a: 123, b: 321 }\"], result: Err(NoMirFor(\"std::sys::unix::fast_thread_local::register_dtor::::__cxa_thread_atexit_impl\")) }\nhit an error. halting\n```\n\nThe full example crate can be found [here](/example/seer-helper-user).\n\n# limitations\n\nSeer is currently in the proof-of-concept stage\nand therefore has lots of `unimplemented!()` holes in it.\nIn particular, it does not yet handle:\n\n - allocations with size depending on symbolic input\n - pointer-to-pointer with symbolic offset\n - overflow checking on symbolic arithmetic\n - ... lots of other things that you will quickly discover if you try to use it!\n\n# long-term vision\n\nThe goal is that Seer will help in two primary use cases:\n\n - in exploratory tests, as a complementary approach to [fuzzing](https://github.com/rust-fuzz)\n - in program verification, to exhaustively check that error states cannot be reached\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwrensha%2Fseer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwrensha%2Fseer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwrensha%2Fseer/lists"}