查看打开的 UDP 端口的一种简单方法是使用以下命令:
netstat -an -p UDP
可以使用 AutoIt 抓取该命令的输出,但更好的方法是使用 Microsoft 提供的 API。特别是GetUdpTable和GetExtendedUdpTable函数。
值得庆幸的是,一个叫 zampoot 的好心人已经为这些调用编写了包装器。我能够采用他的脚本并对其进行修改以适合您的目的。
只看main方法,其余的不用太担心。如果您喜欢冒险,请重新设置该_ArrayDisplay($aUDPArray)
行 - 它会向您显示更多关于哪些进程正在使用开放端口的信息。
这是代码:
#include <Array.au3>
Global Const $hIPHLPAPI = DllOpen("iphlpapi.dll")
Global Const $hWTSAPI32 = DllOpen("wtsapi32.dll")
Global Const $hKERNEL32 = DllOpen("kernel32.dll")
Global Const $hPSAPI = DllOpen("psapi.dll")
Global Const $hNTDLL = DllOpen("ntdll.dll")
Global Const $hWS232 = DllOpen("ws2_32.dll")
Global Const $hADVAPI32 = DllOpen("advapi32.dll")
Global Const $sSystemModule = _CV_SystemModuleInformation()
Global $iIsAdmin = IsAdmin()
$portList = " "
$PortIP = "192.168.11.1"
$PortEndNumberB = "4010"
$PortStartNumberB = "4000"
main()
Func main()
$aUDPArray = _CV_GetExtendedUdpTable()
;_ArrayDisplay($aUDPArray)
$ports = _GetUDPPorts($PortIP)
;_ArrayDisplay($ports)
$timerstart = TimerInit()
$portList = ""
For $port = $PortStartNumberB To $PortEndNumberB
$index = _ArraySearch($ports, $port)
If ($index > -1) Then
;port found
If StringLen($portList) > 0 Then
$portList &= @CRLF
EndIf
$portList &= $port
EndIf
Next
ConsoleWrite($portList)
$timerend = TimerDiff($timerstart)
TrayTip("Port Scanner", "Done Process took " & Round($timerend, -1) / 1000 & " seconds", 7, 1)
EndFunc ;==>main
Func _GetUDPPorts($ipOfInterest)
$aUDPArray = _CV_GetExtendedUdpTable()
Dim $ports[1]
$ports[0] = "Port"
For $rowNum = 1 To UBound($aUDPArray) - 1
$ip = $aUDPArray[$rowNum][1]
$port = $aUDPArray[$rowNum][2]
;only get the ports for the ip of interest
If ($ipOfInterest = $ip) Then
;check if this port already exists in our list
$pos = _ArraySearch($ports, $port)
If $pos = -1 Then
_ArrayAdd($ports, $port)
EndIf
EndIf
Next
_ArrayDelete($ports, 0)
Return $ports
EndFunc ;==>_GetUDPPorts
Func _CV_GetExtendedUdpTable()
Local $aCall = DllCall($hIPHLPAPI, "dword", "GetExtendedUdpTable", _
"ptr*", 0, _
"dword*", 0, _
"int", 1, _ ; 1, sort in ascending order
"dword", 2, _ ; AF_INET4
"dword", 1, _ ; UDP_TABLE_OWNER_PID
"dword", 0)
If @error Then
Return SetError(1, 0, 0)
EndIf
If $aCall[0] <> 122 Then ; ERROR_INSUFFICIENT_BUFFER
Return SetError(2, 0, 0)
EndIf
Local $iSize = $aCall[2]
Local $tByteStructure = DllStructCreate("byte[" & $iSize & "]")
$aCall = DllCall($hIPHLPAPI, "dword", "GetExtendedUdpTable", _
"ptr", DllStructGetPtr($tByteStructure), _
"dword*", $iSize, _
"int", 1, _ ; 1, sort in ascending order
"dword", 2, _ ; AF_INET4
"dword", 1, _ ; UDP_TABLE_OWNER_PID
"dword", 0)
If @error Or $aCall[0] Then
Return SetError(3, 0, 0)
EndIf
Local $tMIB_UDPTABLE_OWNER_PID_DWORDS = DllStructCreate("dword[" & Ceiling($iSize / 4) & "]", DllStructGetPtr($tByteStructure))
Local $iUDPentries = DllStructGetData($tMIB_UDPTABLE_OWNER_PID_DWORDS, 1)
#cs
$tMIB_UDPROW_OWNER_PID = DllStructCreate("dword LocalAddr;" & _
"dword LocalPort;" & _
"dword OwningPid")
#ce
Local $aUDPTable[$iUDPentries + 1][6] = [["Process Name ", "Local IP ", "Local Port", "PID", "Full Path", "User Name"]]
Local $aProcesses = _CV_ProcessList()
Local $iOffset
Local $iIP
UDPStartup()
For $i = 1 To $iUDPentries
$iOffset = ($i - 1) * 3 + 1 ; going thru array of dwords
$iIP = DllStructGetData($tMIB_UDPTABLE_OWNER_PID_DWORDS, 1, $iOffset + 1)
If $iIP = 16777343 Then
$aUDPTable[$i][1] = "127.0.0.1"
ElseIf $iIP = 0 Then
$aUDPTable[$i][1] = "Any local address"
Else
$aUDPTable[$i][1] = BitOR(BinaryMid($iIP, 1, 1), 0) & "." & BitOR(BinaryMid($iIP, 2, 1), 0) & "." & BitOR(BinaryMid($iIP, 3, 1), 0) & "." & BitOR(BinaryMid($iIP, 4, 1), 0)
$aUDPTable[$i][1] = $aUDPTable[$i][1]
EndIf
$aUDPTable[$i][2] = Dec(Hex(BinaryMid(DllStructGetData($tMIB_UDPTABLE_OWNER_PID_DWORDS, 1, $iOffset + 2), 1, 2)))
$aUDPTable[$i][2] &= "" ;_CV_GetPortHint($aUDPTable[$i][2])
$aUDPTable[$i][3] = DllStructGetData($tMIB_UDPTABLE_OWNER_PID_DWORDS, 1, $iOffset + 3)
If Not $aUDPTable[$i][3] Then
$aUDPTable[$i][3] = "-"
$aUDPTable[$i][0] = "System Idle Process"
$aUDPTable[$i][4] = "-"
$aUDPTable[$i][5] = "SYSTEM"
Else
For $j = 1 To $aProcesses[0][0]
If $aProcesses[$j][1] = $aUDPTable[$i][3] Then
$aUDPTable[$i][0] = $aProcesses[$j][0]
$aUDPTable[$i][4] = _CV_GetPIDFileName($aProcesses[$j][1])
If Not $aUDPTable[$i][4] Then
If $aUDPTable[$i][0] = $sSystemModule Then
$aUDPTable[$i][4] = @SystemDir & "\" & $sSystemModule
Else
$aUDPTable[$i][4] = "-"
EndIf
EndIf
If Not $aUDPTable[$i][0] Then $aUDPTable[$i][0] = $aProcesses[$j][0]
$aUDPTable[$i][5] = $aProcesses[$j][2]
If Not $aUDPTable[$i][5] Then
If $iIsAdmin Then
$aUDPTable[$i][5] = "SYSTEM"
Else
$aUDPTable[$i][5] = "-"
EndIf
EndIf
ExitLoop
EndIf
Next
EndIf
Next
UDPShutdown()
Return $aUDPTable
EndFunc ;==>_CV_GetExtendedUdpTable
Func _CV_PtrStringLen($pString)
Local $aCall = DllCall($hKERNEL32, "dword", "lstrlen", "ptr", $pString)
If @error Then Return SetError(1, 0, 0)
Return $aCall[0]
EndFunc ;==>_CV_PtrStringLen
Func _CV_PtrStringLenW($pString)
Local $aCall = DllCall($hKERNEL32, "dword", "lstrlenW", "ptr", $pString)
If @error Then Return SetError(1, 0, 0)
Return $aCall[0]
EndFunc ;==>_CV_PtrStringLenW
Func _CV_ProcessList()
Local $aCall = DllCall($hWTSAPI32, "bool", "WTSEnumerateProcessesW", _
"handle", 0, _
"dword", 0, _
"dword", 1, _
"ptr*", 0, _
"dword*", 0)
If @error Or Not $aCall[0] Then
Local $aProcesses = ProcessList()
ReDim $aProcesses[$aProcesses[0][0]][3]
For $i = 1 To UBound($aProcesses) - 1
$aProcesses[$i][2] = "-"
Next
Return SetError(1, 0, $aProcesses)
EndIf
Local $tWTS_PROCESS_INFO
Local $pString, $iStringLen
Local $aOut[$aCall[5] + 1][3]
$aOut[0][0] = $aCall[5]
For $i = 1 To $aCall[5]
$tWTS_PROCESS_INFO = DllStructCreate("dword SessionId;" & _
"dword ProcessId;" & _
"ptr ProcessName;" & _
"ptr UserSid", _
$aCall[4] + ($i - 1) * DllStructGetSize($tWTS_PROCESS_INFO)) ; looping thru structures
$pString = DllStructGetData($tWTS_PROCESS_INFO, "ProcessName")
$iStringLen = _CV_PtrStringLenW($pString)
$aOut[$i][0] = DllStructGetData(DllStructCreate("wchar[" & $iStringLen + 1 & "]", $pString), 1)
If $aOut[$i][0] = "System" Then $aOut[$i][0] = $sSystemModule ; & " (System)"
$aOut[$i][1] = DllStructGetData($tWTS_PROCESS_INFO, "ProcessId")
$aOut[$i][2] = _CV_AccountName(DllStructGetData($tWTS_PROCESS_INFO, "UserSid"))
Next
DllCall($hWTSAPI32, "none", "WTSFreeMemory", "ptr", $aCall[4])
Return $aOut
EndFunc ;==>_CV_ProcessList
Func _CV_SystemModuleInformation()
Local $aCall = DllCall($hNTDLL, "long", "NtQuerySystemInformation", _
"dword", 11, _ ; SystemModuleInformation
"ptr", 0, _
"dword", 0, _
"dword*", 0)
If @error Then Return SetError(1, 0, "")
Local $iSize = $aCall[4]
Local $tBufferRaw = DllStructCreate("byte[" & $iSize & "]")
Local $pBuffer = DllStructGetPtr($tBufferRaw)
$aCall = DllCall($hNTDLL, "long", "NtQuerySystemInformation", _
"dword", 11, _ ; SystemModuleInformation
"ptr", $pBuffer, _
"dword", $iSize, _
"dword*", 0)
If @error Then Return SetError(2, 0, "")
Local $pPointer = $pBuffer
Local $tSYSTEM_MODULE_Modified = DllStructCreate("dword_ptr ModulesCount;" & _
"dword_ptr Reserved[2];" & _
"ptr ImageBaseAddress;" & _
"dword ImageSize;" & _
"dword Flags;" & _
"word Index;" & _
"word Unknown;" & _
"word LoadCount;" & _
"word ModuleNameOffset;" & _
"char ImageName[256]", _
$pPointer)
Local $iNameOffset = DllStructGetData($tSYSTEM_MODULE_Modified, "ModuleNameOffset")
Local $sImageName = DllStructGetData($tSYSTEM_MODULE_Modified, "ImageName")
Return StringTrimLeft($sImageName, $iNameOffset)
EndFunc ;==>_CV_SystemModuleInformation
Func _CV_IpToName($iIP)
Return $iIP
Local $aCall = DllCall($hWS232, "ptr", "gethostbyaddr", _
"dword*", $iIP, _
"int", 4, _
"int", 2) ; AF_INET
If @error Or Not $aCall[0] Then Return SetError(1, 0, "")
Local $pHostent = $aCall[0]
Local $tHostent = DllStructCreate("align 2; ptr Name;" & _
"ptr Aliases;" & _
"ushort Addrtype;" & _
"ushort Length;" & _
"ptr AddrList", _
$pHostent)
Return DllStructGetData(DllStructCreate("char[" & _CV_PtrStringLen(DllStructGetData($tHostent, "Name")) + 1 & "]", DllStructGetData($tHostent, "Name")), 1)
EndFunc ;==>_CV_IpToName
Func _CV_GetPIDFileName($iPID)
Local $aCall = DllCall($hKERNEL32, "ptr", "OpenProcess", _
"dword", 1040, _ ; PROCESS_QUERY_INFORMATION|PROCESS_VM_READ
"int", 0, _
"dword", $iPID)
If @error Or Not $aCall[0] Then Return SetError(1, 0, "")
Local $hProcess = $aCall[0]
$aCall = DllCall($hPSAPI, "dword", "GetModuleFileNameExW", _
"handle", $hProcess, _
"ptr", 0, _
"wstr", "", _
"dword", 32767)
If @error Or Not $aCall[0] Then
DllCall($hKERNEL32, "bool", "CloseHandle", "handle", $hProcess)
Return SetError(2, 0, "")
EndIf
Local $sFilename = $aCall[3]
DllCall($hKERNEL32, "bool", "CloseHandle", "handle", $hProcess)
Return $sFilename
EndFunc ;==>_CV_GetPIDFileName
Func _CV_AccountName($pSID)
Local $aCall = DllCall($hADVAPI32, "bool", "LookupAccountSidW", _
"ptr", 0, _
"ptr", $pSID, _
"wstr", "", _
"dword*", 1024, _
"wstr", "", _
"dword*", 1024, _
"ptr*", 0)
If @error Or Not $aCall[0] Then Return SetError(1, 0, "")
Return $aCall[3]
EndFunc ;==>_CV_AccountName