sha0coder/scemu

bsf (bit scan forward) broken

brandonros opened this issue · 12 comments

{
    "i": 70,
    "x64dbgLine": {
      "rawLine": {
        "Index": "00046",
        "Address": "0000000144FF95E9",
        "Bytes": "49:0FBCED",
        "Disassembly": "bsf rbp,r13",
        "Registers": "",
        "Memory": "",
        "Comments": ""
      },
      "rip": "144ff95e9",
      "registerChanges": [],
      "memoryChanges": []
    },
    "scemuLine": {
      "rawLine": "diff_reg: rip = 144ff95e9 rbp 7ffe0624 -> 3f;",
      "rip": "144ff95e9",
      "registerChanges": [
        {
          "registerName": "rbp",
          "previousValue": "7ffe0624",
          "newValue": "3f"
        }
      ],
      "memoryChanges": []
    },
    "instructionErrors": [
      {
        "index": 0,
        "message": "unmatchedRegisterChange mismatch (scemu but not x64dbg)",
        "scemu": "rbp"
      }
    ]
  },

rbp = 0x000000007FFE06B2

r13 = 0x0000000000000000

=>r rbp
rbp: 0x7ffe0624
=>r r13
r13: 0x0 0
=>
71 0x144ff95e9: bsf rbp,r13
=>r rbp
rbp: 0x3f
=>

current algorithm:

                let mut bitpos: u8 = 0;
                let mut dest: u64 = 0;
                 
                while bitpos < sz && get_bit!(src, bitpos) == 0 {
                    dest += 1;
                    bitpos += 1;
                }  
                if dest > 0 {
                    dest -= 1;
                }     
                          
                if dest == sz as u64 {
                    self.flags.f_cf = true;
                } else {
                    self.flags.f_cf = false;
                }

                if dest == 0 {
                    self.flags.f_zf = true;
                } else {
                    self.flags.f_zf = false;
                }

yep

in scemu rbp: 7ffe0624 -> 3f
but what is on x64dbg?

no change, leave rbp alone

oddly enough x64dbg also not seeing zf flag

Mnemonic::Bsf => {
                self.show_instruction(&self.colors.green, &ins);
                assert!(ins.op_count() == 2);

                let src = match self.get_operand_value(&ins, 1, true) {
                    Some(v) => v,
                    None => return,
                };

                println!("bsf: src = {:x}", src);

                if src == 0 {
                    self.flags.f_zf = true;
                    println!("/!\\ bsf src == 0 is undefined behavior");
                } else {
                    let sz = self.get_operand_sz(&ins, 0);
                    let mut bitpos: u8 = 0;
                    let mut dest: u64 = 0;

                    while bitpos < sz && get_bit!(src, bitpos) == 0 {
                        dest += 1;
                        bitpos += 1;
                    }
                    if dest > 0 {
                        dest -= 1;
                    }

                    if dest == sz as u64 {
                        self.flags.f_cf = true;
                    } else {
                        self.flags.f_cf = false;
                    }

                    if dest == 0 {
                        self.flags.f_zf = true;
                    } else {
                        self.flags.f_zf = false;
                    }

                    if !self.set_operand_value(&ins, 0, dest) {
                        return;
                    }
                }
            }

so we are good if we do this i guess

fixed