3131210 发表于 2025-8-22 13:07:25

[求助]多线程群PING的问题,部分电脑返回$IP_REQ_TIMED_OUT,是什么原因

本帖最后由 3131210 于 2025-8-22 14:10 编辑

以下代码是多线程群ping的例子,在大部分电脑都可以正常ping的通,但是部分电脑ping的时候都是返回$IP_REQ_TIMED_OUT,原因不明,下段在OD里面检查汇编代码,跟其它正常执行的电脑也是一样的,没有看出哪里有问题。
出现这种问题的电脑,通过CMD去ping,是正常可以连通的。
所以有没有大佬可以解惑?

#include <Memory.au3>
#include <WinAPISys.au3>
#include <Array.au3>

Global Const $DONT_FRAGMENT = 2, $IP_SUCCESS = 0, $IP_DEST_NET_UNREACHABLE = 11002, $IP_DEST_HOST_UNREACHABLE = 11003, $IP_DEST_PROT_UNREACHABLE = 11004, $IP_DEST_PORT_UNREACHABLE = 11005, _
                $IP_NO_RESOURCES = 11006, $IP_HW_ERROR = 11008, $IP_PACKET_TOO_BIG = 11009, $IP_REQ_TIMED_OUT = 11010, $IP_BAD_REQ = 11011, $IP_BAD_ROUTE = 11012, _
                $IP_TTL_EXPIRED_TRANSIT = 11013, $IP_TTL_EXPIRED_REASSEM = 11014, $IP_PARAM_PROBLEM = 11015, $IP_SOURCE_QUENCH = 11016, $IP_BAD_DESTINATION = 11018, _
                $IP_GENERAL_FAILURE = 11050, $NO_STATUS = 10000 ;We will use 10000 as the no status indicator since 0 meens successful reply

Local $hPointers = DllStructCreate("ptr IcmpCloseHandle;ptr IcmpSendEcho;ptr IcmpCreateFile;ptr ExitThread")

Global $hkernel32Dll = DllOpen("kernel32.dll")
DllStructSetData($hPointers, "ExitThread", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("kernel32.dll"), "ExitThread"))
DllStructSetData($hPointers, "IcmpCloseHandle", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpCloseHandle"))
DllStructSetData($hPointers, "IcmpSendEcho", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpSendEcho"))
DllStructSetData($hPointers, "IcmpCreateFile", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpCreateFile"))

TCPStartup() ;This is required, not only to do DNS lookup, but also for WSAStartup()

Global $pings = ;This array will hold all echo reply data in a struct.

Global $hostlist, $listcount = 0
Global $hostarr = StringSplit("180.97.214.190|27.221.120.226|112.46.175.107|163.181.228.144|47.246.38.174|163.181.88.173", "|", 2)

Global $hGUI = GUICreate("多线程群PING", 416, 316)
Global $pingButton = GUICtrlCreateButton("PING", 8, 8, 82, 25)
GUICtrlCreateLabel("TimeOut:", 110, 14, 50, 20)
Global $pingInput = GUICtrlCreateInput(2000, 162, 10, 50, 20, 0x0001 + 0x2000)
GUICtrlCreateLabel("Flags:", 230, 14, 34, 20)
Global $pingCombo = GUICtrlCreateCombo("", 272, 10, 120, 100, 0x0003)
GUICtrlSetData($pingCombo, "IP_FLAG_REVERSE|IP_FLAG_DF", "IP_FLAG_DF")
Global $pingEdit = GUICtrlCreateEdit("", 8, 42, 400, 260, 0x0800)
GUISetState(@SW_SHOW)

While 1
        Switch GUIGetMsg()
                Case -3
                        _Exit()
                Case $pingButton
                        _DoPing()
        EndSwitch
WEnd

Func _DoPing()
        ReDim $hostlist
        $listcount = 0
        GUICtrlSetData($pingEdit, "")
        Local $TimeOut = GUICtrlRead($pingInput)
        If $TimeOut < 1 Then $TimeOut = 2000
        Local $flags = GUICtrlRead($pingCombo)
        If $flags = "IP_FLAG_DF" Then
                $flags = 2
        Else
                $flags = 1
        EndIf

        For $I = 0 To UBound($hostarr) - 1
                pingThreaded($hostarr[$I], $TimeOut, "0", 255, $flags)
        Next

        While $pings > 0
                _managePings()
        WEnd

        _UpEditData("Done.")
EndFunc   ;==>_DoPing

Func _UpEditData($str)
        GUICtrlSetData($pingEdit, GUICtrlRead($pingEdit) & $str)
EndFunc   ;==>_UpEditData

;Function pingThreaded
;$ip_addr will accept valid DNS Name or Normal IP address.
;Timouts only really work when an IP isn't responding. Thats important to remember because if you think you can timeout an IP which has latent responces, you can't!
Func pingThreaded($ip_addr, $TimeOut = 5000, $data = "x", $ttl = 255, $flags = 0)
        Local $hexIP = encodeIP($ip_addr)
        If $hexIP == 0 Then Return 0
        Local $pingID = _addPing($ip_addr)
        If IsNumber($ttl) = 0 Or Number($ttl) > 255 Then $ttl = 255
        If IsNumber($TimeOut) = 0 Or Number($TimeOut) > 5000 Then $TimeOut = 5000
        If StringLen($data) > 256 Then $data = StringTrimRight($data, StringLen($data) - 256)
        If IsNumber($flags) = 0 Or Number($flags) > 2 Then $flags = 2
        DllStructSetData($pings[$pingID], "datasize", StringLen($data)) ;We may wish to report the data size later
        ;Props to trancexx
        Local $CodeBuffer = DllStructCreate("byte") ; Code=154, Data=256, Echo reply Struct + ICMP_OPTIONS Struct = 286
        Local $RemoteCode = _MemVirtualAlloc(0, DllStructGetSize($CodeBuffer), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
        DllStructSetData($CodeBuffer, 1, _
                        "0x" & _ ;Original Assembly started at 401000
                        "E889000000" & _ ;Call 0040108E<IcmpCreateFile>
                        "A3" & SwapEndian($RemoteCode + 410) & _ ;mov dword ptr , eax<hIcmp = IcmpCreateFile Handle>
                        "C605" & SwapEndian($RemoteCode + 418) & Hex($ttl, 2) & _ ;mov byte ptr , xx    <TTL>
                        "C605" & SwapEndian($RemoteCode + 419) & "00" & _ ;mov byte ptr , 00    <TOS>
                        "C605" & SwapEndian($RemoteCode + 420) & Hex($flags, 2) & _ ;mov byte ptr , 02    <Flags, 0x02=DF Bit Set>
                        "C605" & SwapEndian($RemoteCode + 421) & "00" & _ ;mov byte ptr , 00
                        "C705" & SwapEndian($RemoteCode + 422) & "00000000" & _ ;mov dword ptr , 00000000
                        "68" & SwapEndian(Dec(Hex($TimeOut, 4))) & _ ;push 0000xxxx<Timeout>
                        "681E010000" & _ ;push 0000011E<Size of Echo reply Struct + ICMP_OPTIONS Struct>
                        "68" & SwapEndian($RemoteCode + 426) & _ ;push 0040302C<icmpReply>
                        "68" & SwapEndian($RemoteCode + 418) & _ ;push 00403024<icmpOptions>
                        "6A" & Hex(StringLen($data), 2) & _ ;push 000000xx<Data Size>
                        "68" & SwapEndian($RemoteCode + 154) & _ ;push 00403000<Data>
                        "68" & SwapEndian(Dec($hexIP)) & _ ;push <Hex(IP ADDRESS)>
                        "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr <hIcmp>
                        "E839000000" & _ ;Call 00401094<IcmpSendEcho>
                        "A1" & SwapEndian($RemoteCode + 434) & _ ;mov eax, dword ptr <Get the ms responce time from icmpReply.RoundTripTime>
                        "A3" & SwapEndian(DllStructGetPtr($pings[$pingID], "reply")) & _ ;mov dword ptr , eax<Store the ms responce time>
                        "A1" & SwapEndian($RemoteCode + 430) & _ ;mov eax, dword ptr <Get the status from icmpReply.Status>
                        "A3" & SwapEndian(DllStructGetPtr($pings[$pingID], "status")) & _ ;mov dword ptr , eax<Store the status>
                        "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr <hIcmp>
                        "E80E000000" & _ ;Call 00401088<IcmpCloseHandle>
                        "6A00" & _ ;push 00000000
                        "E801000000" & _ ;Call 00401082<ExitThread>
                        "CC" & _ ;int 03
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "ExitThread")) & _ ;JMP dword ptr<kernel32.ExitThread>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpCloseHandle")) & _ ;JMP dword ptr<ICMP.IcmpCloseHandle>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpCreateFile")) & _ ;JMP dword ptr<ICMP.IcmpCreateFile>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpSendEcho")) & _ ;JMP dword ptr<ICMP.IcmpSendEcho>
                        SwapEndian(StringToBinary($data)) _ ;This is our ping Data, Max 256 bytes of space here.
                        )
        _MemMoveMemory(DllStructGetPtr($CodeBuffer), $RemoteCode, DllStructGetSize($CodeBuffer))
        Local $aCall = DllCall($hkernel32Dll, "ptr", "CreateThread", "ptr", 0, "int", 0, "ptr", $RemoteCode, "ptr", 0, "int", 0, "dword*", 0)
        Return $aCall
EndFunc   ;==>pingThreaded

;Function _addPing is just for array management of the $pings[] array.
Func _addPing($ip_addr)
        $pings = UBound($pings)
        ReDim $pings[$pings + 1]
        $pings[$pings] = DllStructCreate("char ip[" & StringLen($ip_addr) & "];ulong reply;ulong status;int datasize") ;You could add a timeout struct here
        DllStructSetData($pings[$pings], "ip", $ip_addr)
        DllStructSetData($pings[$pings], "status", $NO_STATUS)
        Return $pings
EndFunc   ;==>_addPing

;Function _removePing is just for array management of the $pings[] array.
Func _removePing($pingID)
        If $pingID > $pings Then Return ;Ensure our ID is valid
        $pings[$pingID] = 0 ;Free the DLLStruct
        _ArrayDelete($pings, $pingID)
        $pings -= 1
EndFunc   ;==>_removePing

;Function _managePings()
;This is where the reply's get sorted out, and actions taken
Func _managePings()
        Local $pingID, $status
        $pingID = 1
        While $pingID <= $pings
                $status = DllStructGetData($pings[$pingID], "status")
                If $status <> $NO_STATUS Then
                        Switch $status
                                Case $IP_SUCCESS
                                        $listcount += 1
                                        ReDim $hostlist[$listcount]
                                        $hostlist[$listcount - 1] = DllStructGetData($pings[$pingID], "ip")
                                        $hostlist[$listcount - 1] = DllStructGetData($pings[$pingID], "reply")
                                        If DllStructGetData($pings[$pingID], "reply") = 0 Then
                                                _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " replied in <1ms" & @CRLF)
                                        Else
                                                _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " replied in " & DllStructGetData($pings[$pingID], "reply") & "ms" & @CRLF)
                                        EndIf
                                Case $IP_REQ_TIMED_OUT
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " timed-out" & @CRLF)
                                Case $IP_DEST_NET_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination network was unreachable." & @CRLF)
                                Case $IP_DEST_HOST_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination host was unreachable." & @CRLF)
                                Case $IP_DEST_PROT_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination protocol was unreachable." & @CRLF)
                                Case $IP_DEST_PORT_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination port was unreachable." & @CRLF)
                                Case $IP_NO_RESOURCES
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " Insufficient IP resources were available." & @CRLF)
                                Case $IP_HW_ERROR
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A hardware error occurred." & @CRLF)
                                Case $IP_PACKET_TOO_BIG
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The packet was too big." & @CRLF)
                                Case $IP_BAD_REQ
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad request." & @CRLF)
                                Case $IP_BAD_ROUTE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad route." & @CRLF)
                                Case $IP_TTL_EXPIRED_TRANSIT
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The time to live (TTL) expired in transit." & @CRLF)
                                Case $IP_TTL_EXPIRED_REASSEM
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The time to live expired during fragment reassembly." & @CRLF)
                                Case $IP_PARAM_PROBLEM
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A parameter problem." & @CRLF)
                                Case $IP_SOURCE_QUENCH
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " Datagrams are arriving too fast to be processed and datagrams may have been discarded." & @CRLF)
                                Case $IP_BAD_DESTINATION
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad destination." & @CRLF)
                                Case $IP_GENERAL_FAILURE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A general failure. This error can be returned for some malformed ICMP packets or lost network connection." & @CRLF)
                        EndSwitch
                        _removePing($pingID)
                EndIf
                $pingID += 1
        WEnd
EndFunc   ;==>_managePings

Func encodeIP($ip_addr)
        If Not _isIP($ip_addr) Then $ip_addr = TCPNameToIP($ip_addr)
        Local $ip_addr_temp = DllCall("ws2_32.dll", "uint", "inet_addr", "str", $ip_addr)
        Return Hex($ip_addr_temp, 8)
EndFunc   ;==>encodeIP

Func SwapEndian($hex)
        Return Hex(Binary($hex))
EndFunc   ;==>SwapEndian

Func _getIPOctet($ip_addr, $octet = 1)
        Switch $octet
                Case 1
                        Return Int(StringMid($ip_addr, 1, StringInStr($ip_addr, ".")))
                Case 4
                        Return Int(StringMid($ip_addr, StringInStr($ip_addr, ".", 0, 3) + 1))
                Case Else
                        Return Int(StringMid($ip_addr, StringInStr($ip_addr, ".", 0, $octet - 1) + 1, StringInStr($ip_addr, ".", 0, $octet) + 1))
        EndSwitch
EndFunc   ;==>_getIPOctet

Func _isIP($text)
        Return StringRegExp($text, "(((25)|(2)|(1)|(?))\.){3}((25)|(2)|(1)|(?))")
EndFunc   ;==>_isIP

Func _Exit()
        TCPShutdown()
        DllClose($hkernel32Dll)
        Exit
EndFunc   ;==>_Exit

3131210 发表于 2025-8-22 18:11:54

再给一个demo,更直观
用PING1按钮,有小部分电脑一直返回$IP_REQ_TIMED_OUT,无法ping通,但是用PING2按钮,就可以ping通,迷惑了。。。难不成机器码有什么问题?



#include <Memory.au3>
#include <WinAPISys.au3>
#include <Array.au3>

Global Const $DONT_FRAGMENT = 2, $IP_SUCCESS = 0, $IP_DEST_NET_UNREACHABLE = 11002, $IP_DEST_HOST_UNREACHABLE = 11003, $IP_DEST_PROT_UNREACHABLE = 11004, $IP_DEST_PORT_UNREACHABLE = 11005, _
                $IP_NO_RESOURCES = 11006, $IP_HW_ERROR = 11008, $IP_PACKET_TOO_BIG = 11009, $IP_REQ_TIMED_OUT = 11010, $IP_BAD_REQ = 11011, $IP_BAD_ROUTE = 11012, _
                $IP_TTL_EXPIRED_TRANSIT = 11013, $IP_TTL_EXPIRED_REASSEM = 11014, $IP_PARAM_PROBLEM = 11015, $IP_SOURCE_QUENCH = 11016, $IP_BAD_DESTINATION = 11018, _
                $IP_GENERAL_FAILURE = 11050, $NO_STATUS = 10000 ;We will use 10000 as the no status indicator since 0 meens successful reply

Local $hPointers = DllStructCreate("ptr IcmpCloseHandle;ptr IcmpSendEcho;ptr IcmpCreateFile;ptr ExitThread")

Global $hkernel32Dll = DllOpen("kernel32.dll")
DllStructSetData($hPointers, "ExitThread", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("kernel32.dll"), "ExitThread"))
DllStructSetData($hPointers, "IcmpCloseHandle", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpCloseHandle"))
DllStructSetData($hPointers, "IcmpSendEcho", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpSendEcho"))
DllStructSetData($hPointers, "IcmpCreateFile", _WinAPI_GetProcAddress(_WinAPI_GetModuleHandle("Iphlpapi.dll"), "IcmpCreateFile"))

TCPStartup() ;This is required, not only to do DNS lookup, but also for WSAStartup()

Global $pings = ;This array will hold all echo reply data in a struct.

Global $hostlist, $listcount = 0
Global $hostarr = StringSplit("180.97.214.190|27.221.120.226|112.46.175.107|163.181.228.144|47.246.38.174|163.181.88.173", "|", 2)

Global $hGUI = GUICreate("多线程群PING", 416, 316)
Global $pingButton1 = GUICtrlCreateButton("PING1", 8, 8, 48, 25)
Global $pingButton2 = GUICtrlCreateButton("PING2", 60, 8, 48, 25)
GUICtrlCreateLabel("TimeOut:", 118, 14, 50, 20)
Global $pingInput = GUICtrlCreateInput(2000, 170, 10, 50, 20, 0x0001 + 0x2000)
GUICtrlCreateLabel("Flags:", 230, 14, 34, 20)
Global $pingCombo = GUICtrlCreateCombo("", 272, 10, 120, 100, 0x0003)
GUICtrlSetData($pingCombo, "IP_FLAG_REVERSE|IP_FLAG_DF", "IP_FLAG_DF")
Global $pingEdit = GUICtrlCreateEdit("", 8, 42, 400, 260, 0x0800)
GUISetState(@SW_SHOW)

While 1
        Switch GUIGetMsg()
                Case -3
                        _Exit()
                Case $pingButton1
                        _DoPing1()
                Case $pingButton2
                        _DoPing2()
        EndSwitch
WEnd

Func _DoPing1()
        GUICtrlSetData($pingEdit, "")
        ReDim $hostlist
        $listcount = 0
        Local $TimeOut = GUICtrlRead($pingInput)
        If $TimeOut < 1 Then $TimeOut = 2000
        Local $flags = GUICtrlRead($pingCombo)
        If $flags = "IP_FLAG_DF" Then
                $flags = 2
        Else
                $flags = 1
        EndIf

        For $I = 0 To UBound($hostarr) - 1
                pingThreaded($hostarr[$I], $TimeOut, "0", 255, $flags)
        Next

        While $pings > 0
                _managePings()
        WEnd

        _UpEditData("Done.")
EndFunc   ;==>_DoPing1

Func _DoPing2()
        GUICtrlSetData($pingEdit, "")
        Local $iPing
        Local $TimeOut = GUICtrlRead($pingInput)
        If $TimeOut < 1 Then $TimeOut = 2000
        For $I = 0 To UBound($hostarr) - 1
                $iPing = Ping($hostarr[$I], $TimeOut)
                If $iPing > 0 Then
                        _UpEditData("Ping to " & $hostarr[$I] & " replied in " & $iPing & "ms" & @CRLF)
                Else
                        _UpEditData("Ping to " & $hostarr[$I] & " timed-out" & @CRLF)
                EndIf
        Next
        _UpEditData("Done.")
EndFunc   ;==>_DoPing2

Func _UpEditData($str)
        GUICtrlSetData($pingEdit, GUICtrlRead($pingEdit) & $str)
EndFunc   ;==>_UpEditData

;Function pingThreaded
;$ip_addr will accept valid DNS Name or Normal IP address.
;Timouts only really work when an IP isn't responding. Thats important to remember because if you think you can timeout an IP which has latent responces, you can't!
Func pingThreaded($ip_addr, $TimeOut = 5000, $data = "x", $ttl = 255, $flags = 0)
        Local $hexIP = encodeIP($ip_addr)
        If $hexIP == 0 Then Return 0
        Local $pingID = _addPing($ip_addr)
        If IsNumber($ttl) = 0 Or Number($ttl) > 255 Then $ttl = 255
        If IsNumber($TimeOut) = 0 Or Number($TimeOut) > 5000 Then $TimeOut = 5000
        If StringLen($data) > 256 Then $data = StringTrimRight($data, StringLen($data) - 256)
        If IsNumber($flags) = 0 Or Number($flags) > 2 Then $flags = 2
        DllStructSetData($pings[$pingID], "datasize", StringLen($data)) ;We may wish to report the data size later
        ;Props to trancexx
        Local $CodeBuffer = DllStructCreate("byte") ; Code=154, Data=256, Echo reply Struct + ICMP_OPTIONS Struct = 286
        Local $RemoteCode = _MemVirtualAlloc(0, DllStructGetSize($CodeBuffer), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
        DllStructSetData($CodeBuffer, 1, _
                        "0x" & _ ;Original Assembly started at 401000
                        "E889000000" & _ ;Call 0040108E<IcmpCreateFile>
                        "A3" & SwapEndian($RemoteCode + 410) & _ ;mov dword ptr , eax<hIcmp = IcmpCreateFile Handle>
                        "C605" & SwapEndian($RemoteCode + 418) & Hex($ttl, 2) & _ ;mov byte ptr , xx    <TTL>
                        "C605" & SwapEndian($RemoteCode + 419) & "00" & _ ;mov byte ptr , 00    <TOS>
                        "C605" & SwapEndian($RemoteCode + 420) & Hex($flags, 2) & _ ;mov byte ptr , 02    <Flags, 0x02=DF Bit Set>
                        "C605" & SwapEndian($RemoteCode + 421) & "00" & _ ;mov byte ptr , 00
                        "C705" & SwapEndian($RemoteCode + 422) & "00000000" & _ ;mov dword ptr , 00000000
                        "68" & SwapEndian(Dec(Hex($TimeOut, 4))) & _ ;push 0000xxxx<Timeout>
                        "681E010000" & _ ;push 0000011E<Size of Echo reply Struct + ICMP_OPTIONS Struct>
                        "68" & SwapEndian($RemoteCode + 426) & _ ;push 0040302C<icmpReply>
                        "68" & SwapEndian($RemoteCode + 418) & _ ;push 00403024<icmpOptions>
                        "6A" & Hex(StringLen($data), 2) & _ ;push 000000xx<Data Size>
                        "68" & SwapEndian($RemoteCode + 154) & _ ;push 00403000<Data>
                        "68" & SwapEndian(Dec($hexIP)) & _ ;push <Hex(IP ADDRESS)>
                        "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr <hIcmp>
                        "E839000000" & _ ;Call 00401094<IcmpSendEcho>
                        "A1" & SwapEndian($RemoteCode + 434) & _ ;mov eax, dword ptr <Get the ms responce time from icmpReply.RoundTripTime>
                        "A3" & SwapEndian(DllStructGetPtr($pings[$pingID], "reply")) & _ ;mov dword ptr , eax<Store the ms responce time>
                        "A1" & SwapEndian($RemoteCode + 430) & _ ;mov eax, dword ptr <Get the status from icmpReply.Status>
                        "A3" & SwapEndian(DllStructGetPtr($pings[$pingID], "status")) & _ ;mov dword ptr , eax<Store the status>
                        "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr <hIcmp>
                        "E80E000000" & _ ;Call 00401088<IcmpCloseHandle>
                        "6A00" & _ ;push 00000000
                        "E801000000" & _ ;Call 00401082<ExitThread>
                        "CC" & _ ;int 03
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "ExitThread")) & _ ;JMP dword ptr<kernel32.ExitThread>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpCloseHandle")) & _ ;JMP dword ptr<ICMP.IcmpCloseHandle>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpCreateFile")) & _ ;JMP dword ptr<ICMP.IcmpCreateFile>
                        "FF25" & SwapEndian(DllStructGetPtr($hPointers, "IcmpSendEcho")) & _ ;JMP dword ptr<ICMP.IcmpSendEcho>
                        SwapEndian(StringToBinary($data)) _ ;This is our ping Data, Max 256 bytes of space here.
                        )
        _MemMoveMemory(DllStructGetPtr($CodeBuffer), $RemoteCode, DllStructGetSize($CodeBuffer))
        Local $aCall = DllCall($hkernel32Dll, "ptr", "CreateThread", "ptr", 0, "int", 0, "ptr", $RemoteCode, "ptr", 0, "int", 0, "dword*", 0)
        Return $aCall
EndFunc   ;==>pingThreaded

;Function _addPing is just for array management of the $pings[] array.
Func _addPing($ip_addr)
        $pings = UBound($pings)
        ReDim $pings[$pings + 1]
        $pings[$pings] = DllStructCreate("char ip[" & StringLen($ip_addr) & "];ulong reply;ulong status;int datasize") ;You could add a timeout struct here
        DllStructSetData($pings[$pings], "ip", $ip_addr)
        DllStructSetData($pings[$pings], "status", $NO_STATUS)
        Return $pings
EndFunc   ;==>_addPing

;Function _removePing is just for array management of the $pings[] array.
Func _removePing($pingID)
        If $pingID > $pings Then Return ;Ensure our ID is valid
        $pings[$pingID] = 0 ;Free the DLLStruct
        _ArrayDelete($pings, $pingID)
        $pings -= 1
EndFunc   ;==>_removePing

;Function _managePings()
;This is where the reply's get sorted out, and actions taken
Func _managePings()
        Local $pingID, $status
        $pingID = 1
        While $pingID <= $pings
                $status = DllStructGetData($pings[$pingID], "status")
                If $status <> $NO_STATUS Then
                        Switch $status
                                Case $IP_SUCCESS
                                        $listcount += 1
                                        ReDim $hostlist[$listcount]
                                        $hostlist[$listcount - 1] = DllStructGetData($pings[$pingID], "ip")
                                        $hostlist[$listcount - 1] = DllStructGetData($pings[$pingID], "reply")
                                        If DllStructGetData($pings[$pingID], "reply") = 0 Then
                                                _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " replied in <1ms" & @CRLF)
                                        Else
                                                _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " replied in " & DllStructGetData($pings[$pingID], "reply") & "ms" & @CRLF)
                                        EndIf
                                Case $IP_REQ_TIMED_OUT
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " timed-out" & @CRLF)
                                Case $IP_DEST_NET_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination network was unreachable." & @CRLF)
                                Case $IP_DEST_HOST_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination host was unreachable." & @CRLF)
                                Case $IP_DEST_PROT_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination protocol was unreachable." & @CRLF)
                                Case $IP_DEST_PORT_UNREACHABLE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The destination port was unreachable." & @CRLF)
                                Case $IP_NO_RESOURCES
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " Insufficient IP resources were available." & @CRLF)
                                Case $IP_HW_ERROR
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A hardware error occurred." & @CRLF)
                                Case $IP_PACKET_TOO_BIG
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The packet was too big." & @CRLF)
                                Case $IP_BAD_REQ
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad request." & @CRLF)
                                Case $IP_BAD_ROUTE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad route." & @CRLF)
                                Case $IP_TTL_EXPIRED_TRANSIT
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The time to live (TTL) expired in transit." & @CRLF)
                                Case $IP_TTL_EXPIRED_REASSEM
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " The time to live expired during fragment reassembly." & @CRLF)
                                Case $IP_PARAM_PROBLEM
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A parameter problem." & @CRLF)
                                Case $IP_SOURCE_QUENCH
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " Datagrams are arriving too fast to be processed and datagrams may have been discarded." & @CRLF)
                                Case $IP_BAD_DESTINATION
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A bad destination." & @CRLF)
                                Case $IP_GENERAL_FAILURE
                                        _UpEditData("Ping with " & DllStructGetData($pings[$pingID], "datasize") & " byte(s) to " & DllStructGetData($pings[$pingID], "ip") & " A general failure. This error can be returned for some malformed ICMP packets or lost network connection." & @CRLF)
                        EndSwitch
                        _removePing($pingID)
                EndIf
                $pingID += 1
        WEnd
EndFunc   ;==>_managePings

Func encodeIP($ip_addr)
        If Not _isIP($ip_addr) Then $ip_addr = TCPNameToIP($ip_addr)
        Local $ip_addr_temp = DllCall("ws2_32.dll", "uint", "inet_addr", "str", $ip_addr)
        Return Hex($ip_addr_temp, 8)
EndFunc   ;==>encodeIP

Func SwapEndian($hex)
        Return Hex(Binary($hex))
EndFunc   ;==>SwapEndian

Func _getIPOctet($ip_addr, $octet = 1)
        Switch $octet
                Case 1
                        Return Int(StringMid($ip_addr, 1, StringInStr($ip_addr, ".")))
                Case 4
                        Return Int(StringMid($ip_addr, StringInStr($ip_addr, ".", 0, 3) + 1))
                Case Else
                        Return Int(StringMid($ip_addr, StringInStr($ip_addr, ".", 0, $octet - 1) + 1, StringInStr($ip_addr, ".", 0, $octet) + 1))
        EndSwitch
EndFunc   ;==>_getIPOctet

Func _isIP($text)
        Return StringRegExp($text, "(((25)|(2)|(1)|(?))\.){3}((25)|(2)|(1)|(?))")
EndFunc   ;==>_isIP

Func _Exit()
        TCPShutdown()
        DllClose($hkernel32Dll)
        Exit
EndFunc   ;==>_Exit



txm888 发表于 2025-9-11 09:58:30

这是因为该群ping只能使用x86编译运行,首行加上:#PRE_UseX64=n就可以了
我也期待有哪个高人能发个支持x64位运行的
:face (1):

3131210 发表于 2025-9-11 17:07:31

编译出来发给别人 肯定都是x86的
页: [1]
查看完整版本: [求助]多线程群PING的问题,部分电脑返回$IP_REQ_TIMED_OUT,是什么原因