x86: Improvements to breakpoint disassembly

* `CC` and `CD 03` are different instructions, but previously disassembled to
   `INT 3` and `INT 0x3` respectively.

   The proper mnemonic for the former is `INT3` (no space), while the latter
   is a byte sequence only seen in tests and when trying to exploit emulator
   bugs.  Switch `CC` to use its documented mnemonic, which makes it easier to
   distinguish.

 * `INT1`, also commonly known as `ICEBP` (In Circuit Emulator Break-Point)
   has existed since the 486 processor, and was finally documented by Intel
   following the fallout from CVE-2018-8897.  Model it after `INT3`.

 * It is unclear why there is a specialisation for `:INT n29`, because vector
   29 is `#VC` in newer AMD CPUs, and can't be invoked using the `INT $29`
   instruction anyway.

   The byte sequence `CC 1D` always gets disassembled using `:INT imm8`, which
   suggests that SLEIGH has noticed the redundancy and folded the decode
   rules.  Drop the specialisation.

Fixes #514
This commit is contained in:
Andrew Cooper 2019-08-03 18:24:15 +01:00
parent 15ee804009
commit 97b4528388

View file

@ -1370,8 +1370,6 @@ spec_rm64: "qword ptr "^Mem is Mem { export *:8 Mem; }
@endif
n1: "1" is epsilon { tmp:1 = 1; export tmp; }
n3: "3" is epsilon { tmp:1 = 0x3; export tmp; }
n29: "29" is epsilon { tmp:1 = 0x29; export tmp; }
@ifdef IA64
# Handle sign extension in 64-bit mode for 32-bit destination registers
@ -3358,8 +3356,8 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
:INSD^rep^reptail eseDI4,DX is vexMode=0 & rep & reptail & opsize=1 & byte=0x6d & eseDI4 & DX { eseDI4 = in(DX); }
:INSD^rep^reptail eseDI4,DX is vexMode=0 & rep & reptail & opsize=2 & byte=0x6d & eseDI4 & DX { eseDI4 = in(DX); }
:INT n3 is vexMode=0 & byte=0xcc & n3 { tmp:1 = 0x3; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; }
:INT n29 is vexMode=0 & byte=0xcd; byte=0x29 & n29 { tmp:1 = 0x29; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; }
:INT1 is vexMode=0 & byte=0xf1 { tmp:1 = 0x1; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; }
:INT3 is vexMode=0 & byte=0xcc { tmp:1 = 0x3; intloc:$(SIZE) = swi(tmp); call [intloc]; return [0:1]; }
:INT imm8 is vexMode=0 & byte=0xcd; imm8 { tmp:1 = imm8; intloc:$(SIZE) = swi(tmp); call [intloc]; }
:INTO is vexMode=0 & byte=0xce & bit64=0
{