Skip to content

Commit 217cd19

Browse files
committed
Adding a symbol resolver to the Python bindings.
1 parent 679b2e7 commit 217cd19

File tree

5 files changed

+100
-6
lines changed

5 files changed

+100
-6
lines changed

src/rust/iced-x86-py/src/formatter.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,49 @@ pub(crate) struct Formatter {
5454
unsafe impl Send for Formatter {}
5555
unsafe impl Sync for Formatter {}
5656

57+
struct SymbolResolverAdapter {
58+
resolver: PyObject,
59+
}
60+
61+
impl SymbolResolverAdapter {
62+
fn new(resolver: PyObject) -> SymbolResolverAdapter {
63+
SymbolResolverAdapter { resolver }
64+
}
65+
}
66+
67+
impl iced_x86::SymbolResolver for SymbolResolverAdapter {
68+
fn symbol(
69+
&mut self, _instruction: &iced_x86::Instruction, _operand: u32, _instruction_operand: Option<u32>, address: u64, _address_size: u32,
70+
) -> Option<iced_x86::SymbolResult<'_>> {
71+
let instr = Instruction { instr: *_instruction };
72+
Python::with_gil(|py| {
73+
let sym: Option<String> =
74+
self.resolver.call1(py, (instr, _operand, _instruction_operand, address, _address_size)).unwrap().extract(py).unwrap();
75+
76+
if let Some(val) = sym {
77+
Some(iced_x86::SymbolResult::with_string(address, val))
78+
} else {
79+
None
80+
}
81+
})
82+
}
83+
}
84+
5785
#[pymethods]
5886
impl Formatter {
5987
#[new]
60-
#[pyo3(text_signature = "(syntax)")]
61-
fn new(syntax: u32) -> PyResult<Self> {
88+
#[pyo3(signature = (syntax, symbol_resolver = None))]
89+
fn new(syntax: u32, symbol_resolver: Option<PyObject>) -> PyResult<Self> {
90+
let resolver = symbol_resolver.map(|val| -> Box<dyn iced_x86::SymbolResolver> { Box::new(SymbolResolverAdapter::new(val)) });
91+
6292
let formatter: Box<dyn iced_x86::Formatter> = if syntax == FormatterSyntax::Gas as u32 {
63-
Box::new(iced_x86::GasFormatter::new())
93+
Box::new(iced_x86::GasFormatter::with_options(resolver, None))
6494
} else if syntax == FormatterSyntax::Intel as u32 {
65-
Box::new(iced_x86::IntelFormatter::new())
95+
Box::new(iced_x86::IntelFormatter::with_options(resolver, None))
6696
} else if syntax == FormatterSyntax::Masm as u32 {
67-
Box::new(iced_x86::MasmFormatter::new())
97+
Box::new(iced_x86::MasmFormatter::with_options(resolver, None))
6898
} else if syntax == FormatterSyntax::Nasm as u32 {
69-
Box::new(iced_x86::NasmFormatter::new())
99+
Box::new(iced_x86::NasmFormatter::with_options(resolver, None))
70100
} else {
71101
return Err(PyValueError::new_err("Invalid formatter syntax"));
72102
};

src/rust/iced-x86-py/tests/formatter_gas_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,19 @@ def test_format() -> None:
115115
assert formatter.format_u16(0x89AB) == "0x89AB"
116116
assert formatter.format_u32(0x89ABCDEF) == "0x89ABCDEF"
117117
assert formatter.format_u64(0xFEDCBA9876543210) == "0xFEDCBA9876543210"
118+
119+
def test_format_with_symbol_resolver():
120+
def symbol_resolver(instr, op, instr_op, addr, addr_size):
121+
if addr == 0x00:
122+
return "foo"
123+
elif addr == 0x0B:
124+
return "boo"
125+
else:
126+
return None
127+
128+
instr1, _, _, instr4, _, _, instr7 = list(Decoder(32, b"\xE8\x06\x00\x00\x00\x31\xDB\xF7\xE2\xEB\xF5\x83\xC0\x0E\xC3\x8D\x81\x0B\x00\x00\x00"))
129+
formatter = Formatter(FORMATTER_SYNTAX, symbol_resolver)
130+
131+
assert formatter.format(instr1) == "call boo"
132+
assert formatter.format(instr4) == "jmp foo"
133+
assert formatter.format(instr7) == "lea boo(%ecx),%eax"

src/rust/iced-x86-py/tests/formatter_intel_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,19 @@ def test_format() -> None:
115115
assert formatter.format_u16(0x89AB) == "89ABh"
116116
assert formatter.format_u32(0x89ABCDEF) == "89ABCDEFh"
117117
assert formatter.format_u64(0xFEDCBA9876543210) == "0FEDCBA9876543210h"
118+
119+
def test_format_with_symbol_resolver():
120+
def symbol_resolver(instr, op, instr_op, addr, addr_size):
121+
if addr == 0x00:
122+
return "foo"
123+
elif addr == 0x0B:
124+
return "boo"
125+
else:
126+
return None
127+
128+
instr1, _, _, instr4, _, _, instr7 = list(Decoder(32, b"\xE8\x06\x00\x00\x00\x31\xDB\xF7\xE2\xEB\xF5\x83\xC0\x0E\xC3\x8D\x81\x0B\x00\x00\x00"))
129+
formatter = Formatter(FORMATTER_SYNTAX, symbol_resolver)
130+
131+
assert formatter.format(instr1) == "call boo"
132+
assert formatter.format(instr4) == "jmp short foo"
133+
assert formatter.format(instr7) == "lea eax,[ecx+boo]"

src/rust/iced-x86-py/tests/formatter_masm_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,19 @@ def test_format() -> None:
115115
assert formatter.format_u16(0x89AB) == "89ABh"
116116
assert formatter.format_u32(0x89ABCDEF) == "89ABCDEFh"
117117
assert formatter.format_u64(0xFEDCBA9876543210) == "0FEDCBA9876543210h"
118+
119+
def test_format_with_symbol_resolver():
120+
def symbol_resolver(instr, op, instr_op, addr, addr_size):
121+
if addr == 0x00:
122+
return "foo"
123+
elif addr == 0x0B:
124+
return "boo"
125+
else:
126+
return None
127+
128+
instr1, _, _, instr4, _, _, instr7 = list(Decoder(32, b"\xE8\x06\x00\x00\x00\x31\xDB\xF7\xE2\xEB\xF5\x83\xC0\x0E\xC3\x8D\x81\x0B\x00\x00\x00"))
129+
formatter = Formatter(FORMATTER_SYNTAX, symbol_resolver)
130+
131+
assert formatter.format(instr1) == "call boo"
132+
assert formatter.format(instr4) == "jmp short foo"
133+
assert formatter.format(instr7) == "lea eax,[ecx+boo]"

src/rust/iced-x86-py/tests/formatter_nasm_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,19 @@ def test_format() -> None:
115115
assert formatter.format_u16(0x89AB) == "89ABh"
116116
assert formatter.format_u32(0x89ABCDEF) == "89ABCDEFh"
117117
assert formatter.format_u64(0xFEDCBA9876543210) == "0FEDCBA9876543210h"
118+
119+
def test_format_with_symbol_resolver():
120+
def symbol_resolver(instr, op, instr_op, addr, addr_size):
121+
if addr == 0x00:
122+
return "foo"
123+
elif addr == 0x0B:
124+
return "boo"
125+
else:
126+
return None
127+
128+
instr1, _, _, instr4, _, _, instr7 = list(Decoder(32, b"\xE8\x06\x00\x00\x00\x31\xDB\xF7\xE2\xEB\xF5\x83\xC0\x0E\xC3\x8D\x81\x0B\x00\x00\x00"))
129+
formatter = Formatter(FORMATTER_SYNTAX, symbol_resolver)
130+
131+
assert formatter.format(instr1) == "call boo"
132+
assert formatter.format(instr4) == "jmp short foo"
133+
assert formatter.format(instr7) == "lea eax,[ecx+boo]"

0 commit comments

Comments
 (0)