15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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)#ifndef BASE_WIN_IAT_PATCH_FUNCTION_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_WIN_IAT_PATCH_FUNCTION_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class that encapsulates Import Address Table patching helpers and restores
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the original function in the destructor.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It will intercept functions for a specific DLL imported from another DLL.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the case when, for example, we want to intercept
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CertDuplicateCertificateContext function (exported from crypt32.dll) called
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by wininet.dll.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT IATPatchFunction {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IATPatchFunction();
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~IATPatchFunction();
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Intercept a function in an import table of a specific
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // module. Save the original function and the import
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // table address. These values will be used later
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during Unpatch
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Arguments:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // module                 Module to be intercepted
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // imported_from_module   Module that exports the 'function_name'
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function_name          Name of the API to be intercepted
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns: Windows error code (winerror.h). NO_ERROR if successful
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: Patching a function will make the IAT patch take some "ownership" on
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |module|.  It will LoadLibrary(module) to keep the DLL alive until a call
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to Unpatch(), which will call FreeLibrary() and allow the module to be
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unloaded.  The idea is to help prevent the DLL from going away while a
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // patch is still active.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD Patch(const wchar_t* module,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const char* imported_from_module,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const char* function_name,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              void* new_function);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unpatch the IAT entry using internally saved original
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns: Windows error code (winerror.h). NO_ERROR if successful
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD Unpatch();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_patched() const {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (NULL != intercept_function_);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HMODULE module_handle_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* intercept_function_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* original_function_;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IMAGE_THUNK_DATA* iat_thunk_;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IATPatchFunction);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace win
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_WIN_IAT_PATCH_FUNCTION_H_
73