Проверка, открыт ли порт UDP в autoIT

Я работаю над программой для сканирования портов TCP/UDP. TCP работает нормально, но, похоже, я понятия не имею, как добиться сканирования портов UDP с помощью AutoIt.

Поскольку порт UDP не имеет соединения, я использую функцию UDPOpen для привязки моих $PortIP и $PortStartNumberB. К сожалению, когда я сканирую, он выводит список всех портов. К настоящему времени он покажет соответствующий открытый порт для UDP, например 4008 (поскольку я тестировал с помощью расширенного инструмента сканирования портов, и только этот порт должен быть открыт).

Может ли кто-нибудь более осведомленный, чем я, помочь мне понять, как я могу изменить код функции, размещенный ниже, поскольку я не могу воспроизвести список открытых портов UDP в сценарии AutoIt? Платформа Win7 x86.

$portList = "  "
$PortIP = "192.168.11.1"
$PortEndNumberB = "4010"
$PortStartNumberB = "4000"

Func ScanUDP()
    UDPStartup()
    $timerstart = TimerInit()

    For $LetsGo = $PortStartNumberB To $PortEndNumberB
        $a = UDPOpen($PortIP, $PortStartNumberB, 1)
        If @error <> 0 Then
            $portList = $portList & $PortStartNumberB & @CRLF
        EndIf

        $PortStartNumberB = $PortStartNumberB + 1
    Next

    UDPShutdown()
    $timerend = TimerDiff($timerstart)
    TrayTip("Port Scanner", "Done Process took " & Round($timerend,-1)/1000 & " seconds", 7, 1)
EndFunc

Что я пробовал:

когда я пытаюсь запустить, он перечисляет все порты.

4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010

по праву мне нужно отображать только 4008, который является правильным открытым портом udp (я тестировал с помощью других бесплатных инструментов - предварительное сканирование портов)


person SF.    schedule 25.02.2016    source источник
comment
Определите «открытый порт». Вы имеете в виду открытое в брандмауэре или открытое в смысле прослушивания локального приложения?   -  person user207421    schedule 26.02.2016
comment
Привет @EJP .. спасибо за ваш ответ .. это было мое локальное приложение, которое настроено на открытие только 4008. Я уже отключил брандмауэр, чтобы это не имело смысла. но это похоже на сбой, если я попытаюсь проверить создание порта UDP-4008 с помощью сценария autoIT, верна ли логика моего сценария? еще раз спасибо.   -  person SF.    schedule 26.02.2016
comment
Понятия не имею, пока вы не ответите на мой вопрос.   -  person user207421    schedule 26.02.2016
comment
насколько я понимаю, «открытый порт» можно определить, поскольку есть порт, который прослушивается. поэтому в моем случае локальное приложение разрешило открытие 4008 UDP. поэтому мне просто нужно доказать, что порт прослушивает 4008.   -  person SF.    schedule 26.02.2016
comment
Привет, СФ, ты хочешь проверить, открыт ли UDP-порт 4008 на локальном компьютере? Или удаленная машина?   -  person Fidel    schedule 08.03.2016
comment
привет @Fidel. это на моей другой локальной машине, к которой я подключился через USB. Мне нужно отсканировать этот порт, чтобы убедиться, что все порты закрыты, но на самом деле на этой машине он был настроен специально для открытия порта 4008. так что теперь моего скрипта на autoIT недостаточно для правильной проверки порта UDP. У вас есть какие-нибудь идеи, чтобы поделиться со мной? заранее спасибо! :)   -  person SF.    schedule 22.03.2016
comment
Спасибо СФ. Кстати, ваш цикл for был немного сломан. Я исправил это в своем ответе ниже. Я надеюсь, что вы найдете это полезным :)   -  person Fidel    schedule 03.04.2016


Ответы (1)


Простой способ увидеть открытые порты UDP — использовать следующую команду:

netstat -an -p UDP

Можно было бы очистить вывод этой команды с помощью AutoIt, однако лучше использовать API, предоставленный Microsoft. В частности, GetUdpTable и GetExtendedUdpTable.

К счастью, добрый человек по имени zampoot уже написанные оболочки для этих вызовов. Я смог взять его сценарий и изменить его в соответствии с вашими целями.

Просто посмотрите на основной метод и не беспокойтесь об остальном. Если вы предприимчивы, восстановите строку _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
person Fidel    schedule 02.04.2016