diff --git a/capstone-x86-endbr.patch b/capstone-x86-endbr.patch new file mode 100644 index 0000000..2fb518f --- /dev/null +++ b/capstone-x86-endbr.patch @@ -0,0 +1,221 @@ +From 1428c6813eb9708e2379a0a451d48ac8d424c2de Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 19 Feb 2019 11:13:06 +0100 +Subject: [PATCH] capstone-x86-endbr.patch + +--- + MCInst.c | 1 + + MCInst.h | 1 + + arch/X86/X86ATTInstPrinter.c | 5 ++++ + arch/X86/X86Disassembler.c | 38 +++++++++++++++++++++++++++ + arch/X86/X86GenInstrInfo.inc | 4 ++- + arch/X86/X86IntelInstPrinter.c | 6 +++++ + arch/X86/X86Mapping.c | 2 ++ + bindings/java/capstone/X86_const.java | 6 +++-- + bindings/ocaml/x86_const.ml | 4 ++- + bindings/python/capstone/x86_const.py | 4 ++- + include/x86.h | 2 ++ + 11 files changed, 68 insertions(+), 5 deletions(-) + +diff --git a/MCInst.c b/MCInst.c +index 2c27f5e..0ab3159 100644 +--- a/MCInst.c ++++ b/MCInst.c +@@ -29,6 +29,7 @@ void MCInst_Init(MCInst *inst) + inst->has_imm = false; + inst->op1_size = 0; + inst->writeback = false; ++ inst->assembly[0] = '\0'; + } + + void MCInst_clear(MCInst *inst) +diff --git a/MCInst.h b/MCInst.h +index b98f37f..54f88fe 100644 +--- a/MCInst.h ++++ b/MCInst.h +@@ -106,6 +106,7 @@ struct MCInst { + uint8_t x86_prefix[4]; + uint8_t imm_size; // immediate size for X86_OP_IMM operand + bool writeback; // writeback for ARM ++ char assembly[8]; // for special instruction, so that we dont need printer + }; + + void MCInst_Init(MCInst *inst); +diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c +index f9a7c4a..152f2d1 100644 +--- a/arch/X86/X86ATTInstPrinter.c ++++ b/arch/X86/X86ATTInstPrinter.c +@@ -706,6 +706,11 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info) + x86_reg reg, reg2; + int i; + ++ if (MI->assembly[0]) { ++ strncpy(OS->buffer, MI->assembly, sizeof(MI->assembly)); ++ return; ++ } ++ + // Output CALLpcrel32 as "callq" in 64-bit mode. + // In Intel annotation it's always emitted as "call". + // +diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c +index 2c2d680..9fb17cb 100644 +--- a/arch/X86/X86Disassembler.c ++++ b/arch/X86/X86Disassembler.c +@@ -833,6 +833,44 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len, + if (ret) { + *size = (uint16_t)(insn.readerCursor - address); + ++ switch (*size) { ++ default: ++ break; ++ case 4: ++ if (handle->mode != CS_MODE_16) { ++ unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0; ++ ++ reader(&info, &b1, address); ++ reader(&info, &b2, address + 1); ++ reader(&info, &b3, address + 2); ++ reader(&info, &b4, address + 3); ++ if (b1 == 0xf3 && b2 == 0x0f && b3 == 0x1e && b4 == 0xfa) { ++ instr->Opcode = X86_ENDBR64; ++ instr->OpcodePub = X86_INS_ENDBR64; ++ strncpy(instr->assembly, "endbr64", 8); ++ if (instr->flat_insn->detail) { ++ instr->flat_insn->detail->x86.opcode[0] = b1; ++ instr->flat_insn->detail->x86.opcode[1] = b2; ++ instr->flat_insn->detail->x86.opcode[2] = b3; ++ instr->flat_insn->detail->x86.opcode[3] = b4; ++ } ++ return true; ++ } else if (b1 == 0xf3 && b2 == 0x0f && b3 == 0x1e && b4 == 0xfb) { ++ instr->Opcode = X86_ENDBR32; ++ instr->OpcodePub = X86_INS_ENDBR32; ++ strncpy(instr->assembly, "endbr32", 8); ++ if (instr->flat_insn->detail) { ++ instr->flat_insn->detail->x86.opcode[0] = b1; ++ instr->flat_insn->detail->x86.opcode[1] = b2; ++ instr->flat_insn->detail->x86.opcode[2] = b3; ++ instr->flat_insn->detail->x86.opcode[3] = b4; ++ } ++ return true; ++ } ++ } ++ return false; ++ } ++ + return false; + } else { + *size = (uint16_t)insn.length; +diff --git a/arch/X86/X86GenInstrInfo.inc b/arch/X86/X86GenInstrInfo.inc +index ff50129..1a22066 100644 +--- a/arch/X86/X86GenInstrInfo.inc ++++ b/arch/X86/X86GenInstrInfo.inc +@@ -6281,7 +6281,9 @@ enum { + X86_XSHA256 = 6264, + X86_XSTORE = 6265, + X86_XTEST = 6266, +- X86_INSTRUCTION_LIST_END = 6267 ++ X86_ENDBR32 = 6267, ++ X86_ENDBR64 = 6268, ++ X86_INSTRUCTION_LIST_END = 6269 + }; + + #endif // GET_INSTRINFO_ENUM +diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c +index cc10141..06fe00f 100644 +--- a/arch/X86/X86IntelInstPrinter.c ++++ b/arch/X86/X86IntelInstPrinter.c +@@ -484,6 +484,12 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI); + void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info) + { + x86_reg reg, reg2; ++ ++ if (MI->assembly[0]) { ++ strncpy(O->buffer, MI->assembly, sizeof(MI->assembly)); ++ return; ++ } ++ + #ifndef CAPSTONE_DIET + char *mnem; + +diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c +index 9b3609d..4515988 100644 +--- a/arch/X86/X86Mapping.c ++++ b/arch/X86/X86Mapping.c +@@ -2113,6 +2113,8 @@ static const name_map insn_name_maps[] = { + { X86_INS_XSHA256, "xsha256" }, + { X86_INS_XSTORE, "xstore" }, + { X86_INS_XTEST, "xtest" }, ++ { X86_INS_ENDBR32, "endbr32" }, ++ { X86_INS_ENDBR64, "endbr64" }, + }; + #endif + +diff --git a/bindings/java/capstone/X86_const.java b/bindings/java/capstone/X86_const.java +index 6129e5f..936af67 100644 +--- a/bindings/java/capstone/X86_const.java ++++ b/bindings/java/capstone/X86_const.java +@@ -1631,7 +1631,9 @@ public class X86_const { + public static final int X86_INS_XSHA256 = 1292; + public static final int X86_INS_XSTORE = 1293; + public static final int X86_INS_XTEST = 1294; +- public static final int X86_INS_ENDING = 1295; ++ public static final int X86_INS_ENDBR32 = 1295; ++ public static final int X86_INS_ENDBR64 = 1296; ++ public static final int X86_INS_ENDING = 1297; + + // Group of X86 instructions + +@@ -1687,4 +1689,4 @@ public class X86_const { + public static final int X86_GRP_SMAP = 167; + public static final int X86_GRP_NOVLX = 168; + public static final int X86_GRP_ENDING = 169; +-} +\ No newline at end of file ++} +diff --git a/bindings/ocaml/x86_const.ml b/bindings/ocaml/x86_const.ml +index 74b11ff..f2b97af 100644 +--- a/bindings/ocaml/x86_const.ml ++++ b/bindings/ocaml/x86_const.ml +@@ -1628,7 +1628,9 @@ let _X86_INS_XSHA1 = 1291;; + let _X86_INS_XSHA256 = 1292;; + let _X86_INS_XSTORE = 1293;; + let _X86_INS_XTEST = 1294;; +-let _X86_INS_ENDING = 1295;; ++let _X86_INS_ENDBR32 = 1295;; ++let _X86_INS_ENDBR64 = 1296;; ++let _X86_INS_ENDING = 1297;; + + (* Group of X86 instructions *) + +diff --git a/bindings/python/capstone/x86_const.py b/bindings/python/capstone/x86_const.py +index 88bb60a..8430173 100644 +--- a/bindings/python/capstone/x86_const.py ++++ b/bindings/python/capstone/x86_const.py +@@ -1628,7 +1628,9 @@ X86_INS_XSHA1 = 1291 + X86_INS_XSHA256 = 1292 + X86_INS_XSTORE = 1293 + X86_INS_XTEST = 1294 +-X86_INS_ENDING = 1295 ++X86_INS_ENDBR32 = 1295 ++X86_INS_ENDBR64 = 1296 ++X86_INS_ENDING = 1297 + + # Group of X86 instructions + +diff --git a/include/x86.h b/include/x86.h +index 2dd162b..026a5bf 100644 +--- a/include/x86.h ++++ b/include/x86.h +@@ -1559,6 +1559,8 @@ typedef enum x86_insn { + X86_INS_XSHA256, + X86_INS_XSTORE, + X86_INS_XTEST, ++ X86_INS_ENDBR32, ++ X86_INS_ENDBR64, + + X86_INS_ENDING, // mark the end of the list of insn + } x86_insn; +-- +2.20.1 + diff --git a/capstone.spec b/capstone.spec index dea6946..3e4caa5 100644 --- a/capstone.spec +++ b/capstone.spec @@ -1,6 +1,6 @@ Name: capstone Version: 3.0.5 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A lightweight multi-platform, multi-architecture disassembly framework %global gituser aquynh @@ -15,6 +15,9 @@ Source0: https://github.com/%{gituser}/%{gitname}/archive/%{commit}/%{nam # Fedora 29 makes python executable separate from python2 and python3. This patch makes # it possible to specify PYTHON2 and PYTHON3 binary to be explicit that by "python" we mean "python2" Patch0: capstone-python.patch +# Add x86 endbr instructions that are very common in Fedora binaries because +# they are compiled with support for Intel CET +Patch1: capstone-x86-endbr.patch %if 0%{?fedora} > 12 %global with_python3 1 @@ -173,6 +176,10 @@ make check LD_LIBRARY_PATH="`pwd`" %{_javadir}/ %changelog +* Tue Feb 19 2019 Riccardo Schirone - 3.0.5-2 +- patch capstone to support endbr64/endbr32 instructions that were added in + capstone 4.0 + * Mon Aug 27 2018 Michal Ambroz - 3.0.5-1 - bump to 3.0.5