use std::ffi::{c_char, c_int, c_void};
use idakit_sys as sys;
use crate::Database;
use crate::address::Address;
use crate::error::Qerrno;
use crate::ffi::cstr;
impl Database {
pub(crate) fn qerrno(&self) -> Qerrno {
Qerrno::from_code(unsafe { sys::get_qerrno() })
}
pub(crate) fn error_reason(&self, code: Qerrno) -> String {
let reason = unsafe { cstr(sys::qstrerror(code.code())) };
if reason.is_empty() {
format!("error_t {}", code.code())
} else {
reason
}
}
pub(crate) fn last_reason(&self) -> (Qerrno, Option<String>) {
let qerrno = self.qerrno();
let reason = match qerrno {
Qerrno::Ok => None,
code => Some(self.error_reason(code)),
};
(qerrno, reason)
}
pub(crate) fn open_database(&mut self, path: *const c_char, run_auto: bool) -> c_int {
unsafe { sys::idakit_guarded_open(path, run_auto as c_int) }
}
pub(crate) fn last_exit_code(&self) -> c_int {
unsafe { sys::idakit_last_exit_code() }
}
pub(crate) fn last_output(&self) -> String {
crate::ffi::read_string(|buf, cap| unsafe { sys::idakit_last_output(buf, cap) as i64 })
.unwrap_or_default()
}
pub(crate) fn reg_accept_eula(&self) -> bool {
unsafe { sys::idakit_accept_eula() != 0 }
}
pub(crate) fn auto_wait(&self) -> c_int {
unsafe { sys::idakit_guarded_auto_wait() }
}
pub(crate) fn close_database(&mut self, save: bool) {
unsafe { sys::idakit_guarded_close(save as c_int) };
}
pub(crate) fn was_trapped(&self) -> bool {
unsafe { sys::idakit_was_trapped() != 0 }
}
pub(crate) fn get_bytes(&self, address: Address, buf: *mut c_void, size: usize) -> i64 {
unsafe { sys::idakit_get_bytes(address.get(), buf, size) }
}
pub(crate) fn get_bytes_owned(&self, address: Address, size: usize) -> Option<Vec<u8>> {
sys::get_bytes(address.get(), size).ok()
}
pub(crate) fn get_u8(&self, address: Address) -> Option<u8> {
sys::get_u8(address.get()).ok()
}
pub(crate) fn get_u16(&self, address: Address) -> Option<u16> {
sys::get_u16(address.get()).ok()
}
pub(crate) fn get_u32(&self, address: Address) -> Option<u32> {
sys::get_u32(address.get()).ok()
}
pub(crate) fn get_u64(&self, address: Address) -> Option<u64> {
sys::get_u64(address.get()).ok()
}
pub(crate) fn get_strlit(&self, address: Address, strtype: c_int) -> Option<String> {
sys::get_strlit(address.get(), strtype).ok()
}
pub(crate) fn decode_insn(&self, address: Address) -> sys::InstructionData {
sys::decode_insn(address.get())
}
pub(crate) fn get_flags(&self, address: Address) -> u64 {
sys::get_flags(address.get())
}
pub(crate) fn get_item_head(&self, address: Address) -> sys::Address {
sys::get_item_head(address.get())
}
pub(crate) fn get_item_end(&self, address: Address) -> sys::Address {
sys::get_item_end(address.get())
}
pub(crate) fn get_next_head(&self, address: Address, maxea: Address) -> sys::Address {
sys::get_next_head(address.get(), maxea.get())
}
pub(crate) fn get_prev_head(&self, address: Address, minea: Address) -> sys::Address {
sys::get_prev_head(address.get(), minea.get())
}
pub(crate) fn bitness_bits(&self) -> c_int {
sys::bitness()
}
pub(crate) fn image_base(&self) -> sys::Address {
sys::image_base()
}
pub(crate) fn min_ea(&self) -> sys::Address {
sys::min_ea()
}
pub(crate) fn max_ea(&self) -> sys::Address {
sys::max_ea()
}
pub(crate) fn proc_name(&self) -> Option<String> {
sys::proc_name().ok()
}
pub(crate) fn file_type_name(&self) -> Option<String> {
sys::file_type_name().ok()
}
pub(crate) fn input_path(&self) -> Option<String> {
sys::input_path().ok()
}
pub(crate) fn root_filename(&self) -> Option<String> {
sys::root_filename().ok()
}
pub(crate) fn get_ea_name(&self, address: Address) -> Option<String> {
sys::get_ea_name(address.get()).ok()
}
pub(crate) fn get_name_ea(&self, name: &str) -> sys::Address {
sys::get_name_ea(name)
}
pub(crate) fn demangle_name(&self, name: &str) -> Option<String> {
sys::demangle_name(name).ok()
}
pub(crate) fn nlist_size(&self) -> usize {
sys::nlist_size()
}
pub(crate) fn nlist_ea(&self, idx: usize) -> sys::Address {
sys::nlist_ea(idx)
}
pub(crate) fn nlist_name(&self, idx: usize) -> Option<String> {
sys::nlist_name(idx).ok()
}
pub(crate) fn xrefs_build(&self, address: Address, is_to: bool) -> Vec<sys::XrefRec> {
sys::xrefs_build(address.get(), is_to)
}
pub(crate) fn hexrays_init(&self) -> c_int {
unsafe { sys::idakit_hexrays_init() }
}
pub(crate) fn set_name(&mut self, address: Address, name: *const c_char) -> bool {
unsafe { sys::set_name(address.get(), name, 0) }
}
pub(crate) fn set_cmt(
&mut self,
address: Address,
comment: *const c_char,
repeatable: bool,
) -> bool {
unsafe { sys::set_cmt(address.get(), comment, repeatable) }
}
pub(crate) fn get_cmt(&self, address: Address, repeatable: bool) -> Option<String> {
sys::get_cmt(address.get(), repeatable).ok()
}
pub(crate) fn patch_bytes(
&mut self,
address: Address,
buf: *const c_void,
size: usize,
) -> c_int {
unsafe { sys::idakit_patch_bytes(address.get(), buf, size) }
}
pub(crate) fn func_qty(&self) -> usize {
sys::func_qty()
}
pub(crate) fn func_ea(&self, n: usize) -> sys::Address {
sys::func_ea(n)
}
pub(crate) fn func_name(&self, address: Address) -> Option<String> {
sys::func_name(address.get()).ok()
}
pub(crate) fn range_all_chunks(&self, address: Address) -> Vec<sys::RangeT> {
sys::range_all_chunks(address.get()).unwrap_or_default()
}
pub(crate) fn func_type(&self, address: Address, buf: *mut c_char, cap: usize) -> i64 {
unsafe { sys::idakit_func_type(address.get(), buf, cap) }
}
pub(crate) fn type_ordinal_limit(&self) -> u32 {
unsafe { sys::idakit_type_ordinal_limit() }
}
pub(crate) fn type_name_at(&self, ordinal: u32, buf: *mut c_char, cap: usize) -> i64 {
unsafe { sys::idakit_type_name_at(ordinal, buf, cap) }
}
pub(crate) fn func_start(&self, address: Address) -> sys::Address {
sys::func_start(address.get())
}
pub(crate) fn func_end(&self, address: Address) -> sys::Address {
sys::func_end(address.get())
}
pub(crate) fn apply_type_decl(
&mut self,
address: Address,
decl: &str,
flags: c_int,
) -> sys::TypeWriteResult {
sys::apply_type_decl(address.get(), decl, flags)
}
pub(crate) fn apply_named_type(
&mut self,
address: Address,
name: &str,
) -> sys::TypeWriteResult {
sys::apply_named_type(address.get(), name)
}
pub(crate) fn clear_type(&mut self, address: Address) -> sys::TypeWriteResult {
sys::clear_type(address.get())
}
pub(crate) fn apply_type_recipe(
&mut self,
address: Address,
buf: &[u8],
flags: c_int,
) -> sys::TypeWriteResult {
sys::apply_type_recipe(address.get(), buf, flags)
}
pub(crate) fn apply_tinfo(
&mut self,
address: Address,
handle: &sys::TInfo,
flags: c_int,
) -> sys::TypeWriteResult {
sys::tinfo_apply(address.get(), handle, flags)
}
pub(crate) fn func_set_rettype(
&mut self,
address: Address,
buf: &[u8],
) -> sys::TypeWriteResult {
sys::func_set_rettype(address.get(), buf)
}
pub(crate) fn func_set_argtype(
&mut self,
address: Address,
idx: usize,
buf: &[u8],
) -> sys::SigWriteResult {
sys::func_set_argtype(address.get(), idx, buf)
}
pub(crate) fn func_rename_arg(
&mut self,
address: Address,
idx: usize,
name: &str,
) -> sys::SigWriteResult {
sys::func_rename_arg(address.get(), idx, name)
}
pub(crate) fn func_set_cc(&mut self, address: Address, cc: c_int) -> sys::TypeWriteResult {
sys::func_set_cc(address.get(), cc)
}
pub(crate) fn func_prepend_this(
&mut self,
address: Address,
buf: &[u8],
) -> sys::TypeWriteResult {
sys::func_prepend_this(address.get(), buf)
}
pub(crate) fn udt_add_member(
&mut self,
type_name: &str,
member_name: &str,
buf: &[u8],
member_bit: u64,
) -> sys::TypeWriteResult {
sys::udt_add_member(type_name, member_name, buf, member_bit)
}
pub(crate) fn udt_set_member_type(
&mut self,
type_name: &str,
member_name: &str,
member_bit: u64,
buf: &[u8],
) -> sys::TypeWriteResult {
sys::udt_set_member_type(type_name, member_name, member_bit, buf)
}
pub(crate) fn udt_rename_member(
&mut self,
type_name: &str,
member_name: &str,
member_bit: u64,
new_name: &str,
) -> sys::TypeWriteResult {
sys::udt_rename_member(type_name, member_name, member_bit, new_name)
}
pub(crate) fn udt_del_member(
&mut self,
type_name: &str,
member_name: &str,
member_bit: u64,
) -> sys::TypeWriteResult {
sys::udt_del_member(type_name, member_name, member_bit)
}
pub(crate) fn enum_add_member(
&mut self,
type_name: &str,
member_name: &str,
value: u64,
) -> sys::TypeWriteResult {
sys::enum_add_member(type_name, member_name, value)
}
pub(crate) fn enum_set_member_value(
&mut self,
type_name: &str,
member_name: &str,
value: u64,
) -> sys::TypeWriteResult {
sys::enum_set_member_value(type_name, member_name, value)
}
pub(crate) fn enum_rename_member(
&mut self,
type_name: &str,
member_name: &str,
new_name: &str,
) -> sys::TypeWriteResult {
sys::enum_rename_member(type_name, member_name, new_name)
}
pub(crate) fn enum_del_member(
&mut self,
type_name: &str,
member_name: &str,
) -> sys::TypeWriteResult {
sys::enum_del_member(type_name, member_name)
}
pub(crate) fn define_type(&mut self, input: &str) -> sys::TypeWriteResult {
sys::define_type(input)
}
pub(crate) fn func_flags(&self, address: Address) -> u64 {
sys::func_flags(address.get())
}
pub(crate) fn seg_qty(&self) -> c_int {
sys::gen_seg_qty() as c_int
}
pub(crate) fn seg_name(&self, n: c_int) -> Option<String> {
sys::gen_seg_name(n).ok()
}
pub(crate) fn seg_start(&self, n: c_int) -> sys::Address {
sys::gen_seg_start(n)
}
pub(crate) fn seg_end(&self, n: c_int) -> sys::Address {
sys::gen_seg_end(n)
}
pub(crate) fn seg_perm(&self, n: c_int) -> c_int {
sys::gen_seg_perm(n)
}
pub(crate) fn seg_bitness(&self, n: c_int) -> c_int {
sys::gen_seg_bitness(n)
}
pub(crate) fn seg_class(&self, n: c_int) -> Option<String> {
sys::gen_seg_class(n).ok()
}
pub(crate) fn export_qty(&self) -> usize {
sys::export_qty()
}
pub(crate) fn export_ea(&self, idx: usize) -> sys::Address {
sys::export_ea(idx)
}
pub(crate) fn export_ordinal(&self, idx: usize) -> u64 {
sys::export_ordinal(idx)
}
pub(crate) fn export_name(&self, idx: usize) -> Option<String> {
sys::export_name(idx).ok()
}
pub(crate) fn export_forwarder(&self, idx: usize) -> Option<String> {
sys::export_forwarder(idx).ok()
}
pub(crate) fn imports_build(&self) -> Vec<sys::ImportRec> {
sys::imports_build()
}
pub(crate) fn strlist_build(&self) {
sys::strlist_build();
}
pub(crate) fn strlist_qty(&self) -> usize {
sys::strlist_qty()
}
pub(crate) fn strlist_item(&self, n: usize) -> Option<sys::StrlistItem> {
sys::strlist_item(n).ok()
}
pub(crate) fn strlit_contents(
&self,
address: Address,
len: usize,
ty: c_int,
) -> Option<String> {
sys::strlit_contents(address.get(), len, ty).ok()
}
}