ws2_32的任何函数都不能在WSAStartup之前hook,是因为这段代码static char *aszFuncNames[] ={ "accept", "bind", "closesocket", "connect", "getpeername", "getsockname", "getsockopt", "htonl", "htons", "ioctlsocket", "inet_addr", "inet_ntoa", "listen", "ntohl", "ntohs", "recv", "recvfrom", "select", "send", "sendto", "setsockopt", "shutdown", "socket", "gethostbyaddr", "gethostbyname", "getprotobyname", "getprotobynumber", "getservbyname", "getservbyport", "gethostname", "WSAAsyncSelect", "WSAAsyncGetHostByAddr", "WSAAsyncGetHostByName", "WSAAsyncGetProtoByNumber", "WSAAsyncGetProtoByName", "WSAAsyncGetServByPort", "WSAAsyncGetServByName", "WSACancelAsyncRequest", "WSASetBlockingHook", "WSAUnhookBlockingHook", "WSAGetLastError", "WSASetLastError", "WSACancelBlockingCall", "WSAIsBlocking", "WSAStartup", "WSACleanup",
"WSAAccept", "WSACloseEvent", "WSAConnect", "WSACreateEvent", "WSADuplicateSocketA", "WSADuplicateSocketW", "WSAEnumNetworkEvents", "WSAEnumProtocolsA", "WSAEnumProtocolsW", "WSAEventSelect", "WSAGetOverlappedResult", "WSAGetQOSByName", "WSAHtonl", "WSAHtons", "WSAIoctl", "WSAJoinLeaf", "WSANtohl", "WSANtohs", "WSARecv", "WSARecvDisconnect", "WSARecvFrom", "WSAResetEvent", "WSASend", "WSASendDisconnect", "WSASendTo", "WSASetEvent", "WSASocketA", "WSASocketW", "WSAWaitForMultipleEvents",
"WSAAddressToStringA", "WSAAddressToStringW", "WSAStringToAddressA", "WSAStringToAddressW", "WSALookupServiceBeginA", "WSALookupServiceBeginW", "WSALookupServiceNextA", "WSALookupServiceNextW", "WSALookupServiceEnd", "WSAInstallServiceClassA", "WSAInstallServiceClassW", "WSARemoveServiceClass", "WSAGetServiceClassInfoA", "WSAGetServiceClassInfoW", "WSAEnumNameSpaceProvidersA", "WSAEnumNameSpaceProvidersW", "WSAGetServiceClassNameByClassIdA", "WSAGetServiceClassNameByClassIdW", "WSASetServiceA", "WSASetServiceW",
"WSCDeinstallProvider", "WSCInstallProvider", "WSCEnumProtocols", "WSCGetProviderPath", "WSCInstallNameSpace", "WSCUnInstallNameSpace", "WSCEnableNSProvider",
"WPUCompleteOverlappedRequest",
"WSAProviderConfigChange",
"WSCWriteProviderOrder", "WSCWriteNameSpaceOrder",
NULL};
INTCheckForHookersOrChainers()/*++
Routine Description:
This procedure checks to see if there are any ws2_32 hookers or chainers out there, returning ERROR_SUCCESS if not or SOCKET_ERROR if so.
Arguments:
None
Return Value:
None--*/{ LPVOID pfnXxx; int i;
DEBUGF(DBG_TRACE, ("Checking for ws2_32 hookers or chainers...\n"));
for (i = 0; aszFuncNames[i]; i++) { if (!(pfnXxx = (LPVOID) GetProcAddress (gDllHandle, aszFuncNames[i])) || pfnXxx != apfns[i]) { DEBUGF(DBG_ERR, ("Hooker or chainer found, failing init\n"));
return SOCKET_ERROR; } }
DEBUGF(DBG_TRACE, ("No ws2_32 hookers or chainers found\n"));
return ERROR_SUCCESS;
} // CheckForHookersOrChainersint WSAAPIWSAStartup( IN WORD wVersionRequired, OUT LPWSADATA lpWSAData )函数中if (ReturnCode==ERROR_SUCCESS) { // Do this outside of critical section // because it does GetModuleHandle and GetProcAddress // which take loader lock. if (CheckForHookersOrChainers() == ERROR_SUCCESS) {
BOOL process_class_init_done = FALSE; BOOL thread_class_init_done = FALSE; BOOL socket_class_init_done = FALSE; PDPROCESS CurrentProcess=NULL; PDTHREAD CurrentThread=NULL;
EnterCriticalSection( & Startup_Synchro );
while (1) { CurrentProcess = DPROCESS::GetCurrentDProcess();
// GetCurrentDProcess has a most-likely "normal" failure case in the // case where this is the first time WSAStartup is called.
if (CurrentProcess != NULL) { break; }
ReturnCode = DPROCESS::DProcessClassInitialize(); if (ReturnCode != ERROR_SUCCESS) { break; } process_class_init_done = TRUE;
ReturnCode = DSOCKET::DSocketClassInitialize(); if (ReturnCode != ERROR_SUCCESS) { break; } socket_class_init_done = TRUE;
ReturnCode = DTHREAD::DThreadClassInitialize(); if (ReturnCode != ERROR_SUCCESS) { break; } thread_class_init_done = TRUE;
CurrentProcess = DPROCESS::GetCurrentDProcess(); if (CurrentProcess==NULL) { ReturnCode = WSASYSNOTREADY; break; }
// We don't need a reference to the current thread. // Nevertheless, we retrieve the current thread here just as a // means of validating that initialization has gotten far // enough to be able to retrieve the current thread. // Otherwise, we might detect a peculiar failure at some later // time when the client tries to do some real operation. ReturnCode = DTHREAD::GetCurrentDThread( CurrentProcess, // Process & CurrentThread); // CurrentThread } // while (1)这段代码的版权应该是intell的 |