DaoVanTrong

MAC Address Finder

Sep 24th, 2025
1,461
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 9.91 KB | Source Code | 0 0
  1. #include <Array.au3>
  2. #include <WinAPI.au3>
  3.  
  4. ;==============================================
  5. ; MAC Address Finder
  6. ; Đào Văn Trong - TRONG.PRO
  7. : Hàm lấy MAC từ IP (LAN) - Phiên bản cải tiến
  8. ; $sIP         : địa chỉ IP
  9. ; $bForce      : True = vẫn cố tìm kể cả không ping được
  10. ; $aExtraPorts : mảng các port TCP bổ sung để thử
  11. ; $iTimeout    : timeout cho mỗi TCP connection (ms)
  12. ; $iRetries    : số lần thử lại
  13. ; $bVerbose    : hiển thị thông tin debug
  14. ;==============================================
  15. Func _GetMACEx($sIP, $bForce = False, $aExtraPorts = Default, $iTimeout = 1000, $iRetries = 2, $bVerbose = False)
  16. Local $sMAC = “”
  17.  
  18. ; Validate IP address
  19. If Not __IsValidIP($sIP) Then
  20.     If $bVerbose Then ConsoleWrite("ERROR: Invalid IP address format: " & $sIP & @CRLF)
  21.     Return ""
  22. EndIf
  23.  
  24. If $bVerbose Then ConsoleWrite("INFO: Starting MAC discovery for " & $sIP & @CRLF)
  25.  
  26. ; 0) Thử ping trước với timeout ngắn
  27. Local $iPingResult = Ping($sIP, 500)
  28. If Not $iPingResult Then
  29.     If $bVerbose Then ConsoleWrite("WARNING: Ping failed for " & $sIP & @CRLF)
  30.     If Not $bForce Then
  31.         If $bVerbose Then ConsoleWrite("INFO: Aborting (force=false)" & @CRLF)
  32.         Return ""
  33.     EndIf
  34. Else
  35.     If $bVerbose Then ConsoleWrite("INFO: Ping successful (" & $iPingResult & "ms)" & @CRLF)
  36. EndIf
  37.  
  38. ; Retry loop
  39. For $iRetry = 1 To $iRetries
  40.     If $bVerbose And $iRetry > 1 Then ConsoleWrite("INFO: Retry attempt " & $iRetry & "/" & $iRetries & @CRLF)
  41.    
  42.     ; 1) Thử SendARP trước
  43.     If $bVerbose Then ConsoleWrite("INFO: Trying SendARP method..." & @CRLF)
  44.     $sMAC = __GetMAC_SendARP($sIP, $bVerbose)
  45.     If $sMAC <> "" Then
  46.         If $bVerbose Then ConsoleWrite("SUCCESS: Found MAC via SendARP: " & $sMAC & @CRLF)
  47.         Return $sMAC
  48.     EndIf
  49.    
  50.     ; 2) Thử ép ARP qua TCP các cổng phổ biến với timeout
  51.     If $bVerbose Then ConsoleWrite("INFO: Trying TCP ARP probing..." & @CRLF)
  52.     Local $aPorts = [135, 139, 445, 3389, 80, 443, 22, 21, 25, 53]
  53.     __ProbePortsForARP($sIP, $aPorts, $iTimeout, $bVerbose)
  54.    
  55.     ; 2b) Thử các cổng tùy chỉnh
  56.     If IsArray($aExtraPorts) Then
  57.         If $bVerbose Then ConsoleWrite("INFO: Probing extra ports..." & @CRLF)
  58.         __ProbePortsForARP($sIP, $aExtraPorts, $iTimeout, $bVerbose)
  59.     EndIf
  60.    
  61.     ; Đợi một chút để ARP table cập nhật
  62.     Sleep(200)
  63.    
  64.     ; 3) Thử lại SendARP sau khi probe
  65.     If $bVerbose Then ConsoleWrite("INFO: Retry SendARP after probing..." & @CRLF)
  66.     $sMAC = __GetMAC_SendARP($sIP, $bVerbose)
  67.     If $sMAC <> "" Then
  68.         If $bVerbose Then ConsoleWrite("SUCCESS: Found MAC via SendARP (after probe): " & $sMAC & @CRLF)
  69.         Return $sMAC
  70.     EndIf
  71.    
  72.     ; 4) Thử đọc từ ARP table
  73.     If $bVerbose Then ConsoleWrite("INFO: Trying ARP table lookup..." & @CRLF)
  74.     $sMAC = __GetMAC_ARP($sIP, $bVerbose)
  75.     If $sMAC <> "" Then
  76.         If $bVerbose Then ConsoleWrite("SUCCESS: Found MAC via ARP table: " & $sMAC & @CRLF)
  77.         Return $sMAC
  78.     EndIf
  79.    
  80.     ; 5) Thử refresh ARP table và đọc lại
  81.     If $iRetry < $iRetries Then
  82.         If $bVerbose Then ConsoleWrite("INFO: Refreshing ARP table..." & @CRLF)
  83.         __RefreshARPTable($sIP)
  84.         Sleep(500) ; Đợi lâu hơn trước retry
  85.     EndIf
  86. Next
  87.  
  88. If $bVerbose Then ConsoleWrite("FAILED: Could not find MAC address for " & $sIP & @CRLF)
  89. Return ""
  90.  
  91.  
  92. EndFunc
  93.  
  94. ;–––––––––––––––––––––––
  95. ; Validate IP address format
  96. ;–––––––––––––––––––––––
  97. Func __IsValidIP($sIP)
  98. Local $aIP = StringSplit($sIP,., 2)
  99. If UBound($aIP) <> 4 Then Return False
  100.  
  101. For $i = 0 To 3
  102.     If Not StringIsDigit($aIP[$i]) Then Return False
  103.     Local $iOctet = Number($aIP[$i])
  104.     If $iOctet < 0 Or $iOctet > 255 Then Return False
  105. Next
  106. Return True
  107.  
  108.  
  109. EndFunc
  110.  
  111. ;–––––––––––––––––––––––
  112. ; Probe multiple ports to trigger ARP
  113. ;–––––––––––––––––––––––
  114. Func __ProbePortsForARP($sIP, $aPorts, $iTimeout, $bVerbose = False)
  115. TCPStartup()
  116.  
  117.  
  118. Local $aConnections[UBound($aPorts)]
  119. Local $hTimer = TimerInit()
  120.  
  121. ; Start all connections
  122. For $i = 0 To UBound($aPorts) - 1
  123.     $aConnections[$i] = TCPConnect($sIP, $aPorts[$i])
  124.     If $bVerbose And $aConnections[$i] <> -1 Then
  125.         ConsoleWrite("INFO: TCP connection attempt to port " & $aPorts[$i] & @CRLF)
  126.     EndIf
  127. Next
  128.  
  129. ; Wait for timeout or connections
  130. While TimerDiff($hTimer) < $iTimeout
  131.     Local $bAnyConnected = False
  132.     For $i = 0 To UBound($aConnections) - 1
  133.         If $aConnections[$i] <> -1 Then
  134.             $bAnyConnected = True
  135.             ExitLoop
  136.         EndIf
  137.     Next
  138.     If Not $bAnyConnected Then ExitLoop
  139.     Sleep(10)
  140. WEnd
  141.  
  142. ; Close all connections
  143. For $i = 0 To UBound($aConnections) - 1
  144.     If $aConnections[$i] <> -1 Then
  145.         TCPCloseSocket($aConnections[$i])
  146.     EndIf
  147. Next
  148.  
  149. TCPShutdown()
  150.  
  151. EndFunc
  152.  
  153. ;–––––––––––––––––––––––
  154. ; Enhanced SendARP with better error handling
  155. ;–––––––––––––––––––––––
  156. Func __GetMAC_SendARP($sIP, $bVerbose = False)
  157. ; Convert IP to network byte order
  158. Local $aIP = DllCall(“ws2_32.dll, “uint”, “inet_addr”, “str”, $sIP)
  159. If @error Or $aIP[0] = 0xFFFFFFFF Then
  160. If $bVerbose Then ConsoleWrite(“ERROR: inet_addr failed for& $sIP & @CRLF)
  161. Return “”
  162. EndIf
  163.  
  164.  
  165. Local $tMac = DllStructCreate("byte[6]")
  166. Local $tLen = DllStructCreate("ulong")
  167. DllStructSetData($tLen, 1, 6)
  168.  
  169. Local $aResult = DllCall("iphlpapi.dll", "dword", "SendARP", _
  170.     "uint", $aIP[0], _
  171.     "uint", 0, _
  172.     "ptr", DllStructGetPtr($tMac), _
  173.     "ptr", DllStructGetPtr($tLen))
  174.  
  175. If @error Then
  176.     If $bVerbose Then ConsoleWrite("ERROR: SendARP DLL call failed" & @CRLF)
  177.     Return ""
  178. EndIf
  179.  
  180. If $aResult[0] <> 0 Then
  181.     If $bVerbose Then ConsoleWrite("WARNING: SendARP returned error code " & $aResult[0] & @CRLF)
  182.     Return ""
  183. EndIf
  184.  
  185. ; Build MAC string
  186. Local $sMAC = ""
  187. For $i = 1 To 6
  188.     If $i > 1 Then $sMAC &= ":"
  189.     $sMAC &= StringFormat("%02X", DllStructGetData($tMac, 1, $i))
  190. Next
  191.  
  192. Return $sMAC
  193.  
  194.  
  195. EndFunc
  196.  
  197. ;–––––––––––––––––––––––
  198. ; Enhanced ARP table reading with multiple patterns
  199. ;–––––––––––––––––––––––
  200. Func __GetMAC_ARP($sIP, $bVerbose = False)
  201. Local $sCmd = @ComSpec &/c arp -a | findstr /i “’ & $sIP & ‘”’
  202. Local $iPID = Run($sCmd, “”, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
  203. ProcessWaitClose($iPID, 5000) ; 5 second timeout
  204.  
  205.  
  206. Local $sOutput = StdoutRead($iPID)
  207. Local $sError = StderrRead($iPID)
  208.  
  209. If $sError <> "" And $bVerbose Then
  210.     ConsoleWrite("WARNING: ARP command error: " & $sError & @CRLF)
  211. EndIf
  212.  
  213. If $sOutput = "" Then Return ""
  214.  
  215. ; Try multiple regex patterns
  216. Local $aPatterns[4] = [ _
  217.     $sIP & "\s+([0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2})", _
  218.     "([0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2}[-:][0-9A-Fa-f]{2})", _
  219.     $sIP & ".*?([0-9A-Fa-f-:]{17})", _
  220.     "([0-9A-Fa-f-:]{17})" _
  221. ]
  222.  
  223. For $i = 0 To UBound($aPatterns) - 1
  224.     Local $aMatches = StringRegExp($sOutput, $aPatterns[$i], 3)
  225.     If Not @error And UBound($aMatches) > 0 Then
  226.         Local $sMAC = StringReplace($aMatches[0], "-", ":")
  227.         $sMAC = StringUpper($sMAC)
  228.         If StringLen($sMAC) = 17 Then ; Valid MAC format
  229.             If $bVerbose Then ConsoleWrite("INFO: Found MAC in ARP table: " & $sMAC & @CRLF)
  230.             Return $sMAC
  231.         EndIf
  232.     EndIf
  233. Next
  234.  
  235. If $bVerbose Then ConsoleWrite("WARNING: No valid MAC found in ARP output" & @CRLF)
  236. Return ""
  237.  
  238.  
  239. EndFunc
  240.  
  241. ;–––––––––––––––––––––––
  242. ; Refresh ARP table by clearing and re-probing
  243. ;–––––––––––––––––––––––
  244. Func __RefreshARPTable($sIP)
  245. ; Clear specific ARP entry
  246. Run(@ComSpec &/c arp -d “ & $sIP, “”, @SW_HIDE)
  247. Sleep(100)
  248.  
  249.  
  250. ; Force new ARP request with ping
  251. Ping($sIP, 1000)
  252.  
  253.  
  254. EndFunc
  255.  
  256. ;–––––––––––––––––––––––
  257. ; Batch function to get multiple MACs
  258. ;–––––––––––––––––––––––
  259. Func _GetMultipleMACs($aIPs, $bForce = False, $aExtraPorts = Default, $bVerbose = False)
  260. If Not IsArray($aIPs) Then Return SetError(1, 0, “”)
  261.  
  262.  
  263. Local $aResults[UBound($aIPs)][2]
  264.  
  265. For $i = 0 To UBound($aIPs) - 1
  266.     $aResults[$i][0] = $aIPs[$i]
  267.     $aResults[$i][1] = _GetMACEx($aIPs[$i], $bForce, $aExtraPorts, 1000, 2, $bVerbose)
  268.     If $bVerbose Then
  269.         ConsoleWrite("RESULT: " & $aIPs[$i] & " -> " & ($aResults[$i][1] <> "" ? $aResults[$i][1] : "Not found") & @CRLF)
  270.     EndIf
  271. Next
  272.  
  273. Return $aResults
  274.  
  275.  
  276. EndFunc
  277.  
  278. ;–––––––––––––––––––––––
  279. ; Demo usage with enhanced features
  280. ;–––––––––––––––––––––––
  281. Func _Demo()
  282. ConsoleWrite(=== Enhanced MAC Address Finder Demo ===& @CRLF)
  283.  
  284.  
  285. ; Single IP with verbose output
  286. ConsoleWrite(@CRLF & "--- Testing single IP ---" & @CRLF)
  287. Local $sMAC = _GetMACEx("192.168.1.1", True, [8080, 8443], 1500, 3, True)
  288. ConsoleWrite("Final result: " & ($sMAC <> "" ? $sMAC : "MAC not found") & @CRLF)
  289.  
  290. ; Multiple IPs
  291. ConsoleWrite(@CRLF & "--- Testing multiple IPs ---" & @CRLF)
  292. Local $aTestIPs[3] = ["192.168.1.1", "192.168.1.10", "8.8.8.8"]
  293. Local $aResults = _GetMultipleMACs($aTestIPs, False, Default, True)
  294.  
  295. ConsoleWrite(@CRLF & "Summary:" & @CRLF)
  296. For $i = 0 To UBound($aResults) - 1
  297.     ConsoleWrite($aResults[$i][0] & " -> " & ($aResults[$i][1] <> "" ? $aResults[$i][1] : "Not found") & @CRLF)
  298. Next
  299.  
  300.  
  301. EndFunc
  302.  
  303. ; Uncomment to run demo
  304. ; _Demo()
Advertisement
Add Comment
Please, Sign In to add comment