#![allow(clippy::needless_lifetimes)]
use std::marker::PhantomData;
use std::sync::{Mutex, MutexGuard, OnceLock};
pub mod bookmarks;
pub mod decompiler;
pub mod func;
pub mod idb;
pub mod insn;
pub mod license;
pub mod meta;
pub mod name;
pub mod plugin;
pub mod processor;
pub mod segment;
pub mod strings;
pub mod xref;
pub use idalib_sys as ffi;
pub use ffi::IDAError;
pub use idb::IDB;
#[cfg(not(feature = "plugin"))]
pub use idb::IDBOpenOptions;
pub use license::{LicenseId, is_valid_license, license_id};
#[cfg(feature = "plugin")]
pub use plugin::{IDAPlugin, PluginFlags};
#[cfg(feature = "plugin")]
pub use idalib_macros::plugin;
pub type Address = u64;
pub struct AddressFlags<'a> {
flags: ffi::bytes::flags64_t,
_marker: PhantomData<&'a IDB>,
}
impl<'a> AddressFlags<'a> {
pub(crate) fn new(flags: ffi::bytes::flags64_t) -> Self {
Self {
flags,
_marker: PhantomData,
}
}
pub fn is_code(&self) -> bool {
unsafe { ffi::bytes::is_code(self.flags) }
}
pub fn is_data(&self) -> bool {
unsafe { ffi::bytes::is_data(self.flags) }
}
}
pub struct IDA;
impl IDA {
pub fn new(_: &IDB) -> Self {
Self
}
pub fn msg(&self, message: impl AsRef<str>) -> Result<(), IDAError> {
unsafe { ffi::ida::msg(message) }
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct IDAVersion {
major: i32,
minor: i32,
build: i32,
}
impl IDAVersion {
pub fn major(&self) -> i32 {
self.major
}
pub fn minor(&self) -> i32 {
self.minor
}
pub fn build(&self) -> i32 {
self.build
}
}
static INIT: OnceLock<Mutex<()>> = OnceLock::new();
#[cfg(not(any(target_os = "windows", feature = "plugin")))]
unsafe extern "C" {
static mut batch: std::ffi::c_char;
}
pub(crate) type IDARuntimeHandle = MutexGuard<'static, ()>;
#[cfg(not(feature = "plugin"))]
pub fn force_batch_mode() {
#[cfg(not(target_os = "windows"))]
unsafe {
batch = 1;
}
}
#[cfg(feature = "plugin")]
pub fn init_library() -> &'static Mutex<()> {
INIT.get_or_init(|| Mutex::new(()))
}
#[cfg(not(feature = "plugin"))]
pub fn init_library() -> &'static Mutex<()> {
INIT.get_or_init(|| {
force_batch_mode();
ffi::ida::init_library().expect("IDA initialised successfully");
Mutex::new(())
})
}
pub(crate) fn prepare_library() -> IDARuntimeHandle {
let mutex = init_library();
mutex.lock().unwrap()
}
#[cfg(not(feature = "plugin"))]
pub fn enable_console_messages(enabled: bool) {
init_library();
ffi::ida::enable_console_messages(enabled);
}
pub fn version() -> Result<IDAVersion, IDAError> {
ffi::ida::library_version().map(|(major, minor, build)| IDAVersion {
major,
minor,
build,
})
}