本人尝试做spi包过滤程序,写了一个SSPI.DLL,该只DLL导出了WSPStartup函数。在正确安装了该DLL以后,NOW IN WSPSend不重新启动机器,尝试上个80端口的网站,正确输出了调试信息
RSSPI.dll: WSPStartup...
NOW IN WSPSend
但是重新启动以后,打开IE,只能看到RSSPI.dll: WSPStartup...
没有调试信息NOW IN WSPSend,而且上网行为被阻断了。
但是尝试用REMOTE连接别的机器,正确输出了调试信息,而且行为没有被阻断。各位高手,有谁知道是什么原因导致的?多谢了!! 程序主体如下:
#include "StdAfx.h"#include "NetACL.h"#define REG_INSTALL_KEY \
_T("SYSTEM\\CurrentControlSet\\Services\\WinSock2\\SS_SPI")//REG_INSTALL_KEY是安装SPI时在注册表中的位置。WSPPROC_TABLE NextProcTable ;
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;
}BOOL WINAPI DllMain(
HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
TRACE0(_T("DllMain DLL_PROCESS_ATTACH")); }
else if(ul_reason_for_call == DLL_PROCESS_DETACH)
{
TRACE0(_T("DllMain DLL_PROCESS_DETACH"));
} return TRUE;
}int WSPAPI WSPSend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
TRACE0(_T("NOW IN 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)
{
TRACE0(_T("NOW IN WSPSendTo"));
return NextProcTable.lpWSPSendTo(s,lpBuffers,dwBufferCount,
lpnumberofbytessent,dwflags,lpto,itolen,
lpoverlapped,lpcompletionroutine,lpthreadid,lpErrno);
}int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
WSPUPCALLTABLE upcallTable,
LPWSPPROC_TABLE lpProcTable
)
{
DEBUGSTRING(_T("RSSPI.dll: WSPStartup...\n")); TCHAR sLibraryPath[512];
LPWSPSTARTUP WSPStartupFunc = NULL;
HMODULE hLibraryHandle = NULL;
INT ErrorCode = 0; if (!GetHookProvider(lpProtocolInfo, sLibraryPath)
|| (hLibraryHandle = LoadLibrary(sLibraryPath)) == NULL
|| (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(
hLibraryHandle, "WSPStartup")) == NULL
)
return WSAEPROVIDERFAILEDINIT; if ((ErrorCode = WSPStartupFunc(wVersionRequested, lpWSPData
, lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
return ErrorCode;
NextProcTable = *lpProcTable; lpProcTable->lpWSPSend = WSPSend;
lpProcTable->lpWSPSendTo = WSPSendTo; return 0;
}
RSSPI.dll: WSPStartup...
NOW IN WSPSend
但是重新启动以后,打开IE,只能看到RSSPI.dll: WSPStartup...
没有调试信息NOW IN WSPSend,而且上网行为被阻断了。
但是尝试用REMOTE连接别的机器,正确输出了调试信息,而且行为没有被阻断。各位高手,有谁知道是什么原因导致的?多谢了!! 程序主体如下:
#include "StdAfx.h"#include "NetACL.h"#define REG_INSTALL_KEY \
_T("SYSTEM\\CurrentControlSet\\Services\\WinSock2\\SS_SPI")//REG_INSTALL_KEY是安装SPI时在注册表中的位置。WSPPROC_TABLE NextProcTable ;
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;
}BOOL WINAPI DllMain(
HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
TRACE0(_T("DllMain DLL_PROCESS_ATTACH")); }
else if(ul_reason_for_call == DLL_PROCESS_DETACH)
{
TRACE0(_T("DllMain DLL_PROCESS_DETACH"));
} return TRUE;
}int WSPAPI WSPSend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
TRACE0(_T("NOW IN 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)
{
TRACE0(_T("NOW IN WSPSendTo"));
return NextProcTable.lpWSPSendTo(s,lpBuffers,dwBufferCount,
lpnumberofbytessent,dwflags,lpto,itolen,
lpoverlapped,lpcompletionroutine,lpthreadid,lpErrno);
}int WSPAPI WSPStartup(
WORD wVersionRequested,
LPWSPDATA lpWSPData,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
WSPUPCALLTABLE upcallTable,
LPWSPPROC_TABLE lpProcTable
)
{
DEBUGSTRING(_T("RSSPI.dll: WSPStartup...\n")); TCHAR sLibraryPath[512];
LPWSPSTARTUP WSPStartupFunc = NULL;
HMODULE hLibraryHandle = NULL;
INT ErrorCode = 0; if (!GetHookProvider(lpProtocolInfo, sLibraryPath)
|| (hLibraryHandle = LoadLibrary(sLibraryPath)) == NULL
|| (WSPStartupFunc = (LPWSPSTARTUP)GetProcAddress(
hLibraryHandle, "WSPStartup")) == NULL
)
return WSAEPROVIDERFAILEDINIT; if ((ErrorCode = WSPStartupFunc(wVersionRequested, lpWSPData
, lpProtocolInfo, upcallTable, lpProcTable)) != ERROR_SUCCESS)
return ErrorCode;
NextProcTable = *lpProcTable; lpProcTable->lpWSPSend = WSPSend;
lpProcTable->lpWSPSendTo = WSPSendTo; return 0;
}
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, 0, KEY_ALL_ACCESS, &hSubkey)
为:
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_INSTALL_KEY, 0, KEY_READ, &hSubkey)
如果是KEY_ALL_ACCESS,有个系统进程会被拒绝访问导致IE初始化失败。