pub fn rep_prefix(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        if control_flow_graph.entry().is_none() || control_flow_graph.exit().is_none() {
            bail!("control_flow_graph entry/exit was none");
        }

        let cx = self.get_register(x86_reg::X86_REG_ECX)?.get_full()?;

        let head_index = control_flow_graph.new_block()?.index();

        let loop_index = {
            let loop_block = control_flow_graph.new_block()?;
            cx.set(
                loop_block,
                Expr::sub(cx.get()?, expr_const(1, self.mode().bits()))?,
            )?;
            loop_block.index()
        };

        let terminating_index = control_flow_graph.new_block()?.index();

        let entry = control_flow_graph.entry().unwrap();
        let exit = control_flow_graph.exit().unwrap();

        // head -> entry
        // head -> terminating
        control_flow_graph.conditional_edge(
            head_index,
            entry,
            Expr::cmpneq(cx.get()?, expr_const(0, self.mode().bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            head_index,
            terminating_index,
            Expr::cmpeq(cx.get()?, expr_const(0, self.mode().bits()))?,
        )?;

        // exit -> loop
        control_flow_graph.unconditional_edge(exit, loop_index)?;

        if let capstone::InstrIdArch::X86(instruction_id) = self.instruction().id {
            match instruction_id {
                capstone::x86_insn::X86_INS_CMPSB
                | capstone::x86_insn::X86_INS_CMPSW
                | capstone::x86_insn::X86_INS_CMPSD
                | capstone::x86_insn::X86_INS_CMPSQ
                | capstone::x86_insn::X86_INS_SCASB
                | capstone::x86_insn::X86_INS_SCASW
                | capstone::x86_insn::X86_INS_SCASD
                | capstone::x86_insn::X86_INS_SCASQ => {
                    // loop -> head
                    control_flow_graph.conditional_edge(
                        loop_index,
                        head_index,
                        Expr::cmpeq(expr_scalar("ZF", 1), expr_const(1, 1))?,
                    )?;
                    // loop -> terminating
                    control_flow_graph.conditional_edge(
                        loop_index,
                        terminating_index,
                        Expr::cmpeq(expr_scalar("ZF", 1), expr_const(0, 1))?,
                    )?;
                }
                capstone::x86_insn::X86_INS_STOSB
                | capstone::x86_insn::X86_INS_STOSW
                | capstone::x86_insn::X86_INS_STOSD
                | capstone::x86_insn::X86_INS_STOSQ
                | capstone::x86_insn::X86_INS_MOVSB
                | capstone::x86_insn::X86_INS_MOVSW
                | capstone::x86_insn::X86_INS_MOVSD
                | capstone::x86_insn::X86_INS_MOVSQ => {
                    // loop -> head
                    control_flow_graph.unconditional_edge(loop_index, head_index)?;
                }
                _ => bail!(
                    "unsupported instruction for rep prefix, 0x{:x}",
                    self.instruction().address
                ),
            }
        }

        control_flow_graph.set_entry(head_index)?;
        control_flow_graph.set_exit(terminating_index)?;

        Ok(())
    }
/// Wraps the given instruction graph with the rep prefix inplace
Wraps the given instruction graph with the rep prefix inplace
Wraps the given instruction graph with the rep prefix inplace
pub fn rep_prefix(&self, control_flow_graph: &mut ControlFlowGraph) -> Result<()> {
        if control_flow_graph.entry().is_none() || control_flow_graph.exit().is_none() {
            bail!("control_flow_graph entry/exit was none");
        }
        let cx = self.get_register(x86_reg::X86_REG_ECX)?.get_full()?;
        let head_index = control_flow_graph.new_block()?.index();
        let loop_index = {
            let loop_block = control_flow_graph.new_block()?;
            cx.set(
                loop_block,
                Expr::sub(cx.get()?, expr_const(1, self.mode().bits()))?,
            )?;
            loop_block.index()
        };
        let terminating_index = control_flow_graph.new_block()?.index();
        let entry = control_flow_graph.entry().unwrap();
        let exit = control_flow_graph.exit().unwrap();
        // head -> entry
        // head -> terminating
        control_flow_graph.conditional_edge(
            head_index,
            entry,
            Expr::cmpneq(cx.get()?, expr_const(0, self.mode().bits()))?,
        )?;
        control_flow_graph.conditional_edge(
            head_index,
            terminating_index,
            Expr::cmpeq(cx.get()?, expr_const(0, self.mode().bits()))?,
        )?;
        // exit -> loop
        control_flow_graph.unconditional_edge(exit, loop_index)?;
        if let capstone::InstrIdArch::X86(instruction_id) = self.instruction().id {
            match instruction_id {
                capstone::x86_insn::X86_INS_CMPSB
                | capstone::x86_insn::X86_INS_CMPSW
                | capstone::x86_insn::X86_INS_CMPSD
                | capstone::x86_insn::X86_INS_CMPSQ
                | capstone::x86_insn::X86_INS_SCASB
                | capstone::x86_insn::X86_INS_SCASW
                | capstone::x86_insn::X86_INS_SCASD
                | capstone::x86_insn::X86_INS_SCASQ => {
                    // loop -> head
                    control_flow_graph.conditional_edge(
                        loop_index,
                        head_index,
                        Expr::cmpeq(expr_scalar("ZF", 1), expr_const(1, 1))?,
                    )?;
                    // loop -> terminating
                    control_flow_graph.conditional_edge(
                        loop_index,
                        terminating_index,
                        Expr::cmpeq(expr_scalar("ZF", 1), expr_const(0, 1))?,
                    )?;
                }
                capstone::x86_insn::X86_INS_STOSB
                | capstone::x86_insn::X86_INS_STOSW
                | capstone::x86_insn::X86_INS_STOSD
                | capstone::x86_insn::X86_INS_STOSQ
                | capstone::x86_insn::X86_INS_MOVSB
                | capstone::x86_insn::X86_INS_MOVSW
                | capstone::x86_insn::X86_INS_MOVSD
                | capstone::x86_insn::X86_INS_MOVSQ => {
                    // loop -> head
                    control_flow_graph.unconditional_edge(loop_index, head_index)?;
                }
                _ => bail!(
                    "unsupported instruction for rep prefix, 0x{:x}",
                    self.instruction().address
                ),
            }
        }
        control_flow_graph.set_entry(head_index)?;
        control_flow_graph.set_exit(terminating_index)?;
        Ok(())
    }
pub fn rep_prefix ( & self , control_flow_graph : & mut ControlFlowGraph ) -> Result < ( ) > { if control_flow_graph . entry ( ) . is_none ( ) || control_flow_graph . exit ( ) . is_none ( ) { bail ! ( " " ) ; } let cx = self . get_register ( x86_reg :: X86_REG_ECX ) ? . get_full ( ) ? ; let head_index = control_flow_graph . new_block ( ) ? . index ( ) ; let loop_index = { let loop_block = control_flow_graph . new_block ( ) ? ; cx . set ( loop_block , Expr :: sub ( cx . get ( ) ? , expr_const ( 1 , self . mode ( ) . bits ( ) ) ) ? , ) ? ; loop_block . index ( ) } ; let terminating_index = control_flow_graph . new_block ( ) ? . index ( ) ; let entry = control_flow_graph . entry ( ) . unwrap ( ) ; let exit = control_flow_graph . exit ( ) . unwrap ( ) ; // head -> entry // head -> terminating control_flow_graph . conditional_edge ( head_index , entry , Expr :: cmpneq ( cx . get ( ) ? , expr_const ( 0 , self . mode ( ) . bits ( ) ) ) ? , ) ? ; control_flow_graph . conditional_edge ( head_index , terminating_index , Expr :: cmpeq ( cx . get ( ) ? , expr_const ( 0 , self . mode ( ) . bits ( ) ) ) ? , ) ? ; // exit -> loop control_flow_graph . unconditional_edge ( exit , loop_index ) ? ; if let capstone :: InstrIdArch :: X86 ( instruction_id ) = self . instruction ( ) . id { match instruction_id { capstone :: x86_insn :: X86_INS_CMPSB | capstone :: x86_insn :: X86_INS_CMPSW | capstone :: x86_insn :: X86_INS_CMPSD | capstone :: x86_insn :: X86_INS_CMPSQ | capstone :: x86_insn :: X86_INS_SCASB | capstone :: x86_insn :: X86_INS_SCASW | capstone :: x86_insn :: X86_INS_SCASD | capstone :: x86_insn :: X86_INS_SCASQ => { // loop -> head control_flow_graph . conditional_edge ( loop_index , head_index , Expr :: cmpeq ( expr_scalar ( " " , 1 ) , expr_const ( 1 , 1 ) ) ? , ) ? ; // loop -> terminating control_flow_graph . conditional_edge ( loop_index , terminating_index , Expr :: cmpeq ( expr_scalar ( " " , 1 ) , expr_const ( 0 , 1 ) ) ? , ) ? ; } capstone :: x86_insn :: X86_INS_STOSB | capstone :: x86_insn :: X86_INS_STOSW | capstone :: x86_insn :: X86_INS_STOSD | capstone :: x86_insn :: X86_INS_STOSQ | capstone :: x86_insn :: X86_INS_MOVSB | capstone :: x86_insn :: X86_INS_MOVSW | capstone :: x86_insn :: X86_INS_MOVSD | capstone :: x86_insn :: X86_INS_MOVSQ => { // loop -> head control_flow_graph . unconditional_edge ( loop_index , head_index ) ? ; } _ => bail ! ( " " self instruction ( ) address ) , } } control_flow_graph . set_entry ( head_index ) ? ; control_flow_graph . set_exit ( terminating_index ) ? ; Ok ( ( ) ) }
Wraps the given instruction graph with the rep prefix inplace
Wraps the given instruction graph with the rep prefix inplace
&self
control_flow_graph
&mut ControlFlowGraph
&self
control_flow_graph
&mut ControlFlowGraph