1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#![recursion_limit = "128"]

//! Falcon: A Binary Analysis Framework in Rust.
//!
//! Falcon is a framework in rust for implementing formal analyses over binary
//! programs. A quick synopsis of Falcon's modules:
//!
//! * **analysis** - A fixed-point engine and methods for abstract interpretation
//! over Falcon IL. Example, usable analyses are given.
//! * **architecture** - Information on Falcon's supported architectures.
//! * **executor** - A concrete execution engine over Falcon IL.
//! * **graph** - A simple directed graph library.
//! * **il** - Falcon's Intermediate Language.
//! * **loader** - Loaders for binary formats, currently supporting Elf.
//! * **memory** - A layered memory model over generic types.
//! * **translator** - Translators from native architectures to Falcon IL.
//!
//! Falcon also has bindings for the scripting language
//! [gluon](https://github.com/gluon-lang/gluon), which makes exploratory
//! analysis over Falcon quick and pleasant.
//!
//! ```
//! # use falcon::error::*;
//! use falcon::loader::Elf;
//! use falcon::loader::Loader;
//! use std::path::Path;
//!
//! # fn example () -> Result<()> {
//! let elf = Elf::from_file(Path::new("test_binaries/simple-0/simple-0"))?;
//! for function in elf.program()?.functions() {
//!     for block in function.blocks() {
//!         println!("Block {} in Function {:x}", block.index(), function.address());
//!         println!("{}", block);
//!     }
//! }
//! # Ok(())
//! # }
//! ```

#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate serde_derive;

pub mod analysis;
pub mod architecture;
pub mod executor;
pub mod graph;
pub mod il;
pub mod loader;
pub mod memory;
pub mod transformation;
pub mod translator;

#[cfg(not(feature = "thread_safe"))]
use std::rc::Rc;
#[cfg(not(feature = "thread_safe"))]
pub type RC<T> = Rc<T>;

#[cfg(feature = "thread_safe")]
use std::sync::Arc;
#[cfg(feature = "thread_safe")]
pub type RC<T> = Arc<T>;

/// Falcon Error types.
pub mod error {
    error_chain! {
        types {
            Error, ErrorKind, ResultExt, Result;
        }

        foreign_links {
            Base64(::base64::DecodeError);
            Capstone(::falcon_capstone::capstone::CsErr);
            Goblin(::goblin::error::Error);
            Io(::std::io::Error);
            Json(::serde_json::Error);
            ParseBigIntError(::num_bigint::ParseBigIntError);
            ParseIntError(::std::num::ParseIntError);
            Utf8(::std::string::FromUtf8Error);
        }

        errors {
            Analysis(m: String) {
                description("An error in the analysis")
                display("Analysis error: {}", m)
            }
            Arithmetic(m: String) {
                description("Error in evaluation of arithmetic expression")
                display("Arithmetic expression evaluation error: {}", m)
            }
            AccessUnmappedMemory(address: u64) {
                description("Attempt to access unmapped memory")
                display("Attempt to access unmapped memory at address 0x{:x}", address)
            }
            CapstoneError {
                description("Capstone failed")
                display("Capstone failed")
            }
            DisassemblyFailure {
                description("Unrecoverable error during disassembly")
                display("Disassembly Failure")
            }
            DivideByZero {
                description("Division by zero")
                display("Division by zero")
            }
            ExecutorScalar(name: String) {
                description("Executor can only execute over constant values")
                display("A scalar \"{}\" was found while executor was evaluating expression", name)
            }
            FunctionLocationApplication {
                description("Failed to apply il::FunctionLocation")
                display("Failed to apply il::FunctionLocation")
            }
            GraphEdgeNotFound(head: usize, tail: usize) {
                description("An edge was not found in a graph")
                display("The edge with head {} and tail {} does not exist in the graph", head, tail)
            }
            GraphVertexNotFound(vertex_id: usize) {
                description("A vertex was not found in a graph")
                display("The vertex id {} does not exist in the graph", vertex_id)
            }
            ProgramLocationMigration(reason: String) {
                description("Error migrating ProgramLocation between Program")
                display("Failed to migrate ProgramLocation between Program: {}", reason)
            }
            ProgramLocationApplication {
                description("Failed to apply il::ProgramLocation")
                display("Failed to apply il::ProgramLocation")
            }
            Sort {
                description("Sort error, invalid bitness between expressions")
                display("Sort error, invalid bitness between expressions")
            }
            TooManyAddressBits {
                description("A constant with >64 bits was used as an address")
                display("A constant with >64 bits was used as an address")
            }
            UnhandledIntrinsic(intrinsic_str: String) {
                description("An unhandled intrinsic was encountered during evaluation")
                display("Encountered unhandled intrinsic {}", intrinsic_str)
            }
        }
    }
}

pub use error::*;