Skip to content

Commit

Permalink
r2iced: support AT&T, masm syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
riptl authored and trufae committed May 7, 2024
1 parent ec94bfc commit 78f4e70
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
37 changes: 29 additions & 8 deletions r2iced/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
#[allow(dead_code)]
mod r2api_ext;

use iced_x86::{Decoder, DecoderOptions, Formatter, Instruction, IntelFormatter};
use iced_x86::{Decoder, DecoderOptions, Formatter, GasFormatter, Instruction, IntelFormatter, MasmFormatter};
use std::ffi::{c_char, c_int, c_void, CStr};
use std::ptr::{null, null_mut};

use crate::r2api_ext::*;
use r2api::*;

macro_rules! static_cstr {
($str: tt) => {
unsafe { CStr::from_bytes_with_nul_unchecked(concat!($str, "\x00").as_bytes()).as_ptr() }
};
}

/// r2c_strdup creates a new libc malloc()ed C String from a Rust string.
unsafe fn r2c_strdup(s: &str) -> *mut c_char {
let out_ptr = libc::malloc(s.len() + 1) as *mut c_char;
Expand Down Expand Up @@ -41,7 +47,28 @@ unsafe extern "C" fn decode(
decoder.decode_out(&mut instruction);
op.size = instruction.len() as c_int;

let mut formatter = IntelFormatter::new();
let mut att_fmt = GasFormatter::new();
let mut intel_fmt = IntelFormatter::new();
let mut masm_fmt = MasmFormatter::new();

let formatter: &mut dyn Formatter = match config.syntax {
R_ARCH_SYNTAX_NONE | R_ARCH_SYNTAX_INTEL => &mut intel_fmt,
R_ARCH_SYNTAX_ATT => &mut att_fmt,
R_ARCH_SYNTAX_MASM => &mut masm_fmt,
_ => {
if r_log_match(R_LOG_LEVEL_ERROR as c_int, static_cstr!("r2iced")) {
r_log_message(
R_LOG_LEVEL_ERROR,
static_cstr!("r2iced"),
static_cstr!("lib.rs"),
line!() as c_int,
static_cstr!("asm.x86.iced only support intel, masm, at&t syntax"),
);
}
return false;
}
};

let mut output = String::new();
formatter.format(&instruction, &mut output);
op.mnemonic = r2c_strdup(&output);
Expand All @@ -54,12 +81,6 @@ pub struct UnsafeSync<T>(pub T);

unsafe impl<T> Sync for UnsafeSync<T> {}

macro_rules! static_cstr {
($str: tt) => {
unsafe { CStr::from_bytes_with_nul_unchecked(concat!($str, "\x00").as_bytes()).as_ptr() }
};
}

static ARCH_PLUGIN: UnsafeSync<RArchPlugin> = UnsafeSync(RArchPlugin {
meta: RPluginMeta {
name: static_cstr!("x86.iced") as *mut c_char,
Expand Down
15 changes: 14 additions & 1 deletion r2iced/src/r2api_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* This module contains bindings that are missing in r2api */

use r2api::RPluginStatus;
use r2api::{RLogLevel, RPluginStatus};
use std::ffi::c_int;

pub const R_SYS_ENDIAN_LITTLE: u32 = 1;
Expand All @@ -12,3 +12,16 @@ pub const R_PLUGIN_STATUS_INCOMPLETE: RPluginStatus = 1;
pub const R_PLUGIN_STATUS_BASIC: RPluginStatus = 2;

pub const R_ARCH_OP_MASK_DISASM: u32 = 16;

pub const R_ARCH_SYNTAX_NONE: c_int = 0;
pub const R_ARCH_SYNTAX_INTEL: c_int = 1;
pub const R_ARCH_SYNTAX_ATT: c_int = 2;
pub const R_ARCH_SYNTAX_MASM: c_int = 3;

pub const R_LOG_LEVEL_FATAL: c_int = 0;
pub const R_LOG_LEVEL_ERROR: RLogLevel = 1;
pub const R_LOG_LEVEL_INFO: RLogLevel = 2;
pub const R_LOG_LEVEL_WARN: RLogLevel = 3;
pub const R_LOG_LEVEL_TODO: RLogLevel = 4;
pub const R_LOG_LEVEL_DEBUG: RLogLevel = 5;
pub const R_LOG_LEVEL_LAST: RLogLevel = 6;

0 comments on commit 78f4e70

Please sign in to comment.