idalib/
lib.rs

1//! # idalib
2//!
3//! idalib is a Rust library providing idiomatic bindings for the IDA SDK, enabling the development
4//! of standalone analysis tools using IDA v9.0’s idalib.
5//!
6//! ## Usage
7//!
8//! To use idalib, add it as a dependency in your `Cargo.toml` and include a `build.rs` file in
9//! your project to properly link against IDA:
10//!
11//! ```toml
12//! [dependencies]
13//! idalib = "0.4"
14//!
15//! [build-dependencies]
16//! idalib-build = "0.4"
17//! ```
18//!
19//! Here is a basic example of a `build.rs` file:
20//!
21//! ```rust,ignore
22//! fn main() -> Result<(), Box<dyn std::error::Error>> {
23//!     idalib_build::configure_linkage()?;
24//!     Ok(())
25//! }
26//! ```
27//!
28//! This script uses the `idalib-build` crate to automatically configure the linkage against IDA.
29//! Ensure that the environment variables `IDASDKDIR` and optionally `IDADIR` are set to point to
30//! your IDA SDK and installation directories, respectively.
31//!
32//! ## Setting Environment Variables
33//!
34//! ### On Linux/macOS
35//!
36//! You can set the environment variables in your terminal session or add them to your shell
37//! configuration file (e.g., `.bashrc`, `.zshrc`):
38//!
39//! ```sh,ignore
40//! export IDASDKDIR=/path/to/ida/sdk
41//! export IDADIR=/path/to/ida/installation
42//! ```
43//!
44//! ### On Windows
45//!
46//! Set environment variables using Command Prompt, PowerShell, or System Properties.
47//!
48//! **Command Prompt:**
49//! ```cmd
50//! set IDASDKDIR=C:\path\to\ida\sdk
51//! set IDADIR=C:\path\to\ida\installation
52//! ```
53//!
54//! **PowerShell:**
55//! ```powershell,ignore
56//! $env:IDASDKDIR = "C:\path\to\ida\sdk"
57//! $env:IDADIR = "C:\path\to\ida\installation"
58//! ```
59//!
60//! **System Properties:**
61//! Go to "Environment Variables" in System Properties and add `IDASDKDIR` and `IDADIR`.
62//!
63//! ## Example
64//!
65//! Here's a simple example of how to use idalib:
66//!
67//! ```rust,ignore
68//! use idalib::idb::IDB;
69//!
70//! fn main() -> Result<(), Box<dyn std::error::Error>> {
71//!     let idb = IDB::open("/path/to/binary")?;
72//!     // Perform analysis...
73//!     Ok(())
74//! }
75//! ```
76//!
77#![allow(clippy::needless_lifetimes)]
78
79use std::ffi::c_char;
80use std::sync::{Mutex, MutexGuard, OnceLock};
81
82pub mod bookmarks;
83pub mod decompiler;
84pub mod func;
85pub mod idb;
86pub mod insn;
87pub mod license;
88pub mod meta;
89pub mod plugin;
90pub mod processor;
91pub mod segment;
92pub mod strings;
93pub mod xref;
94
95pub use idalib_sys as ffi;
96
97pub use ffi::IDAError;
98pub use license::{is_valid_license, license_id, LicenseId};
99
100pub type Address = u64;
101
102static INIT: OnceLock<Mutex<()>> = OnceLock::new();
103
104#[cfg(not(target_os = "windows"))]
105extern "C" {
106    static mut batch: c_char;
107}
108
109pub(crate) type IDARuntimeHandle = MutexGuard<'static, ()>;
110
111pub fn force_batch_mode() {
112    #[cfg(not(target_os = "windows"))]
113    unsafe {
114        batch = 1;
115    }
116}
117
118pub fn init_library() -> &'static Mutex<()> {
119    INIT.get_or_init(|| {
120        force_batch_mode();
121        ffi::ida::init_library().expect("IDA initialised successfully");
122        Mutex::new(())
123    })
124}
125
126pub(crate) fn prepare_library() -> IDARuntimeHandle {
127    let mutex = init_library();
128    mutex.lock().unwrap()
129}
130
131pub fn enable_console_messages(enabled: bool) {
132    init_library();
133    ffi::ida::enable_console_messages(enabled);
134}