disassembler_x86.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // All rights reserved.
  2. //
  3. // Redistribution and use in source and binary forms, with or without
  4. // modification, are permitted provided that the following conditions are
  5. // met:
  6. //
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above
  10. // copyright notice, this list of conditions and the following disclaimer
  11. // in the documentation and/or other materials provided with the
  12. // distribution.
  13. // * Neither the name of Google Inc. nor the names of its
  14. // contributors may be used to endorse or promote products derived from
  15. // this software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  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.
  28. // disassembler_x86.h: Basic x86 bytecode disassembler
  29. //
  30. // Provides a simple disassembler which wraps libdisasm. This allows simple
  31. // tests to be run against bytecode to test for various properties.
  32. //
  33. // Author: Cris Neckar
  34. #ifndef GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
  35. #define GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_
  36. #include <stddef.h>
  37. #include <sys/types.h>
  38. #include "google_breakpad/common/breakpad_types.h"
  39. namespace libdis {
  40. #include "third_party/libdisasm/libdis.h"
  41. }
  42. namespace google_breakpad {
  43. enum {
  44. DISX86_NONE = 0x0,
  45. DISX86_BAD_BRANCH_TARGET = 0x1,
  46. DISX86_BAD_ARGUMENT_PASSED = 0x2,
  47. DISX86_BAD_WRITE = 0x4,
  48. DISX86_BAD_BLOCK_WRITE = 0x8,
  49. DISX86_BAD_READ = 0x10,
  50. DISX86_BAD_BLOCK_READ = 0x20,
  51. DISX86_BAD_COMPARISON = 0x40
  52. };
  53. class DisassemblerX86 {
  54. public:
  55. // TODO(cdn): Modify this class to take a MemoryRegion instead of just
  56. // a raw buffer. This will make it easier to use this on arbitrary
  57. // minidumps without first copying out the code segment.
  58. DisassemblerX86(const uint8_t *bytecode, uint32_t, uint32_t);
  59. ~DisassemblerX86();
  60. // This walks to the next instruction in the memory region and
  61. // sets flags based on the type of instruction and previous state
  62. // including any registers marked as bad through setBadRead()
  63. // or setBadWrite(). This method can be called in a loop to
  64. // disassemble until the end of a region.
  65. uint32_t NextInstruction();
  66. // Indicates whether the current disassembled instruction was valid.
  67. bool currentInstructionValid() { return instr_valid_; }
  68. // Returns the current instruction as defined in libdis.h,
  69. // or NULL if the current instruction is not valid.
  70. const libdis::x86_insn_t* currentInstruction() {
  71. return instr_valid_ ? &current_instr_ : NULL;
  72. }
  73. // Returns the type of the current instruction as defined in libdis.h.
  74. libdis::x86_insn_group currentInstructionGroup() {
  75. return current_instr_.group;
  76. }
  77. // Indicates whether a return instruction has been encountered.
  78. bool endOfBlock() { return end_of_block_; }
  79. // The flags set so far for the disassembly.
  80. uint16_t flags() { return flags_; }
  81. // This sets an indicator that the register used to determine
  82. // src or dest for the current instruction is tainted. These can
  83. // be used after examining the current instruction to indicate,
  84. // for example that a bad read or write occurred and the pointer
  85. // stored in the register is currently invalid.
  86. bool setBadRead();
  87. bool setBadWrite();
  88. protected:
  89. const uint8_t *bytecode_;
  90. uint32_t size_;
  91. uint32_t virtual_address_;
  92. uint32_t current_byte_offset_;
  93. uint32_t current_inst_offset_;
  94. bool instr_valid_;
  95. libdis::x86_insn_t current_instr_;
  96. // TODO(cdn): Maybe also track an expression's index register.
  97. // ex: mov eax, [ebx + ecx]; ebx is base, ecx is index.
  98. bool register_valid_;
  99. libdis::x86_reg_t bad_register_;
  100. bool pushed_bad_value_;
  101. bool end_of_block_;
  102. uint16_t flags_;
  103. };
  104. } // namespace google_breakpad
  105. #endif // GOOGLE_BREAKPAD_PROCESSOR_DISASSEMBLER_X86_H_