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
#![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(())
//! # }
//! ```


extern crate base64;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate error_chain;
extern crate falcon_capstone;
extern crate goblin;
#[macro_use]
extern crate log;
extern crate num_bigint;
extern crate num_traits;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;


pub mod analysis;
pub mod architecture;
pub mod executor;
pub mod graph;
pub mod il;
pub mod loader;
pub mod memory;
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 {
            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)
            }
            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)
            }
            ProgramLocationMigration(reason: String) {
                description("Error migrating ProgramLocation between Program")
                display("Failed to migrate ProgramLocation between Program: {}", reason)
            }
            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::*;