// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Definition of PreamblePatcher

#ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
#define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__

#include <stddef.h>

namespace sidestep {

// Maximum size of the preamble stub. We overwrite at least the first 5
// bytes of the function. Considering the worst case scenario, we need 4
// bytes + the max instruction size + 5 more bytes for our jump back to
// the original code. With that in mind, 32 is a good number :)
const size_t kMaxPreambleStubSize = 32;

// Possible results of patching/unpatching
enum SideStepError {
  SIDESTEP_SUCCESS = 0,
  SIDESTEP_INVALID_PARAMETER,
  SIDESTEP_INSUFFICIENT_BUFFER,
  SIDESTEP_JUMP_INSTRUCTION,
  SIDESTEP_FUNCTION_TOO_SMALL,
  SIDESTEP_UNSUPPORTED_INSTRUCTION,
  SIDESTEP_NO_SUCH_MODULE,
  SIDESTEP_NO_SUCH_FUNCTION,
  SIDESTEP_ACCESS_DENIED,
  SIDESTEP_UNEXPECTED,
};

// Implements a patching mechanism that overwrites the first few bytes of
// a function preamble with a jump to our hook function, which is then
// able to call the original function via a specially-made preamble-stub
// that imitates the action of the original preamble.
//
// Note that there are a number of ways that this method of patching can
// fail.  The most common are:
//    - If there is a jump (jxx) instruction in the first 5 bytes of
//    the function being patched, we cannot patch it because in the
//    current implementation we do not know how to rewrite relative
//    jumps after relocating them to the preamble-stub.  Note that
//    if you really really need to patch a function like this, it
//    would be possible to add this functionality (but at some cost).
//    - If there is a return (ret) instruction in the first 5 bytes
//    we cannot patch the function because it may not be long enough
//    for the jmp instruction we use to inject our patch.
//    - If there is another thread currently executing within the bytes
//    that are copied to the preamble stub, it will crash in an undefined
//    way.
//
// If you get any other error than the above, you're either pointing the
// patcher at an invalid instruction (e.g. into the middle of a multi-
// byte instruction, or not at memory containing executable instructions)
// or, there may be a bug in the disassembler we use to find
// instruction boundaries.
class PreamblePatcher {
 public:
  // Patches target_function to point to replacement_function using a provided
  // preamble_stub of stub_size bytes.
  // Returns An error code indicating the result of patching.
  template <class T>
  static SideStepError Patch(T target_function, T replacement_function,
                             void* preamble_stub, size_t stub_size) {
    return RawPatchWithStub(target_function, replacement_function,
                            reinterpret_cast<unsigned char*>(preamble_stub),
                            stub_size, NULL);
  }

 private:

  // Patches a function by overwriting its first few bytes with
  // a jump to a different function.  This is similar to the RawPatch
  // function except that it uses the stub allocated by the caller
  // instead of allocating it.
  //
  // To use this function, you first have to call VirtualProtect to make the
  // target function writable at least for the duration of the call.
  //
  // target_function: A pointer to the function that should be
  // patched.
  //
  // replacement_function: A pointer to the function that should
  // replace the target function.  The replacement function must have
  // exactly the same calling convention and parameters as the original
  // function.
  //
  // preamble_stub: A pointer to a buffer where the preamble stub
  // should be copied. The size of the buffer should be sufficient to
  // hold the preamble bytes.
  //
  // stub_size: Size in bytes of the buffer allocated for the
  // preamble_stub
  //
  // bytes_needed: Pointer to a variable that receives the minimum
  // number of bytes required for the stub.  Can be set to NULL if you're
  // not interested.
  //
  // Returns An error code indicating the result of patching.
  static SideStepError RawPatchWithStub(void* target_function,
                                        void *replacement_function,
                                        unsigned char* preamble_stub,
                                        size_t stub_size,
                                        size_t* bytes_needed);
};

};  // namespace sidestep

#endif  // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
