⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet32.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (Type != REG_SZ)
		{
			*pValueLen = 0;
			
			SetLastError(ERROR_INVALID_DATA);
			return FALSE;
		}
		else
		{
			//success!
			return TRUE;
		}
	}
	else
	if (QveRes == ERROR_MORE_DATA)
	{
		//
		//the needed bytes are already set by RegQueryValueExA
		//

		SetLastError(QveRes);
		return FALSE;
	}
	else
	{
		//
		//print the error
		//
		ODSEx("QueryWinpcapRegistryKey, RegQueryValueEx failed, code %d",QveRes);
		//
		//JUST CONTINUE WITH THE DEFAULT VALUE
		//
	}

#endif // WPCAP_OEM

	if ((*pValueLen) < strlen(DefaultVal) + 1)
	{
		memcpy(Value, DefaultVal, *pValueLen - 1);
		Value[*pValueLen - 1] = '\0';
		*pValueLen = strlen(DefaultVal) + 1;
		SetLastError(ERROR_MORE_DATA);
		return FALSE;
	}
	else
	{
		strcpy(Value, DefaultVal);
		*pValueLen = strlen(DefaultVal) + 1;
		return TRUE;
	}

}
						
BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName,
								 WCHAR *Value,
								 UINT *pValueLen,
								 WCHAR *DefaultVal)
{
#ifdef WPCAP_OEM
	DWORD Type;
	LONG QveRes;
	HKEY hWinPcapKey;
	DWORD InternalLenBytes;

	if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 
			WINPCAP_INSTANCE_KEY_WIDECHAR,
			0,
			KEY_ALL_ACCESS,
			&hWinPcapKey) != ERROR_SUCCESS)
	{
		*pValueLen = 0;
		return FALSE;
	}

	InternalLenBytes = *pValueLen * 2;
	
	//
	// Query the requested value
	//
	QveRes = RegQueryValueExW(hWinPcapKey,
		SubKeyName,
		NULL,
		&Type,
		(LPBYTE)Value,
		&InternalLenBytes);

	RegCloseKey(hWinPcapKey);

	if (QveRes == ERROR_SUCCESS)
	{
		//let's check that the key is text
		if (Type != REG_SZ)
		{
			*pValueLen = 0;
			SetLastError(ERROR_INVALID_DATA);
			return FALSE;
		}
		else
		{
			//success!
			*pValueLen = wcslen(Value) + 1;
		
			return TRUE;
		}
	}
	else
	if (QveRes == ERROR_MORE_DATA)
	{
		//
		//the needed bytes are not set by RegQueryValueExW
		//
		
		//the +1 is needed to round the needed buffer size (in WCHARs) to a number of WCHARs that will fit
		//the number of needed bytes. In any case if it's a W string, the number of needed bytes should always be even!

		*pValueLen = (InternalLenBytes + 1) / 2;

		SetLastError(ERROR_MORE_DATA);
		return FALSE;
	}
	else
	{
		//
		//print the error
		//
		ODSEx("QueryWinpcapRegistryKey, RegQueryValueEx failed, code %d\n",QveRes);
		//
		//JUST CONTINUE WITH THE DEFAULT VALUE
		//
	}

#endif // WPCAP_OEM

	if (*pValueLen < wcslen(DefaultVal) + 1)
	{
		memcpy(Value, DefaultVal, (*pValueLen  - 1) * 2);
		Value[*pValueLen - 1] = '\0';
		*pValueLen = wcslen(DefaultVal) + 1;
		SetLastError(ERROR_MORE_DATA);
		return FALSE;
	}
	else
	{
		wcscpy(Value, DefaultVal);
		*pValueLen = wcslen(DefaultVal) + 1;
		return TRUE;
	}

}

*/

/*! 
  \brief Convert a Unicode dotted-quad to a 32-bit IP address.
  \param cp A string containing the address.
  \return the converted 32-bit numeric address.

   Doesn't check to make sure the address is valid.
*/
ULONG inet_addrU(const WCHAR *cp)
{
	ULONG val, part;
	WCHAR c;
	int i;

	val = 0;
	for (i = 0; i < 4; i++) {
		part = 0;
		while ((c = *cp++) != '\0' && c != '.') {
			if (c < '0' || c > '9')
				return (ULONG)-1;
			part = part*10 + (c - '0');
		}
		if (part > 255)
			return (ULONG)-1;	
		val = val | (part << i*8);
		if (i == 3) {
			if (c != '\0')
				return (ULONG)-1;	// extra gunk at end of string 
		} else {
			if (c == '\0')
				return (ULONG)-1;	// string ends early 
		}
	}
	return val;
}

/*! 
  \brief Converts an ASCII string to UNICODE. Uses the MultiByteToWideChar() system function.
  \param string The string to convert.
  \return The converted string.
*/
static PWCHAR SChar2WChar(PCHAR string)
{
	PWCHAR TmpStr;
	TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)(strlen(string)+2)*sizeof(WCHAR));

	MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (DWORD)(strlen(string)+2));

	return TmpStr;
}

/*! 
  \brief Converts an UNICODE string to ASCII. Uses the WideCharToMultiByte() system function.
  \param string The string to convert.
  \return The converted string.
*/
static PCHAR WChar2SChar(PWCHAR string)
{
	PCHAR TmpStr;
	TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)(wcslen(string)+2));

	// Conver to ASCII
	WideCharToMultiByte(
		CP_ACP,
		0,
		string,
		-1,
		TmpStr,
		(DWORD)(wcslen(string)+2),          // size of buffer
		NULL,
		NULL);

	return TmpStr;
}

/*! 
  \brief Sets the maximum possible lookahead buffer for the driver's Packet_tap() function.
  \param AdapterObject Handle to the service control manager.
  \return If the function succeeds, the return value is nonzero.

  The lookahead buffer is the portion of packet that Packet_tap() can access from the NIC driver's memory
  without performing a copy. This function tries to increase the size of that buffer.

  NOTE: this function is used for NPF adapters, only.
*/

BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
{
    BOOLEAN    Status;
    ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
    PPACKET_OID_DATA  OidData;

	TRACE_ENTER("PacketSetMaxLookaheadsize");

    OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
    if (OidData == NULL) {
        TRACE_PRINT("PacketSetMaxLookaheadsize failed");
        Status = FALSE;
    }
	else
	{
		//set the size of the lookahead buffer to the maximum available by the the NIC driver
		OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
		OidData->Length=sizeof(ULONG);
		Status=PacketRequest(AdapterObject,FALSE,OidData);
		OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
		Status=PacketRequest(AdapterObject,TRUE,OidData);
		GlobalFreePtr(OidData);
	}

	TRACE_EXIT("PacketSetMaxLookaheadsize");
	return Status;
}

/*! 
  \brief Allocates the read event associated with the capture instance, passes it down to the kernel driver
  and stores it in an _ADAPTER structure.
  \param AdapterObject Handle to the adapter.
  \return If the function succeeds, the return value is nonzero.

  This function is used by PacketOpenAdapter() to allocate the read event and pass it to the driver by means of an ioctl
  call and set it in the _ADAPTER structure pointed by AdapterObject.

  NOTE: this function is used for NPF adapters, only.
*/
BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
{
	DWORD BytesReturned;
	HANDLE hEvent;

 	TRACE_ENTER("PacketSetReadEvt");

	if (AdapterObject->ReadEvent != NULL)
	{
		SetLastError(ERROR_INVALID_FUNCTION);
		return FALSE;
	}

 	hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	if (hEvent == NULL)
	{
		//SetLastError done by CreateEvent	
 		TRACE_EXIT("PacketSetReadEvt");
		return FALSE;
	}

	if(DeviceIoControl(AdapterObject->hFile,
			pBIOCSETEVENTHANDLE,
			&hEvent,
			sizeof(hEvent),
			NULL,
			0,
			&BytesReturned,
			NULL)==FALSE) 
	{
		DWORD dwLastError = GetLastError();

		CloseHandle(hEvent);

		SetLastError(dwLastError);

		TRACE_EXIT("PacketSetReadEvt");
		return FALSE;
	}

	AdapterObject->ReadEvent = hEvent;
	AdapterObject->ReadTimeOut=0;

	TRACE_EXIT("PacketSetReadEvt");
	return TRUE;
}

/*! 
  \brief Installs the NPF device driver.
  \return If the function succeeds, the return value is nonzero.

  This function installs the driver's service in the system using the CreateService function.
*/

BOOLEAN PacketInstallDriver()
{
	BOOLEAN result = FALSE;
	ULONG err = 0;
	SC_HANDLE svcHandle;
	SC_HANDLE scmHandle;
//  
//	Old registry based WinPcap names
//
//	CHAR driverName[MAX_WINPCAP_KEY_CHARS];
//	CHAR driverDesc[MAX_WINPCAP_KEY_CHARS];
//	CHAR driverLocation[MAX_WINPCAP_KEY_CHARS;
//	UINT len;

	CHAR driverName[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_NAME;
	CHAR driverDesc[MAX_WINPCAP_KEY_CHARS] = NPF_SERVICE_DESC;
	CHAR driverLocation[MAX_WINPCAP_KEY_CHARS] = NPF_DRIVER_COMPLETE_PATH;

 	TRACE_ENTER("PacketInstallDriver");

//  
//	Old registry based WinPcap names
//
//	len = sizeof(driverName)/sizeof(driverName[0]);
//	if (QueryWinPcapRegistryStringA(NPF_DRIVER_NAME_REG_KEY, driverName, &len, NPF_DRIVER_NAME) == FALSE && len == 0)
//		return FALSE;
//
//	len = sizeof(driverDesc)/sizeof(driverDesc[0]);
//	if (QueryWinPcapRegistryStringA(NPF_SERVICE_DESC_REG_KEY, driverDesc, &len, NPF_SERVICE_DESC) == FALSE && len == 0)
//		return FALSE;
//
//	len = sizeof(driverLocation)/sizeof(driverLocation[0]);
//	if (QueryWinPcapRegistryStringA(NPF_DRIVER_COMPLETE_PATH_REG_KEY, driverLocation, &len, NPF_DRIVER_COMPLETE_PATH) == FALSE && len == 0)
//		return FALSE;
	
	scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	
	if(scmHandle == NULL)
		return FALSE;

	svcHandle = CreateServiceA(scmHandle, 
		driverName,
		driverDesc,
		SERVICE_ALL_ACCESS,
		SERVICE_KERNEL_DRIVER,
		SERVICE_DEMAND_START,
		SERVICE_ERROR_NORMAL,
		driverLocation,
		NULL, NULL, NULL, NULL, NULL);
	if (svcHandle == NULL) 
	{
		err = GetLastError();
		if (err == ERROR_SERVICE_EXISTS) 
		{
			TRACE_PRINT("Service npf.sys already exists");
			//npf.sys already existed
			err = 0;
			result = TRUE;
		}
	}
	else 
	{
		TRACE_PRINT("Created service for npf.sys");
		//Created service for npf.sys
		result = TRUE;
	}

	if (svcHandle != NULL)
		CloseServiceHandle(svcHandle);

	if(result == FALSE)
	{
		TRACE_PRINT1("PacketInstallDriver failed, Error=%u",err);
	}

	CloseServiceHandle(scmHandle);
	SetLastError(err);
	TRACE_EXIT("PacketInstallDriver");
	return result;
	
}

/*! 
  \brief Dumps a registry key to disk in text format. Uses regedit.
  \param KeyName Name of the ket to dump. All its subkeys will be saved recursively.
  \param FileName Name of the file that will contain the dump.
  \return If the function succeeds, the return value is nonzero.

  For debugging purposes, we use this function to obtain some registry keys from the user's machine.
*/

#ifdef _DEBUG_TO_FILE

LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
{
	CHAR Command[256];

	TRACE_ENTER("PacketDumpRegistryKey");
	StringCchPrintfA(Command, sizeof(Command), "regedit /e %s %s", FileName, KeyName);

	/// Let regedit do the dirty work for us
	system(Command);

	TRACE_EXIT("PacketDumpRegistryKey");
	return TRUE;
}
#endif

/*! 
  \brief Returns the version of a dll or exe file 
  \param FileName Name of the file whose version has to be retrieved.
  \param VersionBuff Buffer that will contain the string with the file version.
  \param VersionBuffLen Length of the buffer poited by VersionBuff.
  \return If the function succeeds, the return value is TRUE.

  \note uses the GetFileVersionInfoSize() and GetFileVersionInfo() WIN32 API functions
*/
BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen)
{
    DWORD   dwVerInfoSize;  // Size of version information block
    DWORD   dwVerHnd=0;   // An 'ignored' parameter, always '0'
	LPSTR   lpstrVffInfo;
	UINT	cbTranslate, dwBytes;
	TCHAR	SubBlock[64];
	PVOID	lpBuffer;
	PCHAR	TmpStr;
	
	// Structure used to store enumerated languages and code pages.
	struct LANGANDCODEPAGE {
	  WORD wLanguage;
	  WORD wCodePage;
	} *lpTranslate;

	TRACE_ENTER("PacketGetFileVersion");

	// Now lets dive in and pull out the version information:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -