代码排版太乱了,帮你扔给AI整理下
#include <Crypt.au3>
#include <File.au3>
#include <FileConstants.au3>
#include <WinAPIFiles.au3>
; 获取脚本的路径
Local $sScriptPath = @ScriptFullPath
; 定义注册表项和名称
Local $sRegPath = "HKLM\Software\Microsoft\Windows\CurrentVersion\Run"
Local $sAppName = "自动黑名单" ; 替换成自己想要的启动项名称
; 检查是否已经在启动项中
If RegRead($sRegPath, $sAppName) <> $sScriptPath Then
; 添加脚本路径到启动项
RegWrite($sRegPath, $sAppName, "REG_SZ", $sScriptPath)
If @error Then
ConsoleWrite("添加启动项失败: " & @error & @CRLF)
Else
ConsoleWrite("已将脚本添加到启动项: " & $sScriptPath & @CRLF)
EndIf
Else
ConsoleWrite("脚本已在启动项中,无需再次添加。" & @CRLF)
EndIf
; 定义要监控的文件路径
Local $sFilePath = "C:\ProgramData\Huorong\Sysdiag\log.db"
Local $sLogFile = @ScriptDir & "\change_log.txt" ; 程序运行目录下的日志文件
Local $sOutputFile = @ScriptDir & "\ip_list.txt" ; 当前脚本运行路径下的 ip_list.txt
Local $sRuleName = "01_外网ip黑名单" ; 修改后的规则名称
ExecuteIPExtractionAndFirewallRule()
; 检查文件是否存在
If Not FileExists($sFilePath) Then
ConsoleWrite("文件不存在: " & $sFilePath & @CRLF)
FileWrite($sLogFile, _Now() & " - 文件不存在: " & $sFilePath & @CRLF)
Exit
EndIf
; 获取初始的 MD5 散列值
Local $sInitialMD5 = _GetFileMD5($sFilePath)
If $sInitialMD5 = "" Then
ConsoleWrite("无法计算文件的 MD5 散列值。" & @CRLF)
FileWrite($sLogFile, _Now() & " - 无法计算文件的 MD5 散列值。" & @CRLF)
Exit
EndIf
ConsoleWrite("初始文件MD5值: " & $sInitialMD5 & @CRLF)
FileWrite($sLogFile, _Now() & " - 初始文件MD5值: " & $sInitialMD5 & @CRLF)
; 进入监控循环
While True
; 获取当前的 MD5 散列值
Local $sCurrentMD5 = _GetFileMD5($sFilePath)
; 检查 MD5 是否发生变化
If $sCurrentMD5 <> $sInitialMD5 Then
Local $sLogEntry = _Now() & " - 文件内容发生了变化。" & @CRLF
ConsoleWrite($sLogEntry)
FileWrite($sLogFile, $sLogEntry)
; 更新 MD5 值
$sInitialMD5 = $sCurrentMD5
; 执行 IP 提取和防火墙规则更新
ExecuteIPExtractionAndFirewallRule()
EndIf
; 每次循环间隔 5 秒钟,避免频繁检测
Sleep(5000)
WEnd
; 函数:计算文件的 MD5 散列值
Func _GetFileMD5($sFilePath)
Local $hHash = _Crypt_HashFile($sFilePath, $CALG_MD5)
If @error Then
Return ""
EndIf
Return $hHash
EndFunc
; 函数:获取当前日期和时间的字符串
Func _Now()
Return @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC
EndFunc
; 函数:执行 IP 提取和防火墙规则添加
Func ExecuteIPExtractionAndFirewallRule()
; 读取整个文件为二进制
Local $hFile = FileOpen($sFilePath, $FO_BINARY)
If $hFile = -1 Then
ConsoleWrite("无法读取文件: " & $sFilePath & @CRLF)
Return
EndIf
Local $sContent = FileRead($hFile)
FileClose($hFile)
; 打开目标文件写入(ANSI 编码)
Local $hOutput = FileOpen($sOutputFile, $FO_OVERWRITE + $FO_CREATEPATH)
If $hOutput = -1 Then
ConsoleWrite("无法创建文件: " & $sOutputFile & @CRLF)
Return
EndIf
; 使用字典来去除重复IP
Local $oDict = ObjCreate("Scripting.Dictionary")
Local $sAllIPs = "" ; 用于存储所有IP的字符串
; 转换二进制数据为字符串
Local $sText = BinaryToString($sContent)
ConsoleWrite("读取的文件内容(部分): " & StringLeft($sText, 100) & @CRLF) ; 输出部分内容用于调试
; 使用正则表达式匹配单个 raddr 中的 IP 地址
Local $aSingleMatch = StringRegExp($sText, '"raddr":\s*"([\d\.]+)"', 3)
For $i = 0 To UBound($aSingleMatch) - 1
Local $sIP = StringStripWS($aSingleMatch[$i], 3) ; 去除前后空白字符
If Not $oDict.Exists($sIP) And $sIP <> "" Then
$oDict.Add($sIP, 1)
ConsoleWrite("提取到的单个IP: " & $sIP & @CRLF) ; 输出到控制台
FileWriteLine($hOutput, $sIP) ; 写入文件
$sAllIPs &= $sIP & "," ; 将IP地址添加到字符串中,用逗号分隔
EndIf
Next
; 使用正则表达式匹配多个 raddr 中的 IP 地址
Local $aArrayMatch = StringRegExp($sText, '"raddr":\s*\[(.*?)\]', 1)
If IsArray($aArrayMatch) Then
; 分割匹配到的IP数组内容
Local $aIPs = StringRegExp($aArrayMatch[0], '([\d\.]+)', 3)
For $i = 0 To UBound($aIPs) - 1
Local $sIP = StringStripWS($aIPs[$i], 3)
If Not $oDict.Exists($sIP) And $sIP <> "" Then
$oDict.Add($sIP, 1)
ConsoleWrite("提取到的数组IP: " & $sIP & @CRLF) ; 输出到控制台
FileWriteLine($hOutput, $sIP) ; 写入文件
$sAllIPs &= $sIP & "," ; 将IP地址添加到字符串中,用逗号分隔
EndIf
Next
EndIf
; 关闭文件句柄
FileClose($hOutput)
; 去除最后一个逗号
If StringRight($sAllIPs, 1) = "," Then
$sAllIPs = StringTrimRight($sAllIPs, 1)
EndIf
; 删除已有的防火墙规则,以避免重复添加
Local $sDeleteCommand = 'netsh advfirewall firewall delete rule name="' & $sRuleName & '"'
ConsoleWrite("删除已有的规则(如果存在): " & $sDeleteCommand & @CRLF)
RunWait(@ComSpec & " /c " & $sDeleteCommand, "", @SW_HIDE)
; 如果存在提取到的IP地址,执行防火墙规则添加
If $sAllIPs <> "" Then
; 生成 netsh 命令,阻止这些IP地址的入站连接
Local $sCommand = 'netsh advfirewall firewall add rule name="' & $sRuleName & '" dir=in action=block remoteip=' & $sAllIPs & ' protocol=any'
ConsoleWrite("执行命令: " & $sCommand & @CRLF)
RunWait(@ComSpec & " /c " & $sCommand, "", @SW_HIDE)
ConsoleWrite("IP地址已添加到防火墙,规则名称为: " & $sRuleName & @CRLF)
Else
ConsoleWrite("没有提取到有效的IP地址。" & @CRLF)
EndIf
ConsoleWrite("IP地址提取完成,已保存到: " & $sOutputFile & @CRLF)
EndFunc
|