From 97b4528388628c2c5972a29a23ad0a7974334e14 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 3 Aug 2019 18:24:15 +0100 Subject: [PATCH] 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 --- Ghidra/Processors/x86/data/languages/ia.sinc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index b4e9abb9c5..1ce3747ae7 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -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 {