?? tcpipdog.cpp
字號:
/*——————————————————————————————————————
文件: TcpIpDog.cpp
說明:
——————————————————————————
Winsock 鉤子,用來截獲 Winsock 調用從而攔截
TCP/IP封包,并做相應處理。這里將發送接收的封包
作為調試信息輸出
——————————————————————————
工程: PacketCapture
作者: 朱雁輝,朱雁冰
創建日期: 2001/08/21
網址: http://www.xfilt.com
電子郵件: xstudio@xfilt.com
版權所有 (c) 2001-2002 X 工作室
警告:
——————————————————————————
本電腦程序受著作權法的保護。未經授權,不能使用
和修改本軟件全部或部分源代碼。凡擅自復制、盜用或散
布此程序或部分程序或者有其它任何越權行為,將遭到民
事賠償及刑事的處罰,并將依法以最高刑罰進行追訴。
凡通過合法途徑購買本軟件源代碼的用戶被默認授權
可以在自己的程序中使用本軟件的部分代碼,但作者不對
代碼產生的任何后果負責。
使用了本軟件代碼的程序只能以可執行文件形式發布,
未經特別許可,不能將含有本軟件源代碼的源程序以任何
形式發布。
——————————————————————————
*/
//——————————————————————————————————————
// include header file and global variables
#include<stdio.h>
#include "stdafx.h"
#include "overlapped.h"
//
// 進程間全局變量
//
#pragma data_seg(".inidata")
int m_iDllCount = 0;
#pragma data_seg()
//
// 進程內全局變量
//
CRITICAL_SECTION gCriticalSection; // 代碼段保護變量
WSPPROC_TABLE NextProcTable ; // 保存30個服務提供者指針
TCHAR m_sProcessName[MAX_PATH]; // 保存當前進程名稱
COverlapped m_Overlapped; // 保存重疊操作相關信息的類
//
// 自定義注冊表分支用來保存系統基礎服務提供者的路徑
//
#define REG_INSTALL_KEY \
_T("SYSTEM\\CurrentControlSet\\Services\\WinSock2\\Xstudio_Packet_Capture")
//——————————————————————————————————————
// 私有函數
void ShutdownSocket( SOCKET s )
{
int iError;
if( NextProcTable.lpWSPShutdown( s, SD_BOTH, &iError ) != 0 )
WSASetLastError( iError );
}
void PrintSocket(SOCKET s, DWORD bytes, TCHAR *sExt)
{
SOCKADDR_IN local_addr, remote_addr;
int local_addr_len = sizeof(local_addr);
int remote_addr_len = sizeof(remote_addr);
getsockname(s, (SOCKADDR*)&local_addr, &local_addr_len);
getpeername(s, (SOCKADDR*)&remote_addr, &remote_addr_len);
CString sTemp;
sTemp.Format(" Socket %u %s\n", s, sExt);
OutputDebugString(sTemp);
sTemp.Format(" %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u transfered %u bytes\n"
, local_addr.sin_addr.S_un.S_un_b.s_b1
, local_addr.sin_addr.S_un.S_un_b.s_b2
, local_addr.sin_addr.S_un.S_un_b.s_b3
, local_addr.sin_addr.S_un.S_un_b.s_b4
, ntohs(local_addr.sin_port)
, remote_addr.sin_addr.S_un.S_un_b.s_b1
, remote_addr.sin_addr.S_un.S_un_b.s_b2
, remote_addr.sin_addr.S_un.S_un_b.s_b3
, remote_addr.sin_addr.S_un.S_un_b.s_b4
, ntohs(remote_addr.sin_port)
, bytes
);
OutputDebugString(sTemp);
}
void PrintReturnCode(int iReturnCode, LPINT lpErrno)
{
CString sOutput , sTemp, sTemp1;
switch(iReturnCode)
{
case SOCKET_ERROR:
sTemp = "SOCKET_ERROR";
break;
case 0:
sTemp = "SOCKET_SUCCESS";
break;
default:
sTemp = "OTHER";
break;
}
switch(*lpErrno)
{
case WSA_IO_PENDING:
sTemp1 = "WSA_IO_PENDING";
break;
default:
sTemp1 = "OTHER";
break;
}
sOutput.Format(" ReturnCode: %s(%d); *lpErrno: %s(%d)\n"
, sTemp, iReturnCode, sTemp1, *lpErrno);
OutputDebugString(sOutput);
}
void PrintProtocolInfo(
IN WSAPROTOCOL_INFOW *pProtocolInfo,
IN TCHAR *sPathName
)
{
OutputDebugString(" ProtocolInfo:\n");
CString sTemp, sOutput;
sTemp.Format(" LibraryPath: %s\n", sPathName);
OutputDebugString(sTemp);
sTemp.Format(" dwServiceFlags1: 0x%08X; %d\n"
, pProtocolInfo->dwServiceFlags1
, pProtocolInfo->dwServiceFlags1
);
OutputDebugString(sTemp);
sTemp.Format(" dwServiceFlags2: 0x%08X; %d\n"
, pProtocolInfo->dwServiceFlags2
, pProtocolInfo->dwServiceFlags2
);
OutputDebugString(sTemp);
sTemp.Format(" dwServiceFlags3: 0x%08X; %d\n"
, pProtocolInfo->dwServiceFlags3
, pProtocolInfo->dwServiceFlags3
);
OutputDebugString(sTemp);
sTemp.Format(" dwServiceFlags4: 0x%08X; %d\n"
, pProtocolInfo->dwServiceFlags4
, pProtocolInfo->dwServiceFlags4
);
OutputDebugString(sTemp);
sTemp.Format(" dwProviderFlags: 0x%08X; %d\n"
, pProtocolInfo->dwProviderFlags
, pProtocolInfo->dwProviderFlags
);
OutputDebugString(sTemp);
sTemp.Format(" ProviderId: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n"
, pProtocolInfo->ProviderId.Data1
, pProtocolInfo->ProviderId.Data2
, pProtocolInfo->ProviderId.Data3
, pProtocolInfo->ProviderId.Data4[0]
, pProtocolInfo->ProviderId.Data4[1]
, pProtocolInfo->ProviderId.Data4[2]
, pProtocolInfo->ProviderId.Data4[3]
, pProtocolInfo->ProviderId.Data4[4]
, pProtocolInfo->ProviderId.Data4[5]
, pProtocolInfo->ProviderId.Data4[6]
, pProtocolInfo->ProviderId.Data4[7]
);
OutputDebugString(sTemp);
sTemp.Format(" dwCatalogEntryId: 0x%08X; %d\n"
, pProtocolInfo->dwCatalogEntryId
, pProtocolInfo->dwCatalogEntryId
);
OutputDebugString(sTemp);
sTemp.Format(" ProtocolChain.ChainLen: 0x%08X; %d\n"
, pProtocolInfo->ProtocolChain.ChainLen
, pProtocolInfo->ProtocolChain.ChainLen
);
OutputDebugString(sTemp);
sTemp.Empty();
OutputDebugString(" ProtocolChain.ChainEntries: ");
for(int i = 0; i < MAX_PROTOCOL_CHAIN; i++)
{
CString s = "";
if(i == MAX_PROTOCOL_CHAIN - 1)
s.Format("0x%08X\n", pProtocolInfo->ProtocolChain.ChainEntries[i]);
else
s.Format("0x%08X->", pProtocolInfo->ProtocolChain.ChainEntries[i]);
sTemp += s;
}
OutputDebugString(sTemp);
sTemp.Format(" iVersion: 0x%08X; %d\n"
, pProtocolInfo->iVersion
, pProtocolInfo->iVersion
);
OutputDebugString(sTemp);
sTemp.Format(" iAddressFamily: 0x%08X; %d\n"
, pProtocolInfo->iAddressFamily
, pProtocolInfo->iAddressFamily
);
OutputDebugString(sTemp);
sTemp.Format(" iMaxSockAddr: 0x%08X; %d\n"
, pProtocolInfo->iMaxSockAddr
, pProtocolInfo->iMaxSockAddr
);
OutputDebugString(sTemp);
sTemp.Format(" iMinSockAddr: 0x%08X; %d\n"
, pProtocolInfo->iMinSockAddr
, pProtocolInfo->iMinSockAddr
);
OutputDebugString(sTemp);
sTemp.Format(" iSocketType: 0x%08X; %d\n"
, pProtocolInfo->iSocketType
, pProtocolInfo->iSocketType
);
OutputDebugString(sTemp);
sTemp.Format(" iProtocol: 0x%08X; %d\n"
, pProtocolInfo->iProtocol
, pProtocolInfo->iProtocol
);
OutputDebugString(sTemp);
sTemp.Format(" iProtocolMaxOffset: 0x%08X; %d\n"
, pProtocolInfo->iProtocolMaxOffset
, pProtocolInfo->iProtocolMaxOffset
);
OutputDebugString(sTemp);
sTemp.Format(" iNetworkByteOrder: 0x%08X; %d\n"
, pProtocolInfo->iNetworkByteOrder
, pProtocolInfo->iNetworkByteOrder
);
OutputDebugString(sTemp);
sTemp.Format(" iSecurityScheme: 0x%08X; %d\n"
, pProtocolInfo->iSecurityScheme
, pProtocolInfo->iSecurityScheme
);
OutputDebugString(sTemp);
sTemp.Format(" dwMessageSize: 0x%08X; %d\n"
, pProtocolInfo->dwMessageSize
, pProtocolInfo->dwMessageSize
);
OutputDebugString(sTemp);
sTemp.Format(" dwProviderReserved: 0x%08X; %d\n"
, pProtocolInfo->dwProviderReserved
, pProtocolInfo->dwProviderReserved
);
OutputDebugString(sTemp);
sTemp = pProtocolInfo->szProtocol;
OutputDebugString(" szProtocol: ");
OutputDebugString(sTemp);
OutputDebugString("\n");
}
void GetRightEntryIdItem(
IN WSAPROTOCOL_INFOW *pProtocolInfo,
OUT TCHAR *sItem
)
{
if(pProtocolInfo->ProtocolChain.ChainLen <= 1)
_stprintf(sItem, _T("%u"), pProtocolInfo->dwCatalogEntryId);
else
_stprintf(sItem, _T("%u"), pProtocolInfo->ProtocolChain
.ChainEntries[pProtocolInfo->ProtocolChain.ChainLen - 1]);
}
BOOL GetHookProvider(
IN WSAPROTOCOL_INFOW *pProtocolInfo,
OUT TCHAR *sPathName
)
{
TCHAR sItem[21];
GetRightEntryIdItem(pProtocolInfo, sItem);
HKEY hSubkey;
DWORD ulDateLenth = MAX_PATH;
TCHAR sTemp[MAX_PATH];
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
, REG_INSTALL_KEY, 0, KEY_ALL_ACCESS, &hSubkey) != ERROR_SUCCESS)
return FALSE;
if (RegQueryValueEx(hSubkey, sItem, 0, NULL, (BYTE*)sTemp, &ulDateLenth)
|| ExpandEnvironmentStrings(sTemp, sPathName, ulDateLenth) == 0)
return FALSE;
if(sPathName[0] == '\0' && sTemp[0] != '\0')
_tcscpy(sPathName, sTemp);
RegCloseKey(hSubkey);
return TRUE;
}
//——————————————————————————————————————
// Winsock 2 服務提供者鉤子函數
void CALLBACK CompletionRoutine (
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
)
{
ODS(_T("CompletionRoutine ..."));
int iIndex = m_Overlapped.FindOverlapped(lpOverlapped);
if(iIndex < 0)
return;
CString sTemp;
if(m_Overlapped.m_OverlappedRecorder[iIndex].FunctionType == 1)//WSPRecvFrom
{
PrintSocket(m_Overlapped.m_OverlappedRecorder[iIndex].s
, cbTransferred, "WSPRecvFrom");
OutputDebugString(" <==WSPRecvFrom WSA_IO_PENDING\n");
}
else if(m_Overlapped.m_OverlappedRecorder[iIndex].FunctionType == 0) //WSPRecv
{
PrintSocket(m_Overlapped.m_OverlappedRecorder[iIndex].s
, cbTransferred, "WSPRecv");
OutputDebugString(" <==WSPRecv WSA_IO_PENDING\n");
}
if(m_Overlapped.m_OverlappedRecorder[iIndex].lpCompletionRoutine != NULL)
{
m_Overlapped.m_OverlappedRecorder[iIndex].lpCompletionRoutine(dwError
, cbTransferred, lpOverlapped, dwFlags);
}
m_Overlapped.DeleteOverlapped(iIndex);
}
SOCKET WSPAPI WSPSocket(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
GROUP g,
DWORD dwFlags,
LPINT lpErrno
)
{
ODS(_T("WSPSocket ..."));
return NextProcTable.lpWSPSocket(af, type
, protocol, lpProtocolInfo, g, dwFlags, lpErrno);
}
int WSPAPI WSPCloseSocket(
SOCKET s,
LPINT lpErrno
)
{
ODS(_T("WSPCloseSocket ..."));
return NextProcTable.lpWSPCloseSocket(s, lpErrno);
}
int WSPAPI WSPConnect(
SOCKET s,
const struct sockaddr FAR * name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS,
LPINT lpErrno
)
{
ODS(_T("WSPConnect ..."));
return NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData
, lpCalleeData, lpSQOS, lpGQOS, lpErrno);
}
SOCKET WSPAPI WSPAccept(
SOCKET s,
struct sockaddr FAR *addr,
LPINT addrlen,
LPCONDITIONPROC lpfnCondition,
DWORD dwCallbackData,
LPINT lpErrno
)
{
ODS(_T("WSPAccept ..."));
return NextProcTable.lpWSPAccept(s, addr, addrlen, lpfnCondition
, dwCallbackData, lpErrno);
}
int WSPAPI WSPSend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
ODS(_T("WSPSend ..."));
PrintSocket(s, *lpNumberOfBytesSent, "WSPSend");
return NextProcTable.lpWSPSend(s, lpBuffers, dwBufferCount
, lpNumberOfBytesSent, dwFlags, lpOverlapped
, lpCompletionRoutine, lpThreadId, lpErrno);
}
int WSPAPI WSPSendTo(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
const struct sockaddr FAR * lpTo,
int iTolen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
ODS(_T("WSPSendTo ..."));
PrintSocket(s, *lpNumberOfBytesSent, "WSPSendTo");
return NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount
, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, lpOverlapped
, lpCompletionRoutine, lpThreadId, lpErrno);
}
int WSPAPI WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
return SOCKET_ERROR;
/*
FILE * fp;
int i;
char cOutputDebugString_Buf [80];
int n_len_to_cmp;
ODS(_T("WSPRecv ..."));
BOOL IsSetCompletionRoutine = FALSE;
///////////////////////////////////////////////////////////////
sockaddr_in local_name = {0};
sockaddr_in remote_name = {0};
u_short us_local_port, us_remote_port;
int namelen = sizeof(sockaddr_in);
getsockname( s, (sockaddr*)&local_name, &namelen );
getpeername( s, (sockaddr*)&remote_name, &namelen );
us_local_port = ntohs( local_name.sin_port );
us_remote_port = ntohs( remote_name.sin_port );
char cTemp [20];
sprintf( cTemp, "local_port : %u <==> remote_port : %u\n", us_local_port, us_remote_port );
fp = fopen( "d:\\temp\\WSPRecv_Buf.txt", "a+" );
if ( fp != NULL )
{
fwrite( cTemp, 1, strlen( cTemp ), fp );
fclose(fp);
}
else
OutputDebugString( _T("fp == NULL !\n") );
///////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
fp = fopen( "d:\\temp\\WSPRecv_Buf.txt", "a+" );
if ( fp != NULL )
{
fwrite( "**********************WSPRecv1***********************\n", 1, strlen("*************************WSPRecv1********************\n"), fp );
if ( IsSetCompletionRoutine )
fwrite( "WSPRecv --- IsSetCompletionRoutine !\n", 1, strlen("WSPRecv --- IsSetCompletionRoutine !\n"), fp );;
fwrite( lpBuffers[0].buf, 1, (lpBuffers[0].len < 250) ? lpBuffers[0].len : 250, fp );
fwrite( "\n", 1, 1, fp );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -