|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 // Definition of MiniDisassembler. |
|
6 |
|
7 #ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ |
|
8 #define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ |
|
9 |
|
10 #include "sandbox/win/src/sidestep/mini_disassembler_types.h" |
|
11 |
|
12 namespace sidestep { |
|
13 |
|
14 // This small disassembler is very limited |
|
15 // in its functionality, and in fact does only the bare minimum required by the |
|
16 // preamble patching utility. It may be useful for other purposes, however. |
|
17 // |
|
18 // The limitations include at least the following: |
|
19 // -# No support for coprocessor opcodes, MMX, etc. |
|
20 // -# No machine-readable identification of opcodes or decoding of |
|
21 // assembly parameters. The name of the opcode (as a string) is given, |
|
22 // however, to aid debugging. |
|
23 // |
|
24 // You may ask what this little disassembler actually does, then? The answer is |
|
25 // that it does the following, which is exactly what the patching utility needs: |
|
26 // -# Indicates if opcode is a jump (any kind) or a return (any kind) |
|
27 // because this is important for the patching utility to determine if |
|
28 // a function is too short or there are jumps too early in it for it |
|
29 // to be preamble patched. |
|
30 // -# The opcode length is always calculated, so that the patching utility |
|
31 // can figure out where the next instruction starts, and whether it |
|
32 // already has enough instructions to replace with the absolute jump |
|
33 // to the patching code. |
|
34 // |
|
35 // The usage is quite simple; just create a MiniDisassembler and use its |
|
36 // Disassemble() method. |
|
37 // |
|
38 // If you would like to extend this disassembler, please refer to the |
|
39 // IA-32 Intel Architecture Software Developer's Manual Volume 2: |
|
40 // Instruction Set Reference for information about operand decoding |
|
41 // etc. |
|
42 class MiniDisassembler { |
|
43 public: |
|
44 |
|
45 // Creates a new instance and sets defaults. |
|
46 // |
|
47 // operand_default_32_bits: If true, the default operand size is |
|
48 // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits. |
|
49 // address_default_32_bits: If true, the default address size is |
|
50 // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits. |
|
51 MiniDisassembler(bool operand_default_32_bits, |
|
52 bool address_default_32_bits); |
|
53 |
|
54 // Equivalent to MiniDisassembler(true, true); |
|
55 MiniDisassembler(); |
|
56 |
|
57 // Attempts to disassemble a single instruction starting from the |
|
58 // address in memory it is pointed to. |
|
59 // |
|
60 // start: Address where disassembly should start. |
|
61 // instruction_bytes: Variable that will be incremented by |
|
62 // the length in bytes of the instruction. |
|
63 // Returns enItJump, enItReturn or enItGeneric on success. enItUnknown |
|
64 // if unable to disassemble, enItUnused if this seems to be an unused |
|
65 // opcode. In the last two (error) cases, cbInstruction will be set |
|
66 // to 0xffffffff. |
|
67 // |
|
68 // Postcondition: This instance of the disassembler is ready to be used again, |
|
69 // with unchanged defaults from creation time. |
|
70 InstructionType Disassemble(unsigned char* start, |
|
71 unsigned int* instruction_bytes); |
|
72 |
|
73 private: |
|
74 |
|
75 // Makes the disassembler ready for reuse. |
|
76 void Initialize(); |
|
77 |
|
78 // Sets the flags for address and operand sizes. |
|
79 // Returns Number of prefix bytes. |
|
80 InstructionType ProcessPrefixes(unsigned char* start, unsigned int* size); |
|
81 |
|
82 // Sets the flag for whether we have ModR/M, and increments |
|
83 // operand_bytes_ if any are specifies by the opcode directly. |
|
84 // Returns Number of opcode bytes. |
|
85 InstructionType ProcessOpcode(unsigned char* start, |
|
86 unsigned int table, |
|
87 unsigned int* size); |
|
88 |
|
89 // Checks the type of the supplied operand. Increments |
|
90 // operand_bytes_ if it directly indicates an immediate etc. |
|
91 // operand. Asserts have_modrm_ if the operand specifies |
|
92 // a ModR/M byte. |
|
93 bool ProcessOperand(int flag_operand); |
|
94 |
|
95 // Increments operand_bytes_ by size specified by ModR/M and |
|
96 // by SIB if present. |
|
97 // Returns 0 in case of error, 1 if there is just a ModR/M byte, |
|
98 // 2 if there is a ModR/M byte and a SIB byte. |
|
99 bool ProcessModrm(unsigned char* start, unsigned int* size); |
|
100 |
|
101 // Processes the SIB byte that it is pointed to. |
|
102 // start: Pointer to the SIB byte. |
|
103 // mod: The mod field from the ModR/M byte. |
|
104 // Returns 1 to indicate success (indicates 1 SIB byte) |
|
105 bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int* size); |
|
106 |
|
107 // The instruction type we have decoded from the opcode. |
|
108 InstructionType instruction_type_; |
|
109 |
|
110 // Counts the number of bytes that is occupied by operands in |
|
111 // the current instruction (note: we don't care about how large |
|
112 // operands stored in registers etc. are). |
|
113 unsigned int operand_bytes_; |
|
114 |
|
115 // True iff there is a ModR/M byte in this instruction. |
|
116 bool have_modrm_; |
|
117 |
|
118 // True iff we need to decode the ModR/M byte (sometimes it just |
|
119 // points to a register, we can tell by the addressing mode). |
|
120 bool should_decode_modrm_; |
|
121 |
|
122 // Current operand size is 32 bits if true, 16 bits if false. |
|
123 bool operand_is_32_bits_; |
|
124 |
|
125 // Default operand size is 32 bits if true, 16 bits if false. |
|
126 bool operand_default_is_32_bits_; |
|
127 |
|
128 // Current address size is 32 bits if true, 16 bits if false. |
|
129 bool address_is_32_bits_; |
|
130 |
|
131 // Default address size is 32 bits if true, 16 bits if false. |
|
132 bool address_default_is_32_bits_; |
|
133 |
|
134 // Huge big opcode table based on the IA-32 manual, defined |
|
135 // in Ia32OpcodeMap.cpp |
|
136 static const OpcodeTable s_ia32_opcode_map_[]; |
|
137 |
|
138 // Somewhat smaller table to help with decoding ModR/M bytes |
|
139 // when 16-bit addressing mode is being used. Defined in |
|
140 // Ia32ModrmMap.cpp |
|
141 static const ModrmEntry s_ia16_modrm_map_[]; |
|
142 |
|
143 // Somewhat smaller table to help with decoding ModR/M bytes |
|
144 // when 32-bit addressing mode is being used. Defined in |
|
145 // Ia32ModrmMap.cpp |
|
146 static const ModrmEntry s_ia32_modrm_map_[]; |
|
147 |
|
148 // Indicators of whether we got certain prefixes that certain |
|
149 // silly Intel instructions depend on in nonstandard ways for |
|
150 // their behaviors. |
|
151 bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_; |
|
152 }; |
|
153 |
|
154 }; // namespace sidestep |
|
155 |
|
156 #endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__ |