123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- // disassembler_x86.h: Basic x86 bytecode disassembler
- //
- // Provides a simple disassembler which wraps libdisasm. This allows simple
- // tests to be run against bytecode to test for various properties.
- //
- // Author: Cris Neckar
- #ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
- #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
- #include <stddef.h>
- #include <sys/types.h>
- #include "google_breakpad/common/breakpad_types.h"
- namespace libdis {
- #include "third_party/libdisasm/libdis.h"
- }
- namespace google_breakpad {
- enum {
- DISX86_NONE = 0x0,
- DISX86_BAD_BRANCH_TARGET = 0x1,
- DISX86_BAD_ARGUMENT_PASSED = 0x2,
- DISX86_BAD_WRITE = 0x4,
- DISX86_BAD_BLOCK_WRITE = 0x8,
- DISX86_BAD_READ = 0x10,
- DISX86_BAD_BLOCK_READ = 0x20,
- DISX86_BAD_COMPARISON = 0x40
- };
- class DisassemblerX86 {
- public:
- // TODO(cdn): Modify this class to take a MemoryRegion instead of just
- // a raw buffer. This will make it easier to use this on arbitrary
- // minidumps without first copying out the code segment.
- DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t);
- ~DisassemblerX86();
- // This walks to the next instruction in the memory region and
- // sets flags based on the type of instruction and previous state
- // including any registers marked as bad through setBadRead()
- // or setBadWrite(). This method can be called in a loop to
- // disassemble until the end of a region.
- uint32_t NextInstruction();
- // Indicates whether the current disassembled instruction was valid.
- bool currentInstructionValid() { return instr_valid_; }
- // Returns the current instruction as defined in libdis.h,
- // or NULL if the current instruction is not valid.
- const libdis::x86_insn_t* currentInstruction() {
- return instr_valid_ ? ¤t_instr_ : NULL;
- }
- // Returns the type of the current instruction as defined in libdis.h.
- libdis::x86_insn_group currentInstructionGroup() {
- return current_instr_.group;
- }
- // Indicates whether a return instruction has been encountered.
- bool endOfBlock() { return end_of_block_; }
- // The flags set so far for the disassembly.
- uint16_t flags() { return flags_; }
- // This sets an indicator that the register used to determine
- // src or dest for the current instruction is tainted. These can
- // be used after examining the current instruction to indicate,
- // for example that a bad read or write occurred and the pointer
- // stored in the register is currently invalid.
- bool setBadRead();
- bool setBadWrite();
- protected:
- const uint8_t *bytecode_;
- uint32_t size_;
- uint32_t virtual_address_;
- uint32_t current_byte_offset_;
- uint32_t current_inst_offset_;
- bool instr_valid_;
- libdis::x86_insn_t current_instr_;
- // TODO(cdn): Maybe also track an expression's index register.
- // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index.
- bool register_valid_;
- libdis::x86_reg_t bad_register_;
- bool pushed_bad_value_;
- bool end_of_block_;
- uint16_t flags_;
- };
- } // namespace google_breakpad
- #endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
|