| 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 |