zyantific / zydis-rs

Zydis Rust Bindings
MIT License
83 stars 14 forks source link

InstructionAttributes not applied to FullInstruction #35

Closed r3bb1t closed 10 months ago

r3bb1t commented 10 months ago

Take a look at this example:

use zydis::{self, Decoder, FullInstruction, InstructionAttributes};

fn main() {
    let push_rax = [0x50];
    // Btw i get a hint to include zydis::ffi::Decoder. 
    // I dont think we need it. Need to check visibility of some funcs
    let decoder = Decoder::new64();
    let decoded: FullInstruction = decoder.decode_first(&push_rax).unwrap().unwrap();

    dbg!(decoded.operands());
    dbg!(decoded.attributes);
    assert!(decoded.attributes.contains(InstructionAttributes::HAS_SEGMENT_SS));

    // Also idk how decoded.segments() work

    // Offtop: I need a hint on how to detect conditional branches and conditional reads/writes
}
Click here to see output ``` [src/main.rs:11] decoded.operands() = [ DecodedOperand { id: 0, visibility: EXPLICIT, action: OperandAction( READ, ), encoding: OPCODE, size: 64, element_type: INT, element_size: 64, element_count: 1, attributes: OperandAttributes( 0x0, ), kind: Reg( RAX, ), }, DecodedOperand { id: 1, visibility: HIDDEN, action: OperandAction( READ | WRITE, ), encoding: NONE, size: 64, element_type: INT, element_size: 64, element_count: 1, attributes: OperandAttributes( 0x0, ), kind: Reg( RSP, ), }, DecodedOperand { id: 2, visibility: HIDDEN, action: OperandAction( WRITE, ), encoding: NONE, size: 64, element_type: INT, element_size: 64, element_count: 1, attributes: OperandAttributes( 0x0, ), kind: Mem( MemoryInfo { ty: MEM, segment: SS, base: RSP, index: NONE, scale: 0, disp: DisplacementInfo { has_displacement: false, displacement: 0, }, }, ), }, ] [src/main.rs:12] decoded.attributes = InstructionAttributes( 0x0, ) thread 'main' panicked at src/main.rs:13:5: assertion failed: decoded.attributes.contains(InstructionAttributes::HAS_SEGMENT_SS) note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ```

As we can see, the InstructionAttributes is nonexistent and also lacks some pretty representation. I have tested it with lots of instructions and the issue is present in all of them.

r3bb1t commented 10 months ago

Update: I was wrong, InstructionAttributes are getting applied to instruction, but at least the one which i'm interested (HAS_SEGMENT_SS) in - doesn't.

athre0z commented 10 months ago

This is consistent with what the C library reports. The segment flags are only set when an explicit segment override prefix is set, but not for the implicit (instruction dependent) default segment.

I'd generally recommend to instead use the segment reported in MemoryInfo (the enum variant of mem operands) to determine the effective segment.