fcml 1.3.0
Loading...
Searching...
No Matches
fcml_disassembler.hpp
Go to the documentation of this file.
1/*
2 * FCML - Free Code Manipulation Library.
3 * Copyright (C) 2010-2020 Slawomir Wojtasiak
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
27#ifndef FCML_DISASSEMBLER_HPP_
28#define FCML_DISASSEMBLER_HPP_
29
30#include <string.h>
31
32#include "fcml_disassembler.h"
33
34#include "fcml_common.hpp"
35#include "fcml_errors.hpp"
36#include "fcml_dialect.hpp"
37
38namespace fcml {
39
45public:
47 const ErrorContainer &errorContainer,
49 ErrorContainerAwareException(msg, errorContainer, error) {
50 }
51};
52
59public:
60
66 _throwExceptionOnError(true),
67 _incrementIP(true),
68 _enableErrorMessages(true),
69 _carryFlagConditionalSuffix(false),
70 _conditionalGroup(false),
71 _shortForms(false),
72 _extendDispToASA(false),
73 _failIfUnknownInstruction(false) {
74 }
75
78 return _carryFlagConditionalSuffix;
79 }
80
82 void setCarryFlagConditionalSuffix(bool carryFlagConditionalSuffix) {
83 _carryFlagConditionalSuffix = carryFlagConditionalSuffix;
84 }
85
87 fcml_uint8_t getConditionalGroup() const {
88 return _conditionalGroup;
89 }
90
92 void setConditionalGroup(fcml_uint8_t conditionalGroup) {
93 _conditionalGroup = conditionalGroup;
94 }
95
97 bool isEnableErrorMessages() const {
98 return _enableErrorMessages;
99 }
100
102 void setEnableErrorMessages(bool enableErrorMessages) {
103 _enableErrorMessages = enableErrorMessages;
104 }
105
107 bool isExtendDispToAsa() const {
108 return _extendDispToASA;
109 }
110
112 void setExtendDispToAsa(bool extendDispToAsa) {
113 _extendDispToASA = extendDispToAsa;
114 }
115
118 return _failIfUnknownInstruction;
119 }
120
122 void setFailIfUnknownInstruction(bool failIfUnknownInstruction) {
123 _failIfUnknownInstruction = failIfUnknownInstruction;
124 }
125
127 bool isIncrementIp() const {
128 return _incrementIP;
129 }
130
132 void setIncrementIp(bool incrementIp) {
133 _incrementIP = incrementIp;
134 }
135
137 bool isShortForms() const {
138 return _shortForms;
139 }
140
142 void setShortForms(bool shortForms) {
143 _shortForms = shortForms;
144 }
145
154 return _throwExceptionOnError;
155 }
156
164 void setThrowExceptionOnError(bool throwExceptionOnError) {
165 _throwExceptionOnError = throwExceptionOnError;
166 }
167
168private:
169 bool _throwExceptionOnError;
170 bool _incrementIP;
171 bool _enableErrorMessages;
172 bool _carryFlagConditionalSuffix;
173 fcml_uint8_t _conditionalGroup;
174 bool _shortForms;
175 bool _extendDispToASA;
176 bool _failIfUnknownInstruction;
177
178};
179
184public:
185
191 _code(NULL), _codeLength(0) {
192 }
193
201 DisassemblerContext(fcml_ptr code, fcml_usize codeLength) :
202 _code(code), _codeLength(codeLength) {
203 }
204
205public:
206
213 fcml_ptr getCode() const {
214 return _code;
215 }
216
223 void setCode(fcml_ptr code) {
224 _code = code;
225 }
226
233 fcml_usize getCodeLength() const {
234 return _codeLength;
235 }
236
243 void setCodeLength(fcml_usize codeLength) {
244 _codeLength = codeLength;
245 }
246
254 return _disassemblerConf;
255 }
256
264 return _disassemblerConf;
265 }
266
273 void setDisassemblerConf(DisassemblerConf disassemblerConf) {
274 _disassemblerConf = disassemblerConf;
275 }
276
284 const EntryPoint& getEntryPoint() const {
285 return _entryPoint;
286 }
287
295 return _entryPoint;
296 }
305 void setEntryPoint(const EntryPoint &entryPoint) {
306 _entryPoint = entryPoint;
307 }
308
315 void setIP(fcml_ip ip) {
316 _entryPoint.setIP(ip);
317 }
318
327 _entryPoint.incrementIP(ip);
328 }
329
337 _entryPoint.setOpMode(operatingMode);
338 }
339
346 void setAddressSizeAttribute(fcml_usize addressSizeAttribute) {
347 _entryPoint.setAddressSizeAttribute(addressSizeAttribute);
348 }
349
356 void setOperandSizeAttribute(fcml_usize operandSizeAttribute) {
357 _entryPoint.setOperandSizeAttribute(operandSizeAttribute);
358 }
359
360private:
362 DisassemblerConf _disassemblerConf;
364 EntryPoint _entryPoint;
366 fcml_ptr _code;
368 fcml_usize _codeLength;
369};
370
375public:
376
381 PT_GROUP_UNKNOWN = FCML_PT_GROUP_UNKNOWN,
382 PT_GROUP_1 = FCML_PT_GROUP_1,
383 PT_GROUP_2 = FCML_PT_GROUP_2,
384 PT_GROUP_3 = FCML_PT_GROUP_3,
385 PT_GROUP_4 = FCML_PT_GROUP_4,
386 PT_REX = FCML_PT_REX,
387 PT_VEX = FCML_PT_VEX,
388 PT_XOP = FCML_PT_XOP,
389 PT_EVEX = FCML_PT_EVEX
390 };
391
398 bool isMandatoryPrefix() const {
399 return _mandatoryPrefix;
400 }
401
409 void setMandatoryPrefix(bool mandatoryPrefix) {
410 _mandatoryPrefix = mandatoryPrefix;
411 }
412
419 fcml_uint8_t getPrefix() const {
420 return _prefix;
421 }
422
429 void setPrefix(fcml_uint8_t prefix) {
430 _prefix = prefix;
431 }
432
440 return _prefixType;
441 }
442
449 void setPrefixType(PrefixType prefixType) {
450 _prefixType = prefixType;
451 }
452
459 const fcml_uint8_t* getAvxBytes() const {
460 return _AvxBytes;
461 }
462
469 fcml_uint8_t* getAvxBytes() {
470 return _AvxBytes;
471 }
472
473private:
475 fcml_uint8_t _prefix;
477 PrefixType _prefixType;
479 bool _mandatoryPrefix;
483 fcml_uint8_t _AvxBytes[3];
484};
485
490public:
491
497 _prefixesCount(0),
498 _prefixesBytesCount(0),
499 _isBranch(false),
500 _isNobranch(false),
501 _isLock(false),
502 _isRep(false),
503 _isRepne(false),
504 _isXrelease(false),
505 _isXacquire(false),
506 _isVex(false),
507 _isEvex(false),
508 _isXop(false),
509 _isAvx(false),
510 _isRex(false),
511 _AvxPrefixFirstByte(false),
512 _R(0),
513 _RPrim(0),
514 _X(0),
515 _B(0),
516 _W(0),
517 _L(0),
518 _LPrim(0),
519 _mmmm(0),
520 _vvvv(0),
521 _VPrim(0),
522 _pp(0),
523 _aaa(0),
524 _b(false),
525 _z(false) {
526 }
527
535 const InstructionPrefixDetails& operator[](fcml_usize index) const {
536 if (index >= FCML_DASM_PREFIXES_COUNT) {
537 throw IllegalArgumentException(FCML_TEXT("Index out of bound."));
538 }
539 return _prefixes[index];
540 }
541
550 if (index >= FCML_DASM_PREFIXES_COUNT) {
551 throw IllegalArgumentException(FCML_TEXT("Index out of bound."));
552 }
553 return _prefixes[index];
554 }
555
562 fcml_uint8_t getB() const {
563 return _B;
564 }
565
572 void setB(fcml_uint8_t B) {
573 _B = B;
574 }
575
582 bool isBranch() const {
583 return _isBranch;
584 }
585
592 void setBranch(bool isBranch) {
593 _isBranch = isBranch;
594 }
595
602 bool isLock() const {
603 return _isLock;
604 }
605
612 void setLock(bool isLock) {
613 _isLock = isLock;
614 }
615
622 bool isNobranch() const {
623 return _isNobranch;
624 }
625
633 _isNobranch = isNobranch;
634 }
635
642 bool isRep() const {
643 return _isRep;
644 }
645
652 void setRep(bool isRep) {
653 _isRep = isRep;
654 }
655
662 bool isRepne() const {
663 return _isRepne;
664 }
665
672 void setRepne(bool isRepne) {
673 _isRepne = isRepne;
674 }
675
682 bool isRex() const {
683 return _isRex;
684 }
685
692 void setRex(bool isRex) {
693 _isRex = isRex;
694 }
695
702 bool isVex() const {
703 return _isVex;
704 }
705
712 void setVex(bool isVex) {
713 _isVex = isVex;
714 }
715
722 void setEvex(bool isEvex) {
723 _isEvex = isEvex;
724 }
725
732 bool isEvex() const {
733 return _isEvex;
734 }
735
742 bool isXacquire() const {
743 return _isXacquire;
744 }
745
753 _isXacquire = isXacquire;
754 }
755
762 bool isXop() const {
763 return _isXop;
764 }
765
772 void setXop(bool isXop) {
773 _isXop = isXop;
774 }
775
782 bool isAvx() const {
783 return _isAvx;
784 }
785
792 void setAvx(bool isAvx) {
793 _isAvx = isAvx;
794 }
795
802 bool isXrelease() const {
803 return _isXrelease;
804 }
805
813 _isXrelease = isXrelease;
814 }
815
822 fcml_uint8_t getL() const {
823 return _L;
824 }
825
832 void setL(fcml_uint8_t L) {
833 _L = L;
834 }
835
842 fcml_uint8_t getLPrim() const {
843 return _LPrim;
844 }
845
852 void setLPrim(fcml_uint8_t lPrim) {
853 _LPrim = lPrim;
854 }
855
862 fcml_uint8_t getMmmm() const {
863 return _mmmm;
864 }
865
872 void setMmmm(fcml_uint8_t mmmm) {
873 _mmmm = mmmm;
874 }
875
882 fcml_uint8_t getPp() const {
883 return _pp;
884 }
885
892 void setPp(fcml_uint8_t pp) {
893 _pp = pp;
894 }
895
904 const InstructionPrefixDetails& getPrefixes(fcml_usize index) const {
905 if (index > FCML_DASM_PREFIXES_COUNT) {
906 throw BadArgumentException(FCML_TEXT("Array index out of bound."),
908 }
909 return _prefixes[index];
910 }
911
921 if (index > FCML_DASM_PREFIXES_COUNT) {
922 throw BadArgumentException(FCML_TEXT("Array index out of bound."),
924 }
925 return _prefixes[index];
926 }
927
934 fcml_int getPrefixesBytesCount() const {
935 return _prefixesBytesCount;
936 }
937
944 void setPrefixesBytesCount(fcml_int prefixesBytesCount) {
945 _prefixesBytesCount = prefixesBytesCount;
946 }
947
954 fcml_int getPrefixesCount() const {
955 return _prefixesCount;
956 }
957
964 void setPrefixesCount(fcml_int prefixesCount) {
965 _prefixesCount = prefixesCount;
966 }
967
974 fcml_uint8_t getR() const {
975 return _R;
976 }
977
984 void setR(fcml_uint8_t r) {
985 _R = r;
986 }
987
994 fcml_uint8_t getRPrim() const {
995 return _RPrim;
996 }
997
1004 void setRPrim(fcml_uint8_t rPrim) {
1005 _RPrim = rPrim;
1006 }
1007
1014 fcml_uint8_t getAvxFirstByte() const {
1015 return _AvxPrefixFirstByte;
1016 }
1017
1024 void setAvxFirstByte(fcml_uint8_t avxFirstByte) {
1025 _AvxPrefixFirstByte = avxFirstByte;
1026 }
1027
1034 fcml_uint8_t getVvvv() const {
1035 return _vvvv;
1036 }
1037
1044 void setVvvv(fcml_uint8_t vvvv) {
1045 _vvvv = vvvv;
1046 }
1047
1054 fcml_uint8_t getAaa() const {
1055 return _aaa;
1056 }
1057
1064 void setAaa(fcml_uint8_t aaa) {
1065 _aaa = aaa;
1066 }
1067
1074 fcml_uint8_t getVPrim() const {
1075 return _VPrim;
1076 }
1077
1084 void setVPrim(fcml_uint8_t vPrim) {
1085 _VPrim = vPrim;
1086 }
1087
1094 fcml_uint8_t getW() const {
1095 return _W;
1096 }
1097
1104 void setW(fcml_uint8_t W) {
1105 _W = W;
1106 }
1107
1114 fcml_uint8_t getX() const {
1115 return _X;
1116 }
1117
1124 void setX(fcml_uint8_t X) {
1125 _X = X;
1126 }
1127
1134 bool getBcast() const {
1135 return _b;
1136 }
1137
1144 void setBcast(bool b) {
1145 _b = b;
1146 }
1147
1154 bool getZ() const {
1155 return _z;
1156 }
1157
1164 void setZ(bool z) {
1165 _z = z;
1166 }
1167
1168private:
1172 fcml_int _prefixesCount;
1174 fcml_int _prefixesBytesCount;
1176 bool _isBranch;
1178 bool _isNobranch;
1180 bool _isLock;
1182 bool _isRep;
1184 bool _isRepne;
1186 bool _isXrelease;
1188 bool _isXacquire;
1190 bool _isVex;
1194 bool _isEvex;
1196 bool _isXop;
1200 bool _isAvx;
1202 bool _isRex;
1206 fcml_uint8_t _AvxPrefixFirstByte;
1208 fcml_uint8_t _R;
1212 fcml_uint8_t _RPrim;
1214 fcml_uint8_t _X;
1216 fcml_uint8_t _B;
1218 fcml_uint8_t _W;
1220 fcml_uint8_t _L;
1224 fcml_uint8_t _LPrim;
1226 fcml_uint8_t _mmmm;
1228 fcml_uint8_t _vvvv;
1232 fcml_uint8_t _VPrim;
1234 fcml_uint8_t _pp;
1238 fcml_uint8_t _aaa;
1242 bool _b;
1246 bool _z;
1247};
1248
1253public:
1254
1266
1272 _accessMode(AM_ACCESS_MODE_UNDEFINED) {
1273 }
1274
1282 _accessMode(accessMode) {
1283 }
1284
1292 return _accessMode;
1293 }
1294
1301 void setAccessMode(AccessMode accessMode) {
1302 _accessMode = accessMode;
1303 }
1304
1305private:
1307 AccessMode _accessMode;
1308};
1309
1314public:
1315
1321 _isRip(false) {
1322 }
1323
1330 bool isRip() const {
1331 return _isRip;
1332 }
1333
1340 void setRip(bool isRip) {
1341 _isRip = isRip;
1342 }
1343
1351 return _modRM;
1352 }
1353
1361 return _modRM;
1362 }
1363
1371 _modRM = modRM;
1372 }
1373
1381 return _sib;
1382 }
1383
1391 return _sib;
1392 }
1393
1401 _sib = sib;
1402 }
1403
1411 return _N;
1412 }
1413
1421 return _N;
1422 }
1423
1431 _N = N;
1432 }
1433
1440 const Integer& getDisplacement() const {
1441 return _displacement;
1442 }
1443
1451 return _displacement;
1452 }
1453
1460 void setDisplacement(const Integer &displacement) {
1461 _displacement = displacement;
1462 }
1463
1464private:
1471 bool _isRip;
1475 Integer _displacement;
1476 /* N from AVX-512 compressed disp8.
1477 * since 1.2.0
1478 */
1480};
1481
1486public:
1487
1497 fcml_uint16_t getAddrMode() const {
1498 return _addrMode;
1499 }
1500
1507 void setAddrMode(fcml_uint16_t addrMode) {
1508 _addrMode = addrMode;
1509 }
1510
1518 return _instruction;
1519 }
1520
1528 _instruction = instruction;
1529 }
1530
1538 const fcml_uint8_t* getInstructionCode() const {
1539 return _instructionCode;
1540 }
1541
1549 fcml_uint8_t* getInstructionCode() {
1550 return _instructionCode;
1551 }
1552
1560 fcml_uint64_t getInstructionGroup() const {
1561 return _instructionGroup;
1562 }
1563
1571 void setInstructionGroup(fcml_uint64_t instructionGroup) {
1572 _instructionGroup = instructionGroup;
1573 }
1574
1581 fcml_usize getInstructionSize() const {
1582 return _instructionSize;
1583 }
1584
1591 void setInstructionSize(fcml_usize instructionSize) {
1592 _instructionSize = instructionSize;
1593 }
1594
1601 bool isShortcut() const {
1602 return _isShortcut;
1603 }
1604
1612 _isShortcut = isShortcut;
1613 }
1614
1622 return _modRMDetails;
1623 }
1624
1632 return _modRMDetails;
1633 }
1634
1641 void setModRmDetails(const DecodedModRMDetails &modRmDetails) {
1642 _modRMDetails = modRmDetails;
1643 }
1644
1651 bool isOpcodeFieldSBit() const {
1652 return _opcodeFieldSBit;
1653 }
1654
1661 void setOpcodeFieldSBit(bool opcodeFieldSBit) {
1662 _opcodeFieldSBit = opcodeFieldSBit;
1663 }
1664
1671 bool isOpcodeFieldWBit() const {
1672 return _opcodeFieldWBit;
1673 }
1674
1681 void setOpcodeFieldWBit(bool opcodeFieldWBit) {
1682 _opcodeFieldWBit = opcodeFieldWBit;
1683 }
1684
1693 const OperandDetails& getOperandDetails(fcml_usize index) const {
1694 if (index > FCML_OPERANDS_COUNT) {
1695 throw BadArgumentException(FCML_TEXT("Array index out of bound."),
1697 }
1698 return _operandDetails[index];
1699 }
1700
1710 if (index > FCML_OPERANDS_COUNT) {
1711 throw BadArgumentException(FCML_TEXT("Array index out of bound."),
1713 }
1714 return _operandDetails[index];
1715 }
1716
1724 return _prefixesDetails;
1725 }
1726
1734 return _prefixesDetails;
1735 }
1736
1743 void setPrefixesDetails(const PrefixesDetails &prefixesDetails) {
1744 _prefixesDetails = prefixesDetails;
1745 }
1746
1754 return _pseudoOp;
1755 }
1756
1764 _pseudoOp = pseudoOp;
1765 }
1766
1773 bool isPseudoOp() const {
1774 return _isPseudoOp;
1775 }
1776
1784 _isPseudoOp = isPseudoOp;
1785 }
1786
1791 fcml_uint8_t getTupleType() const {
1792 return _tupleType;
1793 }
1794
1801 void setTupleType(fcml_uint8_t tupleType) {
1802 _tupleType = tupleType;
1803 }
1804
1805private:
1806
1814 bool _isShortcut;
1819 bool _isPseudoOp;
1823 fcml_uint8_t _instructionCode[FCML_INSTRUCTION_SIZE];
1827 fcml_usize _instructionSize;
1831 PrefixesDetails _prefixesDetails;
1835 OperandDetails _operandDetails[FCML_OPERANDS_COUNT];
1839 DecodedModRMDetails _modRMDetails;
1844 bool _opcodeFieldSBit;
1849 bool _opcodeFieldWBit;
1853 fcml_en_instruction _instruction;
1857 fcml_en_pseudo_operations _pseudoOp;
1861 fcml_uint16_t _addrMode;
1865 fcml_uint64_t _instructionGroup;
1869 fcml_uint8_t _tupleType;
1870};
1871
1878
1879public:
1880
1889 return _errorContainer;
1890 }
1891
1900 return _instruction;
1901 }
1902
1910 return _instructionDetails;
1911 }
1912
1917 void clean() {
1918 _errorContainer.clean();
1919 _instructionDetails = InstructionDetails();
1920 _instruction = Instruction();
1921 }
1922
1923protected:
1924
1925 friend class Disassembler;
1926 friend class DisassemblerTypeConverter;
1927
1934 return _instructionDetails;
1935 }
1936
1942 void setInstructionDetails(const InstructionDetails &instructionDetails) {
1943 _instructionDetails = instructionDetails;
1944 }
1945
1952 return _instruction;
1953 }
1954
1960 void setInstruction(const Instruction &instruction) {
1961 _instruction = instruction;
1962 }
1963
1969 void setErrorContainer(const ErrorContainer &errorContainer) {
1970 _errorContainer = errorContainer;
1971 }
1972
1973private:
1974
1976 ErrorContainer _errorContainer;
1978 InstructionDetails _instructionDetails;
1980 Instruction _instruction;
1981
1982};
1983
1990
1991public:
1992
1993 static void convert(const DisassemblerContext &src,
1995 dest.code = src.getCode();
1996 dest.code_length = src.getCodeLength();
1997 TypeConverter::convert(src.getEntryPoint(), dest.entry_point);
1998 convert(src.getDisassemblerConf(), dest.configuration);
1999 }
2000
2001 static void convert(const DisassemblerConf &src,
2003 dest.conditional_group = src.getConditionalGroup();
2004 dest.carry_flag_conditional_suffix = src.isCarryFlagConditionalSuffix();
2005 dest.enable_error_messages = src.isEnableErrorMessages();
2006 dest.extend_disp_to_asa = src.isExtendDispToAsa();
2007 dest.fail_if_unknown_instruction = src.isFailIfUnknownInstruction();
2008 dest.increment_ip = src.isIncrementIp();
2009 dest.short_forms = src.isShortForms();
2010 }
2011
2012 static void convert(const fcml_st_decoded_modrm_details &src,
2013 DecodedModRMDetails &dest) {
2014 dest.setRip(FCML_TO_CPP_BOOL(src.is_rip));
2015 Nullable<fcml_uint8_t> &modRM = dest.getModRM();
2016 modRM.setNotNull(FCML_TO_CPP_BOOL(src.is_modrm));
2017 modRM.setValue(src.modrm);
2018 Nullable<fcml_uint8_t> &sib = dest.getSib();
2019 sib.setNotNull(FCML_TO_CPP_BOOL(src.sib.is_not_null));
2020 sib.setValue(src.sib.value);
2021 TypeConverter::convert(src.displacement.displacement,
2022 dest.getDisplacement());
2024 N.setNotNull(FCML_TO_CPP_BOOL(src.displacement.N.is_not_null));
2025 N.setValue(src.displacement.N.value);
2026 dest.setN(N);
2027 }
2028
2029 static void convert(const DecodedModRMDetails &src,
2031 dest.is_modrm = src.getModRM().isNotNull();
2032 dest.is_rip = src.isRip();
2033 dest.modrm = src.getModRM().getValue();
2034 fcml_nuint8_t &sib = dest.sib;
2035 sib.is_not_null = src.getSib().isNotNull();
2036 sib.value = src.getSib().getValue();
2037 TypeConverter::convert(src.getDisplacement(),
2039 dest.displacement.N.is_not_null = src.getN().isNotNull();
2040 dest.displacement.N.value = src.getN().getValue();
2041 }
2042
2043 static void convert(const fcml_st_operand_details &src,
2044 OperandDetails &dest) {
2045 dest.setAccessMode(
2046 static_cast<OperandDetails::AccessMode>(src.access_mode));
2047 }
2048
2049 static void convert(const OperandDetails &src,
2051 dest.access_mode =
2052 static_cast<fcml_en_access_mode>(src.getAccessMode());
2053 }
2054
2055 static void convert(const fcml_st_instruction_prefix &src,
2057 dest.setMandatoryPrefix(FCML_TO_CPP_BOOL(src.mandatory_prefix));
2058 dest.setPrefix(src.prefix);
2059 dest.setPrefixType(
2060 static_cast<InstructionPrefixDetails::PrefixType>(src.prefix_type));
2061 ::memcpy(dest.getAvxBytes(), src.avx_bytes, sizeof(src.avx_bytes));
2062 }
2063
2064 static void convert(const InstructionPrefixDetails &src,
2066 dest.mandatory_prefix = src.isMandatoryPrefix();
2067 dest.prefix = src.getPrefix();
2068 dest.prefix_type =
2069 static_cast<fcml_en_prefix_types>(src.getPrefixType());
2070 ::memcpy(dest.avx_bytes, src.getAvxBytes(), sizeof(dest.avx_bytes));
2071 }
2072
2073 static void convert(const fcml_st_prefixes_details src,
2074 PrefixesDetails &dest) {
2075 for (int i = 0; i < FCML_DASM_PREFIXES_COUNT; i++) {
2076 convert(src.prefixes[i], dest.getPrefixes(i));
2077 }
2078 dest.setPrefixesCount(src.prefixes_count);
2079 dest.setPrefixesBytesCount(src.prefixes_bytes_count);
2080 dest.setBranch(FCML_TO_CPP_BOOL(src.is_branch));
2081 dest.setNobranch(FCML_TO_CPP_BOOL(src.is_nobranch));
2082 dest.setLock(FCML_TO_CPP_BOOL(src.is_lock));
2083 dest.setRep(FCML_TO_CPP_BOOL(src.is_rep));
2084 dest.setRepne(FCML_TO_CPP_BOOL(src.is_repne));
2085 dest.setXrelease(FCML_TO_CPP_BOOL(src.is_xrelease));
2086 dest.setXacquire(FCML_TO_CPP_BOOL(src.is_xacquire));
2087 dest.setVex(FCML_TO_CPP_BOOL(src.is_vex));
2088 dest.setEvex(FCML_TO_CPP_BOOL(src.is_evex));
2089 dest.setXop(FCML_TO_CPP_BOOL(src.is_xop));
2090 dest.setAvx(FCML_TO_CPP_BOOL(src.is_avx));
2091 dest.setRex(FCML_TO_CPP_BOOL(src.is_rex));
2092 dest.setAvxFirstByte(src.avx_first_byte);
2093 dest.setR(src.R);
2094 dest.setRPrim(src.R_prim);
2095 dest.setX(src.X);
2096 dest.setB(src.B);
2097 dest.setW(src.W);
2098 dest.setL(src.L);
2099 dest.setLPrim(src.L_prim);
2100 dest.setMmmm(src.mmmm);
2101 dest.setVvvv(src.vvvv);
2102 dest.setVPrim(src.V_prim);
2103 dest.setPp(src.pp);
2104 dest.setAaa(src.aaa);
2105 dest.setBcast(src.b);
2106 dest.setZ(src.z);
2107 }
2108
2109 static void convert(const PrefixesDetails src,
2111 for (int i = 0; i < FCML_DASM_PREFIXES_COUNT; i++) {
2112 convert(src.getPrefixes(i), dest.prefixes[i]);
2113 }
2114 dest.prefixes_count = src.getPrefixesCount();
2115 dest.prefixes_bytes_count = src.getPrefixesBytesCount();
2116 dest.is_branch = src.isBranch();
2117 dest.is_nobranch = src.isNobranch();
2118 dest.is_lock = src.isLock();
2119 dest.is_rep = src.isRep();
2120 dest.is_repne = src.isRepne();
2121 dest.is_xrelease = src.isXrelease();
2122 dest.is_xacquire = src.isXacquire();
2123 dest.is_vex = src.isVex();
2124 dest.is_xop = src.isXop();
2125 dest.is_avx = src.isAvx();
2126 dest.is_evex = src.isEvex();
2127 dest.is_rex = src.isRex();
2128 dest.avx_first_byte = src.getAvxFirstByte();
2129 dest.R = src.getR();
2130 dest.R_prim = src.getRPrim();
2131 dest.X = src.getX();
2132 dest.B = src.getB();
2133 dest.W = src.getW();
2134 dest.L = src.getL();
2135 dest.L_prim = src.getLPrim();
2136 dest.mmmm = src.getMmmm();
2137 dest.vvvv = src.getVvvv();
2138 dest.V_prim = src.getVPrim();
2139 dest.pp = src.getPp();
2140 dest.aaa = src.getAaa();
2141 dest.b = src.getBcast();
2142 dest.z = src.getZ() ? 1 : 0;
2143 }
2144
2145 static void convert(const fcml_st_instruction_details &src,
2146 InstructionDetails &dest) {
2147 dest.setTupleType(src.tuple_type);
2148 dest.setAddrMode(src.addr_mode);
2149 dest.setInstruction(src.instruction);
2150 dest.setInstructionGroup(src.instruction_group);
2151 dest.setInstructionSize(src.instruction_size);
2152 dest.setOpcodeFieldSBit(FCML_TO_CPP_BOOL(src.opcode_field_s_bit));
2153 dest.setOpcodeFieldWBit(FCML_TO_CPP_BOOL(src.opcode_field_w_bit));
2154 dest.setIsPseudoOp(FCML_TO_CPP_BOOL(src.is_pseudo_op));
2155 dest.setPseudoOp(src.pseudo_op);
2156 dest.setShortcut(FCML_TO_CPP_BOOL(src.is_shortcut));
2157 convert(src.modrm_details, dest.getModRmDetails());
2158 for (int i = 0; i < FCML_OPERANDS_COUNT; i++) {
2159 convert(src.operand_details[i], dest.getOperandDetails(i));
2160 }
2161 fcml_uint8_t *code = dest.getInstructionCode();
2162 for (int i = 0; i < FCML_INSTRUCTION_SIZE; i++) {
2163 code[i] = src.instruction_code[i];
2164 }
2165 convert(src.prefixes_details, dest.getPrefixesDetails());
2166 }
2167
2168 static void convert(const InstructionDetails &src,
2170 dest.tuple_type = src.getTupleType();
2171 dest.addr_mode = src.getAddrMode();
2172 dest.instruction = src.getInstruction();
2173 dest.instruction_group = src.getInstructionGroup();
2174 dest.instruction_size = src.getInstructionSize();
2175 dest.opcode_field_s_bit = src.isOpcodeFieldSBit();
2176 dest.opcode_field_w_bit = src.isOpcodeFieldWBit();
2177 dest.is_pseudo_op = src.isPseudoOp();
2178 dest.pseudo_op = src.getPseudoOp();
2179 dest.is_shortcut = src.isShortcut();
2180 convert(src.getModRmDetails(), dest.modrm_details);
2181 for (int i = 0; i < FCML_OPERANDS_COUNT; i++) {
2182 convert(src.getOperandDetails(i), dest.operand_details[i]);
2183 }
2184 for (int i = 0; i < FCML_INSTRUCTION_SIZE; i++) {
2185 dest.instruction_code[i] = src.getInstructionCode()[i];
2186 }
2187 convert(src.getPrefixesDetails(), dest.prefixes_details);
2188 }
2189
2190 static void convert(const fcml_st_disassembler_result &src,
2191 DisassemblerResult &dest) {
2192 TypeConverter::convert(src.instruction, dest.getInstructionInternal());
2193 convert(src.instruction_details, dest.getInstructionDetailsInternal());
2194 }
2195
2196 static void convert(const DisassemblerResult &src,
2198 TypeConverter::convert(src.getInstruction(), dest.instruction);
2199 convert(src.getInstructionDetails(), dest.instruction_details);
2200 }
2201
2202 static void free(fcml_st_disassembler_result &src) {
2203 TypeConverter::free(src.instruction);
2204 }
2205
2206};
2207
2211class Disassembler: public NonCopyable, protected DialectAware {
2212public:
2213
2222 _dialect(dialect) {
2224 extractDialect(dialect), &_disassembler);
2225 if (error) {
2226 throw InitException(
2227 FCML_TEXT("Cannot initialize the disassembler."), error);
2228 }
2229 }
2230
2235 virtual ~Disassembler() {
2236 if (_disassembler) {
2237 ::fcml_fn_disassembler_free(_disassembler);
2238 _disassembler = NULL;
2239 }
2240 }
2241
2242public:
2243
2254 DisassemblerResult &disassemblerResult) {
2255
2257
2259 DisassemblerTypeConverter::convert(ctx, context);
2260
2261 context.disassembler = _disassembler;
2262
2263 /* Prepare assembler result. */
2264 fcml_st_disassembler_result disassembler_result;
2265 ::fcml_fn_disassembler_result_prepare(&disassembler_result);
2266
2267 try {
2268
2269 disassemblerResult.clean();
2270
2271 error = ::fcml_fn_disassemble(&context, &disassembler_result);
2272
2273 ErrorContainer errorContainer;
2274 ErrorTypeConverter::convert(disassembler_result.errors,
2275 errorContainer);
2276
2277 disassemblerResult.setErrorContainer(errorContainer);
2278
2279 if (error && ctx.getDisassemblerConf().isThrowExceptionOnError()) {
2280 ::fcml_fn_disassembler_result_free(&disassembler_result);
2282 FCML_TEXT("Assembling failed."), errorContainer, error);
2283 }
2284
2285 if (!error) {
2286
2287 // Convert result.
2288 DisassemblerTypeConverter::convert(disassembler_result,
2289 disassemblerResult);
2290
2291 ctx.getEntryPoint().setIP(context.entry_point.ip);
2292 ctx.setCode(context.code);
2293 ctx.setCodeLength(context.code_length);
2294
2295 }
2296
2297 ::fcml_fn_disassembler_result_free(&disassembler_result);
2298
2299 } catch (std::exception &exc) {
2300 // If anything failed, free assembler results.
2301 ::fcml_fn_disassembler_result_free(&disassembler_result);
2302 throw exc;
2303 }
2304
2305 return error;
2306 }
2307
2314 return _dialect;
2315 }
2316
2317private:
2318
2320 Dialect &_dialect;
2322 fcml_st_disassembler *_disassembler;
2323
2324};
2325
2326}
2327
2328#endif //FCML_DISASSEMBLER_HPP_
2329
Bad arguments.
Definition fcml_common.hpp:242
ModRM details.
Definition fcml_disassembler.hpp:1313
Nullable< fcml_uint8_t > & getSib()
Gets SIB nullable byte.
Definition fcml_disassembler.hpp:1390
const Nullable< fcml_uint8_t > & getSib() const
Gets SIB nullable byte.
Definition fcml_disassembler.hpp:1380
void setSib(const Nullable< fcml_uint8_t > &sib)
Sets SIB nullable byte.
Definition fcml_disassembler.hpp:1400
DecodedModRMDetails()
Creates an empty ModR/M details.
Definition fcml_disassembler.hpp:1320
const Nullable< fcml_uint32_t > & getN() const
Gets constant N (see AVX-512 compressed disp8).
Definition fcml_disassembler.hpp:1410
void setDisplacement(const Integer &displacement)
Sets displacement.
Definition fcml_disassembler.hpp:1460
Nullable< fcml_uint32_t > & getN()
Gets N (see compressed AVX-512 disp8).
Definition fcml_disassembler.hpp:1420
void setModRM(const Nullable< fcml_uint8_t > &modRM)
Sets ModR/M nullable byte.
Definition fcml_disassembler.hpp:1370
bool isRip() const
Gets true if RIP byte is available.
Definition fcml_disassembler.hpp:1330
Integer & getDisplacement()
Gets raw displacement.
Definition fcml_disassembler.hpp:1450
Nullable< fcml_uint8_t > & getModRM()
Gets ModR/M nullable byte.
Definition fcml_disassembler.hpp:1360
const Nullable< fcml_uint8_t > & getModRM() const
Gets ModR/M nullable byte.
Definition fcml_disassembler.hpp:1350
void setRip(bool isRip)
Sets RIP byte availability.
Definition fcml_disassembler.hpp:1340
void setN(const Nullable< fcml_uint32_t > &N)
Sets N (see compressed AVX-512 disp8).
Definition fcml_disassembler.hpp:1430
const Integer & getDisplacement() const
Gets constant raw displacement.
Definition fcml_disassembler.hpp:1440
Inherit from this class in order to get access to the native FCML dialect structure.
Definition fcml_dialect.hpp:98
fcml_st_dialect * extractDialect(const Dialect &dialect) const
Extracts the native FCML dialect from the dialect object.
Definition fcml_dialect.hpp:122
An abstract dialect.
Definition fcml_dialect.hpp:41
Disassembler configuration.
Definition fcml_disassembler.hpp:58
DisassemblerConf()
Default constructor.
Definition fcml_disassembler.hpp:65
void setShortForms(bool shortForms)
Definition fcml_disassembler.hpp:142
bool isThrowExceptionOnError() const
Returns true if exception should be thrown when disassembling fails.
Definition fcml_disassembler.hpp:153
bool isCarryFlagConditionalSuffix() const
Definition fcml_disassembler.hpp:77
void setEnableErrorMessages(bool enableErrorMessages)
Definition fcml_disassembler.hpp:102
void setCarryFlagConditionalSuffix(bool carryFlagConditionalSuffix)
Definition fcml_disassembler.hpp:82
void setExtendDispToAsa(bool extendDispToAsa)
Definition fcml_disassembler.hpp:112
bool isExtendDispToAsa() const
Definition fcml_disassembler.hpp:107
bool isEnableErrorMessages() const
Definition fcml_disassembler.hpp:97
fcml_uint8_t getConditionalGroup() const
Definition fcml_disassembler.hpp:87
bool isFailIfUnknownInstruction() const
Definition fcml_disassembler.hpp:117
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets the way how the error handling is done.
Definition fcml_disassembler.hpp:164
bool isShortForms() const
Definition fcml_disassembler.hpp:137
void setIncrementIp(bool incrementIp)
Definition fcml_disassembler.hpp:132
void setFailIfUnknownInstruction(bool failIfUnknownInstruction)
Definition fcml_disassembler.hpp:122
bool isIncrementIp() const
Definition fcml_disassembler.hpp:127
void setConditionalGroup(fcml_uint8_t conditionalGroup)
Definition fcml_disassembler.hpp:92
Disassembler context.
Definition fcml_disassembler.hpp:183
fcml_ptr getCode() const
Gets pointer to the machine code buffer.
Definition fcml_disassembler.hpp:213
void setAddressSizeAttribute(fcml_usize addressSizeAttribute)
Sets a new address size attribute for the entry point.
Definition fcml_disassembler.hpp:346
DisassemblerContext()
Creates empty disassembler context.
Definition fcml_disassembler.hpp:190
void setCodeLength(fcml_usize codeLength)
Sets length of the code buffer in bytes.
Definition fcml_disassembler.hpp:243
void setIP(fcml_ip ip)
Sets instruction pointer directly into the entry point.
Definition fcml_disassembler.hpp:315
DisassemblerConf & getDisassemblerConf()
Gets a reference to the configuration object associated with the context.
Definition fcml_disassembler.hpp:263
DisassemblerContext(fcml_ptr code, fcml_usize codeLength)
Creates disassembler context for given piece of machine code.
Definition fcml_disassembler.hpp:201
fcml_usize getCodeLength() const
Gets length of the buffer in bytes.
Definition fcml_disassembler.hpp:233
void setCode(fcml_ptr code)
Sets a new buffer with machine code for the context.
Definition fcml_disassembler.hpp:223
void setOperandSizeAttribute(fcml_usize operandSizeAttribute)
Sets a new operand size attribute for the entry point.
Definition fcml_disassembler.hpp:356
const EntryPoint & getEntryPoint() const
Gets reference to the constant entry point instance associated with the context.
Definition fcml_disassembler.hpp:284
void setOperatingMode(EntryPoint::OperatingMode operatingMode)
Sets processor operating mode directly into the entry point.
Definition fcml_disassembler.hpp:336
void incrementIP(fcml_ip ip)
Increments entry point by given number of bytes.
Definition fcml_disassembler.hpp:326
void setDisassemblerConf(DisassemblerConf disassemblerConf)
Sets a new disassembler configuration for the context.
Definition fcml_disassembler.hpp:273
void setEntryPoint(const EntryPoint &entryPoint)
Copies given entry point to the instance associated with the context.
Definition fcml_disassembler.hpp:305
EntryPoint & getEntryPoint()
Gets reference to the entry point instance associated with the context.
Definition fcml_disassembler.hpp:294
const DisassemblerConf & getDisassemblerConf() const
Gets a reference to the configuration object associated with the context.
Definition fcml_disassembler.hpp:253
Disassembler result.
Definition fcml_disassembler.hpp:1877
void setInstruction(const Instruction &instruction)
Sets a new instruction for the result.
Definition fcml_disassembler.hpp:1960
Instruction & getInstructionInternal()
Gets mutable instruction.
Definition fcml_disassembler.hpp:1951
const Instruction & getInstruction() const
Gets errors container with errors related to the failed disassembling process.
Definition fcml_disassembler.hpp:1899
void setErrorContainer(const ErrorContainer &errorContainer)
Sets error container.
Definition fcml_disassembler.hpp:1969
InstructionDetails & getInstructionDetailsInternal()
Gets mutable instruction details.
Definition fcml_disassembler.hpp:1933
void clean()
Cleans the disassembling result.
Definition fcml_disassembler.hpp:1917
void setInstructionDetails(const InstructionDetails &instructionDetails)
Sets new instruction details for the disassembler.
Definition fcml_disassembler.hpp:1942
const InstructionDetails & getInstructionDetails() const
Gets instruction details associated with the instruction.
Definition fcml_disassembler.hpp:1909
const ErrorContainer & getErrorContainer() const
Gets errors container with errors related to the failed disassembling process.
Definition fcml_disassembler.hpp:1888
Converts objects to their structures counterparts.
Definition fcml_disassembler.hpp:1989
Disassembler wrapper.
Definition fcml_disassembler.hpp:2211
fcml_ceh_error disassemble(DisassemblerContext &ctx, DisassemblerResult &disassemblerResult)
Disassembled the next instruction from the context.
Definition fcml_disassembler.hpp:2253
Dialect & getDialect() const
Gets dialect associated with the disassembler.
Definition fcml_disassembler.hpp:2313
virtual ~Disassembler()
Destructor.
Definition fcml_disassembler.hpp:2235
Disassembler(Dialect &dialect)
Creates a disassembler instance for the given dialect.
Definition fcml_disassembler.hpp:2221
Component can not be initialized correctly.
Definition fcml_disassembler.hpp:44
Holds instruction pointer, processor operating mode and memory segment flags.
Definition fcml_common.hpp:524
void setIP(fcml_ip ip)
Sets a new instruction pointer for the entry point.
Definition fcml_common.hpp:651
void setAddressSizeAttribute(fcml_usize addressSizeAttribute)
Sets a new address size attribute for the entry point.
Definition fcml_common.hpp:611
void setOpMode(OperatingMode opMode)
Sets a new processor operating mode for the entry point.
Definition fcml_common.hpp:671
OperatingMode
Supported operating modes.
Definition fcml_common.hpp:531
void incrementIP(fcml_ip ip)
Increments the instruction pointer by given number of bytes.
Definition fcml_common.hpp:681
void setOperandSizeAttribute(fcml_usize operandSizeAttribute)
Sets a new operand size attribute for the entry point.
Definition fcml_common.hpp:631
Base class for all exceptions that are aware of ErrorContainer.
Definition fcml_errors.hpp:347
Wraps multiple errors into one component.
Definition fcml_errors.hpp:148
void clean()
Cleans all errors and warnings.
Definition fcml_errors.hpp:296
Illegal argument exception.
Definition fcml_common.hpp:264
Component can not be initialized correctly.
Definition fcml_common.hpp:231
Additional details about an instruction.
Definition fcml_disassembler.hpp:1485
bool isOpcodeFieldSBit() const
Gets opcode field 'S'.
Definition fcml_disassembler.hpp:1651
fcml_uint8_t * getInstructionCode()
Gets a pointer to the instruction code.
Definition fcml_disassembler.hpp:1549
PrefixesDetails & getPrefixesDetails()
Gets instruction prefixes details.
Definition fcml_disassembler.hpp:1733
fcml_uint16_t getAddrMode() const
Gets address mode/instruction form.
Definition fcml_disassembler.hpp:1497
fcml_en_pseudo_operations getPseudoOp() const
Gets pseudo operation code.
Definition fcml_disassembler.hpp:1753
fcml_usize getInstructionSize() const
Instruction size in bytes.
Definition fcml_disassembler.hpp:1581
void setShortcut(bool isShortcut)
Marks the instruction as a shortcut.
Definition fcml_disassembler.hpp:1611
const DecodedModRMDetails & getModRmDetails() const
Gets ModR/M instruction details.
Definition fcml_disassembler.hpp:1621
void setInstruction(fcml_en_instruction instruction)
Gets a new instruction code for the instruction.
Definition fcml_disassembler.hpp:1527
fcml_uint8_t getTupleType() const
Gets avx-512 tuple type.
Definition fcml_disassembler.hpp:1791
const OperandDetails & getOperandDetails(fcml_usize index) const
Gets the operand details for given index.
Definition fcml_disassembler.hpp:1693
void setInstructionSize(fcml_usize instructionSize)
Sets the instruction size in bytes.
Definition fcml_disassembler.hpp:1591
bool isOpcodeFieldWBit() const
Gets opcode field 'W'.
Definition fcml_disassembler.hpp:1671
void setPseudoOp(fcml_en_pseudo_operations pseudoOp)
Sets pseudo operation for the instruction.
Definition fcml_disassembler.hpp:1763
void setInstructionGroup(fcml_uint64_t instructionGroup)
Sets an instruction group.
Definition fcml_disassembler.hpp:1571
DecodedModRMDetails & getModRmDetails()
Gets ModR/M instruction details.
Definition fcml_disassembler.hpp:1631
void setPrefixesDetails(const PrefixesDetails &prefixesDetails)
Sets a new instruction prefixes details.
Definition fcml_disassembler.hpp:1743
void setIsPseudoOp(bool isPseudoOp)
Sets pseudo operation flag.
Definition fcml_disassembler.hpp:1783
void setOpcodeFieldSBit(bool opcodeFieldSBit)
Sets 'S' field of the opcode byte.
Definition fcml_disassembler.hpp:1661
fcml_uint64_t getInstructionGroup() const
Gets instruction group.
Definition fcml_disassembler.hpp:1560
fcml_en_instruction getInstruction() const
Gets instruction code.
Definition fcml_disassembler.hpp:1517
void setModRmDetails(const DecodedModRMDetails &modRmDetails)
Sets a new instruction details for the instruction.
Definition fcml_disassembler.hpp:1641
const PrefixesDetails & getPrefixesDetails() const
Gets instruction prefixes details.
Definition fcml_disassembler.hpp:1723
bool isPseudoOp() const
Gets true is it's a pseudo operation.
Definition fcml_disassembler.hpp:1773
void setAddrMode(fcml_uint16_t addrMode)
Sets instruction form.
Definition fcml_disassembler.hpp:1507
void setTupleType(fcml_uint8_t tupleType)
Sets avx-512 tuple type.
Definition fcml_disassembler.hpp:1801
OperandDetails & getOperandDetails(fcml_usize index)
Gets the operand details for given index.
Definition fcml_disassembler.hpp:1709
bool isShortcut() const
Gets true if it's a shortcut instruction.
Definition fcml_disassembler.hpp:1601
const fcml_uint8_t * getInstructionCode() const
Gets a pointer to the instruction code.
Definition fcml_disassembler.hpp:1538
void setOpcodeFieldWBit(bool opcodeFieldWBit)
Sets 'W' field of the opcode byte.
Definition fcml_disassembler.hpp:1681
Instruction prefix.
Definition fcml_disassembler.hpp:374
fcml_uint8_t getPrefix() const
Gets the prefix byte.
Definition fcml_disassembler.hpp:419
void setPrefixType(PrefixType prefixType)
Sets a new prefix type.
Definition fcml_disassembler.hpp:449
bool isMandatoryPrefix() const
Returns true if it's a mandatory prefix.
Definition fcml_disassembler.hpp:398
PrefixType getPrefixType() const
Gets the prefix type.
Definition fcml_disassembler.hpp:439
void setMandatoryPrefix(bool mandatoryPrefix)
Sets mandatory prefix flag for the prefix.
Definition fcml_disassembler.hpp:409
void setPrefix(fcml_uint8_t prefix)
Sets the prefix byte.
Definition fcml_disassembler.hpp:429
fcml_uint8_t * getAvxBytes()
Gets the second and third bytes of the XOP/VEX prefix.
Definition fcml_disassembler.hpp:469
PrefixType
Type of the instruction prefix.
Definition fcml_disassembler.hpp:380
const fcml_uint8_t * getAvxBytes() const
Gets the second and third bytes of the XOP/VEX prefix.
Definition fcml_disassembler.hpp:459
Describes an instruction.
Definition fcml_common.hpp:7185
Represents integer value.
Definition fcml_common.hpp:700
Object which shouldn't be copied can inherit from this class.
Definition fcml_common.hpp:288
Wrapper for nullable value types.
Definition fcml_common.hpp:120
Operand details.
Definition fcml_disassembler.hpp:1252
OperandDetails(AccessMode accessMode)
Creates operand details for given access mode.
Definition fcml_disassembler.hpp:1281
AccessMode getAccessMode() const
Gets access mode for the operand.
Definition fcml_disassembler.hpp:1291
OperandDetails()
Creates default operand details with an undefined access mode.
Definition fcml_disassembler.hpp:1271
AccessMode
Definition fcml_disassembler.hpp:1256
@ AM_READ
Operand is read by instruction.
Definition fcml_disassembler.hpp:1260
@ AM_WRITE
Operand is set by instruction.
Definition fcml_disassembler.hpp:1262
@ AM_READ_WRITE
Operand is read but can be also set.
Definition fcml_disassembler.hpp:1264
@ AM_ACCESS_MODE_UNDEFINED
Undefined mode.
Definition fcml_disassembler.hpp:1258
void setAccessMode(AccessMode accessMode)
Sets an access mode for the operand.
Definition fcml_disassembler.hpp:1301
Prefixes details.
Definition fcml_disassembler.hpp:489
bool getBcast() const
Gets EVEX.b bit.
Definition fcml_disassembler.hpp:1134
fcml_uint8_t getLPrim() const
Gets L' flag.
Definition fcml_disassembler.hpp:842
void setRepne(bool isRepne)
Sets Repne prefix availability.
Definition fcml_disassembler.hpp:672
void setVex(bool isVex)
Sets VEX prefix availability.
Definition fcml_disassembler.hpp:712
void setVPrim(fcml_uint8_t vPrim)
Sets V' flag.
Definition fcml_disassembler.hpp:1084
void setBcast(bool b)
Sets EVEX.b bit.
Definition fcml_disassembler.hpp:1144
void setAaa(fcml_uint8_t aaa)
Sets 'aaa' field of the EVEX prefix.
Definition fcml_disassembler.hpp:1064
void setAvxFirstByte(fcml_uint8_t avxFirstByte)
Sets a first byte of the XOP/VEX prefix.
Definition fcml_disassembler.hpp:1024
void setX(fcml_uint8_t X)
Sets X flag.
Definition fcml_disassembler.hpp:1124
fcml_uint8_t getVPrim() const
Gets V' flag.
Definition fcml_disassembler.hpp:1074
InstructionPrefixDetails & operator[](fcml_usize index)
Gets reference to the instruction prefix at given index.
Definition fcml_disassembler.hpp:549
fcml_uint8_t getW() const
Gets W flag.
Definition fcml_disassembler.hpp:1094
fcml_uint8_t getPp() const
Gets PP field.
Definition fcml_disassembler.hpp:882
void setPrefixesBytesCount(fcml_int prefixesBytesCount)
Sets number of prefixes bytes available for the instruction.
Definition fcml_disassembler.hpp:944
void setEvex(bool isEvex)
Sets EVEX prefix availability.
Definition fcml_disassembler.hpp:722
fcml_uint8_t getAaa() const
Gets 'aaa' field of the EVEX prefix.
Definition fcml_disassembler.hpp:1054
void setPrefixesCount(fcml_int prefixesCount)
Sets number of prefixes available for the instruction.
Definition fcml_disassembler.hpp:964
void setRPrim(fcml_uint8_t rPrim)
Sets R' flag.
Definition fcml_disassembler.hpp:1004
void setPp(fcml_uint8_t pp)
Sets PP field.
Definition fcml_disassembler.hpp:892
void setLock(bool isLock)
Sets lock prefix availability.
Definition fcml_disassembler.hpp:612
fcml_uint8_t getL() const
Gets L flag.
Definition fcml_disassembler.hpp:822
PrefixesDetails()
Default constructor.
Definition fcml_disassembler.hpp:496
void setXrelease(bool isXrelease)
Sets xrelease prefix availability.
Definition fcml_disassembler.hpp:812
void setMmmm(fcml_uint8_t mmmm)
Sets MMMM field.
Definition fcml_disassembler.hpp:872
fcml_int getPrefixesBytesCount() const
Gets number of bytes interpreted to be prefixes.
Definition fcml_disassembler.hpp:934
void setLPrim(fcml_uint8_t lPrim)
Sets L' flag.
Definition fcml_disassembler.hpp:852
void setXop(bool isXop)
Sets XOP prefix availability.
Definition fcml_disassembler.hpp:772
bool isRex() const
Gets true if Rex prefix is available.
Definition fcml_disassembler.hpp:682
bool isBranch() const
Gets true if branch prefix is available.
Definition fcml_disassembler.hpp:582
InstructionPrefixDetails & getPrefixes(fcml_usize index)
Gets a reference to the prefix of the given index.
Definition fcml_disassembler.hpp:920
void setL(fcml_uint8_t L)
Sets L flag.
Definition fcml_disassembler.hpp:832
fcml_uint8_t getAvxFirstByte() const
Gets the first byte of the AVX prefix.
Definition fcml_disassembler.hpp:1014
void setB(fcml_uint8_t B)
Sets B flag.
Definition fcml_disassembler.hpp:572
void setBranch(bool isBranch)
Sets branch prefix availability.
Definition fcml_disassembler.hpp:592
void setW(fcml_uint8_t W)
Sets W flag.
Definition fcml_disassembler.hpp:1104
bool isEvex() const
Gets true if EVEX prefix is available.
Definition fcml_disassembler.hpp:732
void setR(fcml_uint8_t r)
Sets R flag.
Definition fcml_disassembler.hpp:984
bool isAvx() const
Gets true if any AVX prefix is available.
Definition fcml_disassembler.hpp:782
fcml_uint8_t getR() const
Gets R flag.
Definition fcml_disassembler.hpp:974
bool isLock() const
Gets true if lock prefix is available.
Definition fcml_disassembler.hpp:602
fcml_uint8_t getB() const
Gets b flag.
Definition fcml_disassembler.hpp:562
bool isXop() const
Gets true if XOP prefix is available.
Definition fcml_disassembler.hpp:762
bool isRepne() const
Gets true if Repne prefix is available.
Definition fcml_disassembler.hpp:662
bool isRep() const
Gets true if Rep prefix is available.
Definition fcml_disassembler.hpp:642
const InstructionPrefixDetails & getPrefixes(fcml_usize index) const
Gets a reference to the prefix of the given index.
Definition fcml_disassembler.hpp:904
fcml_uint8_t getMmmm() const
Gets MMMM field.
Definition fcml_disassembler.hpp:862
bool isXacquire() const
Gets true if xacquire prefix is available.
Definition fcml_disassembler.hpp:742
bool isNobranch() const
Gets true if no-branch prefix is available.
Definition fcml_disassembler.hpp:622
void setRep(bool isRep)
Sets Rep prefix availability.
Definition fcml_disassembler.hpp:652
bool isVex() const
Gets true if Vex prefix is available.
Definition fcml_disassembler.hpp:702
void setAvx(bool isAvx)
Sets XOP prefix availability.
Definition fcml_disassembler.hpp:792
fcml_uint8_t getX() const
Gets X flag.
Definition fcml_disassembler.hpp:1114
fcml_int getPrefixesCount() const
Gets number of prefixes available for the instruction.
Definition fcml_disassembler.hpp:954
void setVvvv(fcml_uint8_t vvvv)
Sets VVVV field of the XOP/VEX prefix.
Definition fcml_disassembler.hpp:1044
bool getZ() const
Gets EVEX.z bit.
Definition fcml_disassembler.hpp:1154
bool isXrelease() const
Gets true if xrelease prefix is available.
Definition fcml_disassembler.hpp:802
void setXacquire(bool isXacquire)
Sets xacquire prefix availability.
Definition fcml_disassembler.hpp:752
const InstructionPrefixDetails & operator[](fcml_usize index) const
Gets reference to the instruction prefix at given index.
Definition fcml_disassembler.hpp:535
void setZ(bool z)
Sets EVEX.z bit.
Definition fcml_disassembler.hpp:1164
fcml_uint8_t getRPrim() const
Gets R' flag.
Definition fcml_disassembler.hpp:994
void setNobranch(bool isNobranch)
Sets no-branch prefix availability.
Definition fcml_disassembler.hpp:632
void setRex(bool isRex)
Sets REX prefix availability.
Definition fcml_disassembler.hpp:692
fcml_uint8_t getVvvv() const
Gets VVVV field of the XOP/VEX prefix.
Definition fcml_disassembler.hpp:1034
#define FCML_INSTRUCTION_SIZE
Maximal number of bytes instruction can use.
Definition fcml_common.h:37
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition fcml_common.h:96
#define FCML_OPERANDS_COUNT
Maximal number of the instruction operands.
Definition fcml_common.h:35
fcml_en_access_mode
Operand access mode.
Definition fcml_common.h:542
@ FCML_AM_WRITE
Operand is set by instruction.
Definition fcml_common.h:548
@ FCML_AM_ACCESS_MODE_UNDEFINED
Undefined mode.
Definition fcml_common.h:544
@ FCML_AM_READ
Operand is read by instruction.
Definition fcml_common.h:546
C++ wrappers common classes.
std::basic_string< fcml_char > fcml_cstring
By using this type definition here, it will be definitely much easier to support UNICODE in future re...
Definition fcml_common.hpp:53
C++ wrapper for the base dialect.
Structures and functions declarations related to FCML disassembler.
struct fcml_st_disassembler fcml_st_disassembler
This structure and type declaration represents an abstract disassembler.
Definition fcml_disassembler.h:50
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassemble(fcml_st_disassembler_context *context, fcml_st_disassembler_result *result)
Disassembles one instruction from provided code buffer.
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_free(fcml_st_disassembler_result *result)
Cleans result holder.
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_prepare(fcml_st_disassembler_result *result)
Prepares reusable result holder for disassembler.
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_free(fcml_st_disassembler *disassembler)
Frees disassembler instance.
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassembler_init(const fcml_st_dialect *dialect, fcml_st_disassembler **disassembler)
Initializes disassembler instance.
#define FCML_DASM_PREFIXES_COUNT
Maximal number of instruction prefixes.
Definition fcml_disassembler.h:42
fcml_en_prefix_types
Available types of instruction prefixes.
Definition fcml_disassembler.h:97
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition fcml_errors.h:156
C++ wrapper for the FCML errors handling.
#define FCML_TEXT(x)
Used to code literal strings.
Definition fcml_types.h:61
@ FCML_CEH_GEC_NO_ERROR
Operation succeed.
Definition fcml_errors.h:42
@ FCML_CEH_GEC_VALUE_OUT_OF_RANGE
Used mainly in case of integers and offsets.
Definition fcml_errors.h:55
fcml_en_instruction
Instruction codes.
Definition fcml_instructions.h:184
fcml_en_pseudo_operations
Pseudo operations.
Definition fcml_instructions.h:1539
Definition fcml_types.h:217
Some basic information about decoded ModR/M and SIB bytes.
Definition fcml_disassembler.h:207
fcml_uint8_t modrm
ModR/M byte if exists.
Definition fcml_disassembler.h:209
fcml_bool is_modrm
True if ModR/M exists.
Definition fcml_disassembler.h:216
fcml_st_raw_displacement displacement
Raw displacement.
Definition fcml_disassembler.h:218
fcml_nuint8_t sib
SIB byte if exists.
Definition fcml_disassembler.h:211
fcml_bool is_rip
True if RIP encoding is used by decoded instruction.
Definition fcml_disassembler.h:214
Disassembler configuration.
Definition fcml_disassembler.h:53
fcml_bool increment_ip
Set to true in order to make disassembler to increment IP address by length of the disassembled instr...
Definition fcml_disassembler.h:56
fcml_bool short_forms
Set to true in order to use short forms.
Definition fcml_disassembler.h:69
fcml_bool enable_error_messages
True if optional error and warning messages should be collected during processing.
Definition fcml_disassembler.h:59
fcml_uint8_t conditional_group
There are two groups of suffixes for conditional instructions, you can choose which one should be use...
Definition fcml_disassembler.h:64
fcml_bool extend_disp_to_asa
True if displacement should be sign extended to effective address size; otherwise false.
Definition fcml_disassembler.h:72
fcml_bool fail_if_unknown_instruction
If set to true assembler will return FCML_CEH_GEC_UNKNOWN_INSTRUCTION error code if instruction is no...
Definition fcml_disassembler.h:76
fcml_bool carry_flag_conditional_suffix
True if suffixes for carry flag has to be used by disassembler.
Definition fcml_disassembler.h:61
Disassembler context.
Definition fcml_disassembler.h:80
fcml_st_disassembler_conf configuration
Disassembler configuration.
Definition fcml_disassembler.h:84
fcml_ptr code
Pointer to the encoded instruction.
Definition fcml_disassembler.h:88
fcml_usize code_length
Size of the code in the buffer above.
Definition fcml_disassembler.h:90
fcml_st_disassembler * disassembler
Disassembler used to decode instructions.
Definition fcml_disassembler.h:82
fcml_st_entry_point entry_point
Instruction entry point configuration.
Definition fcml_disassembler.h:86
Reusable disassembler result holder.
Definition fcml_disassembler.h:268
fcml_st_instruction instruction
Decoded instruction in its generic form.
Definition fcml_disassembler.h:275
fcml_st_ceh_error_container errors
All errors and warnings messages going here.
Definition fcml_disassembler.h:270
fcml_st_instruction_details instruction_details
Additional disassembler specific information about decoded instruction.
Definition fcml_disassembler.h:273
fcml_ip ip
The instruction pointer EIP/RIP.
Definition fcml_common.h:847
Additional instruction details provided by disassembler.
Definition fcml_disassembler.h:222
fcml_uint16_t addr_mode
Code of the instruction form/addressing mode of the instruction above.
Definition fcml_disassembler.h:260
fcml_st_prefixes_details prefixes_details
Some additional information about decoded instruction prefixes.
Definition fcml_disassembler.h:239
fcml_en_pseudo_operations pseudo_op
Pseudo operation code.
Definition fcml_disassembler.h:257
fcml_uint8_t instruction_code[FCML_INSTRUCTION_SIZE]
Code of the disassembled instruction.
Definition fcml_disassembler.h:235
fcml_bool opcode_field_s_bit
Opcode field 's'.
Definition fcml_disassembler.h:248
fcml_bool opcode_field_w_bit
Opcode field 'w'.
Definition fcml_disassembler.h:253
fcml_st_operand_details operand_details[FCML_OPERANDS_COUNT]
All disassembler specific information about operands going there.
Definition fcml_disassembler.h:241
fcml_usize instruction_size
Instruction size in bytes.
Definition fcml_disassembler.h:237
fcml_bool is_shortcut
True if this is a shortcut.
Definition fcml_disassembler.h:230
fcml_st_decoded_modrm_details modrm_details
Details about decoded ModR/M and SIB bytes.
Definition fcml_disassembler.h:243
fcml_en_instruction instruction
Instruction code/number.
Definition fcml_disassembler.h:255
fcml_uint64_t instruction_group
Instruction group.
Definition fcml_disassembler.h:262
fcml_uint8_t tuple_type
avx-512 tuple type
Definition fcml_disassembler.h:264
fcml_bool is_pseudo_op
True if a given instruction is a short form of pseudo-ops instructions.
Definition fcml_disassembler.h:233
Describes one decoded prefix.
Definition fcml_disassembler.h:110
fcml_uint8_t prefix
Prefix itself as raw byte.
Definition fcml_disassembler.h:112
fcml_en_prefix_types prefix_type
Type of the prefix.
Definition fcml_disassembler.h:114
fcml_uint8_t avx_bytes[3]
Place for additional bytes of VEX/EVEX/XOP prefix.
Definition fcml_disassembler.h:120
fcml_bool mandatory_prefix
FCML_TRUE if prefix is treated as mandatory one.
Definition fcml_disassembler.h:116
Some additional disassembler specific information about decoded operands.
Definition fcml_disassembler.h:191
fcml_en_access_mode access_mode
Instruction operand access mode READ, WRITE or both.
Definition fcml_disassembler.h:193
Contains some additional information about all decoded instruction prefixes.
Definition fcml_disassembler.h:127
fcml_uint8_t L
L field of XOP or VEX prefix.
Definition fcml_disassembler.h:173
fcml_uint8_t W
W field of REX,XOP or VEX/EVEX prefix.
Definition fcml_disassembler.h:171
fcml_bool is_evex
FCML TRUE if EVEX prefix exists.
Definition fcml_disassembler.h:151
fcml_uint8_t B
B field of REX,XOP or VEX prefix.
Definition fcml_disassembler.h:167
fcml_bool is_rex
FCML_TRUE if REX prefix exists.
Definition fcml_disassembler.h:157
fcml_uint8_t R_prim
EVEX R’ High-16 register specifier modifier.
Definition fcml_disassembler.h:163
fcml_uint8_t L_prim
L’ field of EVEX prefix.
Definition fcml_disassembler.h:175
fcml_uint8_t z
z field of EVEX prefix
Definition fcml_disassembler.h:183
fcml_uint8_t mmmm
m-mmmm field of XOP or VEX prefix.
Definition fcml_disassembler.h:177
fcml_bool is_branch
FCML_TRUE if branch prefix exists.
Definition fcml_disassembler.h:135
fcml_bool is_rep
FCML_TRUE if rep explicit prefix exists.
Definition fcml_disassembler.h:141
fcml_uint8_t pp
pp field of XOP or VEX/EVEX prefix.
Definition fcml_disassembler.h:181
fcml_bool is_lock
FCML_TRUE if lock explicit prefix exists.
Definition fcml_disassembler.h:139
fcml_uint8_t b
b field of EVEX prefix.
Definition fcml_disassembler.h:169
fcml_bool is_avx
True if it is an AVX instruction (VEX/XOP/EVEX).
Definition fcml_disassembler.h:155
fcml_uint8_t R
R field of REX,XOP or VEX prefix.
Definition fcml_disassembler.h:161
fcml_bool is_xrelease
FCML_TRUE if xrelease explicit prefix exists.
Definition fcml_disassembler.h:145
fcml_bool is_vex
FCML_TRUE if VEX prefix exists.
Definition fcml_disassembler.h:149
fcml_bool is_xop
FCML_TRUE if XOP prefix exists.
Definition fcml_disassembler.h:153
fcml_bool is_repne
FCML_TRUE if repne explicit prefix exists.
Definition fcml_disassembler.h:143
fcml_uint8_t vvvv
vvvv field of XOP or VEX prefix.
Definition fcml_disassembler.h:179
fcml_uint8_t avx_first_byte
First byte of AVX prefix.
Definition fcml_disassembler.h:159
fcml_st_instruction_prefix prefixes[FCML_DASM_PREFIXES_COUNT]
Array with decoded prefixes.
Definition fcml_disassembler.h:129
fcml_uint8_t aaa
Embedded opmask register specifier.
Definition fcml_disassembler.h:187
fcml_uint8_t X
X field of REX,XOP or VEX prefix.
Definition fcml_disassembler.h:165
fcml_bool is_nobranch
FCML_TRUE if nobranch prefix exists.
Definition fcml_disassembler.h:137
fcml_int prefixes_count
Number of decoded prefixes.
Definition fcml_disassembler.h:131
fcml_uint8_t V_prim
V’ field of EVEX prefix.
Definition fcml_disassembler.h:185
fcml_bool is_xacquire
FCML_TRUE if xacquire explicit prefix exists.
Definition fcml_disassembler.h:147
fcml_int prefixes_bytes_count
Number of bytes used by all decoded prefixes.
Definition fcml_disassembler.h:133
fcml_st_integer displacement
Displacement as encoded in disp8/disp16/disp32/disp8*N.
Definition fcml_disassembler.h:201
fcml_nuint32_t N
Scaling factor N in EVEX specific compressed disp8*N.
Definition fcml_disassembler.h:203