ModuleScope.cpp
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:12k
- //---------------------------------------------------------------------------
- //
- // ModuleScope.h
- //
- // SUBSYSTEM: Hook system
- //
- // MODULE: Hook tool
- //
- // DESCRIPTION: Implementation of the CModuleScope class.
- // This class is designed to provide single interface for
- // all hook related activities.
- //
- //
- // AUTHOR: Ivo Ivanov (ivopi@hotmail.com)
- // DATE: 2001 December v1.00
- //
- //---------------------------------------------------------------------------
- #include "..CommonCommon.h"
- #include "ModuleScope.h"
- #include "..CommonSysUtils.h"
- #include "..CommonIniFile.h"
- #include "..CommonCustomMessages.h"
- #include "Injector.h"
- //---------------------------------------------------------------------------
- //
- // class CModuleScope
- //
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- //
- // Static memeber declarations
- //
- //---------------------------------------------------------------------------
- CModuleScope* CModuleScope::sm_pInstance = NULL;
- CLogFile* CModuleScope::sm_pLogFile = NULL;
- CApiHookMgr* CModuleScope::sm_pHookMgr = NULL;
- //---------------------------------------------------------------------------
- //
- // Constructor
- //
- //---------------------------------------------------------------------------
- CModuleScope::CModuleScope(
- HWND* phwndServer,
- BOOL* pbHookInstalled,
- HHOOK* pHook
- ):
- m_phwndServer(phwndServer),
- m_bTraceEnabledInitialized(FALSE),
- m_bTraceEnabled(FALSE),
- m_bUseWindowsHookInitialized(FALSE),
- m_bUseWindowsHook(TRUE),
- m_pInjector(NULL),
- m_pbHookInstalled(pbHookInstalled),
- m_pWhenZero(NULL)
- {
- //
- // Make sure we now where we are.
- //
- m_bIsThisServerProcess = (NULL == *phwndServer);
- //
- // Instantiate the object that looks after DLL ref counting
- //
- m_pWhenZero = new CWhenZeroDword(m_bIsThisServerProcess);
- //
- // Get the name of the current process
- //
- GetProcessHostName(m_szProcessName);
- //
- // and its process id
- //
- m_dwProcessId = ::GetCurrentProcessId();
- //
- // Create instance of the log file manager
- //
- sm_pLogFile = new CLogFile(GetTraceEnabled());
- //
- // Instantiate the only one hook manager
- //
- sm_pHookMgr = new CApiHookMgr(this);
- //
- // Which kind of injection we would like to use?
- //
- if (IsWindows9x() || UseWindowsHook())
- m_pInjector = new CWinHookInjector(m_bIsThisServerProcess, pHook);
- else
- m_pInjector = new CRemThreadInjector(m_bIsThisServerProcess);
- }
- //---------------------------------------------------------------------------
- //
- // Destructor
- //
- //---------------------------------------------------------------------------
- CModuleScope::~CModuleScope()
- {
- delete m_pInjector;
- delete m_pWhenZero;
- delete sm_pHookMgr;
- delete sm_pLogFile;
- }
- //---------------------------------------------------------------------------
- //
- // Copy constructor
- //
- //---------------------------------------------------------------------------
- CModuleScope::CModuleScope(const CModuleScope& rhs)
- {
-
- }
- //---------------------------------------------------------------------------
- //
- // Assignment operator
- //
- //---------------------------------------------------------------------------
- CModuleScope& CModuleScope::operator=(const CModuleScope& rhs)
- {
- if (this == &rhs)
- return *this;
- return *this; // return reference to left-hand object
- }
- //---------------------------------------------------------------------------
- // GetInstance
- //
- // Implements the "double-checking" locking pattern combined with
- // Scott Meyers single instance
- // For more details see -
- // 1. "Modern C++ Design" by Andrei Alexandrescu - 6.9 Living in a
- // Multithreaded World
- // 2. "More Effective C++" by Scott Meyers - Item 26
- //---------------------------------------------------------------------------
- CModuleScope* CModuleScope::GetInstance(
- HWND* phwndServer,
- BOOL* pbHookInstalled,
- HHOOK* pHook
- )
- {
- if (!sm_pInstance)
- {
- CLockMgr<CCSWrapper> guard(g_ModuleSingeltonLock, TRUE);
- if (!sm_pInstance)
- {
- static CModuleScope instance(phwndServer, pbHookInstalled, pHook);
- sm_pInstance = &instance;
- char szFileName[MAX_PATH];
- char *pdest;
- ::GetModuleFileName(
- ModuleFromAddress(CModuleScope::GetInstance),
- szFileName,
- MAX_PATH
- );
- pdest = &szFileName[strlen(szFileName) - 4];
- strcpy(pdest, ".log");
- sm_pLogFile->InitializeFileName(szFileName);
- }
- } // if
- return sm_pInstance;
- }
- //
- // Called on DLL_PROCESS_ATTACH DLL notification
- //
- BOOL CModuleScope::ManageModuleEnlistment()
- {
- BOOL bResult = FALSE;
- //
- // Check if it is the hook server we should allow mapping of the DLL into
- // its address space
- //
- if (FALSE == *m_pbHookInstalled)
- {
- LogMessage( "------- Hook server loads HookTool library -------" );
- //
- // Set the flag, thus we will know that the server has been installed
- //
- *m_pbHookInstalled = TRUE;
- //
- // and return success error code
- //
- bResult = TRUE;
- }
- //
- // and any other process should be examined whether it should be
- // hooked up by the DLL
- //
- else
- {
- bResult = m_pInjector->IsProcessForHooking(m_szProcessName);
- if (bResult)
- InitializeHookManagement();
- //
- // DLL is about to be mapped
- //
- //
- // Notify the server process the DLL will be mapped
- //
- ::PostMessage(
- *m_phwndServer,
- UWM_HOOKTOOL_DLL_LOADED,
- 0,
- ::GetCurrentProcessId()
- );
- }
- return bResult;
- }
- //
- // Called on DLL_PROCESS_DETACH notification
- //
- void CModuleScope::ManageModuleDetachment()
- {
- //
- // Check if the request comes from hooked up application
- //
- if ( !m_bIsThisServerProcess )
- {
- FinalizeHookManagement();
- //
- // Is the server still running ?
- //
- if (NULL != *m_phwndServer)
- //
- // Notify the server process the DLL is about to be unmapped
- //
- ::PostMessage(
- *m_phwndServer,
- UWM_HOOKTOOL_DLL_UNLOADED,
- 0,
- ::GetCurrentProcessId()
- );
- } // if
- else
- {
- //
- // attempt to eject the dll
- //
- m_pInjector->EjectModuleFromAllProcesses(m_pWhenZero->GetZeroHandle());
- LogMessage( "------- Hook server shuts down and unloads HookTool library -------");
- }
- }
- //
- // Activate/Deactivate hooking engine
- //
- BOOL CModuleScope::InstallHookMethod(
- BOOL bActivate,
- HWND hWndServer
- )
- {
- BOOL bResult;
- if (bActivate)
- {
- *m_phwndServer = hWndServer;
- bResult = m_pInjector->InjectModuleIntoAllProcesses();
- }
- else
- {
- m_pInjector->EjectModuleFromAllProcesses(m_pWhenZero->GetZeroHandle());
- *m_phwndServer = NULL;
- bResult = TRUE;
- }
- return bResult;
- }
- //
- //
- //
- void CModuleScope::LogMessage(const char* pszBuffer)
- {
- char szPrintBuffer[MAX_PATH];
- sprintf(
- szPrintBuffer,
- "%s(%u) - %s",
- m_szProcessName,
- m_dwProcessId,
- pszBuffer
- );
- sm_pLogFile->DoLogMessage(szPrintBuffer);
- }
- //
- // Accessor method
- //
- char* CModuleScope::GetProcessName() const
- {
- return const_cast<char*>(m_szProcessName);
- }
- //
- // Accessor method
- //
- DWORD CModuleScope::GetProcessId() const
- {
- return m_dwProcessId;
- }
- //
- // Return the name of the INI file
- //
- void CModuleScope::GetIniFile(char* pszIniFile)
- {
- char *pdest;
- ::GetModuleFileName(
- ModuleFromAddress(CModuleScope::GetInstance),
- pszIniFile,
- MAX_PATH
- );
- pdest = &pszIniFile[strlen(pszIniFile) - 4];
- strcpy(pdest, ".ini");
- }
- //
- // Get the value of [Trace] / Enabled from the INI file
- //
- BOOL CModuleScope::GetTraceEnabled()
- {
- if (!m_bTraceEnabledInitialized)
- {
- m_bTraceEnabled = FALSE;
- char szIniFile[MAX_PATH];
- GetIniFile(szIniFile);
- CIniFile iniFile(szIniFile);
- m_bTraceEnabled = iniFile.ReadBool(
- "Trace",
- "Enabled",
- FALSE
- );
- m_bTraceEnabledInitialized = TRUE;
- } // if
- return m_bTraceEnabled;
- }
- //
- // Determines whether Windows hook is going to be used
- //
- BOOL CModuleScope::UseWindowsHook()
- {
- if (!m_bUseWindowsHookInitialized)
- {
- char szIniFile[MAX_PATH];
- GetIniFile(szIniFile);
- CIniFile iniFile(szIniFile);
- m_bUseWindowsHook = iniFile.ReadBool(
- "Scope",
- "UseWindowsHook",
- TRUE
- );
- m_bUseWindowsHookInitialized = TRUE;
- }
- return m_bUseWindowsHook;
- }
- //
- // Hooks up an API function
- //
- BOOL CModuleScope::HookImport(
- PCSTR pszCalleeModName,
- PCSTR pszFuncName,
- PROC pfnHook
- )
- {
- return sm_pHookMgr->HookImport(
- pszCalleeModName,
- pszFuncName,
- pfnHook
- );
- }
- //
- // Restores the original API function pointer
- //
- BOOL CModuleScope::UnHookImport(
- PCSTR pszCalleeModName,
- PCSTR pszFuncName
- )
- {
- return sm_pHookMgr->UnHookImport(
- pszCalleeModName,
- pszFuncName
- );
- }
- //
- // Initialize hook engine
- //
- void CModuleScope::InitializeHookManagement()
- {
- //
- // Initially we must hook a few important functions
- //
- sm_pHookMgr->HookSystemFuncs();
- //
- // and now we can set-up some custom (demonstration) hooks
- //
- sm_pHookMgr->HookImport("Gdi32.DLL", "TextOutA", (PROC)CModuleScope::MyTextOutA);
- sm_pHookMgr->HookImport("Gdi32.DLL", "TextOutW", (PROC)CModuleScope::MyTextOutW);
- sm_pHookMgr->HookImport("Kernel32.DLL", "ExitProcess", (PROC)CModuleScope::MyExitProcess);
- LogMessage("The hook engine has been activated.");
- }
- //
- // Release all resource required by the hooking engine
- //
- void CModuleScope::FinalizeHookManagement()
- {
- if (sm_pHookMgr->AreThereHookedFunctions())
- LogMessage("The hook engine has been deactivated.");
- sm_pHookMgr->UnHookAllFuncs();
- }
- //
- // Our own TextOutA
- //
- BOOL WINAPI CModuleScope::MyTextOutA(
- HDC hdc, // handle to DC
- int nXStart, // x-coordinate of starting position
- int nYStart, // y-coordinate of starting position
- LPSTR lpString, // character string
- int cbString // number of characters
- )
- {
- BOOL bResult;
- char szBuffer[1024];
- ::ZeroMemory((PBYTE)szBuffer, sizeof(szBuffer));
- if (0 == stricmp(lpString, "Hello from TestApp!"))
- {
- strcpy(szBuffer, "Do you recon this is the original text ?");
- cbString = strlen(szBuffer);
- } // if
- else
- memcpy((PBYTE)szBuffer, (PBYTE)lpString, cbString*sizeof(char));
- bResult = ::TextOutA(
- hdc, // handle to DC
- nXStart, // x-coordinate of starting position
- nYStart, // y-coordinate of starting position
- szBuffer, // character string
- cbString // number of characters
- );
- return bResult;
- }
- //
- // Our own TextOutA
- //
- BOOL WINAPI CModuleScope::MyTextOutW(
- HDC hdc, // handle to DC
- int nXStart, // x-coordinate of starting position
- int nYStart, // y-coordinate of starting position
- LPWSTR lpString, // character string
- int cbString // number of characters
- )
- {
- BOOL bResult;
- wchar_t szBuffer[1024];
- ::ZeroMemory((PBYTE)szBuffer, sizeof(szBuffer));
- if (0 == wcsicmp(lpString, L"Hello from TestApp!"))
- {
- wcscpy(szBuffer, L"Do you recon this is the original text ?");
- cbString = wcslen(szBuffer);
- } // if
- else
- memcpy((PBYTE)szBuffer, (PBYTE)lpString, cbString*sizeof(wchar_t));
- bResult = ::TextOutW(
- hdc, // handle to DC
- nXStart, // x-coordinate of starting position
- nYStart, // y-coordinate of starting position
- szBuffer, // character string
- cbString // number of characters
- );
- return bResult;
- }
- //
- // Our own ExitProcess
- //
- VOID WINAPI CModuleScope::MyExitProcess(
- UINT uExitCode // exit code for all threads
- )
- {
- char szBuffer[MAX_PATH];
- sprintf(szBuffer, "Process (%u) shuts down.", ::GetCurrentProcessId());
- sm_pInstance->LogMessage(szBuffer);
- ::ExitProcess(uExitCode);
- return;
- }
- //----------------------------End of the file -------------------------------