├── .gitignore
├── README.md
├── CMakeLists.txt
├── tests
├── CMakeLists.txt
└── test_x86_64.cpp
├── Instruction.cpp
├── include
└── edisassm
│ ├── ModRM.h
│ ├── SIB.h
│ ├── Model.h
│ ├── REX.h
│ ├── OPTable_Group11.tcc
│ ├── OPTable_Group4.tcc
│ ├── OPTable_Group8.tcc
│ ├── OPTable_Group5.tcc
│ ├── OPTable_Group6.tcc
│ ├── OPTable_Group10.tcc
│ ├── edisassm_exception.h
│ ├── OPTable_Group12.tcc
│ ├── edisassm_functions.h
│ ├── OPTable_Group3.tcc
│ ├── OPTable_Group13.tcc
│ ├── OPTable_Group14.tcc
│ ├── OPTable_Group15.tcc
│ ├── OPTable_Group16.tcc
│ ├── OPTable_Group17.tcc
│ ├── Formatter.h
│ ├── OPTable_Group1.tcc
│ ├── OPTable_Group9.tcc
│ ├── OPTable_Group2.tcc
│ ├── Operand.tcc
│ ├── edisassm_ops.h
│ ├── OPTable_Group7.tcc
│ ├── Operand.h
│ ├── OPTable_Other.tcc
│ ├── Formatter.tcc
│ ├── OPTable_1byte.tcc
│ ├── OPTable_3byte.tcc
│ └── Instruction.h
├── Formatter.cpp
├── edisassm.cpp
└── COPYING
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Compilation makes use of cmake and is fairly straight forward. The following
2 | command should successfully build (from withing the root edisassm directory):
3 |
4 | $ mkdir build
5 | $ cd build
6 | $ cmake ..
7 | $ make
8 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
2 | set(CMAKE_CXX_STANDARD 11)
3 | PROJECT(edisassm)
4 | INCLUDE_DIRECTORIES(include)
5 | SET(edisassm_SOURCES Instruction.cpp edisassm.cpp Formatter.cpp)
6 | SET(edisassm_HEADERS Instruction.h ModRM.h Operand.h REX.h SIB.h edisassm_exception.h edisassm_util.h Formatter.h)
7 | ADD_EXECUTABLE(edisassm ${edisassm_SOURCES})
8 | ENABLE_TESTING()
9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long -Wmissing-field-initializers -ansi -pedantic -W -Wall")
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
2 | set(CMAKE_CXX_STANDARD 11)
3 | SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
4 | INCLUDE_DIRECTORIES(../include)
5 |
6 | SET(test_x86_SOURCES test_x86.cpp ../Instruction.cpp ../Formatter.cpp)
7 | SET(test_x86_64_SOURCES test_x86_64.cpp ../Instruction.cpp ../Formatter.cpp)
8 |
9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-field-initializers -Wno-long-long -ansi -pedantic -W -Wall")
10 |
11 | ADD_EXECUTABLE(test_x86 ${test_x86_SOURCES})
12 | ADD_EXECUTABLE(test_x86_64 ${test_x86_64_SOURCES})
13 |
14 | SET(CMAKE_BUILD_TYPE Debug)
15 |
--------------------------------------------------------------------------------
/Instruction.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "edisassm/Instruction.h"
20 | #include "edisassm/Instruction32.h"
21 | #include "edisassm/Instruction64.h"
22 |
23 | // explicitly instantiate these two
24 | // to make sure everything links ok
25 | namespace edisassm {
26 |
27 | template class Instruction;
28 | template class Instruction;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/include/edisassm/ModRM.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef MODRM_20070530_H_
20 | #define MODRM_20070530_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 | namespace modrm {
26 | inline uint8_t rm(uint8_t value) { return value & 0x07; }
27 | inline uint8_t reg(uint8_t value) { return (value >> 3) & 0x07; }
28 | inline uint8_t mod(uint8_t value) { return (value >> 6) & 0x03; }
29 | }
30 | }
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/include/edisassm/SIB.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef SIB_20070530_H_
20 | #define SIB_20070530_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 | namespace sib {
26 | inline uint8_t base(uint8_t value) { return value & 0x07; }
27 | inline uint8_t index(uint8_t value) { return (value >> 3) & 0x07; }
28 | inline uint8_t scale(uint8_t value) { return (value >> 6) & 0x03; }
29 | }
30 | }
31 |
32 | #endif
33 |
34 |
--------------------------------------------------------------------------------
/include/edisassm/Model.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef EDISASSM_MODEL_20100915_H_
20 | #define EDISASSM_MODEL_20100915_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 |
26 | struct x86 {
27 | public:
28 | static const int BITS = 32;
29 | static const int MAX_SIZE = 20;
30 | static const int MAX_OPERANDS = 3;
31 |
32 | public:
33 | typedef uint32_t address_type;
34 | };
35 |
36 | struct x86_64 {
37 | public:
38 | static const int BITS = 64;
39 | static const int MAX_SIZE = 20;
40 | static const int MAX_OPERANDS = 3;
41 |
42 | public:
43 | typedef uint64_t address_type;
44 | };
45 |
46 | }
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/include/edisassm/REX.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef REX_20071217_H_
20 | #define REX_20071217_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 | namespace rex {
26 | inline bool is_rex(uint8_t value) { return (value & 0xf0) == 0x40; }
27 | inline uint8_t w(uint8_t value) { return (value >> 3) & 0x01; } // 64 bit mode
28 | inline uint8_t r(uint8_t value) { return (value >> 2) & 0x01; } // modRM extension
29 | inline uint8_t x(uint8_t value) { return (value >> 1) & 0x01; } // SIB extension
30 | inline uint8_t b(uint8_t value) { return (value >> 0) & 0x01; } // ModRM OR SIB base or Opcode Reg extension
31 | }
32 | }
33 |
34 | #endif
35 |
36 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group11.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP11_20080314_TCC_
20 | #define OPTABLE_GROUP11_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group11[8] = {
26 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
27 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
28 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
29 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
30 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
31 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
32 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
33 | { "ud", &Instruction::decode0, OP_UD, FLAG_NONE },
34 | };
35 |
36 | }
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group4.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP4_20080314_TCC_
20 | #define OPTABLE_GROUP4_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group4[8] = {
26 | { "inc", &Instruction::decode_Eb, OP_INC, FLAG_W_FLAGS },
27 | { "dec", &Instruction::decode_Eb, OP_DEC, FLAG_W_FLAGS },
28 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | }
37 |
38 | #endif
39 |
40 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group8.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP8_20080314_TCC_
20 | #define OPTABLE_GROUP8_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group8[8] = {
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
27 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
28 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "bt", &Instruction::decode_Ev_Ib, OP_BT, FLAG_W_FLAGS },
31 | { "bts", &Instruction::decode_Ev_Ib, OP_BTS, FLAG_W_FLAGS },
32 | { "btr", &Instruction::decode_Ev_Ib, OP_BTR, FLAG_W_FLAGS },
33 | { "btc", &Instruction::decode_Ev_Ib, OP_BTC, FLAG_W_FLAGS },
34 | };
35 |
36 | }
37 |
38 | #endif
39 |
40 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group5.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP5_20080314_TCC_
20 | #define OPTABLE_GROUP5_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group5[8] = {
26 | { "inc", &Instruction::decode_Ev, OP_INC, FLAG_W_FLAGS },
27 | { "dec", &Instruction::decode_Ev, OP_DEC, FLAG_W_FLAGS },
28 | { "call", &Instruction::decode_Ev, OP_CALL, FLAG_STACK },
29 | { "callf", &Instruction::decode_Ep, OP_CALL, FLAG_32BIT_ONLY | FLAG_STACK },
30 | { "jmp", &Instruction::decode_Ev, OP_JMP, FLAG_NONE },
31 | { "jmpf", &Instruction::decode_Ep, OP_JMP, FLAG_NONE },
32 | { "push", &Instruction::decode_Ev, OP_PUSH, FLAG_STACK },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | }
37 |
38 | #endif
39 |
40 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group6.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP6_20080314_TCC_
20 | #define OPTABLE_GROUP6_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group6[8] = {
26 | { "sldt", &Instruction::decode_Rv_Mw, OP_SLDT, FLAG_NONE },
27 | { "str", &Instruction::decode_Rv_Mw, OP_STR, FLAG_NONE },
28 | { "lldt", &Instruction::decode_Ew, OP_LLDT, FLAG_NONE },
29 | { "ltr", &Instruction::decode_Ew, OP_LTR, FLAG_NONE },
30 | { "verr", &Instruction::decode_Ew, OP_VERR, FLAG_NONE },
31 | { "verw", &Instruction::decode_Ew, OP_VERW, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE }, // NOTE: jmpe Ev on x86-64
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | }
37 |
38 | #endif
39 |
40 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group10.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP10_20080314_TCC_
20 | #define OPTABLE_GROUP10_20080314_TCC_
21 |
22 | // Group 1A in Intel docs
23 |
24 | namespace edisassm {
25 |
26 | template
27 | const typename Instruction::opcode_entry Instruction::Opcodes_Group10[8] = {
28 | { "pop", &Instruction::decode_Ev, OP_POP, FLAG_STACK },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
35 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
36 | };
37 |
38 | }
39 |
40 | #endif
41 |
42 |
--------------------------------------------------------------------------------
/include/edisassm/edisassm_exception.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef EDISASSM_EXCEPTION_20080414_H_
20 | #define EDISASSM_EXCEPTION_20080414_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 |
26 | struct invalid_instruction : public std::exception {
27 | public:
28 | invalid_instruction(std::size_t size) : size_(size) {
29 | }
30 |
31 | std::size_t size() const { return size_; }
32 |
33 | private:
34 | std::size_t size_;
35 | };
36 |
37 | struct instruction_too_big : invalid_instruction { instruction_too_big(std::size_t size) : invalid_instruction(size) {} };
38 | struct invalid_operand : invalid_instruction { invalid_operand(std::size_t size) : invalid_instruction(size) {} };
39 | struct too_many_operands : invalid_instruction { too_many_operands(std::size_t size) : invalid_instruction(size) {} };
40 | struct multiple_displacements : invalid_instruction { multiple_displacements(std::size_t size) : invalid_instruction(size) {} };
41 |
42 | }
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group12.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP12_20080314_TCC_
20 | #define OPTABLE_GROUP12_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group12[16] = {
26 | { "mov", &Instruction::decode_Eb_Ib, OP_MOV, FLAG_NONE },
27 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
28 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 |
35 | { "mov", &Instruction::decode_Ev_Iz, OP_MOV, FLAG_NONE },
36 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
37 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
43 | };
44 |
45 | }
46 |
47 | #endif
48 |
49 |
--------------------------------------------------------------------------------
/include/edisassm/edisassm_functions.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef EDISASSM_FUNCTIONS_20130610_H_
20 | #define EDISASSM_FUNCTIONS_20130610_H_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | bool is_call(const Instruction &insn) {
26 | return insn.type() == Instruction::OP_CALL;
27 | }
28 |
29 | template
30 | bool is_ret(const Instruction &insn) {
31 | return insn.type() == Instruction::OP_RET;
32 | }
33 |
34 | template
35 | bool is_conditional_jump(const Instruction &insn) {
36 |
37 | switch(insn.type()) {
38 | case Instruction::OP_JCC:
39 | case Instruction::OP_LOOP:
40 | case Instruction::OP_LOOPE:
41 | case Instruction::OP_LOOPNE:
42 | return true;
43 | default:
44 | return false;
45 | }
46 | }
47 |
48 | template
49 | bool is_unconditional_jump(const Instruction &insn) {
50 | return insn.type() == Instruction::OP_JMP;
51 | }
52 |
53 | template
54 | bool is_jump(const Instruction &insn) {
55 | return is_unconditional_jump(insn) || is_conditional_jump(insn);
56 | }
57 |
58 | template
59 | bool is_nop(const Instruction &insn) {
60 | return insn.type() == Instruction::OP_NOP;
61 | }
62 |
63 | template
64 | bool is_halt(const Instruction &insn) {
65 | return insn.type() == Instruction::OP_HLT;
66 | }
67 |
68 | template
69 | bool is_terminator(const Instruction &insn) {
70 | return is_halt(insn) || is_jump(insn) || is_ret(insn);
71 | }
72 |
73 | }
74 |
75 | #endif
76 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group3.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP3_20080314_TCC_
20 | #define OPTABLE_GROUP3_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group3[16] = {
26 | { "test", &Instruction::decode_Eb_Ib, OP_TEST, FLAG_NONE },
27 | { "test", &Instruction::decode_Eb_Ib, OP_TEST, FLAG_NONE }, // undocumented
28 | { "not", &Instruction::decode_Eb, OP_NOT, FLAG_NONE },
29 | { "neg", &Instruction::decode_Eb, OP_NEG, FLAG_W_FLAGS },
30 | { "mul", &Instruction::decode_Eb, OP_MUL, FLAG_W_FLAGS },
31 | { "imul", &Instruction::decode_Eb, OP_IMUL, FLAG_W_FLAGS },
32 | { "div", &Instruction::decode_Eb, OP_DIV, FLAG_NONE },
33 | { "idiv", &Instruction::decode_Eb, OP_IDIV, FLAG_NONE },
34 |
35 | { "test", &Instruction::decode_Ev_Iz, OP_TEST, FLAG_NONE },
36 | { "test", &Instruction::decode_Ev_Iz, OP_TEST, FLAG_NONE }, // undocumented
37 | { "not", &Instruction::decode_Ev, OP_NOT, FLAG_NONE },
38 | { "neg", &Instruction::decode_Ev, OP_NEG, FLAG_W_FLAGS },
39 | { "mul", &Instruction::decode_Ev, OP_MUL, FLAG_W_FLAGS },
40 | { "imul", &Instruction::decode_Ev, OP_IMUL, FLAG_W_FLAGS },
41 | { "div", &Instruction::decode_Ev, OP_DIV, FLAG_NONE },
42 | { "idiv", &Instruction::decode_Ev, OP_IDIV, FLAG_NONE },
43 | };
44 |
45 | }
46 |
47 | #endif
48 |
49 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group13.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP13_20080314_TCC_
20 | #define OPTABLE_GROUP13_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group13[8] = {
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
27 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
28 | { "psrlw", &Instruction::decode_Nq_Ib, OP_PSRLW, FLAG_MMX },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "psraw", &Instruction::decode_Nq_Ib, OP_PSRAW, FLAG_MMX },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "psllw", &Instruction::decode_Nq_Ib, OP_PSLLW, FLAG_MMX },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group13_66[8] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "psrlw", &Instruction::decode_Uo_Ib, OP_PSRLW, FLAG_SSE2 },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "psraw", &Instruction::decode_Uo_Ib, OP_PSRAW, FLAG_SSE2 },
43 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
44 | { "psllw", &Instruction::decode_Uo_Ib, OP_PSLLW, FLAG_SSE2 },
45 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
46 | };
47 |
48 | }
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group14.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP14_20080314_TCC_
20 | #define OPTABLE_GROUP14_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group14[8] = {
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
27 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
28 | { "psrld", &Instruction::decode_Nq_Ib, OP_PSRLD, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "psrad", &Instruction::decode_Nq_Ib, OP_PSRAD, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "pslld", &Instruction::decode_Nq_Ib, OP_PSLLD, FLAG_NONE },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group14_66[8] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "psrld", &Instruction::decode_Uo_Ib, OP_PSRLD, FLAG_NONE },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "psrad", &Instruction::decode_Uo_Ib, OP_PSRAD, FLAG_NONE },
43 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
44 | { "pslld", &Instruction::decode_Uo_Ib, OP_PSLLD, FLAG_NONE },
45 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
46 | };
47 |
48 | }
49 |
50 | #endif
51 |
52 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group15.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP15_20080314_TCC_
20 | #define OPTABLE_GROUP15_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group15[8] = {
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
27 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
28 | { "psrlq", &Instruction::decode_Nq_Ib, OP_PSRLQ, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "psllq", &Instruction::decode_Nq_Ib, OP_PSLLQ, FLAG_NONE },
33 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group15_66[8] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "psrlq", &Instruction::decode_Uo_Ib, OP_PSRLQ, FLAG_NONE },
41 | { "psrldq", &Instruction::decode_Uo_Ib, OP_PSRLDQ, FLAG_SSE2 },
42 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
43 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
44 | { "psllq", &Instruction::decode_Uo_Ib, OP_PSLLQ, FLAG_NONE },
45 | { "pslldq", &Instruction::decode_Uo_Ib, OP_PSLLDQ, FLAG_SSE2 },
46 | };
47 |
48 | }
49 |
50 | #endif
51 |
52 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group16.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP16_20080314_TCC_
20 | #define OPTABLE_GROUP16_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group16_Mem[8] = {
26 | { "fxsave", &Instruction::decode_M512, OP_FXSAVE, FLAG_SSE },
27 | { "fxrstor", &Instruction::decode_M512, OP_FXRSTOR, FLAG_SSE },
28 | { "ldmxcsr", &Instruction::decode_Md, OP_LDMXCSR, FLAG_SSE },
29 | { "stmxcsr", &Instruction::decode_Md, OP_STMXCSR, FLAG_SSE },
30 | { "xsave", &Instruction::decode_M, OP_XSAVE, FLAG_NONE },
31 | { "xrstor", &Instruction::decode_M, OP_XRSTOR, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
33 | { "clflush", &Instruction::decode_M, OP_CLFLUSH, FLAG_SSE2 },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group16_Reg[8] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
43 | { "lfence", &Instruction::decode0, OP_LFENCE, FLAG_SSE2 },
44 | { "mfence", &Instruction::decode0, OP_MFENCE, FLAG_SSE2 },
45 | { "sfence", &Instruction::decode0, OP_SFENCE, FLAG_SSE },
46 | };
47 |
48 | }
49 |
50 | #endif
51 |
52 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group17.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP17_20080314_TCC_
20 | #define OPTABLE_GROUP17_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group17[64] = {
26 | { "prefetchnta", &Instruction::decode_M, OP_PREFETCHH, FLAG_NONE },
27 | { "prefetcht0", &Instruction::decode_M, OP_PREFETCHH, FLAG_NONE },
28 | { "prefetcht1", &Instruction::decode_M, OP_PREFETCHH, FLAG_NONE },
29 | { "prefetcht2", &Instruction::decode_M, OP_PREFETCHH, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
33 | { "nop", &Instruction::decode_Ev, OP_NOP, FLAG_NONE }, // undocumented
34 |
35 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
36 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
37 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
40 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
43 |
44 | INVALID_BLOCK,
45 |
46 | INVALID_BLOCK,
47 |
48 | INVALID_BLOCK
49 | };
50 |
51 | }
52 |
53 | #endif
54 |
55 |
--------------------------------------------------------------------------------
/include/edisassm/Formatter.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef FORMATTER_H_
20 | #define FORMATTER_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 |
26 | template
27 | class Instruction;
28 |
29 | template
30 | class Operand;
31 |
32 | enum Syntax {
33 | SyntaxIntel,
34 | // SyntexATT // TODO(eteran): implement this format!
35 | };
36 |
37 | enum Capitalization {
38 | UpperCase,
39 | LowerCase
40 | };
41 |
42 | enum SmallNumberFormat {
43 | SmallNumAsHex,
44 | SmallNumAsDec
45 | };
46 |
47 | struct FormatOptions {
48 | Syntax syntax;
49 | Capitalization capitalization;
50 | SmallNumberFormat smallNumFormat;
51 | };
52 |
53 | class Formatter {
54 | public:
55 | Formatter();
56 | Formatter(const Formatter &other);
57 | ~Formatter();
58 | explicit Formatter(const FormatOptions &options);
59 | Formatter &operator=(const Formatter &rhs);
60 |
61 | public:
62 | FormatOptions options() const;
63 | void setOptions(const FormatOptions &options);
64 |
65 | public:
66 | template
67 | std::string to_string(const Instruction &inst) const;
68 |
69 | template
70 | std::string to_string(const Operand &op) const;
71 |
72 | template
73 | std::string to_byte_string(const Instruction &inst) const;
74 |
75 | template
76 | std::string register_name(typename Operand::Register reg) const;
77 |
78 | private:
79 | template
80 | std::string format_expression(const Operand &op) const;
81 |
82 | template
83 | std::string format_register(const Operand &op) const;
84 |
85 | public:
86 | void swap(Formatter &other);
87 |
88 | private:
89 | FormatOptions options_;
90 | };
91 |
92 | }
93 |
94 | #include "Formatter.tcc"
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/tests/test_x86_64.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "edisassm/Instruction.h"
3 | #include "edisassm/Formatter.h"
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | typedef edisassm::Instruction insn64_t;
10 |
11 | struct test_data_t {
12 | unsigned size;
13 | const char *bytes;
14 | const char *result;
15 | unsigned int flags;
16 | } test64_data[] = {
17 | {6,"\xf0\x66\x0f\x38\xf6\xc1", "lock adcx eax, ecx", insn64_t::FLAG_RW_FLAGS},
18 | {5,"\x48\x0f\xba\xe4\xff", "bt rsp, 0xff", insn64_t::FLAG_W_FLAGS },
19 | {2,"\xcd\x80", "int 0x80", insn64_t::FLAG_W_FLAGS},
20 | {4,"\x66\x83\xe4\xfe", "and sp, 0xfffe", insn64_t::FLAG_W_FLAGS },
21 | {4,"\x48\x83\xe4\xf0", "and rsp, 0xfffffffffffffff0", insn64_t::FLAG_W_FLAGS },
22 | {2,"\x6a\xfe", "push 0xfffffffffffffffe", insn64_t::FLAG_STACK },
23 | {5,"\x68\xff\xff\xff\xff", "push 0xffffffffffffffff", insn64_t::FLAG_STACK },
24 | {7,"\x67\x8b\x05\x10\x00\x00\x00", "mov eax, dword ptr [eip+16]", insn64_t::FLAG_NONE },
25 | {6,"\x8b\x05\x10\x00\x00\x00", "mov eax, dword ptr [rip+16]", insn64_t::FLAG_NONE },
26 |
27 |
28 | {3, "\x0f\x20\x40", "mov eax, cr0", insn64_t::FLAG_R_FLAGS },
29 | {3, "\x0f\x7e\xf0", "movd eax, mm6", insn64_t::FLAG_MMX},
30 | {3, "\x0f\x6e\xf8", "movd mm7, eax", insn64_t::FLAG_MMX},
31 | {5, "\x66\x44\x0f\x6e\xd1", "movd xmm10, ecx", insn64_t::FLAG_MMX},
32 | {8,"\xf2\x0f\x10\x05\xc0\x87\x04\x08", "movsd xmm0, qword ptr [rip+0x080487c0]", insn64_t::FLAG_SSE2},
33 | {9,"\xf2\x0f\x11\x84\x24\x98\x00\x00\x00", "movsd qword ptr [rsp+152], xmm0", insn64_t::FLAG_SSE2},
34 |
35 |
36 | };
37 |
38 | int main() {
39 |
40 | edisassm::FormatOptions options;
41 | options.syntax = edisassm::SyntaxIntel;
42 | options.capitalization = edisassm::LowerCase;
43 | options.smallNumFormat = edisassm::SmallNumAsHex;
44 | edisassm::Formatter formatter(options);
45 |
46 | for(size_t i = 0; i < sizeof(test64_data) / sizeof(test64_data[0]); ++i) {
47 | test_data_t *p = &test64_data[i];
48 |
49 | std::cout << "performing test #" << i << "...";
50 | insn64_t insn(p->bytes, p->bytes + p->size, 0x00000000, std::nothrow);
51 |
52 | if(!insn.valid() || formatter.to_string(insn) != p->result) {
53 | std::cout << "\n----------\n";
54 | std::cout << "GOT : " << formatter.to_string(insn) << std::endl;
55 | std::cout << "EXPECTED : " << p->result << std::endl;
56 | std::cout << "FAIL" << std::endl;
57 | return -1;
58 | }
59 |
60 | if(insn.size() != p->size) {
61 | std::cout << "\n----------\n";
62 | std::cout << formatter.to_byte_string(insn) << " incorrect size" << std::endl;
63 | std::cout << "FAIL" << std::endl;
64 | return -1;
65 | }
66 |
67 | if(insn.flags() != p->flags) {
68 | std::cout << "\n----------\n";
69 | std::cout << formatter.to_byte_string(insn) << " wrong flags" << std::endl;
70 | std::cout << "FLAGS: " << insn.flags() << std::endl;
71 | std::cout << "FAIL" << std::endl;
72 | return -1;
73 | }
74 |
75 | std::cout << " " << formatter.to_byte_string(insn) << " '" << formatter.to_string(insn) << "' " << "OK" << std::endl;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group1.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP1_20080314_TCC_
20 | #define OPTABLE_GROUP1_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group1[32] = {
26 | { "add", &Instruction::decode_Eb_Ib, OP_ADD, FLAG_W_FLAGS },
27 | { "or", &Instruction::decode_Eb_Ib, OP_OR, FLAG_W_FLAGS },
28 | { "adc", &Instruction::decode_Eb_Ib, OP_ADC, FLAG_RW_FLAGS },
29 | { "sbb", &Instruction::decode_Eb_Ib, OP_SBB, FLAG_NONE },
30 | { "and", &Instruction::decode_Eb_Ib, OP_AND, FLAG_W_FLAGS },
31 | { "sub", &Instruction::decode_Eb_Ib, OP_SUB, FLAG_NONE },
32 | { "xor", &Instruction::decode_Eb_Ib, OP_XOR, FLAG_NONE },
33 | { "cmp", &Instruction::decode_Eb_Ib, OP_CMP, FLAG_W_FLAGS },
34 |
35 | { "add", &Instruction::decode_Ev_Iz, OP_ADD, FLAG_W_FLAGS },
36 | { "or", &Instruction::decode_Ev_Iz, OP_OR, FLAG_W_FLAGS },
37 | { "adc", &Instruction::decode_Ev_Iz, OP_ADC, FLAG_RW_FLAGS },
38 | { "sbb", &Instruction::decode_Ev_Iz, OP_SBB, FLAG_NONE },
39 | { "and", &Instruction::decode_Ev_Iz, OP_AND, FLAG_W_FLAGS },
40 | { "sub", &Instruction::decode_Ev_Iz, OP_SUB, FLAG_NONE },
41 | { "xor", &Instruction::decode_Ev_Iz, OP_XOR, FLAG_NONE },
42 | { "cmp", &Instruction::decode_Ev_Iz, OP_CMP, FLAG_W_FLAGS },
43 |
44 | { "add", &Instruction::decode_Eb_Ib, OP_ADD, FLAG_W_FLAGS },
45 | { "or", &Instruction::decode_Eb_Ib, OP_OR, FLAG_W_FLAGS },
46 | { "adc", &Instruction::decode_Eb_Ib, OP_ADC, FLAG_RW_FLAGS },
47 | { "sbb", &Instruction::decode_Eb_Ib, OP_SBB, FLAG_NONE },
48 | { "and", &Instruction::decode_Eb_Ib, OP_AND, FLAG_W_FLAGS },
49 | { "sub", &Instruction::decode_Eb_Ib, OP_SUB, FLAG_NONE },
50 | { "xor", &Instruction::decode_Eb_Ib, OP_XOR, FLAG_NONE },
51 | { "cmp", &Instruction::decode_Eb_Ib, OP_CMP, FLAG_W_FLAGS },
52 |
53 | { "add", &Instruction::decode_Ev_Ixb, OP_ADD, FLAG_W_FLAGS },
54 | { "or", &Instruction::decode_Ev_Ixb, OP_OR, FLAG_W_FLAGS },
55 | { "adc", &Instruction::decode_Ev_Ixb, OP_ADC, FLAG_RW_FLAGS },
56 | { "sbb", &Instruction::decode_Ev_Ixb, OP_SBB, FLAG_NONE },
57 | { "and", &Instruction::decode_Ev_Ixb, OP_AND, FLAG_W_FLAGS },
58 | { "sub", &Instruction::decode_Ev_Ixb, OP_SUB, FLAG_NONE },
59 | { "xor", &Instruction::decode_Ev_Ixb, OP_XOR, FLAG_NONE },
60 | { "cmp", &Instruction::decode_Ev_Ixb, OP_CMP, FLAG_W_FLAGS },
61 | };
62 |
63 | }
64 |
65 | #endif
66 |
67 |
--------------------------------------------------------------------------------
/Formatter.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "edisassm/Formatter.h"
20 | #include
21 |
22 | namespace edisassm {
23 |
24 | //------------------------------------------------------------------------------
25 | // Name: Formatter
26 | //------------------------------------------------------------------------------
27 | Formatter::Formatter() {
28 | options_.syntax = SyntaxIntel;
29 | options_.capitalization = LowerCase;
30 | options_.smallNumFormat = SmallNumAsDec;
31 | }
32 |
33 | //------------------------------------------------------------------------------
34 | // Name: Formatter
35 | //------------------------------------------------------------------------------
36 | Formatter::Formatter(const Formatter &other) : options_(other.options_) {
37 |
38 | }
39 |
40 | //------------------------------------------------------------------------------
41 | // Name: ~Formatter
42 | //------------------------------------------------------------------------------
43 | Formatter::~Formatter() {
44 |
45 | }
46 |
47 | //------------------------------------------------------------------------------
48 | // Name: Formatter
49 | //------------------------------------------------------------------------------
50 | Formatter::Formatter(const FormatOptions &options) : options_(options) {
51 |
52 | }
53 |
54 | //------------------------------------------------------------------------------
55 | // Name: options
56 | //------------------------------------------------------------------------------
57 | FormatOptions Formatter::options() const {
58 | return options_;
59 | }
60 |
61 | //------------------------------------------------------------------------------
62 | // Name: setOptions
63 | //------------------------------------------------------------------------------
64 | void Formatter::setOptions(const FormatOptions &options) {
65 | options_ = options;
66 | }
67 |
68 | //------------------------------------------------------------------------------
69 | // Name: operator=
70 | //------------------------------------------------------------------------------
71 | Formatter &Formatter::operator=(const Formatter &rhs) {
72 | Formatter(rhs).swap(*this);
73 | return *this;
74 | }
75 |
76 | //------------------------------------------------------------------------------
77 | // Name: swap
78 | //------------------------------------------------------------------------------
79 | void Formatter::swap(Formatter &other) {
80 | using std::swap;
81 | swap(options_, other.options_);
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group9.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP9_20080314_TCC_
20 | #define OPTABLE_GROUP9_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group9[8] = {
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
27 | { "cmpxchg8b/cmpxchg16b", &Instruction::decode_invalid_cmpxchg8b_cmpxchg16b, OP_GROUP, FLAG_NONE },
28 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
29 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
30 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "vmptrld", &Instruction::decode_Mq, OP_VMPTRLD, FLAG_VMX },
33 | { "vmptrst", &Instruction::decode_Mq, OP_VMPTRST, FLAG_VMX },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group9_66[8] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "cmpxchg8b/cmpxchg16b", &Instruction::decode_invalid_cmpxchg8b_cmpxchg16b, OP_GROUP, FLAG_NONE },
40 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
41 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
42 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
43 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
44 | { "vmclear", &Instruction::decode_Mq, OP_VMCLEAR, FLAG_VMX },
45 | { "vmptrst", &Instruction::decode_Mq, OP_VMPTRST, FLAG_VMX },
46 | };
47 |
48 | template
49 | const typename Instruction::opcode_entry Instruction::Opcodes_Group9_F3[8] = {
50 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
51 | { "cmpxchg8b/cmpxchg16b", &Instruction::decode_invalid_cmpxchg8b_cmpxchg16b, OP_GROUP, FLAG_NONE },
52 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
53 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
54 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
55 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
56 | { "vmxon", &Instruction::decode_Mq, OP_VMXON, FLAG_VMX },
57 | { "vmptrst", &Instruction::decode_Mq, OP_VMPTRST, FLAG_VMX },
58 | };
59 |
60 | }
61 |
62 | #endif
63 |
64 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group2.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP2_20080314_TCC_
20 | #define OPTABLE_GROUP2_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group2[16] = {
26 | { "rol", &Instruction::decode_Eb_Ib, OP_ROL, FLAG_NONE },
27 | { "ror", &Instruction::decode_Eb_Ib, OP_ROR, FLAG_NONE },
28 | { "rcl", &Instruction::decode_Eb_Ib, OP_RCL, FLAG_NONE },
29 | { "rcr", &Instruction::decode_Eb_Ib, OP_RCR, FLAG_NONE },
30 | { "shl", &Instruction::decode_Eb_Ib, OP_SHL, FLAG_NONE },
31 | { "shr", &Instruction::decode_Eb_Ib, OP_SHR, FLAG_NONE },
32 | { "sal", &Instruction::decode_Eb_Ib, OP_SAL, FLAG_NONE },
33 | { "sar", &Instruction::decode_Eb_Ib, OP_SAR, FLAG_NONE },
34 |
35 | { "rol", &Instruction::decode_Ev_Ib, OP_ROL, FLAG_NONE },
36 | { "ror", &Instruction::decode_Ev_Ib, OP_ROR, FLAG_NONE },
37 | { "rcl", &Instruction::decode_Ev_Ib, OP_RCL, FLAG_NONE },
38 | { "rcr", &Instruction::decode_Ev_Ib, OP_RCR, FLAG_NONE },
39 | { "shl", &Instruction::decode_Ev_Ib, OP_SHL, FLAG_NONE },
40 | { "shr", &Instruction::decode_Ev_Ib, OP_SHR, FLAG_NONE },
41 | { "sal", &Instruction::decode_Ev_Ib, OP_SAL, FLAG_NONE },
42 | { "sar", &Instruction::decode_Ev_Ib, OP_SAR, FLAG_NONE },
43 | };
44 |
45 | template
46 | const typename Instruction::opcode_entry Instruction::Opcodes_Group2D[32] = {
47 | { "rol", &Instruction::decode_Eb_1, OP_ROL, FLAG_NONE },
48 | { "ror", &Instruction::decode_Eb_1, OP_ROR, FLAG_NONE },
49 | { "rcl", &Instruction::decode_Eb_1, OP_RCL, FLAG_NONE },
50 | { "rcr", &Instruction::decode_Eb_1, OP_RCR, FLAG_NONE },
51 | { "shl", &Instruction::decode_Eb_1, OP_SHL, FLAG_NONE },
52 | { "shr", &Instruction::decode_Eb_1, OP_SHR, FLAG_NONE },
53 | { "sal", &Instruction::decode_Eb_1, OP_SAL, FLAG_NONE },
54 | { "sar", &Instruction::decode_Eb_1, OP_SAR, FLAG_NONE },
55 |
56 | { "rol", &Instruction::decode_Ev_1, OP_ROL, FLAG_NONE },
57 | { "ror", &Instruction::decode_Ev_1, OP_ROR, FLAG_NONE },
58 | { "rcl", &Instruction::decode_Ev_1, OP_RCL, FLAG_NONE },
59 | { "rcr", &Instruction::decode_Ev_1, OP_RCR, FLAG_NONE },
60 | { "shl", &Instruction::decode_Ev_1, OP_SHL, FLAG_NONE },
61 | { "shr", &Instruction::decode_Ev_1, OP_SHR, FLAG_NONE },
62 | { "sal", &Instruction::decode_Ev_1, OP_SAL, FLAG_NONE },
63 | { "sar", &Instruction::decode_Ev_1, OP_SAR, FLAG_NONE },
64 |
65 | { "rol", &Instruction::decode_Eb_CL, OP_ROL, FLAG_NONE },
66 | { "ror", &Instruction::decode_Eb_CL, OP_ROR, FLAG_NONE },
67 | { "rcl", &Instruction::decode_Eb_CL, OP_RCL, FLAG_NONE },
68 | { "rcr", &Instruction::decode_Eb_CL, OP_RCR, FLAG_NONE },
69 | { "shl", &Instruction::decode_Eb_CL, OP_SHL, FLAG_NONE },
70 | { "shr", &Instruction::decode_Eb_CL, OP_SHR, FLAG_NONE },
71 | { "sal", &Instruction::decode_Eb_CL, OP_SAL, FLAG_NONE },
72 | { "sar", &Instruction::decode_Eb_CL, OP_SAR, FLAG_NONE },
73 |
74 | { "rol", &Instruction::decode_Ev_CL, OP_ROL, FLAG_NONE },
75 | { "ror", &Instruction::decode_Ev_CL, OP_ROR, FLAG_NONE },
76 | { "rcl", &Instruction::decode_Ev_CL, OP_RCL, FLAG_NONE },
77 | { "rcr", &Instruction::decode_Ev_CL, OP_RCR, FLAG_NONE },
78 | { "shl", &Instruction::decode_Ev_CL, OP_SHL, FLAG_NONE },
79 | { "shr", &Instruction::decode_Ev_CL, OP_SHR, FLAG_NONE },
80 | { "sal", &Instruction::decode_Ev_CL, OP_SAL, FLAG_NONE },
81 | { "sar", &Instruction::decode_Ev_CL, OP_SAR, FLAG_NONE },
82 | };
83 |
84 | }
85 |
86 | #endif
87 |
88 |
--------------------------------------------------------------------------------
/include/edisassm/Operand.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPERAND_20080421_TCC_
20 | #define OPERAND_20080421_TCC_
21 |
22 | #include "Instruction.h"
23 | #include
24 | #include
25 |
26 | namespace edisassm {
27 |
28 | //------------------------------------------------------------------------------
29 | // Name: Operand
30 | //------------------------------------------------------------------------------
31 | template
32 | Operand::Operand() : owner_(0), type_(TYPE_INVALID) {
33 | using std::memset;
34 | memset(&u, 0, sizeof(U));
35 | }
36 |
37 | //------------------------------------------------------------------------------
38 | // Name: swap
39 | //------------------------------------------------------------------------------
40 | template
41 | void Operand::swap(Operand &other) {
42 | using std::swap;
43 |
44 | swap(owner_, other.owner_);
45 | swap(type_, other.type_);
46 | swap(u, other.u);
47 | }
48 |
49 | //------------------------------------------------------------------------------
50 | // Name: relative_target
51 | //------------------------------------------------------------------------------
52 | template
53 | uint64_t Operand::relative_target() const {
54 |
55 | const uint64_t rva = owner_->rva();
56 | const unsigned int size = owner_->size();
57 | const uint64_t offset = rva + size;
58 |
59 | switch(type_) {
60 | case TYPE_REL8:
61 | return static_cast(u.sbyte + offset);
62 | case TYPE_REL16:
63 | // NOTE: intel truncates EIP to 16-bit here
64 | return static_cast((u.sword + offset) & 0xffff);
65 | case TYPE_REL32:
66 | return static_cast(u.sdword + offset);
67 | case TYPE_REL64:
68 | return static_cast(u.sqword + offset);
69 | default:
70 | return 0;
71 | }
72 | }
73 |
74 | //------------------------------------------------------------------------------
75 | // Name: displacement
76 | //------------------------------------------------------------------------------
77 | template
78 | int32_t Operand::displacement() const {
79 |
80 | switch(u.expression.displacement_type) {
81 | case DISP_U8: return static_cast(u.expression.u_disp8);
82 | case DISP_U16: return static_cast(u.expression.u_disp16);
83 | case DISP_U32: return static_cast(u.expression.u_disp32);
84 | case DISP_S8: return static_cast(u.expression.s_disp8);
85 | case DISP_S16: return static_cast(u.expression.s_disp16);
86 | case DISP_S32: return static_cast(u.expression.s_disp32);
87 | default:
88 | return 0;
89 | }
90 | }
91 |
92 | //------------------------------------------------------------------------------
93 | // Name: immediate
94 | //------------------------------------------------------------------------------
95 | template
96 | int64_t Operand::immediate() const {
97 |
98 | switch(type_) {
99 | case TYPE_IMMEDIATE8: return static_cast(u.sbyte);
100 | case TYPE_IMMEDIATE16: return static_cast(u.sword);
101 | case TYPE_IMMEDIATE32: return static_cast(u.sdword);
102 | case TYPE_IMMEDIATE64: return static_cast(u.sqword);
103 | default:
104 | return 0;
105 | }
106 | }
107 |
108 | //------------------------------------------------------------------------------
109 | // Name: general_type
110 | //------------------------------------------------------------------------------
111 | template
112 | typename Operand::Type Operand::general_type() const {
113 | return static_cast(static_cast(type_) & TYPE_MASK);
114 | }
115 |
116 | }
117 |
118 | #endif
119 |
--------------------------------------------------------------------------------
/include/edisassm/edisassm_ops.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef EDISASSM_OPS_20110816_H_
20 | #define EDISASSM_OPS_20110816_H_
21 |
22 | namespace edisassm {
23 |
24 | //------------------------------------------------------------------------------
25 | // Name: operator==
26 | //------------------------------------------------------------------------------
27 | template
28 | bool operator==(const Instruction &lhs, const Instruction &rhs) {
29 | // invalid ops match nothing
30 | if(!lhs.valid() || !rhs.valid()) {
31 | return false;
32 | }
33 |
34 | // do the types match?
35 | if(lhs.type() != rhs.type()) {
36 | return false;
37 | }
38 |
39 | const unsigned int lhs_operand_count = lhs.operand_count();
40 | const unsigned int rhs_operand_count = rhs.operand_count();
41 |
42 | // do the number of operands match?
43 | if(lhs_operand_count != rhs_operand_count) {
44 | return false;
45 | }
46 |
47 | // compare the type and value of each operand
48 | for(unsigned int i = 0; i < lhs_operand_count; ++i) {
49 |
50 | const typename Instruction::operand_type &lhs_operand = lhs.operands_[i];
51 | const typename Instruction::operand_type &rhs_operand = rhs.operands_[i];
52 |
53 | typename Instruction::operand_type::Type lhs_operand_type = lhs_operand.general_type();
54 | typename Instruction::operand_type::Type rhs_operand_type = rhs_operand.general_type();
55 |
56 | if(lhs_operand_type != rhs_operand_type) {
57 | return false;
58 | }
59 |
60 | // TODO(eteran): support generics
61 | switch(lhs_operand_type) {
62 | case Operand::TYPE_REGISTER:
63 | if(lhs_operand.reg() != rhs_operand.reg()) {
64 | return false;
65 | }
66 | break;
67 | case Operand::TYPE_IMMEDIATE:
68 | if(lhs_operand.immediate() != rhs_operand.immediate()) {
69 | return false;
70 | }
71 | break;
72 | case Operand::TYPE_REL:
73 | if(lhs_operand.relative_target() != rhs_operand.relative_target()) {
74 | return false;
75 | }
76 | break;
77 | case Operand::TYPE_ABSOLUTE:
78 | if(lhs_operand.absolute().offset != rhs_operand.absolute().offset) {
79 | return false;
80 | }
81 |
82 | if(lhs_operand.absolute().seg != rhs_operand.absolute().seg) {
83 | return false;
84 | }
85 | break;
86 | default:
87 | case Operand::TYPE_EXPRESSION:
88 | {
89 | // This is a bit more complex, because there are mathematical
90 | // equivalencies
91 | typename Operand::expression_t lhs_expression = lhs_operand.expression();
92 | typename Operand::expression_t rhs_expression = rhs_operand.expression();
93 |
94 |
95 | if(lhs_operand.displacement() != rhs_operand.displacement()) {
96 | return false;
97 | }
98 |
99 | // the simple case
100 | if( lhs_expression.base == rhs_expression.base &&
101 | lhs_expression.index == rhs_expression.index &&
102 | lhs_expression.scale == rhs_expression.scale) {
103 |
104 | return true;
105 | }
106 |
107 | // Inst1 [index * 1] == Inst2 [base]
108 | if( lhs_expression.base == Operand::REG_NULL &&
109 | lhs_expression.scale == 1 &&
110 | lhs_expression.index == rhs_expression.base) {
111 |
112 |
113 | return true;
114 | }
115 |
116 | // Inst2 [index * 1] == Inst1 [base]
117 | if( rhs_expression.base == Operand::REG_NULL &&
118 | rhs_expression.scale == 1 &&
119 | rhs_expression.index == lhs_expression.base) {
120 |
121 |
122 | return true;
123 | }
124 |
125 | if(lhs_expression.index == Operand::REG_NULL || rhs_expression.index == Operand::REG_NULL) {
126 | if(lhs_expression.base == rhs_expression.base) {
127 | return true;
128 | }
129 | }
130 |
131 | return false;
132 | }
133 | break;
134 | }
135 | }
136 |
137 | return true;
138 | }
139 |
140 | //------------------------------------------------------------------------------
141 | // Name: operator!=
142 | //------------------------------------------------------------------------------
143 | template
144 | bool operator!=(const Instruction &lhs, const Instruction &rhs) {
145 | return !(lhs == rhs);
146 | }
147 |
148 | }
149 |
150 | #endif
151 |
--------------------------------------------------------------------------------
/edisassm.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #include "edisassm/Instruction.h"
20 | #include "edisassm/Formatter.h"
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | using namespace edisassm;
28 |
29 | namespace {
30 |
31 | enum DISPLAY_FLAGS {
32 | FLAG_NONE = 0x00,
33 | FLAG_SHOW_BYTES = 0x01
34 | };
35 |
36 | template
37 | std::string format_invalid_instruction(const Instruction &inst) {
38 | char byte_buffer[32];
39 | const uint8_t *const buf = inst.bytes();
40 |
41 | switch(inst.size()) {
42 | case 1:
43 | snprintf(byte_buffer, sizeof(byte_buffer), "db 0x%02x", buf[0] & 0xff);
44 | break;
45 | case 2:
46 | snprintf(byte_buffer, sizeof(byte_buffer), "dw 0x%02x%02x", buf[1] & 0xff, buf[0] & 0xff);
47 | break;
48 | case 4:
49 | snprintf(byte_buffer, sizeof(byte_buffer), "dd 0x%02x%02x%02x%02x", buf[3] & 0xff, buf[2] & 0xff, buf[1] & 0xff, buf[0] & 0xff);
50 | break;
51 | case 8:
52 | snprintf(byte_buffer, sizeof(byte_buffer), "dq 0x%02x%02x%02x%02x%02x%02x%02x%02x", buf[7] & 0xff, buf[6] & 0xff, buf[5] & 0xff, buf[4] & 0xff, buf[3] & 0xff, buf[2] & 0xff, buf[1] & 0xff, buf[0] & 0xff);
53 | break;
54 | default:
55 | // we tried...didn't we?
56 | return "invalid";
57 | }
58 | return byte_buffer;
59 | }
60 |
61 | //------------------------------------------------------------------------------
62 | // Name: disassemble
63 | //------------------------------------------------------------------------------
64 | template
65 | void disassemble(In first, In last, uint64_t rva, unsigned int flags) {
66 |
67 | typedef Instruction insn_t;
68 |
69 | Formatter formatter;
70 |
71 | while(first != last) {
72 |
73 | insn_t instruction(first, last, rva, std::nothrow);
74 | if(instruction) {
75 | std::cout << std::hex << rva << ": ";
76 | if(flags & FLAG_SHOW_BYTES) {
77 | std::cout << formatter.to_byte_string(instruction) << " ";
78 | }
79 | std::cout << formatter.to_string(instruction) << '\n';
80 | first += instruction.size();
81 | rva += instruction.size();
82 | } else {
83 | std::cout << std::hex << rva << ": ";
84 | if(flags & FLAG_SHOW_BYTES) {
85 | std::cout << formatter.to_byte_string(instruction) << " ";
86 | }
87 | std::cout << format_invalid_instruction(instruction) << " (bad)\n";
88 | first += instruction.size();
89 | rva += instruction.size();
90 | }
91 | }
92 | }
93 |
94 | //------------------------------------------------------------------------------
95 | // Name: print_usage
96 | //------------------------------------------------------------------------------
97 | void print_usage(const char *arg0) {
98 | std::cerr << arg0 << " [-m32|-m64] [-x] [--rva ] [--show-bytes] [ | -]" << std::endl;
99 | exit(-1);
100 | }
101 |
102 | //------------------------------------------------------------------------------
103 | // Name: get_input
104 | //------------------------------------------------------------------------------
105 | std::vector get_input(const std::string &filename, bool hex_chars) {
106 |
107 | std::vector r;
108 |
109 | std::ifstream file;
110 | std::istream *s = 0;
111 |
112 | if(filename == "-") {
113 | s = &std::cin;
114 | } else {
115 | file.open(filename.c_str(), std::ios::binary);
116 | if(file) {
117 | s = &file;
118 | } else {
119 | std::cerr << "could not open the file: " << filename << std::endl;
120 | }
121 | }
122 |
123 | if(s) {
124 | std::istream &stream = *s;
125 |
126 | if(hex_chars) {
127 | uint32_t x;
128 | while(stream >> std::hex >> x) {
129 | r.push_back(x);
130 | }
131 | } else {
132 | r.assign(std::istreambuf_iterator(stream), std::istreambuf_iterator());
133 | }
134 | }
135 |
136 | return r;
137 | }
138 |
139 | }
140 |
141 | //------------------------------------------------------------------------------
142 | // Name: main
143 | //------------------------------------------------------------------------------
144 | int main(int argc, char *argv[]) {
145 |
146 | unsigned int flags = FLAG_NONE;
147 | bool x86_64_mode = false;
148 | bool hex_chars = false;
149 | uint64_t rva_address = 0;
150 | std::string filename;
151 |
152 | for(int i = 1; i < argc; ++i) {
153 | if(argv[i][0] == '-') {
154 | if(strcmp(argv[i], "-m32") == 0) {
155 | x86_64_mode = false;
156 | } else if(strcmp(argv[i], "-m64") == 0) {
157 | x86_64_mode = true;
158 | } else if(strcmp(argv[i], "-x") == 0) {
159 | hex_chars = true;
160 | } else if(strcmp(argv[i], "--rva") == 0) {
161 | ++i;
162 | if(argv[i] == 0) {
163 | print_usage(argv[0]);
164 | }
165 | rva_address = strtoul(argv[i], 0, 0);
166 | } else if(strcmp(argv[i], "--show-bytes") == 0) {
167 | flags |= FLAG_SHOW_BYTES;
168 | } else if(strcmp(argv[i], "-") == 0) {
169 | filename = argv[i];
170 | break;
171 | } else {
172 | print_usage(argv[0]);
173 | }
174 | } else {
175 | filename = argv[i];
176 | break;
177 | }
178 | }
179 |
180 | if(filename.empty()) {
181 | print_usage(argv[0]);
182 | }
183 |
184 | const std::vector data = get_input(filename, hex_chars);
185 |
186 | if(x86_64_mode) {
187 | disassemble(data.begin(), data.end(), rva_address, flags);
188 | } else {
189 | disassemble(data.begin(), data.end(), rva_address, flags);
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Group7.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_GROUP7_20080314_TCC_
20 | #define OPTABLE_GROUP7_20080314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcodes_Group7[8] = {
26 | { "sgdt", &Instruction::decode_Ms, OP_SGDT, FLAG_NONE },
27 | { "sidt", &Instruction::decode_Ms, OP_SIDT, FLAG_NONE },
28 | { "lgdt", &Instruction::decode_Ms, OP_LGDT, FLAG_NONE },
29 | { "lidt", &Instruction::decode_Ms, OP_LIDT, FLAG_NONE },
30 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
31 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
32 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
33 | { "invlpg", &Instruction::decode_Mb, OP_INVLPG, FLAG_NONE },
34 | };
35 |
36 | template
37 | const typename Instruction::opcode_entry Instruction::Opcodes_Group7A[64] = {
38 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
39 | { "vmcall", &Instruction::decode0, OP_VMCALL, FLAG_VMX | FLAG_W_FLAGS },
40 | { "vmlaunch", &Instruction::decode0, OP_VMLAUNCH, FLAG_VMX | FLAG_W_FLAGS },
41 | { "vmresume", &Instruction::decode0, OP_VMRESUME, FLAG_VMX | FLAG_W_FLAGS },
42 | { "vmxoff", &Instruction::decode0, OP_VMXOFF, FLAG_VMX | FLAG_W_FLAGS },
43 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
44 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
45 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
46 |
47 | { "monitor", &Instruction::decode0, OP_MONITOR, FLAG_SSE3 },
48 | { "mwait", &Instruction::decode0, OP_MWAIT, FLAG_SSE3 },
49 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
50 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
51 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
52 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
53 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
54 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
55 |
56 | { "xgetbv", &Instruction::decode0, OP_XGETBV, FLAG_NONE },
57 | { "xsetbv", &Instruction::decode0, OP_XSETBV, FLAG_NONE },
58 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
59 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
60 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
61 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
62 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
63 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
64 |
65 | { "vmrun", &Instruction::decode0, OP_VMRUN, FLAG_AMD },
66 | { "vmmcall", &Instruction::decode0, OP_VMMCALL, FLAG_AMD },
67 | { "vmload", &Instruction::decode0, OP_VMLOAD, FLAG_AMD },
68 | { "vmsave", &Instruction::decode0, OP_VMSAVE, FLAG_AMD },
69 | { "stgi", &Instruction::decode0, OP_STGI, FLAG_AMD },
70 | { "clgi", &Instruction::decode0, OP_CLGI, FLAG_AMD },
71 | { "skinit", &Instruction::decode0, OP_SKINIT, FLAG_AMD },
72 | { "invlpga", &Instruction::decode0, OP_INVLPGA, FLAG_AMD },
73 |
74 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
75 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
76 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
77 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
78 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
79 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
80 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
81 | { "smsw", &Instruction::decode_Rv_Mw, OP_SMSW, FLAG_NONE },
82 |
83 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
84 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
85 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
86 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
87 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
88 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
89 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
90 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
91 |
92 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
93 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
94 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
95 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
96 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
97 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
98 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
99 | { "lmsw", &Instruction::decode_Ew, OP_LMSW, FLAG_NONE },
100 |
101 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE }, // x86-64: swapgs
102 | { "rdtscp", &Instruction::decode0, OP_RDTSCP, FLAG_NONE },
103 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
104 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
105 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
106 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
107 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
108 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
109 | };
110 |
111 | }
112 |
113 | #endif
114 |
--------------------------------------------------------------------------------
/include/edisassm/Operand.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPERAND_20070521_H_
20 | #define OPERAND_20070521_H_
21 |
22 | #include
23 |
24 | namespace edisassm {
25 |
26 | template
27 | class Instruction;
28 |
29 | template
30 | class Operand {
31 | private:
32 | friend class Instruction;
33 |
34 | public:
35 | Operand();
36 | ~Operand() {}
37 |
38 | private:
39 | typedef Operand operand_type;
40 | typedef Instruction instruction_type;
41 |
42 | public:
43 | enum Register {
44 | // a special value to mean "no register used" when appropriate
45 | REG_NULL,
46 |
47 | REG_RAX, REG_RCX, REG_RDX, REG_RBX,
48 | REG_RSP, REG_RBP, REG_RSI, REG_RDI,
49 | REG_R8, REG_R9, REG_R10, REG_R11,
50 | REG_R12, REG_R13, REG_R14, REG_R15,
51 |
52 | REG_EAX, REG_ECX, REG_EDX, REG_EBX,
53 | REG_ESP, REG_EBP, REG_ESI, REG_EDI,
54 | REG_R8D, REG_R9D, REG_R10D, REG_R11D,
55 | REG_R12D, REG_R13D, REG_R14D, REG_R15D,
56 |
57 | REG_AX, REG_CX, REG_DX, REG_BX,
58 | REG_SP, REG_BP, REG_SI, REG_DI,
59 | REG_R8W, REG_R9W, REG_R10W, REG_R11W,
60 | REG_R12W, REG_R13W, REG_R14W, REG_R15W,
61 |
62 | REG_AL, REG_CL, REG_DL, REG_BL,
63 | REG_AH, REG_CH, REG_DH, REG_BH,
64 | REG_R8B, REG_R9B, REG_R10B, REG_R11B,
65 | REG_R12B, REG_R13B, REG_R14B, REG_R15B,
66 | REG_SPL, REG_BPL, REG_SIL, REG_DIL,
67 |
68 | REG_ES, REG_CS, REG_SS, REG_DS,
69 | REG_FS, REG_GS, REG_SEG7, REG_SEG8,
70 |
71 | REG_CR0, REG_CR1, REG_CR2, REG_CR3,
72 | REG_CR4, REG_CR5, REG_CR6, REG_CR7,
73 | REG_CR8, REG_CR9, REG_CR10, REG_CR11,
74 | REG_CR12, REG_CR13, REG_CR14, REG_CR15,
75 |
76 | REG_DR0, REG_DR1, REG_DR2, REG_DR3,
77 | REG_DR4, REG_DR5, REG_DR6, REG_DR7,
78 | REG_DR8, REG_DR9, REG_DR10, REG_DR11,
79 | REG_DR12, REG_DR13, REG_DR14, REG_DR15,
80 |
81 | REG_TR0, REG_TR1, REG_TR2, REG_TR3,
82 | REG_TR4, REG_TR5, REG_TR6, REG_TR7,
83 |
84 | REG_MM0, REG_MM1, REG_MM2, REG_MM3,
85 | REG_MM4, REG_MM5, REG_MM6, REG_MM7,
86 |
87 | REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3,
88 | REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7,
89 | REG_XMM8, REG_XMM9, REG_XMM10, REG_XMM11,
90 | REG_XMM12, REG_XMM13, REG_XMM14, REG_XMM15,
91 |
92 | REG_ST,
93 | REG_ST0, REG_ST1, REG_ST2, REG_ST3,
94 | REG_ST4, REG_ST5, REG_ST6, REG_ST7,
95 |
96 | REG_RIP,
97 | REG_EIP,
98 |
99 | // special value meaning an error in decoding
100 | REG_INVALID
101 | };
102 |
103 | enum Type {
104 | TYPE_INVALID = 0x00000000,
105 | TYPE_REGISTER = 0x00000100,
106 | TYPE_IMMEDIATE = 0x00000200,
107 | TYPE_IMMEDIATE8 = 0x00000201,
108 | TYPE_IMMEDIATE16 = 0x00000202,
109 | TYPE_IMMEDIATE32 = 0x00000203,
110 | TYPE_IMMEDIATE64 = 0x00000204,
111 | TYPE_REL = 0x00000300,
112 | TYPE_REL8 = 0x00000301,
113 | TYPE_REL16 = 0x00000302,
114 | TYPE_REL32 = 0x00000303,
115 | TYPE_REL64 = 0x00000304,
116 | TYPE_EXPRESSION = 0x00000400,
117 | TYPE_EXPRESSION8 = 0x00000401,
118 | TYPE_EXPRESSION16 = 0x00000402,
119 | TYPE_EXPRESSION32 = 0x00000403,
120 | TYPE_EXPRESSION48 = 0x00000404,
121 | TYPE_EXPRESSION64 = 0x00000405,
122 | TYPE_EXPRESSION80 = 0x00000406,
123 | TYPE_EXPRESSION128 = 0x00000407,
124 | TYPE_ABSOLUTE = 0x00000500,
125 | TYPE_MASK = 0xffffff00
126 | };
127 |
128 | public:
129 | enum DisplacementType {
130 | DISP_NONE,
131 | DISP_U8,
132 | DISP_U16,
133 | DISP_U32,
134 | DISP_S8,
135 | DISP_S16,
136 | DISP_S32
137 | };
138 |
139 | public:
140 | struct absolute_t {
141 | uint16_t seg;
142 | uint32_t offset;
143 | };
144 |
145 | struct expression_t {
146 | union {
147 | int8_t s_disp8;
148 | int16_t s_disp16;
149 | int32_t s_disp32;
150 | uint8_t u_disp8;
151 | uint16_t u_disp16;
152 | uint32_t u_disp32;
153 | };
154 |
155 | DisplacementType displacement_type;
156 | Register base;
157 | Register index;
158 | uint8_t scale;
159 | };
160 |
161 | public:
162 | int8_t sbyte() const { return u.sbyte; }
163 | int16_t sword() const { return u.sword; }
164 | int32_t sdword() const { return u.sdword; }
165 | int64_t sqword() const { return u.sqword; }
166 | uint8_t byte() const { return u.byte; }
167 | uint16_t word() const { return u.word; }
168 | uint32_t dword() const { return u.dword; }
169 | uint64_t qword() const { return u.qword; }
170 | Register reg() const { return u.reg; }
171 |
172 | const absolute_t absolute() const { return u.absolute; }
173 | const expression_t expression() const { return u.expression; }
174 |
175 | public:
176 | Type complete_type() const { return type_; }
177 | Type general_type() const;
178 | instruction_type *owner() const { return owner_; }
179 | bool valid() const { return type_ != TYPE_INVALID; }
180 | void swap(Operand &other);
181 |
182 | public:
183 | uint64_t relative_target() const;
184 | int32_t displacement() const;
185 | int64_t immediate() const;
186 |
187 | private:
188 | instruction_type *owner_;
189 | Type type_;
190 |
191 | union U {
192 | int8_t sbyte;
193 | int16_t sword;
194 | int32_t sdword;
195 | int64_t sqword;
196 | uint8_t byte;
197 | uint16_t word;
198 | uint32_t dword;
199 | uint64_t qword;
200 | Register reg;
201 | absolute_t absolute;
202 | expression_t expression;
203 | } u;
204 | };
205 |
206 | }
207 |
208 | #include "Operand.tcc"
209 |
210 | #endif
211 |
212 |
--------------------------------------------------------------------------------
/include/edisassm/OPTable_Other.tcc:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2006 - 2015 Evan Teran
3 | evan.teran@gmail.com
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU General Public License as published by
7 | the Free Software Foundation, either version 2 of the License, or
8 | (at your option) any later version.
9 |
10 | This program 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
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program. If not, see .
17 | */
18 |
19 | #ifndef OPTABLE_OTHER_20110314_TCC_
20 | #define OPTABLE_OTHER_20110314_TCC_
21 |
22 | namespace edisassm {
23 |
24 | template
25 | const typename Instruction::opcode_entry Instruction::Opcode_invalid =
26 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE };
27 |
28 | template
29 | const typename Instruction::opcode_entry Instruction::Opcodes_nop_pause_xchg[3] = {
30 | { "nop", &Instruction::decode0, OP_NOP, FLAG_NONE },
31 | { "pause", &Instruction::decode0, OP_PAUSE, FLAG_SSE2 },
32 | { "xchg", &Instruction::template decode2<&instruction_type::decode_rAX, &instruction_type::decode_rAX_NOREX>, OP_XCHG, FLAG_NONE },
33 | };
34 |
35 | template
36 | const typename Instruction::opcode_entry Instruction::Opcodes_cbw_cwde_cdqe[3] = {
37 | { "cbw", &Instruction::decode0, OP_CBW, FLAG_NONE },
38 | { "cwde", &Instruction::decode0, OP_CWDE, FLAG_NONE },
39 | { "cdqe", &Instruction::decode0, OP_CDQE, FLAG_NONE },
40 | };
41 |
42 | template
43 | const typename Instruction::opcode_entry Instruction::Opcodes_cwd_cdq_cqo[3] = {
44 | { "cwd", &Instruction::decode0, OP_CWD, FLAG_NONE },
45 | { "cdq", &Instruction::decode0, OP_CDQ, FLAG_NONE },
46 | { "cqo", &Instruction::decode0, OP_CQO, FLAG_NONE },
47 | };
48 |
49 | template
50 | const typename Instruction::opcode_entry Instruction::Opcodes_stosw_stosd_stosq[3] = {
51 | { "stosw", &Instruction::decode0, OP_STOS, FLAG_R_FLAGS },
52 | { "stosd", &Instruction::decode0, OP_STOS, FLAG_R_FLAGS },
53 | { "stosq", &Instruction::decode0, OP_STOS, FLAG_R_FLAGS },
54 | };
55 |
56 | template
57 | const typename Instruction::opcode_entry Instruction::Opcodes_lodsw_lodsd_lodsq[3] = {
58 | { "lodsw", &Instruction::decode0, OP_LODS, FLAG_R_FLAGS },
59 | { "lodsd", &Instruction::decode0, OP_LODS, FLAG_R_FLAGS },
60 | { "lodsq", &Instruction::decode0, OP_LODS, FLAG_R_FLAGS },
61 | };
62 |
63 | template
64 | const typename Instruction::opcode_entry Instruction::Opcodes_scasw_scasd_scasq[3] = {
65 | { "scasw", &Instruction::decode0, OP_SCAS, FLAG_RW_FLAGS },
66 | { "scasd", &Instruction::decode0, OP_SCAS, FLAG_RW_FLAGS },
67 | { "scasq", &Instruction::decode0, OP_SCAS, FLAG_RW_FLAGS },
68 | };
69 |
70 | template
71 | const typename Instruction::opcode_entry Instruction::Opcodes_iretw_iret_iretq[3] = {
72 | { "iretw", &Instruction::decode0, OP_IRET, FLAG_W_FLAGS | FLAG_STACK },
73 | { "iret", &Instruction::decode0, OP_IRET, FLAG_W_FLAGS | FLAG_STACK },
74 | { "iretq", &Instruction::decode0, OP_IRET, FLAG_W_FLAGS | FLAG_STACK },
75 | };
76 |
77 | template
78 | const typename Instruction::opcode_entry Instruction::Opcodes_movsw_movsd_movsq[3] = {
79 | { "movsw", &Instruction::decode0, OP_MOVS, FLAG_R_FLAGS },
80 | { "movsd", &Instruction::decode0, OP_MOVS, FLAG_R_FLAGS },
81 | { "movsq", &Instruction::decode0, OP_MOVS, FLAG_R_FLAGS },
82 | };
83 |
84 | template
85 | const typename Instruction::opcode_entry Instruction::Opcodes_popfw_popfd_popfq[3] = {
86 | { "popfw", &Instruction::decode0, OP_POPF, FLAG_STACK | FLAG_W_FLAGS },
87 | { "popfd", &Instruction::decode0, OP_POPF, FLAG_STACK | FLAG_W_FLAGS },
88 | { "popfq", &Instruction::decode0, OP_POPF, FLAG_STACK | FLAG_W_FLAGS },
89 | };
90 |
91 | template
92 | const typename Instruction::opcode_entry Instruction::Opcodes_pushfw_pushfd_pushfq[3] = {
93 | { "pushfw", &Instruction::decode0, OP_PUSHF, FLAG_STACK | FLAG_R_FLAGS },
94 | { "pushfd", &Instruction::decode0, OP_PUSHF, FLAG_STACK | FLAG_R_FLAGS },
95 | { "pushfq", &Instruction::decode0, OP_PUSHF, FLAG_STACK | FLAG_R_FLAGS },
96 | };
97 |
98 | template
99 | const typename Instruction::opcode_entry Instruction::Opcodes_invalid_cmpxchg8b_cmpxchg16b[3] = {
100 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
101 | { "cmpxchg8b", &Instruction::decode_Mo, OP_CMPXCHG8B, FLAG_W_FLAGS },
102 | { "cmpxchg16b", &Instruction::decode_Mo, OP_CMPXCHG16B, FLAG_W_FLAGS },
103 | };
104 |
105 | template
106 | const typename Instruction::opcode_entry Instruction::Opcodes_insw_insd_invalid[3] = {
107 | { "insw", &Instruction::decode0, OP_INS, FLAG_R_FLAGS },
108 | { "insd", &Instruction::decode0, OP_INS, FLAG_R_FLAGS },
109 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
110 | };
111 |
112 | template
113 | const typename Instruction::opcode_entry Instruction::Opcodes_outsw_outsd_invalid[3] = {
114 | { "outsw", &Instruction::decode0, OP_OUTS, FLAG_R_FLAGS },
115 | { "outsd", &Instruction::decode0, OP_OUTS, FLAG_R_FLAGS },
116 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
117 | };
118 |
119 | template
120 | const typename Instruction::opcode_entry Instruction::Opcodes_cmpsw_cmpsd_cmpsq[3] = {
121 | { "cmpsw", &Instruction::decode0, OP_CMPS, FLAG_RW_FLAGS },
122 | { "cmpsd", &Instruction::decode0, OP_CMPS, FLAG_RW_FLAGS },
123 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
124 | };
125 |
126 | template
127 | const typename Instruction::opcode_entry Instruction::Opcodes_pushaw_pushad_invalid[3] = {
128 | { "pushaw", &Instruction::decode0, OP_PUSHA, FLAG_32BIT_ONLY | FLAG_STACK }, // ia-32 only
129 | { "pushad", &Instruction::decode0, OP_PUSHA, FLAG_32BIT_ONLY | FLAG_STACK }, // ia-32 only
130 | { "invalid", &Instruction::decode_invalid, OP_INVALID, FLAG_NONE },
131 | };
132 |
133 | template
134 | const typename Instruction::opcode_entry Instruction