Skip to content

Commit

Permalink
Add more core API's to rust
Browse files Browse the repository at this point in the history
  • Loading branch information
rbran authored and emesare committed Jul 26, 2024
1 parent 8a5cd4b commit 031456e
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 0 deletions.
196 changes: 196 additions & 0 deletions rust/src/enterprise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
use std::marker::PhantomData;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use crate::rc::Array;
use crate::string::{BnStrCompatible, BnString};

pub fn server_username() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerUsername()) }
}

pub fn server_url() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerUrl()) }
}

pub fn set_server_url<S: BnStrCompatible>(url: S) -> Result<(), ()> {
let url = url.into_bytes_with_nul();
let result = unsafe {
binaryninjacore_sys::BNSetEnterpriseServerUrl(url.as_ref().as_ptr() as *const i8)
};
if result {
Ok(())
} else {
Err(())
}
}

pub fn server_name() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerName()) }
}

pub fn server_id() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerId()) }
}

pub fn server_version() -> u64 {
unsafe { binaryninjacore_sys::BNGetEnterpriseServerVersion() }
}

pub fn server_build_id() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerBuildId()) }
}

pub fn server_token() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerToken()) }
}

pub fn license_duration() -> Duration {
Duration::from_secs(unsafe { binaryninjacore_sys::BNGetEnterpriseServerLicenseDuration() })
}

pub fn license_expiration_time() -> SystemTime {
let m = Duration::from_secs(unsafe {
binaryninjacore_sys::BNGetEnterpriseServerLicenseExpirationTime()
});
UNIX_EPOCH + m
}

pub fn server_reservation_time_limit() -> Duration {
Duration::from_secs(unsafe { binaryninjacore_sys::BNGetEnterpriseServerReservationTimeLimit() })
}

pub fn is_server_floating_license() -> bool {
unsafe { binaryninjacore_sys::BNIsEnterpriseServerFloatingLicense() }
}

pub fn is_server_license_still_activated() -> bool {
unsafe { binaryninjacore_sys::BNIsEnterpriseServerLicenseStillActivated() }
}

pub fn authenticate_server_with_credentials<U, P>(username: U, password: P, remember: bool) -> bool
where
U: BnStrCompatible,
P: BnStrCompatible,
{
let username = username.into_bytes_with_nul();
let password = password.into_bytes_with_nul();
unsafe {
binaryninjacore_sys::BNAuthenticateEnterpriseServerWithCredentials(
username.as_ref().as_ptr() as *const i8,
password.as_ref().as_ptr() as *const i8,
remember,
)
}
}

pub fn authenticate_server_with_method<S: BnStrCompatible>(method: S, remember: bool) -> bool {
let method = method.into_bytes_with_nul();
unsafe {
binaryninjacore_sys::BNAuthenticateEnterpriseServerWithMethod(
method.as_ref().as_ptr() as *const i8,
remember,
)
}
}

pub fn connect_server() -> bool {
unsafe { binaryninjacore_sys::BNConnectEnterpriseServer() }
}

pub fn deauthenticate_server() -> bool {
unsafe { binaryninjacore_sys::BNDeauthenticateEnterpriseServer() }
}

pub fn cancel_server_authentication() {
unsafe { binaryninjacore_sys::BNCancelEnterpriseServerAuthentication() }
}

pub fn update_server_license(timeout: Duration) -> bool {
unsafe { binaryninjacore_sys::BNUpdateEnterpriseServerLicense(timeout.as_secs()) }
}

pub fn release_server_license() -> bool {
unsafe { binaryninjacore_sys::BNReleaseEnterpriseServerLicense() }
}

pub fn is_server_connected() -> bool {
unsafe { binaryninjacore_sys::BNIsEnterpriseServerConnected() }
}

pub fn is_server_authenticated() -> bool {
unsafe { binaryninjacore_sys::BNIsEnterpriseServerAuthenticated() }
}

pub fn is_server_initialized() -> bool {
unsafe { binaryninjacore_sys::BNIsEnterpriseServerInitialized() }
}

pub fn server_last_error() -> BnString {
unsafe { BnString::from_raw(binaryninjacore_sys::BNGetEnterpriseServerLastError()) }
}

pub fn server_authentication_methods() -> (Array<BnString>, Array<BnString>) {
let mut methods = core::ptr::null_mut();
let mut names = core::ptr::null_mut();
let count = unsafe {
binaryninjacore_sys::BNGetEnterpriseServerAuthenticationMethods(&mut methods, &mut names)
};
unsafe { (Array::new(methods, count, ()), Array::new(names, count, ())) }
}

// NOTE don't implement Clone, Copy, so each callback can only be
// register/unregistered only once
#[repr(transparent)]
#[derive(Debug)]
pub struct EnterpriseServerCallback<'a> {
handle: binaryninjacore_sys::BNEnterpriseServerCallbacks,
lifetime: PhantomData<&'a ()>,
}

pub fn register_license_changed_callback<'a, F: FnMut(bool) + 'a>(
callback: F,
) -> EnterpriseServerCallback<'a> {
unsafe extern "C" fn cb_license_status_changed<F: FnMut(bool)>(
ctxt: *mut ::std::os::raw::c_void,
still_valid: bool,
) {
let ctxt: &mut F = &mut *(ctxt as *mut F);
ctxt(still_valid)
}
let mut handle = binaryninjacore_sys::BNEnterpriseServerCallbacks {
context: Box::leak(Box::new(callback)) as *mut F as *mut core::ffi::c_void,
licenseStatusChanged: Some(cb_license_status_changed::<F>),
};
unsafe { binaryninjacore_sys::BNRegisterEnterpriseServerNotification(&mut handle) }
EnterpriseServerCallback {
handle,
lifetime: PhantomData,
}
}

pub fn unregister_license_changed_callback(mut callback_handle: EnterpriseServerCallback) {
unsafe {
binaryninjacore_sys::BNUnregisterEnterpriseServerNotification(&mut callback_handle.handle)
}
}

impl<'a> EnterpriseServerCallback<'a> {
/// register the license changed callback
pub fn register<F: FnMut(bool) + 'a>(callback: F) -> Self {
register_license_changed_callback(callback)
}

/// deregister the license changed callback, equivalent to drop the struct
pub fn deregister(self) {
// Nothing, just drop self
}
}

impl Drop for EnterpriseServerCallback<'_> {
fn drop(&mut self) {
unregister_license_changed_callback(EnterpriseServerCallback {
handle: self.handle,
lifetime: PhantomData,
})
}
}
4 changes: 4 additions & 0 deletions rust/src/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ pub fn shutdown() {
unsafe { binaryninjacore_sys::BNShutdown() };
}

pub fn is_shutdown_requested() {
unsafe { binaryninjacore_sys::BNIsShutdownRequested() };

This comment has been minimized.

Copy link
@VisualEhrmanntraut

VisualEhrmanntraut Jul 28, 2024

Contributor

Weird, PR's not merged but just saw the changes were already committed. Anyway:
BNIsShutdownRequested returns bool

pub fn is_shutdown_requested() -> bool {
    unsafe { binaryninjacore_sys::BNIsShutdownRequested() }

as seen in #5430 (comment)

This comment has been minimized.

Copy link
@emesare

emesare Jul 28, 2024

Member

It was half done, didn't catch this 😮‍💨, thanks!

This comment has been minimized.

Copy link
@VisualEhrmanntraut

VisualEhrmanntraut Jul 28, 2024

Contributor

No problem, happy to help with Vector35's efforts to create an incredible reverse engineering suite :-)

}

/// Prelued-postlued helper function (calls [`init`] and [`shutdown`] for you)
/// ```no_run
/// # use binaryninja::binaryview::BinaryViewExt;
Expand Down
70 changes: 70 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ pub mod databuffer;
pub mod debuginfo;
pub mod demangle;
pub mod disassembly;
pub mod enterprise;
pub mod component;
pub mod downloadprovider;
pub mod externallibrary;
Expand Down Expand Up @@ -434,6 +435,75 @@ pub fn version() -> string::BnString {
unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetVersionString()) }
}

pub fn build_id() -> u32 {
unsafe { binaryninjacore_sys::BNGetBuildId() }
}

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct VersionInfo {
pub major: u32,
pub minor: u32,
pub build: u32,
pub channel: string::BnString,
}

pub fn version_info() -> VersionInfo {
let info_raw = unsafe { binaryninjacore_sys::BNGetVersionInfo() };
VersionInfo {
major: info_raw.major,
minor: info_raw.minor,
build: info_raw.build,
channel: unsafe { string::BnString::from_raw(info_raw.channel) },
}
}

pub fn serial_number() -> string::BnString {
unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetSerialNumber()) }
}

pub fn is_license_validated() -> bool {
unsafe { binaryninjacore_sys::BNIsLicenseValidated() }
}

pub fn licensed_user_email() -> string::BnString {
unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetLicensedUserEmail()) }
}

pub fn license_count() -> i32 {
unsafe { binaryninjacore_sys::BNGetLicenseCount() }
}

pub fn set_license<S: string::BnStrCompatible>(license: S) {
let license = license.into_bytes_with_nul();
let license_slice = license.as_ref();
unsafe { binaryninjacore_sys::BNSetLicense(license_slice.as_ptr() as *const i8) }
}

pub fn product() -> string::BnString {
unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetProduct()) }
}

pub fn product_type() -> string::BnString {
unsafe { string::BnString::from_raw(binaryninjacore_sys::BNGetProductType()) }
}

pub fn license_expiration_time() -> std::time::SystemTime {
let m = std::time::Duration::from_secs(unsafe {
binaryninjacore_sys::BNGetLicenseExpirationTime()
});
std::time::UNIX_EPOCH + m
}

pub fn is_ui_enabled() -> bool {
unsafe { binaryninjacore_sys::BNIsUIEnabled() }
}

pub fn is_database<S: string::BnStrCompatible>(filename: S) -> bool {
let filename = filename.into_bytes_with_nul();
let filename_slice = filename.as_ref();
unsafe { binaryninjacore_sys::BNIsDatabase(filename_slice.as_ptr() as *const i8) }
}

pub fn plugin_abi_version() -> u32 {
binaryninjacore_sys::BN_CURRENT_CORE_ABI_VERSION
}
Expand Down

0 comments on commit 031456e

Please sign in to comment.