-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support cs_disasm_iter
#1
Comments
hey, thanks for the ping. I'll see if I can get cs_disasm_iter exposed properly as an Iterator when I get a chance. |
Hey @gereeter, I spent some time noodling on this, but I'm not sure how feasible it is without depending really directly on the implementation of slices, which is probably fine but more fiddly than I was hoping to make this. My branch is at https://github.com/richo/capstone-rs/compare/cs_iter if you want to have a look |
The Rust side of the API looks good to me, though it technically isn't quite as powerful as the original C api. As for avoiding implementation details, |
Actually, I just remembered that copying the instruction is probably not valid, because of the detail pointer - copying the instruction would not copy its detail, so any further iterations would then overwrite the detail, since all instructions produced would be pointing at the same I think this means that the pub struct InsnIter<'a> {
handle: &'a Capstone,
ptr: Unique<Insn>
}
impl<'a> Drop for InsnIter<'a> {
fn drop(&mut self) {
cs_free(*self.ptr, 1);
}
}
impl InsnIter<'a> {
pub fn new(handle: &'a Capstone) -> InsnIter<'a> {
InsnIter {
handle: handle,
ptr: Unique::new(cs_malloc(handle.csh))
}
}
pub fn next(&mut self, code: &[u8], address: u64) -> CsResult<&Insn>;
} |
I don't think I need to wrap |
Where are you seeing that documentation? I might be just reading the wrong thing or missing something, but this says that "rather than letting the core allocate memory, user pre-allocates the memory required, then pass it to the core," implying that
|
Aha! You're right, I was just misreading. That makes things a little clearer, I can definitely reimplement the current iterator in these terms. Thanks for the nudge! |
any progress on this? |
|
A somewhat working wrapper: struct CapIter<'a, 'b> {
cs: &'a Capstone,
ptr: *const u8,
size: usize,
addr: u64,
insn: *mut cs_insn,
_data: PhantomData<&'b [u8]>,
}
impl<'a, 'b> CapIter<'a, 'b> {
fn new(cs: &'a Capstone, data: &'b [u8], addr: u64) -> Self {
CapIter {
cs,
ptr: data.as_ptr(),
size: data.len(),
addr,
insn: unsafe { cs_malloc(cs.csh()) },
_data: PhantomData,
}
}
}
impl<'a, 'b> Iterator for CapIter<'a, 'b> {
type Item = Insn<'a>;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if cs_disasm_iter(
self.cs.csh(),
&mut self.ptr,
&mut self.size,
&mut self.addr,
self.insn,
) {
return Some(Insn::from_raw(self.insn));
}
}
None
}
}
impl<'a, 'b> Drop for CapIter<'a, 'b> {
fn drop(&mut self) {
if !self.insn.is_null() {
unsafe { cs_free(self.insn, 1) };
}
}
} |
Introduced in Capstone 3.0.
The text was updated successfully, but these errors were encountered: