michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* Win32 x86/x64 code for stack walking, symbol resolution, and function hooking */ michael@0: michael@0: #ifndef __nsDebugHelpWin32_h__ michael@0: #define __nsDebugHelpWin32_h__ michael@0: michael@0: #if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) michael@0: #ifndef WIN32_LEAN_AND_MEAN michael@0: #define WIN32_LEAN_AND_MEAN michael@0: #endif michael@0: #include michael@0: #include michael@0: #include michael@0: #else michael@0: #error "nsDebugHelpWin32.h should only be included in Win32 x86/x64 builds" michael@0: #endif michael@0: michael@0: // XXX temporary hack... michael@0: //#include "hacky_defines.h" michael@0: michael@0: michael@0: /***************************************************************************/ michael@0: // useful macros... michael@0: michael@0: #ifdef DHW_IMPLEMENT_GLOBALS michael@0: #define DHW_DECLARE_FUN_GLOBAL(name_) decltype(name_)* dhw##name_ michael@0: #else michael@0: #define DHW_DECLARE_FUN_GLOBAL(name_) extern decltype(name_)* dhw##name_ michael@0: #endif michael@0: michael@0: michael@0: /**********************************************************/ michael@0: // This is used to get 'original' function addresses from DHWImportHooker. michael@0: michael@0: #define DHW_ORIGINAL(name_, hooker_) \ michael@0: ((decltype(name_)*) hooker_ . GetOriginalFunction()) michael@0: michael@0: /***************************************************************************/ michael@0: // Global declarations of entry points into ImgHelp functions michael@0: michael@0: #ifndef _WIN64 michael@0: DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules); michael@0: #else michael@0: DHW_DECLARE_FUN_GLOBAL(EnumerateLoadedModules64); michael@0: #endif michael@0: michael@0: DHW_DECLARE_FUN_GLOBAL(ImageDirectoryEntryToData); michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: extern bool michael@0: dhwEnsureImageHlpInitialized(); michael@0: michael@0: /***************************************************************************/ michael@0: michael@0: class DHWImportHooker michael@0: { michael@0: public: michael@0: michael@0: DHWImportHooker(const char* aModuleName, michael@0: const char* aFunctionName, michael@0: PROC aHook, michael@0: bool aExcludeOurModule = false); michael@0: michael@0: ~DHWImportHooker(); michael@0: michael@0: PROC GetOriginalFunction() {return mOriginal;} michael@0: michael@0: bool PatchAllModules(); michael@0: bool PatchOneModule(HMODULE aModule, const char* name); michael@0: static bool ModuleLoaded(HMODULE aModule, DWORD flags); michael@0: michael@0: michael@0: // I think that these should be made not static members, but allocated michael@0: // things created in an explicit static 'init' method and cleaned up in michael@0: // an explicit static 'finish' method. This would allow the application michael@0: // to have proper lifetime control over all the hooks. michael@0: michael@0: static DHWImportHooker &getLoadLibraryWHooker(); michael@0: static DHWImportHooker &getLoadLibraryExWHooker(); michael@0: static DHWImportHooker &getLoadLibraryAHooker(); michael@0: static DHWImportHooker &getLoadLibraryExAHooker(); michael@0: static DHWImportHooker &getGetProcAddressHooker(); michael@0: michael@0: static HMODULE WINAPI LoadLibraryA(PCSTR path); michael@0: michael@0: private: michael@0: DHWImportHooker* mNext; michael@0: const char* mModuleName; michael@0: const char* mFunctionName; michael@0: PROC mOriginal; michael@0: PROC mHook; michael@0: HMODULE mIgnoreModule; michael@0: bool mHooking; michael@0: michael@0: private: michael@0: static PRLock* gLock; michael@0: static DHWImportHooker* gHooks; michael@0: static decltype(GetProcAddress)* gRealGetProcAddress; michael@0: michael@0: static HMODULE WINAPI LoadLibraryW(PCWSTR path); michael@0: static HMODULE WINAPI LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags); michael@0: static HMODULE WINAPI LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags); michael@0: michael@0: static FARPROC WINAPI GetProcAddress(HMODULE aModule, PCSTR aFunctionName); michael@0: }; michael@0: michael@0: /***************************************************************************/ michael@0: // This supports the _CrtSetAllocHook based hooking. michael@0: // This system sucks because you don't get to see the allocated pointer. I michael@0: // don't think it appropriate for nsTraceMalloc, but is useful as a means to make michael@0: // malloc fail for testing purposes. michael@0: #if 0 //comment out this stuff. not necessary michael@0: michael@0: class DHWAllocationSizeDebugHook michael@0: { michael@0: public: michael@0: virtual bool AllocHook(size_t size) = 0; michael@0: virtual bool ReallocHook(size_t size, size_t sizeOld) = 0; michael@0: virtual bool FreeHook(size_t size) = 0; michael@0: }; michael@0: michael@0: extern bool dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook); michael@0: extern bool dhwClearAllocationSizeDebugHook(); michael@0: michael@0: /***************************************************************************/ michael@0: #endif //0 michael@0: michael@0: #endif /* __nsDebugHelpWin32_h__ */