15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definition of PreamblePatcher 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stddef.h> 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sidestep { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum size of the preamble stub. We overwrite at least the first 5 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes of the function. Considering the worst case scenario, we need 4 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes + the max instruction size + 5 more bytes for our jump back to 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the original code. With that in mind, 32 is a good number :) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxPreambleStubSize = 32; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Possible results of patching/unpatching 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SideStepError { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_SUCCESS = 0, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_INVALID_PARAMETER, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_INSUFFICIENT_BUFFER, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_JUMP_INSTRUCTION, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_FUNCTION_TOO_SMALL, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_UNSUPPORTED_INSTRUCTION, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_NO_SUCH_MODULE, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_NO_SUCH_FUNCTION, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_ACCESS_DENIED, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIDESTEP_UNEXPECTED, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements a patching mechanism that overwrites the first few bytes of 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a function preamble with a jump to our hook function, which is then 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// able to call the original function via a specially-made preamble-stub 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that imitates the action of the original preamble. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that there are a number of ways that this method of patching can 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail. The most common are: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If there is a jump (jxx) instruction in the first 5 bytes of 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the function being patched, we cannot patch it because in the 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current implementation we do not know how to rewrite relative 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// jumps after relocating them to the preamble-stub. Note that 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if you really really need to patch a function like this, it 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// would be possible to add this functionality (but at some cost). 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If there is a return (ret) instruction in the first 5 bytes 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we cannot patch the function because it may not be long enough 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the jmp instruction we use to inject our patch. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If there is another thread currently executing within the bytes 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that are copied to the preamble stub, it will crash in an undefined 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// way. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you get any other error than the above, you're either pointing the 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// patcher at an invalid instruction (e.g. into the middle of a multi- 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// byte instruction, or not at memory containing executable instructions) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or, there may be a bug in the disassembler we use to find 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instruction boundaries. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PreamblePatcher { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Patches target_function to point to replacement_function using a provided 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preamble_stub of stub_size bytes. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns An error code indicating the result of patching. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SideStepError Patch(T target_function, T replacement_function, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* preamble_stub, size_t stub_size) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RawPatchWithStub(target_function, replacement_function, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<unsigned char*>(preamble_stub), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stub_size, NULL); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Patches a function by overwriting its first few bytes with 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a jump to a different function. This is similar to the RawPatch 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function except that it uses the stub allocated by the caller 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead of allocating it. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To use this function, you first have to call VirtualProtect to make the 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target function writable at least for the duration of the call. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_function: A pointer to the function that should be 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // patched. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // replacement_function: A pointer to the function that should 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // replace the target function. The replacement function must have 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exactly the same calling convention and parameters as the original 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preamble_stub: A pointer to a buffer where the preamble stub 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be copied. The size of the buffer should be sufficient to 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hold the preamble bytes. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stub_size: Size in bytes of the buffer allocated for the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preamble_stub 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes_needed: Pointer to a variable that receives the minimum 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of bytes required for the stub. Can be set to NULL if you're 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not interested. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns An error code indicating the result of patching. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SideStepError RawPatchWithStub(void* target_function, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *replacement_function, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* preamble_stub, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t stub_size, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* bytes_needed); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; // namespace sidestep 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__ 112