OLD | NEW |
1 // All rights reserved. | 1 // All rights reserved. |
2 // | 2 // |
3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
5 // met: | 5 // met: |
6 // | 6 // |
7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
10 // copyright notice, this list of conditions and the following disclaimer | 10 // copyright notice, this list of conditions and the following disclaimer |
(...skipping 10 matching lines...) Expand all Loading... |
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 28 |
29 // disassembler_x86.h: Basic x86 bytecode disassembler | 29 // disassembler_x86.h: Basic x86 bytecode disassembler |
30 // | 30 // |
31 // Provides a simple disassembler which wraps libdisasm. This allows simple | 31 // Provides a simple disassembler which wraps capstone. This allows simple |
32 // tests to be run against bytecode to test for various properties. | 32 // tests to be run against bytecode to test for various properties. |
33 // | 33 // |
34 // Author: Cris Neckar | 34 // Author: Cris Neckar |
35 | 35 |
36 #ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ | 36 #ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ |
37 #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ | 37 #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ |
38 | 38 |
39 #include <stddef.h> | 39 #include <stddef.h> |
40 #include <sys/types.h> | 40 #include <sys/types.h> |
41 | 41 |
42 #include "google_breakpad/common/breakpad_types.h" | 42 #include "google_breakpad/common/breakpad_types.h" |
43 | 43 |
44 namespace libdis { | 44 #include "capstone.h" |
45 #include "third_party/libdisasm/libdis.h" | 45 |
46 } | |
47 | 46 |
48 namespace google_breakpad { | 47 namespace google_breakpad { |
49 | 48 |
| 49 // Flags for current disassembler state. |
50 enum { | 50 enum { |
51 DISX86_NONE = 0x0, | 51 DISX86_NONE = 0x0, |
52 DISX86_BAD_BRANCH_TARGET = 0x1, | 52 DISX86_BAD_BRANCH_TARGET = 0x1, |
53 DISX86_BAD_ARGUMENT_PASSED = 0x2, | 53 DISX86_BAD_ARGUMENT_PASSED = 0x2, |
54 DISX86_BAD_WRITE = 0x4, | 54 DISX86_BAD_WRITE = 0x4, |
55 DISX86_BAD_BLOCK_WRITE = 0x8, | 55 DISX86_BAD_BLOCK_WRITE = 0x8, |
56 DISX86_BAD_READ = 0x10, | 56 DISX86_BAD_READ = 0x10, |
57 DISX86_BAD_BLOCK_READ = 0x20, | 57 DISX86_BAD_BLOCK_READ = 0x20, |
58 DISX86_BAD_COMPARISON = 0x40 | 58 DISX86_BAD_COMPARISON = 0x40 |
59 }; | 59 }; |
60 | 60 |
61 class DisassemblerX86 { | 61 class DisassemblerX86 { |
62 public: | 62 public: |
63 // TODO(cdn): Modify this class to take a MemoryRegion instead of just | 63 // TODO(cdn): Modify this class to take a MemoryRegion instead of just |
64 // a raw buffer. This will make it easier to use this on arbitrary | 64 // a raw buffer. This will make it easier to use this on arbitrary |
65 // minidumps without first copying out the code segment. | 65 // minidumps without first copying out the code segment. |
66 DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t); | 66 DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t); |
67 ~DisassemblerX86(); | 67 ~DisassemblerX86(); |
68 | 68 |
69 // This walks to the next instruction in the memory region and | 69 // This walks to the next instruction in the memory region and |
70 // sets flags based on the type of instruction and previous state | 70 // sets flags based on the type of instruction and previous state |
71 // including any registers marked as bad through setBadRead() | 71 // including any registers marked as bad through setBadRead() |
72 // or setBadWrite(). This method can be called in a loop to | 72 // or setBadWrite(). This method can be called in a loop to |
73 // disassemble until the end of a region. | 73 // disassemble until the end of a region. |
74 uint32_t NextInstruction(); | 74 // |
| 75 // Returns the size of the instruction in bytes, or zero if |
| 76 // disassembly failed. |
| 77 size_t NextInstruction(); |
75 | 78 |
76 // Indicates whether the current disassembled instruction was valid. | 79 // Indicates whether the current disassembled instruction was valid. |
77 bool currentInstructionValid() { return instr_valid_; } | 80 bool currentInstructionValid() { return instr_valid_; } |
78 | 81 |
79 // Returns the current instruction as defined in libdis.h, | 82 // Returns the current instruction as defined in capstone.h, |
80 // or NULL if the current instruction is not valid. | 83 // or NULL if the current instruction is not valid. |
81 const libdis::x86_insn_t* currentInstruction() { | 84 const cs_insn* currentInstruction() { |
82 return instr_valid_ ? ¤t_instr_ : NULL; | 85 return instr_valid_ ? current_instr_ : nullptr; |
83 } | 86 } |
84 | 87 |
85 // Returns the type of the current instruction as defined in libdis.h. | 88 // Returns true if the current instruction is in group. |
86 libdis::x86_insn_group currentInstructionGroup() { | 89 bool currentInstructionIsGroup(x86_insn_group group) { |
87 return current_instr_.group; | 90 return instr_valid_ ? |
| 91 cs_insn_group(handle_, current_instr_, group) : false; |
88 } | 92 } |
89 | 93 |
| 94 // Returns true if the current instruction is a block data instruction. |
| 95 bool currentInstructionIsBlockData(); |
| 96 |
| 97 |
90 // Indicates whether a return instruction has been encountered. | 98 // Indicates whether a return instruction has been encountered. |
91 bool endOfBlock() { return end_of_block_; } | 99 bool endOfBlock() { return end_of_block_; } |
92 | 100 |
93 // The flags set so far for the disassembly. | 101 // The flags set so far for the disassembly, from the set defined in |
| 102 // the anonymous enum above. |
94 uint16_t flags() { return flags_; } | 103 uint16_t flags() { return flags_; } |
95 | 104 |
96 // This sets an indicator that the register used to determine | 105 // This sets an indicator that the register used to determine |
97 // src or dest for the current instruction is tainted. These can | 106 // src or dest for the current instruction is tainted. These can |
98 // be used after examining the current instruction to indicate, | 107 // be used after examining the current instruction to indicate, |
99 // for example that a bad read or write occurred and the pointer | 108 // for example that a bad read or write occurred and the pointer |
100 // stored in the register is currently invalid. | 109 // stored in the register is currently invalid. |
101 bool setBadRead(); | 110 bool setBadRead(); |
102 bool setBadWrite(); | 111 bool setBadWrite(); |
103 | 112 |
104 protected: | 113 protected: |
105 const uint8_t *bytecode_; | 114 // Memory containing instructions to disassemble. |
106 uint32_t size_; | 115 // Owned by caller. |
107 uint32_t virtual_address_; | 116 const uint8_t* bytecode_; |
108 uint32_t current_byte_offset_; | 117 // Size of remaining bytecode. |
109 uint32_t current_inst_offset_; | 118 size_t size_; |
| 119 // Virtual address of current instruction. |
| 120 uint64_t virtual_address_; |
| 121 |
| 122 // capstone library handle |
| 123 csh handle_; |
110 | 124 |
111 bool instr_valid_; | 125 bool instr_valid_; |
112 libdis::x86_insn_t current_instr_; | 126 cs_insn* current_instr_; |
113 | 127 |
114 // TODO(cdn): Maybe also track an expression's index register. | 128 // TODO(cdn): Maybe also track an expression's index register. |
115 // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index. | 129 // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index. |
116 bool register_valid_; | 130 bool register_valid_; |
117 libdis::x86_reg_t bad_register_; | 131 x86_reg bad_register_; |
118 | 132 |
119 bool pushed_bad_value_; | 133 bool pushed_bad_value_; |
120 bool end_of_block_; | 134 bool end_of_block_; |
121 | 135 |
122 uint16_t flags_; | 136 uint16_t flags_; |
123 }; | 137 }; |
124 | 138 |
125 } // namespace google_breakpad | 139 } // namespace google_breakpad |
126 | 140 |
127 #endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ | 141 #endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_ |
OLD | NEW |