Skip to content
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

Exposing Insn::detail to the public API #127

Open
clubby789 opened this issue Apr 26, 2022 · 4 comments
Open

Exposing Insn::detail to the public API #127

clubby789 opened this issue Apr 26, 2022 · 4 comments
Assignees

Comments

@clubby789
Copy link
Contributor

I'm writing a project which involves analysing large binaries with Capstone. I'd like to perform the disassembly in a single-thread, then parallelise the higher-level analysis of the disassembled instructions.

However, Capstone is not Send/Sync ( #71 ), and as accessing the detail field can only be done (currently) via the Capstone struct.

Would you consider exposing the pub(crate) function Insn::detail (

pub(crate) unsafe fn detail(&self, arch: Arch) -> InsnDetail {
InsnDetail(&*self.insn.detail, arch)
}
) to the public API? This would prevent having to unsafely pass a Capstone handle across threads, as long as the user ensures that the Arch is correct/the pointer is non-null.

@tmfink
Copy link
Member

tmfink commented Apr 28, 2022

I need to think about it more, but it's possible that it would be safe for Capstone to implement Send (move to completely new thread) but I don't think it would be sound for Capstone to implement Sync (due to the C libraries memory model).

As you disassemble with one thread, you can create your own structure with a copy of the information you want to save and need for analysis. Then, there will be nothing in this library that will prevent you from working in parallel.

This Rust library is designed to to be safe while adding minimal (if any) overhead compared to using the C library directly. Sometimes the compromise makes it less ergonomic (like Capstone not being Sync).

@tmfink tmfink self-assigned this Apr 28, 2022
@clubby789
Copy link
Contributor Author

I did end up making my own structure with a copy, but it took me a while to sort out lifetimes because InsnDetail references rather than copying the original cs_detail.
Since cs_detail is POD and Copy, it might help to introduce a second type which owns this data.

@jduck
Copy link

jduck commented Nov 7, 2022

I found this ticket because I'm trying to access some specific members of instruction details. For example, I want to know if a "call" has an immediate operand and if so, what is the immediate value. Is it not currently possible to get access to this information with capston-rs ?

@jduck
Copy link

jduck commented Nov 7, 2022

I figured it out:

    fn get_call_target(&self, _my_insn: &MyInsn, cs_det: &InsnDetail) -> Result<u64, String> {
        let ops = cs_det.arch_detail().operands();
        let op0 = &ops[0];
        let op0 = match op0 {
            X86Operand(op) => { op }
            _ => { return Err("Invalid operand type".to_string()) }
        };
        let ea: u64 = match &op0.op_type {
            Imm(op) => { *op as u64 }
            _ => { return Err("Invalid operand type (not immediate)".to_string()) }
        };
        Ok(ea)
   }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants