security/sandbox/win/src/sidestep/mini_disassembler.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/win/src/sidestep/mini_disassembler.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,156 @@
     1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +// Definition of MiniDisassembler.
     1.9 +
    1.10 +#ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__
    1.11 +#define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__
    1.12 +
    1.13 +#include "sandbox/win/src/sidestep/mini_disassembler_types.h"
    1.14 +
    1.15 +namespace sidestep {
    1.16 +
    1.17 +// This small disassembler is very limited
    1.18 +// in its functionality, and in fact does only the bare minimum required by the
    1.19 +// preamble patching utility.  It may be useful for other purposes, however.
    1.20 +//
    1.21 +// The limitations include at least the following:
    1.22 +//  -# No support for coprocessor opcodes, MMX, etc.
    1.23 +//  -# No machine-readable identification of opcodes or decoding of
    1.24 +//     assembly parameters. The name of the opcode (as a string) is given,
    1.25 +//     however, to aid debugging.
    1.26 +//
    1.27 +// You may ask what this little disassembler actually does, then?  The answer is
    1.28 +// that it does the following, which is exactly what the patching utility needs:
    1.29 +//  -# Indicates if opcode is a jump (any kind) or a return (any kind)
    1.30 +//     because this is important for the patching utility to determine if
    1.31 +//     a function is too short or there are jumps too early in it for it
    1.32 +//     to be preamble patched.
    1.33 +//  -# The opcode length is always calculated, so that the patching utility
    1.34 +//     can figure out where the next instruction starts, and whether it
    1.35 +//     already has enough instructions to replace with the absolute jump
    1.36 +//     to the patching code.
    1.37 +//
    1.38 +// The usage is quite simple; just create a MiniDisassembler and use its
    1.39 +// Disassemble() method.
    1.40 +//
    1.41 +// If you would like to extend this disassembler, please refer to the
    1.42 +// IA-32 Intel Architecture Software Developer's Manual Volume 2:
    1.43 +// Instruction Set Reference for information about operand decoding
    1.44 +// etc.
    1.45 +class MiniDisassembler {
    1.46 + public:
    1.47 +
    1.48 +  // Creates a new instance and sets defaults.
    1.49 +  //
    1.50 +  // operand_default_32_bits: If true, the default operand size is
    1.51 +  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
    1.52 +  // address_default_32_bits: If true, the default address size is
    1.53 +  // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
    1.54 +  MiniDisassembler(bool operand_default_32_bits,
    1.55 +                   bool address_default_32_bits);
    1.56 +
    1.57 +  // Equivalent to MiniDisassembler(true, true);
    1.58 +  MiniDisassembler();
    1.59 +
    1.60 +  // Attempts to disassemble a single instruction starting from the
    1.61 +  // address in memory it is pointed to.
    1.62 +  //
    1.63 +  // start: Address where disassembly should start.
    1.64 +  // instruction_bytes: Variable that will be incremented by
    1.65 +  // the length in bytes of the instruction.
    1.66 +  // Returns enItJump, enItReturn or enItGeneric on success.  enItUnknown
    1.67 +  // if unable to disassemble, enItUnused if this seems to be an unused
    1.68 +  // opcode. In the last two (error) cases, cbInstruction will be set
    1.69 +  // to 0xffffffff.
    1.70 +  //
    1.71 +  // Postcondition: This instance of the disassembler is ready to be used again,
    1.72 +  // with unchanged defaults from creation time.
    1.73 +  InstructionType Disassemble(unsigned char* start,
    1.74 +                              unsigned int* instruction_bytes);
    1.75 +
    1.76 + private:
    1.77 +
    1.78 +  // Makes the disassembler ready for reuse.
    1.79 +  void Initialize();
    1.80 +
    1.81 +  // Sets the flags for address and operand sizes.
    1.82 +  // Returns Number of prefix bytes.
    1.83 +  InstructionType ProcessPrefixes(unsigned char* start, unsigned int* size);
    1.84 +
    1.85 +  // Sets the flag for whether we have ModR/M, and increments
    1.86 +  // operand_bytes_ if any are specifies by the opcode directly.
    1.87 +  // Returns Number of opcode bytes.
    1.88 +  InstructionType ProcessOpcode(unsigned char* start,
    1.89 +                                unsigned int table,
    1.90 +                                unsigned int* size);
    1.91 +
    1.92 +  // Checks the type of the supplied operand.  Increments
    1.93 +  // operand_bytes_ if it directly indicates an immediate etc.
    1.94 +  // operand.  Asserts have_modrm_ if the operand specifies
    1.95 +  // a ModR/M byte.
    1.96 +  bool ProcessOperand(int flag_operand);
    1.97 +
    1.98 +  // Increments operand_bytes_ by size specified by ModR/M and
    1.99 +  // by SIB if present.
   1.100 +  // Returns 0 in case of error, 1 if there is just a ModR/M byte,
   1.101 +  // 2 if there is a ModR/M byte and a SIB byte.
   1.102 +  bool ProcessModrm(unsigned char* start, unsigned int* size);
   1.103 +
   1.104 +  // Processes the SIB byte that it is pointed to.
   1.105 +  // start: Pointer to the SIB byte.
   1.106 +  // mod: The mod field from the ModR/M byte.
   1.107 +  // Returns 1 to indicate success (indicates 1 SIB byte)
   1.108 +  bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int* size);
   1.109 +
   1.110 +  // The instruction type we have decoded from the opcode.
   1.111 +  InstructionType instruction_type_;
   1.112 +
   1.113 +  // Counts the number of bytes that is occupied by operands in
   1.114 +  // the current instruction (note: we don't care about how large
   1.115 +  // operands stored in registers etc. are).
   1.116 +  unsigned int operand_bytes_;
   1.117 +
   1.118 +  // True iff there is a ModR/M byte in this instruction.
   1.119 +  bool have_modrm_;
   1.120 +
   1.121 +  // True iff we need to decode the ModR/M byte (sometimes it just
   1.122 +  // points to a register, we can tell by the addressing mode).
   1.123 +  bool should_decode_modrm_;
   1.124 +
   1.125 +  // Current operand size is 32 bits if true, 16 bits if false.
   1.126 +  bool operand_is_32_bits_;
   1.127 +
   1.128 +  // Default operand size is 32 bits if true, 16 bits if false.
   1.129 +  bool operand_default_is_32_bits_;
   1.130 +
   1.131 +  // Current address size is 32 bits if true, 16 bits if false.
   1.132 +  bool address_is_32_bits_;
   1.133 +
   1.134 +  // Default address size is 32 bits if true, 16 bits if false.
   1.135 +  bool address_default_is_32_bits_;
   1.136 +
   1.137 +  // Huge big opcode table based on the IA-32 manual, defined
   1.138 +  // in Ia32OpcodeMap.cpp
   1.139 +  static const OpcodeTable s_ia32_opcode_map_[];
   1.140 +
   1.141 +  // Somewhat smaller table to help with decoding ModR/M bytes
   1.142 +  // when 16-bit addressing mode is being used.  Defined in
   1.143 +  // Ia32ModrmMap.cpp
   1.144 +  static const ModrmEntry s_ia16_modrm_map_[];
   1.145 +
   1.146 +  // Somewhat smaller table to help with decoding ModR/M bytes
   1.147 +  // when 32-bit addressing mode is being used.  Defined in
   1.148 +  // Ia32ModrmMap.cpp
   1.149 +  static const ModrmEntry s_ia32_modrm_map_[];
   1.150 +
   1.151 +  // Indicators of whether we got certain prefixes that certain
   1.152 +  // silly Intel instructions depend on in nonstandard ways for
   1.153 +  // their behaviors.
   1.154 +  bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_;
   1.155 +};
   1.156 +
   1.157 +};  // namespace sidestep
   1.158 +
   1.159 +#endif  // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__

mercurial