【VC开源代码栏目提醒】:网学会员在VC开源代码频道为大家收集整理了COMMHOOK.CPP提供大家参考,希望对大家有所帮助!
// COMMHOOK.cpp - main module for VxD COMMHOOK
#define DEVICE_MAIN
#include "commhook.h"
Declare_Virtual_Device(COMMHOOK)
#undef DEVICE_MAIN
CommhookVM::CommhookVM(VMHANDLE hVM) : VVirtualMachine(hVM) {}
CommhookThread::CommhookThread(THREADHANDLE hThread) : VThread(hThread) {}
//
// These are used to store the original service addresses
// and the thunks that are used by the hook and unhook
// functions
COMMPORTHANDLE (*VCOMM_OpenCommService)(PCHAR,VMHANDLE);
HDSC_Thunk thunkVCOMM_OpenCommHook;
BOOL (*VCOMM_CloseCommService)(COMMPORTHANDLE);
HDSC_Thunk thunkVCOMM_CloseCommHook;
BOOL (*VCOMM_ReadCommService)(COMMPORTHANDLE,PVOID,DWORD,PDWORD);
HDSC_Thunk thunkVCOMM_ReadCommHook;
BOOL (*VCOMM_WriteCommService)(COMMPORTHANDLE,PVOID,DWORD,PDWORD);
HDSC_Thunk thunkVCOMM_WriteCommHook;
// A pointer to the device context. This is a hack to let
// these non-members of the device class get to its data.
CommhookDevice *CHD;
struct
{
char name[100];
COMMPORTHANDLE handle;
} OpenPorts[10];
// My hook for the VCOMM_OpenComm service. I call the
// original handler, check the return value, then see
// if the opened port was the one I was watching for.
COMMPORTHANDLE VCOMM_OpenCommHook( PCHAR szPortName, VMHANDLE VMid )
{
COMMPORTHANDLE retval = VCOMM_OpenCommService( szPortName, VMid );
if ( (retval != IE_BADID && retval != IE_OPEN) &&
CHD->cpTargetPortName != NULL &&
!stricmp( szPortName, CHD->cpTargetPortName ) )
{
CHD->hPort = retval;
CHD->sAccessStats.dwOpenCount++;
}
return retval;
}
// My hook for the VCOMM_CloseComm service. I check the port
// handle passed in to see if it was the one I was watching
// (or if I hadn't seen an open yet) then call the original
// service.
BOOL VCOMM_CloseCommHook( COMMPORTHANDLE hPort )
{
if ( CHD->hPort == hPort && CHD->hPort != NULL )
{
CHD->sAccessStats.dwCloseCount++;
CHD->hPort = NULL;
}
else if ( CHD->hPort == NULL )
{
CHD->sAccessStats.dwNotMineCloseCount++;
}
return VCOMM_CloseCommService( hPort );
}
// My hook for the VCOMM_ReadComm service. I call the original
// service, then check the port handle. If it was the one I
// was watching (or if I hadn't seen an open yet), I add the
// read data to a list of "trace blocks".
BOOL VCOMM_ReadCommHook( COMMPORTHANDLE hPort, PVOID buf, DWORD nRequest, PDWORD pNRead )
{
BOOL retval = VCOMM_ReadCommService( hPort, buf, nRequest, pNRead );
if ( CHD->hPort == hPort || CHD->hPort == NULL )
{
CHD->sAccessStats.dwReadCount++;
CHD->sAccessStats.dwReadBytes += *pNRead;
CHD->AddTraceBlock( (unsigned char *)buf, false, *pNRead );
}
return retval;
}
// My hook for the VCOMM_WriteComm service. I call the original
// service, then check the port handle. If it was the one I
// was watching (or if I hadn't seen an open yet), I add the
// written data to a list of "trace blocks".
// NOTE THE USE OF THE MUTEX. SINCE I WANT TO BE ABLE TO WRITE
// TO THE PORT (INJECTING MY OWN DATA), I SYNCHRONIZE ACCESS
// TO THE VCOMM_WriteComm SERVICE. I DON'T REALLY KNOW IF THIS
// IS NECESSARY.
BOOL VCOMM_WriteCommHook( COMMPORTHANDLE hPort, PVOID buf, DWORD nRequest, PDWORD pNWritten )
{
if ( CHD->hPort == hPort || CHD->hPort == NULL )
{
CHD->mutexWrite->enter();
}
BOOL rv = VCOMM_WriteCommService( hPort, buf, nRequest, pNWritten );
if ( CHD->hPort == hPort || CHD->hPort == NULL )
{
CHD->mutexWrite->leave();
CHD->sAccessStats.dwWriteCount++;
CHD->sAccessStats.dwWriteBytes += *pNWritten;
CHD->AddTraceBlock( (unsigned char *)buf, true, *pNWritten );
}
return rv;
}
// Remove the head of the trace block list and return it, adjusting
// the total trace size.
CDataBlock *CommhookDevice::GetNextTraceBlock()
{
mutexTrace->enter();
CDataBlock *pNext = m_pFirstTraceBlock;
if ( m_pFirstTraceBlock != NULL )
m_pFirstTraceBlock = m_pFirstTraceBlock->m_pNextBlock;
if ( m_pFirstTraceBlock == NULL )
m_pLastTraceBlock = NULL;
if ( pNext != NULL )
m_dwTraceSize -= pNext->m_dwLength;
mutexTrace->leave();
return pNext;
}
// Add a block to the tail of the trace block list, adjusting the size.
void CommhookDevice::AddTraceBlock( unsigned char *pData, bool bWritten, DWORD dwLength )
{
if ( dwLength )
{
mutexTrace->enter();
CDataBlock *pNewBlock = new CDataBlock( pData, bWritten, dwLength );
if ( m_pFirstTraceBlock == NULL )
m_pFirstTraceBlock = pNewBlock;
else
m_pLastTraceBlock->m_pNextBlock = pNewBlock;
m_pLastTraceBlock = pNewBlock;
m_dwTraceSize += pNewBlock->m_dwLength;
mutexTrace->leave();
}
}
// Install the hooks. Note that the VCOMM services I'm hooking
// follow the C calling convention, so I use Hook_Device_Service_C
VOID CommhookDevice::DoHooks( void )
{
// hook the open comm service
VCOMM_OpenCommService = (COMMPORTHANDLE(*)(PCHAR,VMHANDLE))
Hook_Device_Service_C( ___VCOMM_OpenComm,
VCOMM_OpenCommHook,
&thunkVCOMM_OpenCommHook);
// hook the close comm service
VCOMM_CloseCommService = (BOOL(*)(COMMPORTHANDLE))
Hook_Device_Service_C( ___VCOMM_CloseComm,
VCOMM_CloseCommHook,
&thunkVCOMM_CloseCommHook);
// hook the read comm service
VCOMM_ReadCommService = (BOOL(*)(COMMPORTHANDLE,PVOID,DWORD,PDWORD))
Hook_Device_Service_C( ___VCOMM_ReadComm,
VCOMM_ReadCommHook,
&thunkVCOMM_ReadCommHook);
// hook the write comm service
VCOMM_WriteCommService = (BOOL(*)(COMMPORTHANDLE,PVOID,DWORD,PDWORD))
Hook_Device_Service_C( ___VCOMM_WriteComm,
VCOMM_WriteCommHook,
&thunkVCOMM_WriteCommHook);
}
// Uninstall the hooks with Unhook_Device_Service_C
VOID CommhookDevice::DoUnhooks( void )
{
// unhook the open comm service
Unhook_Device_Service_C(___VCOMM_OpenComm,
&thunkVCOMM_OpenCommHook);
// unhook the close comm service
Unhook_Device_Service_C(___VCOMM_CloseComm,
&thunkVCOMM_CloseCommHook);
// unhook the read comm service
Unhook_Device_Service_C(___VCOMM_ReadComm,
&thunkVCOMM_ReadCommHook);
// unhook the write comm service
Unhook_Device_Service_C(___VCOMM_WriteComm,
&thunkVCOMM_WriteCommHook);
}
void CommhookDevice::ClearStats( void )
{
sAccessStats.dwOpenCount =
sAccessStats.dwCloseCount =
sAccessStats.dwNotMineCloseCount =
sAccessStats.dwReadCount =
sAccessStats.dwReadBytes =
sAccessStats.dwWriteCount =
sAccessStats.dwWriteBytes = 0;
}
void CommhookDevice::SetupData( void )
{
ClearStats();
pHandles = NULL;
nNumHandles = 0;
CHD = this;
mutexWrite = new VMutex;
mutexTrace = new VMutex;
cpTargetPortName = NULL;
hPort = NULL;
for ( int i=0; i<10; i++ )
{
memset( OpenPorts[i].name, 0, 100 );
OpenPorts[i].handle = NULL;
}
FilteredRead =
FilteredWrite =
FilteredCount = 0;
m_pFirstT
上一篇:
CommandRangeDemoView.cpp
下一篇:
恋沫